An Introduction to Python for new Programmers

Welcome to An Introduction to Python for new Programmers! This iPython notebook serves as an instructor-led guide to the Python programming language, particularly for those who are new to programming or have very limited programming experience. iPython notebooks are a novel form of communicating about programming; creating an environment where both text and live code can be executed in an explanatory fashion. Parts of this document will contain live Python code that is interpreted by the notebook and whose output will be rendered directly to the screen. If you would like to follow along on your laptop, you can install iPython and download this workbook from github/DistrictDataLabs/intro-to-python.

Before we get Started....

Prerequisites:

Although this is an introductory course, some prerequisites are required.

  1. The student must have Python installed
  2. Must be familiar with using Python on his or her operating system.
  3. They must also have familiarity with the command line.

The following are suggested tasks to perform before this course:

Installations:

For Windows Users:

Download the course materials from GitHub

Learning how to Learn how to Code

So, let's be clear- what can we accomplish in a two to three hour session? Obviously we're not going to make you an expert programmer in this time, nor are we going to impart a comprehensive theory of programming.

However, there is one fundamental concept about programming that I would like ensure you all take away: programming isn't about knowing syntax it's about learning. Therefore, what were going to try to enable you to do today is help you learn how to learn how to code.

In order to continually improve his or her craft, a programmer must constantly be in a state of education. From reading about new programming paradigms, languages, or frameworks to experimental approaches to reading other's code- programming is is a community activity that encourages the sharing of ideas.

In particular we'll focus on clear expression of code and readability. By ensuring you can write code in a readable form, it will help you to read other's code as well!

Getting Started

Let's start by using the interactive interpreter to run the most basic of programs, "Hello World!" This interactive interpreter is also called the "REPL" or the Read Evaluate Print Loop.


In [ ]:
print "Hello World!"

The REPL is often used during program development. Let's try running this same basic program from a file. This is called a script or a program that is run from the command line (terminal). That first line is called the "hash bang." Put simply, it indicates that the file can be run as a script.


In [ ]:
#!/usr/bin/env python

print "Hello World!"

Output and Input


In [17]:
#  This is writing to standard out:

print "Python is awesome!"


Python is awesome!

In [19]:
#  Basic input (These values will always be interpreted as strings)

name = raw_input("What is your name?")
print name


What is your name?sarah
sarah

What is Programming?

Programming is the act of creating a set of instructions to transform input data to some kind of output.

Yeh- it's that simple. We're making recipes of ingredients and instructions.

However, instead of food, we cook with numbers and strings. The instructions are defined as a formal language.

The instructions are interpreted and executed from top to bottom, and when the interpreter runs out of instructions, the program is done!

The interpreter is what takes your code instructions and translates them into something that your computer understands.

Because of this python is called an interpreted language or a scripting language.

Variables

Variables should follow some simple rules.

  • be lowercase
  • use underscores for word separation
  • not start with numbers

In fact Python has it's own language style guide called PEP8.

Consider the following simple program. This small program for computing the area of a triangle includes quite a few components:

  • Comments (#)
  • Assignment (a = 2)
  • Variables (base)
  • Multiplication (*)
  • Output
    (print)

In [4]:
# Compute the area of a triangle

# Ingredients  (aka: variables)
base   = 4  
height = 7

# Instructions  (aka: an algorithm)
area = 0.5 * base * height
print area


14.0
Interactivity is a powerful idea. It allows variables to be variable.

In [20]:
# The area of a circle
# Must input a number or a decimal
radius = input("Enter radius: ")
area = 3.14 * radius * radius
print area


Enter radius: 10
314.0

Here we create a variable called radius. Note that the name of the variable is expressive (much better than x or y). The value of variable is assigned using the = operator. In this case it is assigned the value of the return value from the input function. We can run this program over and over again and by changing the input we have changed the ouput- thus making our program dynamic. We can then use the variable throughout the program and even modify its value through code during runtime. And through this very simple concept, very complex programs from web servers to self-driving cars are built from just a few simple building blocks!

Your Turn!


In [ ]:
#  Write code with variables to print the area of a rectangle

In [ ]:
#  Write code with variables to print the parameter of a rectangle

Answers:


In [2]:
#  Area of a rectangle

width = input("What is the width?")
height = input("What is the hight?")

area_rectangle = width * height

print area_rectangle


What is the width?5
What is the hight?10
50

In [7]:
# Parameter of a rectangle

width = input("What is the width?")
height = input("What is the hight?")

parameter_rectangle = 2 * width + 2 * height

print area_rectangle


What is the width?5
What is the hight?10
50

Calculation

So let's look at what computers do best- compute things!


In [21]:
print 2 + 5      # Addition


7

In [22]:
print 10 - 3     # Subtraction


7

In [23]:
print 5 * 5      # Multiplication


25

In [24]:
print 2 ** 2     # Power operator


4

In [25]:
print 5 % 2      # Modulus (aka: remainder)


1

In [26]:
print 11 / 2     # Division with an integer
print 11 / 2.0   # Division with a float


5
5.5

Comparison

True and False are booleans in Python and are used to express truth. Let's explore some comparision operators.

Note: Don't confuse assignment = with is equal to ==; this is one of the most common programmer errors.


In [27]:
a = 10  #ASSIGNMENT
b = 20

print a > b   # Greater than
print b >= a  # Greater than or equal to
print a == b  # EQUALITY symbol
print b < a   # Less than
print a <= b  # Less than or equal to


False
True
False
False
True

Simple Data Types

We have already seen three data types:

  1. Strings
  2. Integers
  3. Floats
  4. Booleans

These are all objects in Python.


In [28]:
#String
a = "apple"
print type(a)


<type 'str'>

In [29]:
#Integer (whole number)
b = 1
print type(b)


<type 'int'>

In [30]:
#Float  (real numbers with decimal places)
c = 2.2
print type(c)


<type 'float'>

In [31]:
#Boolean
d = True
print type(d)


<type 'bool'>

Strings


In [32]:
a = "Hello"  # String
b = " World" # Another string
print a + b  # Concatenation


Hello World

In [34]:
a = "World"
# Slicing
print a[0]
print a[-1]
print "World"[0:4]


W
d
Worl

In [35]:
name = "Jonesey"
print "Hello, %s!" % name # Simple string formatting


Hello, Jonesey!

Strings are an example of an imutable data type. Once you instantiate a string you cannot change any characters in it's set.


In [36]:
string = "string"
string[1] = "y"  #Here we attempt to assign the last character in the string to "y"


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-36-5cf8b6c54c2a> in <module>()
      1 string = "string"
----> 2 string[1] = "y"  #Here we attempt to assign the last character in the string to "y"

TypeError: 'str' object does not support item assignment

Formatting Strings


In [37]:
# String Concatination

first_name = "Bob"
last_name = "Roberts"

print first_name + " is my first name. " + last_name + " is my last name."


Bob is my first name. Roberts is my last name.

In [13]:
# String Formatting

food = "pizzas"
number = 20

print "I'm so hungry I'm going to eat %i %s." % (number, food)


I'm so hungry I'm going to eat 20 pizzas.

String Methods


In [38]:
name = "matt"
name.capitalize()        # Capitalizes the first letter of the string


Out[38]:
'Matt'

In [39]:
name = "matt"
last = "jones"
" ".join([name, last])   # Creates a new string by concatenating each item in the list


Out[39]:
'matt jones'

In [40]:
# What other methods do strings have?
# You can use "dir" on any object to find out it's methods
dir(str)


Out[40]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__getslice__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__len__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmod__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '_formatter_field_name_split',
 '_formatter_parser',
 'capitalize',
 'center',
 'count',
 'decode',
 'encode',
 'endswith',
 'expandtabs',
 'find',
 'format',
 'index',
 'isalnum',
 'isalpha',
 'isdigit',
 'islower',
 'isspace',
 'istitle',
 'isupper',
 'join',
 'ljust',
 'lower',
 'lstrip',
 'partition',
 'replace',
 'rfind',
 'rindex',
 'rjust',
 'rpartition',
 'rsplit',
 'rstrip',
 'split',
 'splitlines',
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

In [41]:
# What if you don't know how to use one of the methods?

help(' matt '.strip)

# Now that you know what it does, try it out!
' matt '.strip()


Help on built-in function strip:

strip(...)
    S.strip([chars]) -> string or unicode
    
    Return a copy of the string S with leading and trailing
    whitespace removed.
    If chars is given and not None, remove characters in chars instead.
    If chars is unicode, S will be converted to unicode before stripping

Out[41]:
'matt'

Quick Stretch

Conditionality: "If Else"

Programs can make choices based on particular values of variables using conditional execution. Conditionality forks the flow of execution so that some parts of the program may be executed but others will not.

This brings up a crucial point about Python in particular- blocks of code are grouped by indentation. Every time you get to a place where you have to define a contiguous block of code (usually following a :) then everything under must be indented with the same amount of space (usually 4 spaces). Dedented code does not belong to the indented block.


In [42]:
# Simple Conditionality
if 2 + 2 == 4:
    print "All is right in the world!"
else:
    print "Pigs must be flying!"


All is right in the world!

In [43]:
# Evaluate Temperature
temperature = input("What is today's temperature?  ")

if temperature > 82:
   print "It's too hot, %i degrees will melt you." % temperature
elif temperature < 45:
   print "Are you crazy? You'll freeze at %i degrees" % temperature
else:
    print "Perfect weather! Let's go for a picnic!"


What is today's temperature?  30
Are you crazy? You'll freeze at 30 degrees

Your Turn:


In [ ]:
# Use conditionality to determine if a number is even or odd

Answer


In [44]:
number = input("What number should I test?")

if number % 2 == 0:
    print "The number is even!"
else:
    print "The number is odd!"


What number should I test?10
The number is even!

Logic with Booleans


In [10]:
#Both a and b are True

a = True
b = True

if a and b:                  
    print "a and b == True"


a and b == True

In [11]:
#Either a or c is True

b = True
c = False

if b or c:                  
    print "b and c == True"


b and c == True

In [49]:
#If d is not true

d = False

if d is not True:      
    print "d == False"


d == False

In [50]:
# None denotes lack of value but it is not equal to false

a = None
b = 0

if a is None:
    print "None"

if b is not None:   
    print "Not None"

print None == False


None
Not None
False

Repetition: For and While Loops

The power of computers is their ability to do a repetitive task over and over again without tiring. Most programs don't just shut down on you have executing their instructions- they wait for input from the user and respond. In order to accomplish this some mechanism is required to continually execute a chunk of code.


In [ ]:
for letter in "a", "b", "c", "d", "e":
    print letter

In [37]:
for number in range(1,10):
    print number


1
2
3
4
5
6
7
8
9

In [52]:
# You are importing the sleep function from the time module
from time import sleep

print "Cooking the bacon."

hot_enough  = 180
temperature = 62

while temperature < hot_enough:
    print "Not hot enough..."
    sleep(1)
    temperature = temperature + 15

print "Bacon is done!"


Not hot enough...
Not hot enough...
Spam is done!
Cooking the spam.
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
Spam is done!

Functions

Functions allow you to define proceedures that happen over and over again in your code, almost like mini-programs that take input and return an output. Let's start by looking at a very simple function.


In [53]:
# This function takes no arguments
# Every function starts with a definition, this is where "def" comes from
def hello():
    # This is a docstring
    '''say hi'''
    print "Hello!"

# Invoke the function
hello()

# Help prints the docstring of the function
help(hello)


Hello!
Help on function hello in module __main__:

hello()
    say hi

Let's refactor (aka: rewrite) the bacon code into a cooking function.


In [54]:
from time import sleep

def cook(hot_enough, temperature, food):
    print "Cooking the %s." % food
    while temperature < hot_enough:
        print "Not hot enough..."
        sleep(1)
        temperature = temperature + 15
    print "The %s are done!" % food

cook(100, 50, "coconuts")


Cooking the coconuts.
Not hot enough...
Not hot enough...
Not hot enough...
Not hot enough...
The coconuts are done!
  • Arguments to functions are named buckets that can have defaults associated with them.

  • So far we have only seen Positional arguments. Positional arguments (arguments without a default) must be specified in the order of the arguments.

  • Keyword arguments (those with a default) can be specified in any order, so long as they come after the positional arguments.


In [55]:
# postional and keyword arguments
# positional arguments must go before keyword (default) arguments
def writer(name, color="blue"):
    print name + "'s favorite color is " + color
    
writer("Samantha")
writer("Sarah", "red")
writer("Susan", color="green")


Samantha's favorite color is blue
Sarah's favorite color is red
Susan's favorite color is green

In [56]:
# A stub function that does nothing
def stub():
    pass

stub()

Your Turn:


In [ ]:
# Write a function that checks if a number is evenly divisible by 5

Answer:


In [58]:
def by_4(number = 4):
    '''Check if a number is evenly divisible by 4'''
    if not number % 4:
        print "Yes"
    else:
        print "No"

by_4(10)
by_4()


No
Yes

Lists, Tuples, Sets and Dictionaries

Programmers can't live on numbers and strings alone. The currency of programming is data (information), therefore we need more significant structures to represent information.

  • Unlike integers, floats and strings these data types can hold multiple values

Lists:

Lists are mutable or able to be altered. Lists are a collection of data and that data can be of differing types.


In [57]:
# A new list
 groceries = []

 # Add to list
 groceries.append("Snails")  
 groceries.append("Nutella")
 groceries.append("Cactus")

 # Access by index
 print groceries[2]
 print groceries[0]

 # Find number of things in list
 print len(groceries)

 # Sort the items in the list
 groceries.sort()
 print groceries

 # Remove from list
 groceries.remove("Cactus")

 #The list is mutable
 groceries[0] = 2
 print groceries


Cactus
Snails
3
['Cactus', 'Nutella', 'Snails']
[2, 'Snails']

Tuples

Tuples are an immutable type. Like strings, once you create them, you cannot change them. It is their immutability that allows you to use them as keys in dictionaries. However, they are similar to lists in that they are a collection of data and that data can be of differing types.


In [58]:
# Tuple grocery list

groceries = ('Cactus', 'Nutella', 'Snails')

print groceries


('Cactus', 'Nutella', 'Snails')

Sets:

A set is a sequence of items that cannot contain duplicates. They handle operations like sets in mathmatics.


In [61]:
numbers = range(10)
evens = [2, 4, 6, 8]

evens = set(evens)
numbers = set(numbers)

# Use difference to find the odds
odds = numbers - evens

print odds

# Note: Set also allows for use of union (|), and intersection (&)


set([0, 1, 3, 5, 7, 9])

Dictionaries

A dictionary is a map of keys to values. Keys must be unique.


In [62]:
# A simple dictionary

obvious = {'sky': 'blue'}

# Access by key
print obvious['sky']


blue

In [63]:
# A longer dictionary
obvious = {
    'sky': 'blue',
    'dog': 'woof'
}

# Check if item is in dictionary
print 'two plus two' in obvious

# Add new item
obvious['two plus two'] = 4
print obvious['two plus two']

# Print just the keys
print obvious.keys()

# Print just the values
print obvious.values()

# Print dictionary pairs another way
for key, value in obvious.items():
    print key, value


False
4
['two plus two', 'sky', 'dog']
[4, 'blue', 'woof']
two plus two 4
sky blue
dog woof

In [64]:
# Complex Data structures
# Dictionaries inside a dictionary!

employees = {
    "eid0001": {
        "name": "Bob Jones",
        "department": "Marketing",
        "interests": ["fishing", "deep breathing", "gatorade",]
    },
    "eid0002": {
        "name": "Sherry Lorenzo",
        "department": "Human Resources",
        "interests": ["cooking", "steganography", "cycling",],
    }
}

for employee in employees:
    print employees[employee]["name"]


Bob Jones
Sherry Lorenzo

Quick Stretch

File I/O


In [66]:
# Writing to a file
with open("example.txt", "w") as f:
    f.write("Hello World! \n")
    f.write("How are you? \n")
    f.write("I'm fine.")

In [67]:
# Reading from a file
with open("example.txt", "r") as f:
    data = f.readlines()
    for line in data:
        words = line.split()
        print words


['Hello', 'World!']
['How', 'are', 'you?']
["I'm", 'fine.']

In [68]:
# Count lines and words in a file
lines = 0
words = 0
the_file = "example.txt"

with open(the_file, 'r') as f:
    for line in f:
        lines += 1
        words += len(line.split())
print "There are %i lines and %i words in the %s file." % (lines, words, the_file)


There are 3 lines and 7 words in the example.txt file.

APIs


In [ ]:
# Getting data from an API

import requests

width = '500'
height = '500'
response = requests.get('http://placekitten.com/g/' + width + '/' + height)

print response

with open('kitteh.jpg', 'wb') as f:
    f.write(response.content)

Object Oriented Programming

Now that we have covered the basic building blocks of a Python program, let's discuss a programming paradigm called Object-Oriented Programming (OOP). OOP gives programmers a framework for modeling the real world by using classes - templates that describe an object's methods and attributes. Methods can be thought of as the functions of the class while attributes are it's variables. Using this methodology, a programmer simply has to imagine the component interactions of the structure they're trying to model, then translate that into the executional components described above.

  • The names of classes should be "camel cased." For example, "FrogPrincess."
  • The init method constructs the class when it is instantiated, it takes self as it's first parameter.

In [77]:
class Person(object):
    """
    Base class for all people
    """
    
    #An attribute of the class
    population = 0
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
        Person.population += 1
    
    def displayCount(self):
        print "Total people: %d" % Person.population
    
    def displayPerson(self):
        print "My name is %s and I am %i years old." % (self.name, self.age)

## INHERITENCE ##
# Rude inherits from person
class Rude(Person):
    
    def displayPerson(self):
        print "I don't have to tell you anything!"


# Create Person instance
bob = Person("Bob", 35)
bob.displayPerson()
bob.displayCount()

# Create Rude Person Instance
rude = Rude("None of your business", None)
rude.displayPerson()
rude.displayCount()


My name is Bob and I am 35 years old.
Total people: 1
I don't have to tell you anything!
Total people: 2

Your Turn:


In [ ]:
# Create a base class called animal with at least one attribute and one method.
# Then create two more classes that inherit from the animal class 
# For example "Mammal" and "Reptile."

A Time Formatter

In order to get a feel for how simple programs can be constructed, let's take a look at simple program that I wrote and use every single day. We'll walk through each line of code together and discover how this code works. This exercise will be common as you continue to learn how to program.


In [102]:
#!/usr/bin/env python
# clock
# Prints out the time specially formatted

"""
Prints out the time specially formatted
"""

##########################################################################
## Imports
##########################################################################

import sys
from datetime import datetime
from dateutil.tz import tzlocal

##########################################################################
## A Clock Printer Object
##########################################################################

class Clock(object):

    # The "default" formats. Add more formats via subclasses or in the
    # instantation of a Clock object (or just add more here).

    # These formats are more complicated string formatting
    FORMATS = {
        "code":"%a %b %d %H:%M:%S %Y %z",
        "json":"%Y-%m-%dT%H:%M:%S.%fZ",
        "cute":"%b %d, %Y",
    }

    # class method - bound to the class
    # Get the current time
    # tzlocal will get the local timezone
    @classmethod
    def local_now(klass):
        return datetime.now(tzlocal())

    def __init__(self, formats={}):
        self.formats = self.FORMATS.copy()
        self.formats.update(formats)

    # strftime takes a format and returns a string representing the date
    def _local_format(self, fmt):
        return Clock.local_now().strftime(fmt)

    def get_stamp(self, name):
        # strips "-" from beginning and end of string
        # the string is "-code", "-json" or "-cute"
        name  = name.strip("-")

        if name in self.formats:
            return self._local_format(self.formats[name])

        return None

    def print_stamp(self, name):
            stamp = self.get_stamp(name)
            if stamp:
                print stamp
            else:
                print "No stamp format for name %s" % name

##########################################################################
## Main Method, handle inputs to program from command line
##########################################################################

# print __name__ in the python shell to see how this works
if __name__ == "__main__":

    args  = sys.argv[1:]
    clock = Clock()
    for arg in args:
        clock.print_stamp(arg)


No stamp format for name -f
No stamp format for name /Users/SarahKelley/.ipython/profile_default/security/kernel-4d56b37b-9d68-482e-958c-317352f340c7.json
No stamp format for name --IPKernelApp.parent_appname='ipython-notebook'
No stamp format for name --profile-dir
No stamp format for name /Users/SarahKelley/.ipython/profile_default
No stamp format for name --parent=1

In [ ]: