Lab 2: Computing the Day of the Week

Objectives

In this lab you will write a non-trivial Python script to print out the current day of the week in Williamstown. In doing so, you will gain experience with the following:

  • Define and call functions.

  • Use arithmetic operators in Python.

  • Test your code in interactive Python.

  • Write conditional (if else) statements to make decisions in your code.

time() Solves All Problems

All computers keep track of time. On Unix machines time is represented by the number of seconds after the end of the 1960s (the “Epoch”). The first moments of Thursday, January 1, 1970 had a time less than 1, the first minute had time values less than 60, and the first hour had times less than 3600. The value that represents the current time is a much bigger number.

In Python, we can access this value—understood to be the current time in Universal Coordinated Time, or UTC, in England—through the time() function, which is found in the time module. You can use it in the following way, once you’ve entered interactive Python by typing python3 in the terminal window and pressing enter.

>>> from time import time
>>> time()
1612800680.9091752

The result of calling time is a float value, with the fractional component representing the time after the second. This value is, on most machines, accurate to the millionth of a second.

In this lab, we’ll only be using the integer part of this value, which we can extract using the int() function:

>>> now = int(time())
>>> now
1612800680

In the above example, we’re taking the current time and storing just its integer part in a variable, now.

Exiting Interactive Python

You can quit out of interactive Python by typing exit() or Ctrl + D

Understanding Remainders and Modulo

If a and b are integers, then when we compute a // b the result is always an integer. We can compute the remainder, r, of this integer division with the modulo (%) operation: r = a % b. This is also precisely the amount needed to bring (a//b) * b back up to a.

When a and b are integers, the result of a % b is one of the b possible integer remainders: 0, 1, ..., b-1. This is very convenient if we want to take a large randomly selected integer and reduce it one of a very small range of values.

Our Algorithm

Now let’s apply this to our time value to solve our problem. Suppose, for example, we compute the remainder (%) when a time, now, is divided by 60. The result is a value between 0 and 59 representing the number of seconds past the current minute. Similarly, when we divide a time value by 60—using integer division (//)—the result is the number of minutes since the Epoch (Jan 1, 1970).

Continuing the example from above (where now = 1612800680), we see now must have been captured at 20 seconds past the minute, and 26,880,011 minutes since the Epoch:

>>> secs = now % 60
>>> secs
20
>>> mins = now // 60
>>> mins
26880011

Armed with this info, you might now see that it’s possible to keep dividing to compute the number of hours and whole days that have elapsed since the Epoch. The remainder at each step is the portion of the day that can be accounted for by the hours, minutes, and seconds since midnight, although we don’t really need all of those values. Further, once we know the number of days, we can easily continue dividing to compute the number of whole weeks that have passed, and the remainder is simply the number of whole days since “the beginning of the week”.

For example, once we know that 18666 days have passed, it’s then possible to figure out how many whole weeks have passed (2666), and the remainder (4) is the number of whole days that have passed after “the beginning of the week.” Note that since January 1, 1970 fell on a Thursday, this method treats Thursday as “weekday 0”, Friday as “weekday 1”, etc. Since the remainder is 4 in our example, it suggests the weekday associated with now is Monday.

Because we would like to have the logical start of the week (“weekday 0”) happen on Sunday instead of Thursday, we can adjust the time value, measured as the number of seconds since Thursday, January 1, 1970, to be, instead, the number of seconds from Sunday, January 4, 1970. If we make this correction, then the final remainder, as computed above, would be 1 instead of 4. Again, that suggests it’s a Monday (“weekday 1” in this adjusted system). Using this algorithm, you should be able to solve today’s lab problem!

Getting Started in Lab

You’ll need to follow a few steps to begin working on our lab machines. These are similar to what your did to set up your own machine, but simpler since all of the software has already been installed.

  1. Open the Terminal — on the lab machines, the Terminal application is identified by a > symbol and should be in the dock.

  2. Type the following commands into the shell, replacing Ephelia Williams’s name and email with your own:

    git config --global user.email 'ew5@williams.edu'
    git config --global user.name  'Ephelia Williams'
    git config --global push.default simple
    git config --global pull.rebase false
    git config --global core.editor nano
    
  3. Now we’ll set up your cs134 directory on our machines, similar to how you set up your machine, using the make directory (mkdir) command:

    mkdir cs134
    
  4. Descend into the cs134 directory using the change directory (cd) command:

    cd cs134
    
  5. Now we must retrieve the files we need to complete this week’s lab. Log on to https://evolene.cs.williams.edu using your CS credentials. Under Projects, you should see a repository named cs134-labs/22xyz3/lab02 where 22xyz3 is your CS username which contains the starter files for this week’s lab.

  6. Clone the repository: find the blue button that is a drop-down menu that says Clone. Click on it and click on the “clipboard” icon (Copy URL) option next to Clone with HTTPS.

    Return to the Terminal application and type git clone followed by the URL of the lab project you just copied (you can paste on Mac by pressing Command-V). This should look exactly like the following:

    git clone https://evolene.cs.williams.edu/cs134-labs/22xyz3/lab02.git
    

    where 22xyz3 is a place holder for your CS username.

  7. Navigate to your newly created lab02 subdirectory in the Terminal:

    cd lab02
    
  8. Explore the contents of the directory using the ls command in the Terminal.

  9. Open Atom, go to File menu option, and choose Add Project Folder, and navigate to your lab02 directory and click Open. You should see the starter files of today’s lab, including day.py, on the left pane of Atom.

Today’s Tasks

We would like you to write several functions that will, eventually, allow us to determine today’s day-of-week. Please write your code as a script in the file called day.py, which we have included as part of the starter code in the lab02 directory.

  1. First, write a function, UTCDay(timeval). This function takes a floating point number, timeval as a parameter, where timeval is the number of seconds since the Epoch. Remember you need to convert timeval to an integer. UTCDay(timeval) should return the number of the day of the week, where Sunday is 0, Monday is 1, etc. Refer to the algorithm above for help.

    You can test your function interactively. In the Terminal, type python3 to enter an interactive Python session. You need to first import the function definition as shown below:

    >>> from day import UTCDay
    >>> UTCDay(1612800680)  # the UTC date, discussed above
    1
    >>> UTCDay(345600)      # 00:00:00, Monday, January 5, 1970
    1
    >>> UTCDay(345599)      # 23:59:59, Sunday, January 4, 1970
    0
    

    Here’s how you might find the current day of the week in England (UTC+0 time):

    >>> from time import time
    >>> UTCDay(time())
    ...
    

    Exit Interactive Python after Changing Code

    If you make changes to your function in Atom, you must first quit out of interactive Python by typing exit() or Ctrl + D, and restart a new interactive Python session by typing python3 to test your updated function.

  2. Write a function localDay(timeval, offset) that calls UTCDay to help compute the current day of the week for a timezone that is offset (a floating point value) hours ahead of UTC. In Williamstown, the offset is -5. That means the actual time is 5 hours, or 18000 seconds, earlier than that reported by time(). Here are some well-know locales and their UTC offsets:

    Locale

    UTC Offset

    Locale

    UTC Offset

    Chatham Island

    12.75

    Reykjavik

    0

    Aukland

    12

    Cape Verde

    -1

    Solomon Islands

    11

    South Georgia Island

    -2

    Vladivostok

    10

    São Paulo

    -3

    Tokyo

    9

    Corner Brook

    -3.5

    Hong Kong

    8

    Santiago

    -3

    Jakarta

    7

    Kalamazoo

    -5

    Rangoon

    6.5

    Easter Island

    -5

    India

    5.30

    Phoenix

    -7

    Karachi

    5

    San Francisco

    -8

    Abu Dhabi

    4

    Ancorage

    -9

    Nairobi

    3

    Honolulu

    -10

    Cairo

    2

    Midway Atoll

    -11

    Paris

    1

    Baker Island

    -12

    Positive offsets are an indication that a new day begins that much earlier in these locations—all east of England—while negative offsets indicate a later end to the day—all to the west. (Some of these may be different when Daylight Savings Time applies…)

    For example, your function localDay should behave as follows when tested interactively.

    >>> from day import localDay
    >>> localDay(345000, 0)     # 23:50, Sunday, January 4, 1970, in London
    0
    >>> localDay(345000, +1)     # 00:50, Monday, January 5, 1970, in Paris
    1
    >>> from time import time
    >>> localDay(time(), -5)    # current time in Williamstown
    ...
    

    This offset could be a float because some timezones involve corrections that are partial hours. Remember to convert hours to seconds before adjusting your timeval.

  3. Write a function, dayOfWeek(day), that takes an integer between 0 and 6 (inclusive) and returns the name of that day as a string. You should use conditional (if else) statements to accomplish this. For example, your function dayofWeek() should behave as follows when tested interactively.

    >>> from day import dayOfWeek
    >>> dayOfWeek(1)
    'Monday'
    >>> dayOfWeek(6)
    'Saturday'
    
  4. You are now ready to use your functions to print the current day in Williamstown.

    To run day.py as a script (instead of being tested in interactive Python), replace the remaining pass statement in day.py with the following code block.

    (We will discuss what this is doing in upcoming lectures. For now, just type it into your program.)

    if __name__ == "__main__":         # run as a script?
        now = time()                   # UTC time
        dayNumber = localDay(now, -5)  # Eastern day of week number
        dayName = dayOfWeek(dayNumber) # get day name
        print("It's "+ dayName +"!")   # print it out
    

    To run the Python program day.py as a “script”, exit out of interactive Python, and in the Terminal type python3 day.py. If it is Monday, then you should get the following output ($ represents the prompt in your Terminal).

    $ python3 day.py
    It's Monday!
    

    This should work when run at any time of the day!

  5. Thoroughly test your code before you turn it in. In particular, each of the little tests you have seen in this document should generate the indicated answers. You might think about what kinds of mistakes one could make in writing the above functions, and write tests that prove to yourself you didn’t introduce those mistakes. This is an important skill we will develop as the semester progresses.

Submit Your Work

  1. When you are finished adding your functions to the script day.py, make sure you add and commit your work.

    git add day.py
    git commit -m "Lab 2 completed"
    

    Then you can the push your work (remembering to start the VPN if you’re working from off campus):

    git push
    
  2. You can, if you wish, check that your work is up-to-date on https://evolene.cs.williams.edu. Another way to check that you have committed and pushed all your changes is through the Terminal. In the Terminal in your lab02 directory, type git status:

    git status
    

    It should show your changes in green that have not been committed, and files in red (if any), that have not been added. If you have successfully committed and pushed all your work, it should say so.

  3. Please edit the README.md file and enter the names of any such students on the Collaboration line. Commit and push this change.

  4. Gradesheet.txt gives a breakdown of the rubric you will be graded on for this lab. When graded, this file will contain the feedback as well.