Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding semester_dates function #58

Merged
merged 1 commit into from
May 26, 2017
Merged

Conversation

shex1627
Copy link
Member

A utility function for the semester job distribution chart.

1.I thought of making spring_start and fall_start constants but "year" would be a variable that later I have to fix, which I think will make the code harder to understand unless you guys have some better solutions.

Copy link
Member

@abizer abizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why subtract one day and why switch the order if it's before August?

@shex1627
Copy link
Member Author

shex1627 commented Mar 12, 2017

So the logic is:
from 01/01 to 07/31 is considered "spring"
and 08/01 to 12/31 is considered "fall"

Basically you have one day, and you expand that day to the semester start and semester end. Subtracting one is to make sure the fall and spring don't overlap.

@abizer
Copy link
Member

abizer commented Mar 12, 2017 via email

if day.month < 8:
return (spring_start, fall_start - one_day)
else:
return (fall_start, spring_start - one_day)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be the spring_start of the next year

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is part of the SQLquery for the jobs, so not exactly the academic year.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry Kevin I was wrong. Do you have any better way of fixing this?
My current proposal is

if day < fall_start:                                           
    return (spring_start, fall_start - ONE_DAY)                  
else:                                                              
    return (fall_start, spring_start.replace(year=day.year+1) - ONE_DAY)

day = date.today()
spring_start = date(year, 1, 1)
fall_start = date(year, 8, 1)
if day.month < 8:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would've written it if day < fall_start, I think that's more intuitive...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested, and it works. Originally I was concerned that we can't compare day with fall_start and I was lazy to figure that out.

Copy link
Member

@matthew-mcallister matthew-mcallister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a fine change save for some minor things. Please don't merge without rebasing though; if you need help with that, just ask. PROTIP: Never do merge master; always rebase master.

@@ -79,6 +79,22 @@ def current_semester_start():
return today.replace(month=1, day=1)


def semester_dates(day=None):
"""Return a tuple (start day, end day) for the current semester.
Defaults to today if none is provided.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put a newline before this line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which line(number)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be

"""Return a tuple (start day, end day) for the current semester.

Defaults to today if none is provided.
"""

spring_start = date(year, 1, 1)
fall_start = date(year, 8, 1)
fall_end = date(year, 12, 31)
if day < fall_start:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will error if you give it a datetime object. Can you replace this with something like

if date(day.year, day.month, day.day) < fall_start:

to implicitly convert datetime to date?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if day.month < fall_start.month:

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not assume it starts/ends on a month if we can avoid it, though that is currently the case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good try, but I think @chriskuehl is right.

@matthew-mcallister
Copy link
Member

Also, can you add a simple test for this? Not really sure what would be good. Maybe just pick a couple dates that you think should be in the same semester and test that they return the same tuple?

@shex1627
Copy link
Member Author

commented so that you guys can see the new commit.

def test_semester_dates():
assert semester_dates() is not None
assert semester_dates(date(2016, 1, 1)) == (date(2016, 1, 1), date(2016, 7, 31))
assert semester_dates(date(2017, 12, 30)) == (date(2017, 8, 1), date(2017, 12, 31))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the tests.

year = [day.year]
if [day.month, day.year] < FALL_START:
return (date(*(year + SPRING_START)),
date(*(year + SPRING_END)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why all this list arithmetic? Just make SPRING_START etc. namedtuples or dates and do

return (date(year, SPRING_START.month, SPRING_START.day), date(year, SPRING_END.month, SPRING_END.day))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I use python Date object then I have to use a dummy attribute 'year' since teach year is difference.

#maybe we will use that in the future
DUMMY_YEAR = 1000
SPRING_START = date(DUMMY_YEAR, 1, 1)
# ...
return (date(year, SPRING_START.month, SPRING_START.day), 
date(year, SPRING_END.month, SPRING_END.day))

if I use namedtuples then any other files that use those constants may have to import the 'collection' library.

from collections import namedtuple
Date_No_Year <- namedtuple('month', 'day')
SPRING_START = Date_No_Year(1, 1)

Do you like the dummy_year implementation better or creating a new structure using namedtuple?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say pick one of them and go with it. Both approaches have their own drawbacks.

If you go with the dummy attribute route, note that you can use the replace method on a date object to simplify your code.

If you create a new namedtuple, note that you can do something like this:

return (date(year, *SPRING_START), date(year, *SPRING_END))

@@ -79,6 +83,22 @@ def current_semester_start():
return today.replace(month=1, day=1)


def semester_dates(day=None):
"""Return a tuple (start day, end day) for the current semester.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably meant "for the semester containing the given day"?

if day is None:
day = date.today()
year = [day.year]
if [day.month, day.year] < FALL_START:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean day.day instead of day.year?

@kpengboy
Copy link
Member

While you're at it, you can rewrite the current_semester_start() function to call semester_dates instead.

@shex1627
Copy link
Member Author

New revision updated. Why is Kevin so good at detecting logical bugs?

@shex1627
Copy link
Member Author

could anyone have a look at this?

Copy link
Member

@matthew-mcallister matthew-mcallister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the one comment, please make sure to rebase your branch so we don't pull in your merge commit. As a reminder, you should rebase instead of merging to update your own branch.

@@ -13,6 +13,14 @@
# when we started keeping stats
STATS_EPOCH = date(2014, 2, 15)

# constants for semesters dates
# dummy year variable
DUMMY_YEAR = 1000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any reason to name this constant (and superfluous constants pollute the namespace). How about just leaving a comment? For example,

# The year is a placeholder; we only care about month and day.
SPRING_START = date(1, 1, 1)

SPRING_START = date(DUMMY_YEAR, 1, 1)
SPRING_END = date(DUMMY_YEAR, 7, 31)
FALL_START = date(DUMMY_YEAR, 8, 1)
FALL_END = date(DUMMY_YEAR, 12, 31)
Copy link
Member

@chriskuehl chriskuehl Apr 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels really weird, what about just doing

import functools
from datetime import date

spring_start = functools.partial(date, month=1, day=1)
spring_end = functools.partial(date, month=7, day=31)
fall_start = functools.partial(date, month=8, day=1)
fall_end = functools.partial(date, month=12, day=31)

then later instead of doing SPRING_START.replace(year=2017) just do spring_start(year=2017)

@shex1627
Copy link
Member Author

@chriskuehl I use your functool solution, but also rename constants to be like FALL_START_FUN so that others know they are not date objects when they want to use them.

else:
return today.replace(month=1, day=1)
return (FALL_START_FUNP(year=day.year),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be fall_start but it doesn't really matter.

SPRING_START_FUNP = functools.partial(date, month=1, day=1)
SPRING_END_FUNP = functools.partial(date, month=7, day=31)
FALL_START_FUNP = functools.partial(date, month=8, day=1)
FALL_END_FUNP = functools.partial(date, month=12, day=31)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are functions, why are they uppercase? they're not constants.

you don't need the FUNP suffix to mark them as functions if you just name them like functions :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although those are functions but I think the names could be misleading for people to think they are date objects. Do we need to do anything about that? Or You don't think it is a problem at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the name should indicate that these objects are callable. How about using a verb in the name? E.g. get_fall_start or even fall_start_for_year.

Copy link
Member Author

@shex1627 shex1627 Apr 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those functions are not callable but simply a function that takes the year as argument to return a date object. I think fall_start_funp is a decent option, at least people would get confused and lookup where the variables are defined.

By that standard, the dummy-year-date-constant implementation is not a bad alternative.

@abizer
Copy link
Member

abizer commented Apr 30, 2017 via email

@shex1627
Copy link
Member Author

shex1627 commented Apr 30, 2017

renaming all those function partials to get_xxx_xxx, so are we ready to merge now?

get_spring_start = functools.partial(date, month=1, day=1)
get_spring_end = functools.partial(date, month=7, day=31)
get_fall_start = functools.partial(date, month=8, day=1)
get_fall_end = functools.partial(date, month=12, day=31)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it, these should probably be prefixed with _.

@shex1627
Copy link
Member Author

adding prefix "_" to the functions

Copy link
Member

@matthew-mcallister matthew-mcallister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I think this is finally ready to be shipped. Unless someone objects, I will squash and merge this today.

Thanks for your work, @shex1627. I know it isn't easy pleasing all these picky reviewers.

@shex1627
Copy link
Member Author

do you guys want me to squash the commits as well

@matthew-mcallister
Copy link
Member

Oh, it looks like the squash and merge button isn't available. You can if you want, otherwise I will.

@shex1627
Copy link
Member Author

I will mess with my local repo see if I can do it myself first. Can't rely on others every time

@shex1627
Copy link
Member Author

Seems like I did it(squash the commits) guys
Not sure if the standard way
first
git reset --soft HEAD~9 && git commit
git push --force origin semesterJobUtil

@matthew-mcallister
Copy link
Member

shipit

@shex1627 shex1627 merged commit 568fca3 into ocf:master May 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants