I am working on a personal project using Python. I have been using version control to the best of my abilities and if you would like to check it out and run the app https://github.com/CodeAmend/old-bull-tools/tree/develop
If you prefer Floobits, look at my actual code in a editor here: https://floobits.com/CodeAmend/old-bull-tools/file/app.py:1
I have been learning version control with this project and I have been trying to use TDD with the best of my abilities. Currently opening of the Test_Schedule class, it has been hard to write test methods.
A short slice of what I am trying to do: I am building an api that handles a scheduling system. This will communicate with the web as well as mobile devices. Users sign in and can check their schedule, change dates to view other scheduled times and also pick the amount of information displayed (i.e. only show servers or kitchen staff, daily view, month view, calendar view).
So here is the question: How would one build a schedule object? How should I visualize this? What types of questions should I ask myself to help me move forward? It seems that I need to user information from both user and shift to populate the schedule.
Right now I am stuck. And this is because I have two objects: User and Shift. Now I am thinking I should make a schedule object.
a User contains _id(user_id), name, email....
a Shift contains a _id, user_id, start_time, stop_time
In order to display this stuff on the front end, I need to populate a schedule. Kinda like this:
# mon tues weds thurs fri sat
# user1 4:00 ____ 6:00 4:00 5:00 6:00
# user2 4:00 5:00 6:00 ____ 5:00 6:00
This is only an example but from the look of this, I might need Schedule to return something like this (Shift, None, Shift, Shift, None, Shift)
This is some test cases in my shift object
def test_create_shift(self):
def test_shift_throws_error_if_time_is_not_int(self):
def test_save_shift_to_database(self):
def test_get_shifts_by_id(self):
def test_get_shifts_within_date_range_by_id(self):
def test_get_shifts_on_specific_date_by_id(self):
def test_get_shifts_before_end_time_by_id(self):
def test_get_shifts_after_start_time_by_id(self):
def test_get_shifts_exactly_on_start_date_by_id(self):
def test_get_shifts_exactly_on_end_date_by_id(self):
def test_get_current_weeks_shifts_by_id(self):
Here is my thought process so far:
schedule = Schedule(user_id) <---- no range added
test_no_range_added_returns_this_weeks_shifts_for_user()
assertEquals(len(schedule.shifts), 7)
test_user_with_no_shifts_returns_none_for_each_day_in_range()
for i in range(schedule.shifts):
assertEqual(schedule.shifts[i], None)
This is the most current for of thinking. A schedule is just one row, so basically one user. Schedule has Shifts and a User. Multiple Schedules are loaded to populate all employees. Perhaps Schedule is not the best name, but I am not sure yet.
1 Answer 1
Here's my idea:
class User(object):
"""A user of the scheduling system."""
def __init__(self, name, email):
self.name = name
self.email = email
class Shift(object):
"""
A user's shift.
Does not represent an actual date, only the start and end hours.
"""
def __init__(self, start, end):
self.start = start
self.end = end
class Schedule(object):
"""
A schedule is made out of multiple date objects, linking
these dates to multiple users, and their shifts.
"""
def __init__(self):
self.shifts = {}
def set_user_shift(self, date, user, shift):
try:
self.shifts[date]
except KeyError:
self.shifts[date] = []
self.shifts[date].append({'user': user, 'shift': shift})
Basically, a User is simply a user, and a Shift is simply a definition of start and end hours. The Schedule is the more interesting part: it is made out of multiple possible dates, and each date may have multiple users, each user linked to its respective shift on that date.
As others have said, in general you want to feel and work on the software until nothing is too coupled. The presentation(printing) really doesn't have much to do with the data, and the IDs aren't required to be thought about until you start thinking about the database.
When trying to understand the domain model, it's generally good advice to ignore the other components of the software for that moment. When you have a stronger idea of what you're trying to do, then you can start thinking about the rest. Just as objects and functions shouldn't be too coupled, so must not be our ideas of them.
Explore related questions
See similar questions with these tags.
Schedule
from the way it is displayed. TDD tests rarely verify formatting, instead they probe the properties of an object. Code katas and coding exercises might be an exception though.user
have more than one shift per day? If so, the signature for yourSchedule
idea would have to change. It also sounds likeSchedule
is a service API.