Python Tutorial Section 2

Section 1 was pretty easy, but maybe section 2 will present a better challenge.

How are modules imported and called?

In Python, if one wishes to use a module, they must import the module first. I've known this to be true in many cases, but something I didn't know (and this might just be in Python) is that it creates a module object! You then make calls on that object using dot notation.

#Example with the math module
>>> import math
>>> print math
<module 'math' from '/usr/lib/python2.5/lib-dynload/math.so'>  
>>> answer = math.sqrt(4)
2.0  

Python Function Syntax

Python functions must have a set of parentheses, whether there are arguments or not. Also, to close a Python function (or any block for that matter), one just leaves a blank line. Again, this is an instance of Pythons dependency on white space.

Stack Diagrams

As is the case with most languages I've worked in, variables within functions are scoped to the function.

In order to help manage where variables are, one can draw a stack diagram. They look something like this:

#__main__
line1 => 'Bing tiddle'  
line2 => 'tiddle bang.'  
#cat_twice
part1 => 'Bing tiddle'  
part2 => 'tiddle bang.'  
cat => 'Bing tiddle tiddle bang.'  
#print_twice
bruce => 'Bing tiddle tiddle bang.'  

These are lined up in order in which they're called. The firstmost element in a stack diagram is called __main__.

How do you debug a series of function calls?

When there is an error in a Python program, it will trace back through the program and output the tracback.

What makes a function fruitful?

  • fruitful_functions yield a result which can then be saved to a variable
  • void_functions do not return a result but might still print a value but it is lost forever!

Fruitful functions must have a return statement! In Ruby, this return is implicit and will return the last line that was executed. In Python, you have to explicitly state what you're returning, and the function will terminate upon execution of the return.

Creating my own Module

For starters, I decided I didn't want to rewrite my check_answer function, so I moved it into a module of it's own. Importing this module required some Googling but I figured out how to add the module folder to my sys path for my python scripts:

import sys  
import os.path  
sys.path.append(os.path.join(os.path.dirname(__file__), '../modules/'))

import checkers  

Though I'm sure there is a simpler way...but onto the actual work!

Nested Functions & Stack Diagrams

It was slightly tricky to remember that a function isn't called when it's declared. The use of (at least mental) stack diagrams was helpful here. Remembering to think of the flow of each function call, for example:

#__main__
x = 12  
#g
x = 12  
x = 13 #overwritten within g  
#h
x = 13  
y = 6  

Returns 6 + 13 = 19!

Something that does worry me is that it isn't totally clear whether the variables being called by these nested functions are necessarily always going to be available. I think they are within the scope of the function because they're declared IN the function. If they were two seperate functions though, I don't think these would work necessarily, and it doesn't ever address that during the chapter on scoping.

Conditional Nuances

Only neat item here is that rather than using a bang like you would in Ruby, you simply write not to assert the opposite of a bool. I like the fact that the question also prompted you to return the value directly rather than use an if...else statement! No sense in wasting extra lines of code.

Geometry + Python

This one was a throwback to geometry! The big hint we got was that the shortest distance was on a line that is perpendicular to our given line (which should have been obvious). With that in mind, we can find the perpendicular line's equation. Then we know the two lines will intersect when their y's and x's are the same! When plugged back into the original equation for the line, we can find the point which is closest to our point, and simply find the distance between those two with our distance equation from 2.2.5.

Solutions can be found on github