Python 102 Appendices

Some more information on various topics. See the table of contents:

Dates and Times and Timezones

Note. Dates and times are a lot more complicated than you might think, and the example in this section took me longer to write and debug than I care to admit. I urge you to avoid wrestling with dates and times if you can avoid it. Feel free to skip this if you don't care about dates, times, and timezones.

Here's an example of Armistice Day which happened on "eleventh hour of the eleventh day of the eleventh month" of 1918.

import datetime

armistice_date = datetime.date(1918,11,11) # year, month, date
armistice_time = datetime.time(11,0,0)      # hour, minute, sec
armistice_both = datetime.datetime(1918,11,11,11,0,0)

def print_time(dt):
    print(dt.strftime('%A %B, %d, %Y at %H:%M %p in %Z'))

both = armistice_both # shorthand
print_time(both)

utc = both.replace(tzinfo=datetime.timezone.utc)
print_time(utc)

local = utc.astimezone()
print_time(local)

Here's the output of that code when I ran it on Tempest, which is in the Eastern time zone:

Monday November, 11, 1918 at 11:00 AM in 
Monday November, 11, 1918 at 11:00 AM in UTC
Monday November, 11, 1918 at 06:00 AM in EST

The print_time function uses the strftime method on datetime objects to print it. There are a ton of these % format codes This particular string shows the day of the week, as as string in the local language, the name of the month, the date of the month, the hour and minute with am/pm, and lastly, the timezone.

The both variable (a shorthand for armistice_both) is what Python calls a "naive" datetime object: it doesn't know what time zone it's in. That can be fine in many cases, say where all users of the app are in the local time zone and time zone doesn't matter. In more general cases, this can be a problem.

The utc variable has what's called an "aware" datetime object: it knows it's timezone. The Armistice was signed in France, but I'm unable to determine what timezone is suggested by the phrase "11th hour", so I'm going to use UTC (GMT) for this example.

The local variable is also an "aware" timezone, but this value is modified from utc to the local time zone. For me at the time of this writing, that's EDT. So, when it's printed as a local time, the Armistice happened at 6am EST.

File I/O

TODO: write this section

Standard Error

You know the print function in Python. It prints to the terminal. Let's kick that knowledge up a notch.

You can easily imagine two kinds of print statements: normal output and error messages. Let's start with a very simple example, namely a function that prints a series of N random numbers between two values, a min and a max. (Maybe it's useful for certain games or something.)

import random

def random_numbers(count, min, max):
    for i in range(count):
        num = random.randint(min, max)
        print(num)

This works, but some callers mis-use this function, so we need to add some error checking:

import random

def random_numbers(count, min, max):
    if max <= max:
        print('max must be greater than min, but {max} < {min}'
              .format(max=max, min=min))
    for i in range(count):
        num = random.randint(min, max)
        print(num)

(If the format method is confusing, remember that we are using named placeholders, like {max}, so the keyword arguments say that the placeholder max will be filled in with the value of variable max and similarly for min. You could, of course, name the placeholders differently, if that's less confusing.)

But clearly those are different kind of print statements.

Why does it matter? We are assuming that the user is looking at the results and will be able to tell the difference.

But sometimes, we want to put the output of our programs into a file.

TODO: Say more about this.

Decorators

Python allows you to do fancy things to a function using decorators. A decorator is a function that takes another function as its argument, and does something to it. Flask uses decorators as an interface between the functions that we define and its infrastructure, such as figuring out which function to call to handle some request.

Actually defining decorators is even more advanced than "Python 102". So you should certainly punt on this concept if you want. But if you're intrigued, especially if you took CS 251 (Programming Languages), and you like that kind of stuff, you should definitely learn them, because they're way cool.

More about python decorators

That link was just the top Google link when I searched, and it seems good, but if you find a better one, let me know.

Other?

If there's something you'd like me to say more about, let me know.