5

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.

  • It is really hard to get an answer for this. It really is asking abstract ideas. Any time of help would be appreciated. – Michael Bruce Feb 23 '16 at 18:19
  • 2
    Is this an exercise or a real project ? Maybe you are too obsessed with the way the schedule table looks like. In real life, you should try to separate 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. – guillaume31 Feb 26 '16 at 8:01
  • This is a real project, but it is my personal project. Just to be clear, I am not too concerned with the way the table looks. I just want to be able to put in a range and the api spits out shifts for that user. So lets say I want Monday to Wednesday and the user does not work Tuesday it would return (Shift, None, Shift) Schedule would output that info for the frontend. Not sure if I am thinking of this wrong. It would be awesome to find another project where someone actually created some sort of schedule. – Michael Bruce Feb 26 '16 at 17:41
  • I updated my question at the bottom, with some current thoughts. – Michael Bruce Feb 26 '16 at 17:57
  • Some of this sounds as though you may be confusing your domain model with your data model. I would take a ground-up database-style approach here. What are your entities? What are their relationships to one an other? What is the cardinality of those relations? For example, can a user have more than one shift per day? If so, the signature for your Schedule idea would have to change. It also sounds like Schedule is a service API. – Tersosauros Mar 14 '16 at 14:38
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.