You are on page 1of 33

Variables are used to store values.

A string is a series of Dictionaries store connections between pieces of


characters, surrounded by single or double quotes. List comprehensions information. Each item in a dictionary is a key-value pair.
squares = [x**2 for x in range(1, 11)]
Hello world A simple dictionary
print("Hello world!") Slicing a list alien = {'color': 'green', 'points': 5}
finishers = ['sam', 'bob', 'ada', 'bea']
Hello world with a variable Accessing a value
first_two = finishers[:2]
msg = "Hello world!" print("The alien's color is " + alien['color'])
print(msg)
Copying a list
copy_of_bikes = bikes[:]
Adding a new key-value pair
Concatenation (combining strings)
alien['x_position'] = 0
first_name = 'albert'
last_name = 'einstein' Looping through all key-value pairs
full_name = first_name + ' ' + last_name Tuples are similar to lists, but the items in a tuple can't be fav_numbers = {'eric': 17, 'ever': 4}
print(full_name) modified. for name, number in fav_numbers.items():
print(name + ' loves ' + str(number))
Making a tuple
dimensions = (1920, 1080) Looping through all keys
fav_numbers = {'eric': 17, 'ever': 4}
for name in fav_numbers.keys():
print(name + ' loves a number')
If statements are used to test for particular conditions and
respond appropriately.
Looping through all the values
fav_numbers = {'eric': 17, 'ever': 4}
Conditional tests
for number in fav_numbers.values():
equals x == 42 print(str(number) + ' is a favorite')
A list stores a series of items in a particular order. You
not equal x != 42
access items using an index, or within a loop.
greater than x > 42
Make a list or equal to x >= 42
bikes = ['trek', 'redline', 'giant'] less than x < 42 Your programs can prompt the user for input. All input is
or equal to x <= 42 stored as a string.
Get the first item in a list
Conditional test with lists Prompting for a value
first_bike = bikes[0]
'trek' in bikes name = input("What's your name? ")
Get the last item in a list
'surly' not in bikes print("Hello, " + name + "!")
last_bike = bikes[-1]
Assigning boolean values Prompting for numerical input
game_active = True age = input("How old are you? ") age
can_edit = False = int(age)

A simple if test pi = input("What's the value of pi? ")


if age >= 18: pi = float(pi)
print("You can vote!")

C
If-elif-else statements
if age < 4:
ticket_price = 0
elif age < 18: overs Python 3 and Python 2
ticket_price = 10
else:
ticket_price = 15

Looping through a list

for bike in bikes:


print(bike)
Adding items to a list
bikes = []
bikes.append('trek')
bikes.append('redline')
bikes.append('giant')
Making numerical lists
squares = [] for x in
range(1, 11):
squares.append(x**2)

More cheat sheets available at


A while loop repeats a block of code as long as a certain A class defines the behavior of an object and the kind of Your programs can read from files and write to files. Files
condition is true. information an object can store. The information in a class are opened in read mode ('r') by default, but can also be
is stored in attributes, and functions that belong to a class opened in write mode ('w') and append mode ('a').
A simple while loop are called methods. A child class inherits the attributes and
Reading a file and storing its lines
current_value = 1 while methods from its parent class.
current_value <= 5: filename = 'siddhartha.txt' with
Creating a dog class open(filename) as file_object:
print(current_value)
current_value += 1 class Dog(): lines = file_object.readlines()
"""Represent a dog.""" for line in
Letting the user choose when to quit def __init__(self, name): lines:
msg = '' while msg != 'quit': msg = """Initialize dog object.""" print(line)
input("What's your message? ") self.name = name def
sit(self):
Writing to a file
print(msg)
"""Simulate sitting.""" filename = 'journal.txt' with
print(self.name + " is sitting.") open(filename, 'w') as file_object:
file_object.write("I love programming.")
my_dog = Dog('Peso')
Appending to a file
Functions are named blocks of code, designed to do one
specific job. Information passed to a function is called an print(my_dog.name + " is a great dog!") filename = 'journal.txt' with open(filename,
argument, and information received by a function is called a my_dog.sit() 'a') as file_object:
parameter. file_object.write("\nI love making games.")

A simple function Inheritance


def greet_user(): class SARDog(Dog):
"""Display a simple greeting.""" Exceptions help you respond appropriately to errors that
"""Represent a search dog."""
print("Hello!") are likely to occur. You place code that might cause an
def __init__(self, name):
"""Initialize the sardog.""" error in the try block. Code that should run in response to
greet_user() super().__init__(name) an error goes in the except block. Code that should run only
def if the try block was successful goes in the else block.
Passing an argument
search(self):
def greet_user(username): Catching an exception
"""Simulate searching."""
"""Display a personalized greeting.""" print(self.name + " is searching.") prompt = "How many tickets do you need? "
print("Hello, " + username + "!") num_tickets = input(prompt)
my_dog = SARDog('Willie') try: num_tickets =
greet_user('jesse') int(num_tickets) except ValueError:
Default values for parameters print(my_dog.name + " is a search print("Please try again.") else:
dog.") my_dog.sit() my_dog.search() print("Your tickets are printing.")

C
def make_pizza(topping='bacon'):
"""Make a single-topping pizza.""" You can add elements to the end of a list, or you can insert The sort() method changes the order of a list permanently.
A list stores a series of itemsIf in
themyoua particular
had youorder.
infinite
wherever programming
like in a list. skills, what would you The sorted() function returns a copy of the list, leaving the
print("Have a " + topping + " pizza!")
Lists allow you to store setsbuild?
of information in one Simple list
original is better than complex
unchanged. You can sort the items in a list in
Adding an element to the end of the list
place, whether you have just a few items or millions alphabetical order, or reverse alphabetical order. You can
make_pizza() As you're learning to program, it's helpful to think If you have a choice between a simple and a complex
make_pizza('pepperoni') of items. Lists are one of Python's
You most
canthe
remove powerful
users.append('amy') elements by their position also reverse the original order of the list. Keep in mind that
Use square brackets to define a list, and use commas to about real-world projects you'd likeintoacreate.
list, or by
It's a solution, and
lowercase both work,letters
and uppercase use the
maysimple solution.
affect the Your
sort order.
features readily accessible the
to new
value programmers,
of the item. Ifanandremove an item by its value,
you
Returning
separate a value
individual items in the list. Use plural names for Starting withtoankeep
good habit empty list
"ideas" notebook that you can code will be easier to maintain, and it will be easier
they tie together many important
Pythonconcepts in the first item that has that value.
lists, to make your code easier to read.
def add_numbers(x, y): refer toremoves
users =whenever
[]
only
you want to start a new project. If Sorting
for you aand
list others
permanently
to build on that code later on.
programming.
Making"""Add
a list two numbers and return the sum.""" you haven't
Deleting done
an element by
users.append('val') so already, take a few minutes and
its position users.sort()
return x + y describe three projects you'd like to create.
users.append('bob')
del users[-1] Lists canacontain millions of items, so Python provides an
users = ['val', 'bob', 'mia', 'ron', 'ned'] Sorting list permanently in reverse alphabetical
users.append('mia') efficient way to loop through all the items in a list. When
sum = add_numbers(3, 5) Removing an item by its value order
you set up a loop, Python pulls each item from the list one
print(sum) Inserting elements at a particular position atusers.sort(reverse=True)
a time and stores it in a temporary variable, which you
users.remove('mia')
Individual elements in a list are accessed according to their users.insert(0, 'joe') provide a name for. This name should be the singular
position, called the index. The index of the first element is Sortingofa the
version list list
temporarily
name.
users.insert(3, 'bea')
0, the index of the second element is 1, and so forth. The indented block of code makes up the body of the
print(sorted(users))
Negative indices refer to items at the end of the list. To get If you want to work with an element that you're removing loop, where you can work with each individual item. Any
print(sorted(users, reverse=True))
a particular element, write the name of the list and then the from the list, you can "pop" the element. If you think of the lines that are not indented run after the loop is completed.
index of the element in square brackets. list as a stack of items, pop() takes an item off the top of the Reversing the order of a list
Printing all items in a list
stack. By default pop() returns the last element in the list,
Getting the first element users.reverse()
but you can also pop elements from any position in the list. for user in users:
first_user = users[0] print(user)
Pop the last item from a list
Getting the second element Printing a message for each item, and a separate
most_recent_user = users.pop()
print(most_recent_user) message afterwards
second_user = users[1]
for user in users:
Getting the last element Pop the first item in a list print("Welcome, " + user + "!")
newest_user = users[-1] first_user = users.pop(0)
print(first_user) print("Welcome, we're glad to see you all!")

Once you've defined a list, you can change individual elements


in the list. You do this by referring to the index of the item you The len() function returns the number of items in a list.
want to modify. Find the length of a list
overs Python 3 and Python 2
Changing an element num_users = len(users)
print("We have " + str(num_users) + " users.")
users[0] = 'valerie' users[-2] = 'ronald'

that starts at the first item and ends at the last item. If you try to copy a list without using this approach, whatever you do to the copied list will affect the original list

'abe', 'ada', 'gus', 'zoe'] copy_of_finishers = finishers[:]

More cheat sheets available at


unction to work with a set of You can use a loop to generate a list based on a range of A tuple is like a list, except you can't change the values in a
ange() function starts at 0 by numbers or on another list. This is a common operation, so tuple once it's defined. Tuples are good for storing
mber below the number passed to Python offers a more efficient way to do it. List information that shouldn't be changed throughout the life of
unction to efficiently generate a comprehensions may look complicated at first; if so, use the a program. Tuples are designated by parentheses instead
for loop approach until you're ready to start using of square brackets. (You can overwrite an entire tuple, but
comprehensions.
you can't change the individual elements in a tuple.)
to 1000 To write a comprehension, define an expression for the
values you want to store in the list. Then write a for loop to Defining a tuple
(1001):
generate input values needed to make the list.
dimensions = (800, 600)
Using a loop to generate a list of square numbers
to 1000 Looping through a tuple
squares = [] for x in
(1, 1001): range(1, 11): for dimension in dimensions:
square = x**2 print(dimension)
rs from 1 to a million squares.append(square) Overwriting a tuple
e(1, 1000001)) Using a comprehension to generate a list of square dimensions = (800, 600)
numbers print(dimensions)
squares = [x**2 for x in range(1, 11)] dimensions = (1200, 900)
mple statistics you can run on a list Using a loop to convert a list of names to upper case
a.
names = ['kai', 'abe', 'ada', 'gus', 'zoe']
alue in a list When you're first learning about data structures such as
upper_names = [] for name in names: lists, it helps to visualize how Python is working with the
17, 85, 1, 35, 82, 2, 77]
upper_names.append(name.upper()) information in your program. pythontutor.com is a great tool
)
for seeing how Python keeps track of the information in a
value Using a comprehension to convert a list of names to list. Try running the following code on pythontutor.com, and
17, 85, 1, 35, 82, 2, 77] upper case then run your own code.
names = ['kai', 'abe', 'ada', 'gus', 'zoe'] Build a list and print the items in the list
values
upper_names = [name.upper() for name in names]
17, 85, 1, 35, 82, 2, 77]
ges)

et of elements from a list. A portion


To slice a list start with the index of
en add a colon and the index after
eave off the first index to start at
and leave off the last index to slice
t.

C
ems dogs = []
Use curly braces to define a dictionary. Use colons to You can
You can store
modify asthe
manyvalue associated
key-value with
pairs as any
you key
wantinina a
dogs.append('willie') You can loop through a dictionary in three ways: you can
'abe', 'ada',
connect 'gus',
keys and 'zoe']
values, and use commas to separate dictionary,
dictionary. until
To do your computer
so give runs of
the name out of
the memory.
dictionary
dogs.append('hootz')To
andadd a loop through all the key-value pairs, all the keys, or all the
hers[:3]
individual key-value pairs. Readability counts new key-value
enclose the keypair to an existing
in square dictionary
brackets, give the
then provide thename
dogs.append('peso') new values.
of the dictionary
value for that key. and the new key in dogs.append('goblin')
square brackets, and A dictionary only tracks the connections between keys
Making a dictionary
e items • Use four spaces per indentation set it equal level.
to the new value. and values; it doesn't track the order of items in the
for dog in dogs:
• 'points':
Keep your5} Modifying
This also
lines to 79 characters orvalues
allows
fewer.youin atodictionary
start with an empty dictionary
print("Hello " + and
dog + dictionary. If you want to process the information in order,
"!")
alien_0 = {'color': 'green',To
shers[1:4] access the value associated with an individual key givebecome relevant.
• Use
the namesingle
of theblank
dictionary toadd
linesand groupkey-value
alien_0
then placeparts
=the pairs
of your
{'color':
key
as they'green',
in a set of print("I
'points': love
5} these dogs!")you can sort the keys in your loop.
ems program visually. print(alien_0)
square brackets. Adding
If the key you're a key-value
asking for is not inpair
the Looping through all key-value pairs
ers[-3:] dictionary, an error will occur. print("\nThese were my first two
alien_0
# Change
You can also use the get() method, = the
which {'color':
alien's
returns None'green',
color and 'points':
dogs:") 5}
pointold_dogs = dogs[:2] for old_dog
# Store people's favorite
value.
instead of an error if the key doesn't alien_0['color']
exist. You can also in old_dogs:
= 'yellow' print(old_dog)
languages. fav_languages =
Python's dictionaries allow you tospecify
connecta pieces value to use ifalien_0['x']
default of the key is not in=the
alien_0['points'] 0 = 10 print(alien_0) { 'jen': 'python',
related information. Each piece ofdictionary.
information in a alien_0['y'] = 25 del dogs[0] 'sarah': 'c',
dictionary is stored as a key-value pair. When you alien_0['speed'] = 1.5 dogs.remove('peso')
You can remove any key-value pair you want from a 'edward': 'ruby',
provide a key, Python returns the Getting the value associated with a key print(dogs) 'phil': 'python',
value associated dictionary. To do so use
Adding to an empty dictionary the del keyword and the dictionary
You can
} find the number of key-value pairs in a dictionary.
with that key. You can loop through allalien_0
the key
-value
= {'color': 'green', name, followed
'points': by the
5} key in square brackets. This will
pairs, all the keys, or all the values. alien_0 = {}
delete the key and its associated value. Finding a dictionary's length
print(alien_0['color']) alien_0['color'] = 'green' # Show each person's favorite language. for
Deleting a key-value =pair
alien_0['points'] 5 num_responses
name, language=in len(fav_languages)
fav_languages.items():
print(alien_0['points'])
alien_0 = {'color': 'green', 'points': 5} print(name + ": " + language)
Getting the value with get() print(alien_0)
Looping through all the keys
alien_0 = {'color': 'green'}
del alien_0['points'] # Show everyone who's taken the survey. for
print(alien_0)
alien_color = alien_0.get('color') name in fav_languages.keys():
overs Python 3 and Python 2
print(name)
alien_points = alien_0.get('points', 0)
Looping through all the values
print(alien_color) Try running some of these examples on pythontutor.com.
print(alien_points) # Show all the languages that have been chosen.
for language in fav_languages.values():
print(language)
Looping through all the keys in order
# Show each person's favorite language,
# in order by the person's name. for
name in sorted(fav_languages.keys()):
print(name + ": " + language)

More cheat sheets available at


Nesting is extremely useful in
certain situations. However, be It's sometimes useful to storeYou
Storing
a setcan
ofadictionaries
store
list inside
a dictionary
aindictionary
insidealows
a list; another
youdictionary.
to associate
In this Standard
You can Python dictionaries
use a loop don't keep
to generate tracknumber
a large of the order
of
aware of making your code this is called nesting. more each
case than one
value value with each
associated withkey.
a key is itself a dictionary. dictionaries
in which keysefficiently,
and values if are
all added;
the dictionaries
they only preserve
start out the
overly complex. If you're nesting association
with between each key and its value. If you want to
similar data.
Storing dictionaries in a listStoring dictionaries in a dictionary
lists in a dictionary
items much deeper than what preserve the order in which keys and values are added,
you see here there are # Start with an empty list.
A million aliens
use an OrderedDict.
users
# Store = {
multiple languages for each person.
probably simpler ways of users = [] fav_languages
'aeinstein':= {{ aliens = []
managing your data, such as 'jen': ['python', 'ruby'], Preserving the order of keys and values
'first': 'albert',
using classes. # Make a new user, and add them to the
'sarah':
'last': list.
['c'],
'einstein', #
from
Make
collections
a million green
importaliens,
OrderedDict
worth 5 points
new_user = { 'edward': ['ruby',
'location': 'go'],
'princeton', # each. Have them all start in one row.
'last': 'fermi', 'phil':
}, ['python', 'haskell'], for alien_num
# Store in range(1000000):
each person's languages, keeping
'first': 'enrico', } new_alien = {}
# track of who respoded first.
'mcurie': {
'username': 'efermi', new_alien['color']
fav_languages = 'green'
= OrderedDict()
'first': 'marie',
} # Show all responses for each person. new_alien['points'] = 5 new_alien['x']
'last': 'curie',
users.append(new_user) for name, langs in = 20 * alien_num
fav_languages['jen'] new_alien['y'] = 0
= ['python', 'ruby']
'location': 'paris',
fav_languages.items(): print(name + aliens.append(new_alien)
fav_languages['sarah'] = ['c']
},
# Make another new user,":and
") add them
for lang in langs:
as well. fav_languages['edward'] = ['ruby', 'go']
} for username, user_dict in # Prove the list contains a million'haskell']
aliens.
new_user = { print("- " + lang) fav_languages['phil'] = ['python',
users.items(): print("\nUsername: "
'last': 'curie', num_aliens
# Display = len(aliens)
the results, in the same order
+ username) full_name =
'first': 'marie', user_dict['first'] + " " they
full_name
'username': 'mcurie', # were entered.
print("Number for created:")
of aliens name, langs in
+= user_dict['last'] location =
} fav_languages.items():
print(num_aliens) print(name +
user_dict['location']
users.append(new_user) ":") for lang in langs:
print("- " + lang)
print("\tFull name: " + full_name.title())
# Show all information about each
print("\tLocation: " + location.title())
user. for user_dict in users: for
k, v in user_dict.items():
print(k + ": " + v) print("\n")
You can also define a list of dictionaries directly,
without using append():
# Define a list of users, where each
user # is represented by a dictionary.
users = [
{
'last': 'fermi',
'first': 'enrico',
'username': 'efermi',
},
{
'last': 'curie',
'first': 'marie',
'username': 'mcurie',
},
]

# Show all information about each


user. for user_dict in users: for
k, v in user_dict.items():
C
print(k + ": " + v) print("\n")
A boolean value is either True or False. Variables with boolean values are often used to keep track of certain conditions within a program.
Simple boolean values
game_active = True can_edit = False

Testing numerical values is similar to testing string values. Several kinds of if statements exist. Your choice of which to
If statements allow you to examine the current state use depends on the number of conditions you need to test.
of a program and respond appropriately to that state. Testing equality and inequality You can have as many elif blocks as you need, and the
You can write a simple if statement that checks one >>> age = 18 else block is always optional.
condition, or you can create a complex series of if >>> age == 18
statements that idenitfy the exact conditions you're Simple if statement
True
looking for. >>> age != 18 age = 19
False if age >= 18: print("You're old
While loops run as long as certain conditions remain enough to vote!")
true. You can use while loops to let your programs run Comparison operators
as long as your users want them to. >>> age = 19 If-else statements
>>> age < 21
age = 17
True
if age >= 18: print("You're old
>>> age <= 21
enough to vote!") else: print("You
True
can't vote yet.")
>>> age > 21
False
>>> age >= 21
False The if-elif-else chain

You can easily test whether a certain value is in a list. You


You can check multiple conditions at the same time. The
and operator returns True if all the conditions listed are can also test whether a list is empty before trying to loop
True. The or operator returns True if any condition is True. through the list.
Testing if a value is in a list
>>> players = ['al', 'bea', 'cyn', 'dale']
>>> 'al' in players
True
>>> 'eric' in players
False
Using and to check multiple conditions age = 12
if age < 4:
>>> age_0 = 22 price = 0
A conditional test is an expression that can be evaluated as >>> age_1 = 18 elif age <
True or False. Python uses the values True and False to >>> age_0 >= 21 and age_1 >= 21 18: price
decide whether the code in an if statement should be False = 5 else:
executed. >>> age_1 = 23 price = 10
>>> age_0 >= 21 and age_1 >= 21
Checking for equality
True print("Your cost is $" + str(price) + ".")
A single equal sign assigns a value to a variable. A double equal
sign (==) checks whether two values are equal. Using or to check multiple conditions
>>> car = 'bmw' >>> age_0 = 22
>>> car == 'bmw' >>> age_1 = 18
True >>> age_0 >= 21 or age_1 >= 21
>>> car = 'audi' True
>>> car == 'bmw' >>> age_0 = 18
False >>> age_0 >= 21 or age_1 >= 21
Ignoring case when making a comparison False

>>> car = 'Audi'


>>> car.lower() == 'audi'
True
Checking for inequality
>>> topping = 'mushrooms'
>>> topping != 'anchovies'
True

You can allow your users to enter input using the input()
statement. In Python 3, all input is stored as a string.
Simple input
name = input("What's your name? ")
print("Hello, " + name + ".")
Accepting numerical input
age = input("How old are you? ") age
= int(age)
if age >= 18: print("\nYou
can vote!") else:
print("\nYou can't vote yet.")

Accepting input in Python 2.7


Use raw_input() in Python 2.7. This function interprets all input as a
string, just as input() does in Python 3.
C
Covers Python 3 and Python 2
name = raw_input("What's your name? ")
print("Hello, " + name + ".")
Every while loop needs a way to stop running so it won't
Testing if a value is not in a list Letting the user choose when to quit Using continue
continue in a loop
to run forever. If there's no way for the condition to
banned_users = ['ann', 'chad', 'dee'] prompt = "\nTell me something, and I'll " become False, the
banned_users = loop will never
['eve', stop running.
'fred', 'gary', 'helen']
user = 'erin' prompt += "repeat it back to you."
if user not in prompt += "\nEnter 'quit' to end the program. "
An infinite loop
prompt = "\nAdd a player to your team."
banned_users: message = "" while while
promptTrue: name
+= "\nEnter = input("\nWho
'quit' when you'reare
done. "
print("You can play!") message != 'quit': players
you? ") = [] while True:
print("Nice to meet you, " +
message = input(prompt) player
name + = input(prompt)
"!") if
Checking if a list is empty if message != player == 'quit': break
players = [] 'quit': elif player in banned_users:
if players: for player in players: print(message) print(player + " is
print("Player: " + player.title()) else: banned!") continue else:
print("We have no players yet!") players.append(player)
Using a flag
prompt = "\nTell me something, and I'll " print("\nYour team:")
prompt += "repeat it back to you."
Sublime Text doesn't run programs that prompt the user for for player in players:
prompt
input. +=
You "\nEnter
can use 'quit'
Sublime to
Text to end
write the program.
programs that " print(player)
The remove()
method activefor= input,
prompt True but
while
you'll need to run these programs from
A while loop repeats a block of code as long as aactive:
condition message =
removes a is True. a terminal.
specific value input(prompt)
from a list, but Counting to 5 if message == it
only removes 'quit': active = the first instance of the value you provide. You can use a
while loop to current_number = 1 False else: remove all instances of a particular value.
while current_number <= print(message)
statement and 5:
the continue print(current_number) Removing all cats from a list of pets
statement with current_number += 1 Using break to exit a loop pets = ['dog', 'cat', 'dog', 'fish', 'cat',
any of 'rabbit', 'cat'] print(pets) while 'cat' in
Python's loops. prompt = "\nWhat cities have you visited?" pets: pets.remove('cat') print(pets)
For example you can use break to quit a for loop that's prompt += "\nEnter 'quit' when you're done. "
working through a list or a dictionary. You can use continue to while True: city = input(prompt)
skip over certain items when looping through a list or if city == 'quit': break else:
dictionary as well. print("I've been to " + city + "!")

More cheat sheets available at


The two main kinds of arguments are positional and A function can return a value or a set of values. When a
keyword arguments. When you use positional arguments function returns a value, the calling line must provide a
Python matches the first argument in the function call with variable in which to store the return value. A function stops
the first parameter in the function definition, and so forth. running when it reaches a return statement.
With keyword arguments, you specify which parameter
each argument should be assigned to in the function call.
Returning a single value
When you use keyword arguments, the order of the def get_full_name(first, last):
arguments doesn't matter. """Return a neatly formatted full
name.""" full_name = first + ' ' + last
Using positional arguments return full_name.title()
Functions are named blocks of code designed to do def describe_pet(animal, name):
one specific job. Functions allow you to write code """Display information about a pet.""" musician = get_full_name('jimi', 'hendrix')
once that can then be run whenever you need to print("\nI have a " + animal + ".") print(musician)
accomplish the same task. Functions can take in the print("Its name is " + name + ".")
Returning a dictionary
information they need, and return the information they
describe_pet('hamster', 'harry') def build_person(first, last):
generate. Using functions effectively makes your describe_pet('dog', 'willie') """Return a dictionary of information
programs easier to write, read, test, and fix. about a person.
Using keyword arguments """
def describe_pet(animal, name): person = {'first': first, 'last': last}
The first line of a function is its definition, marked by the """Display information about a pet.""" return person
keyword def. The name of the function is followed by a set print("\nI have a " + animal + ".")
of parentheses and a colon. A docstring, in triple quotes, print("Its name is " + name + ".") musician = build_person('jimi', 'hendrix')
describes what the function does. The body of a function is print(musician)
indented one level. describe_pet(animal='hamster', name='harry')
To call a function, give the name of the function followed Returning a dictionary with optional values
describe_pet(name='willie', animal='dog')
by a set of parentheses. def build_person(first, last, age=None):
"""Return a dictionary of information about
Making a function a person.
def greet_user(): You can provide a default value for a parameter. When """ person = {'first': first,
"""Display a simple greeting.""" function calls omit this argument the default value will be 'last': last} if age:
print("Hello!") used. Parameters with default values must be listed after person['age'] = age return person
parameters without default values in the function's definition
greet_user() musician = build_person('jimi', 'hendrix', 27)
so positional arguments can still work correctly.
print(musician)
Using a default value
musician = build_person('janis', 'joplin')
print(musician)

C
def describe_pet(name, animal='dog'):
You
Sometimes
can pass
"""Display you
ainformation
list
won't
as know
an argument
how many
about toaaarguments
function, and
pet.""" a the You can store your functions in a separate file called a
Information that's passed to a function is called an function will
can need
work to
withaccept.
the Python
values
print("\nI have a " + animal + ".") in allows
the list.you
Any to collect
changes an Try runningand
module, some of these
then examples
import on pythontutor.com.
the functions you need into the file
argument; information that's received by a function is called arbitrary
the number
function
print("Its makes of to
name arguments
the"list
is into
+ will
name one
affect parameter
the
+ ".") original using
list. You containing your main program. This allows for cleaner
a parameter. Arguments are included in parentheses after the *prevent
can operator. A parameter
a function from that accepts
modifying an by
a list arbitrary
passing a program files. (Make sure your module is stored in the
the function's name, and parameters are listed in number
copy of arguments must
of the list as an argument. come last in the function
describe_pet('harry', 'hamster') same directory as your main program.)
parentheses in the function's definition. definition.
describe_pet('willie')
Passing a list as allows
The ** operator an argument
a parameter to collect an arbitrary
Storing a function in a module
File: pizza.py
overs Python 3 and Python 2
Passing a single argument number
Using of keyword
None to makearguments.
an argument optional
def greet_users(names): def make_pizza(size, *toppings):
def greet_user(username): def """Print
Collecting a simple
an arbitrary
describe_pet(animal, greeting
number to
of arguments
name=None): """Make a pizza."""
"""Display a simple greeting.""" everyone."""
"""Display information for name in names:
about a pet."""
def = make_pizza(size, *toppings): print("\nMaking a " + size + "
print("Hello, " + username + "!") msg "Hello,
print("\nI have" +a name + "!" + ".")
" + animal
"""Make
print(msg) a pizza.""" pizza.") print("Toppings:") for
if name: print("Its name is " +
topping in toppings: print("- " +
greet_user('jesse') nameprint("\nMaking
+ ".") a " + size + "
greet_user('diana') pizza.") = ['hannah',
usernames print("Toppings:")
'ty', 'margot'] for topping)
greet_user('brandon') topping in toppings:
greet_users(usernames)
describe_pet('hamster', 'harry') print("- " + Importing an entire module
topping) File: making_pizzas.py
describe_pet('snake')
Allowing a function to modify a list Every function in the module is available in the program file.
# Make
The three
following pizzas
example sendswith
a list ofdifferent toppings.
models to a function for
import pizza
As you can see there are many ways to write and call a make_pizza('small',
printing. 'pepperoni')
The original list is emptied, and the second list is filled.
function. When you're starting out, aim for something that make_pizza('large', 'bacon bits', 'pineapple')
def print_models(unprinted, printed): pizza.make_pizza('medium', 'pepperoni')
make_pizza('medium', 'mushrooms', 'peppers',
simply works. As you gain experience you'll develop an """3d print a set of models.""" while pizza.make_pizza('small', 'bacon', 'pineapple')
'onions', 'extra cheese')=
understanding of the more subtle advantages of different unprinted: current_model
unprinted.pop()
structures such as positional and keyword arguments, and the Collecting print("Printing
an arbitrary number "
of keyword arguments
various approaches to importing functions. For now if your + current_model)
functions do what you need them to, you're doing well. def build_profile(first, last, **user_info):
printed.append(current_model)
"""Build a user's profile dictionary."""
# Build
# Store some aunprinted
dict withdesigns,
the required keys.
profile = {'first': first, 'last': last}
# and print each of them. unprinted =
['phone case', 'pendant', 'ring'] printed =
You can modify an attribute's value directly, or you can write methods that manage updating values more carefully.
[] # Add any other keys and values.
for key, value in user_info.items():
print_models(unprinted, printed)
Modifying an attribute directly profile[key] = value
print("\nUnprinted:",
my_new_car = Car('audi', 'a4', 2016) my_new_car.fuel_level = 5 profile unprinted)
return
print("Printed:", printed)

Writing a method to update an attribute's value Preventing a function


# Create two users from
with modifying
differenta kinds
list
The
# following example is the user_0
of information. same as the= previous one, except the
def update_fuel_level(self, new_level): """Update thelistfuel
original level."""
is unchanged
build_profile('albert', if
after calling new_level <= self.fuel_capacity:
print_models().
'einstein',
self.fuel_level = new_level else: print("The tank can't hold that much!")
location='princeton')
def print_models(unprinted, printed):
user_1print
"""3d = build_profile('marie',
a set of models.""" 'curie', while
location='paris',
unprinted: field='chemistry')
current_model =
unprinted.pop() print("Printing "
print(user_0)
+ current_model)
Writing a method to increment an attribute's value print(user_1)
printed.append(current_model)

# Store some unprinted designs,


# and print each of them. original = Importing a specific function
['phone case', 'pendant', 'ring'] printed = Only the imported functions are available in the program file.
[]

print_models(original[:], printed)
print("\nOriginal:", original) More cheat sheets available at
print("Printed:", printed)
def add_fuel(self, amount): """Add fuel to the tank.""" if (self.fuel_level + amount <= self.fuel_capacity): self.fuel_level
+= amount print("Added fuel.") else: print("The tank won't hold that much.")

If the class you're writing is a specialized version of another


Classes are the foundation of object-oriented class, you can use inheritance. When one class inherits
programming. Classes represent real-world things from another, it automatically takes on all the attributes and
you want to model in your programs: for example methods of the parent class. The child class is free to
dogs, cars, and robots. You use a class to make introduce new attributes and methods, and override
attributes and methods of the parent class.
objects, which are specific instances of dogs, cars, To inherit from another class include the name of the
and robots. A class defines the general behavior that parent class in parentheses when defining the new class.
a whole category of objects can have, and the
information that can be associated with those objects. The __init__() method for a child class
Classes can inherit from each other – you can write a class ElectricCar(Car):
class that extends the functionality of an existing """A simple model of an electric car."""
class. This allows you to code efficiently for a wide def __init__(self, make, model,
variety of situations. year): """Initialize an electric
car.""" super().__init__(make,
model, year)

# Attributes specific to electric cars.


# Battery capacity in kWh.
self.battery_size = 70
# Charge level in %.
self.charge_level = 0
Adding new methods to the child class
class ElectricCar(Car):
--snip-- def
charge(self):
"""Fully charge the vehicle."""
self.charge_level = 100
print("The vehicle is fully charged.")
Using child methods and parent methods
my_ecar = ElectricCar('tesla', 'model s', 2016)

my_ecar.charge()
my_ecar.drive()

C
Consider how we might model a car. What information
Overriding parent methods Creating an object from a class
would we associate with a car, and what behavior would it
class ElectricCar(Car): have?
my_car The=information
Car('audi', is stored
'a4',in variables
2016) called
--snip-- def attributes, and the behavior is represented by functions.
fill_tank(self): Accessing
Functions attribute
that are partvalues
of a class are called methods.
"""Display an error message.""" print(my_car.make)
The Car class
print("This car has no fuel tank!") print(my_car.model)
class Car():
print(my_car.year)
"""A simple attempt to model a car."""
Calling methods
def __init__(self, make, model,
year):
my_car.fill_tank() """Initialize car
attributes."""
my_car.drive() self.make = make
self.model = model self.year =
Creating
year multiple objects
my_car = Car('audi', 'a4', 2016)
# Fuel capacity and level in
my_old_car = Car('subaru', 'outback', 2013)
gallons. self.fuel_capacity = 15
my_truck = Car('toyota',
self.fuel_level = 0 'tacoma', 2010)
def
fill_tank(self):
"""Fill gas tank to capacity."""
self.fuel_level = self.fuel_capacity
print("Fuel tank is full.")
def
drive(self):
"""Simulate driving."""
print("The car is moving.")

There are many ways to model real world objects and situations in code, and sometimes that variety can feel overwhelming. Pick an approach and try it – if your first attempt doesn't work,
try a different approach.

In Python class names are written in CamelCase and object names are written in lowercase with underscores. Modules that contain classes should still be named in lowercase with
underscores.

overs Python 3 and Python 2

More cheat sheets available at


More cheat sheets available at
Class
A classfiles
cancan
havegetobjects
long asasyou add detailed
attributes. information
This allows and
classes A list can hold as many items as you want, so you can
to
functionality.
work together To help
to model
keep complex
your program
situations.
files uncluttered, Classes
make should
a large inherit
number from object
of objects from a class and store
you can store your classes in modules and import the them
class in aClassName(object):
list.
A Battery class
classes you need into your main program. Here's an example showing how to make a fleet of rental
class Battery(): The Car
cars, and class in Python
make sure all the 2.7
cars are ready to drive.
Storing classes in a file
"""A battery for an electric car.""" Aclass Car(object):
fleet of rental cars
car.py
def __init__(self,
Storing the lines
"""Represent
size=70): gasinand
a list
electric cars.""" Child
from class
Opening a__init__()
car import
file usingmethod
Car, is different
anElectricCar
absolute path
class """Initialize battery attributes.""" class ChildClassName(ParentClass):
filename = 'siddhartha.txt' f_path = "/home/ehmatthes/books/alice.txt"
# Capacity in kWh, charge level in %.
Car(): # Make
def lists to hold a fleet of
__init__(self):
with open(filename) as cars. gas_fleet = [] as
with open(f_path) f_obj:
electric_fleet
self.size = size attempt to
"""A simple self.charge_level
model a car.""" =
f_obj: lines = super(ClassName, self).__init__()
0 --snip— = lines
[] = f_obj.readlines()
f_obj.readlines()
class def The ElectricCar class in Python 2.7
for line in lines:
get_range(self):
Battery(): #Opening
Make 500a file
gasoncars and 250 electric cars.
Windows
print(line.rstrip()) class ElectricCar(Car): def
"""A"""Return
battery for the anbattery's
electricrange."""
car.""" for _ inwill
Windows range(500):
__init__(self, sometimes interpret car
make, model,
= Car('ford',
forward slashes incorrectly. If
year):
if self.size
--snip-- == 70: 'focus',
you run into2016) gas_fleet.append(car)
this, use backslashes in your file paths. for
return 240 super(ElectricCar,
_ in range(250): self).__init__(
ecar =
class f_path
make, =
model, year)
elif self.size
ElectricCar(Car): == 85: ElectricCar('nissan', 'leaf', 2016)
Your programs can read information in from files, and "C:\Users\ehmatthes\books\alice.txt" with
electric_fleet.append(ecar)
return"""A 270simple model toofopen()
an electric car."""
they can write data to files. Reading from files allows Passing the 'w' argument tells Python you want to open(f_path) as f_obj: lines =
you to work with a wide variety of information; writing --snip--
Using
write an instance
to the file. Be as an attribute
careful; this will erase the contents of f_obj.readlines()
# Fill the gas cars, and charge electric
to files allows users to pick up where they left off the the file if itindividual
Importing already exists.
classesPassing
fromthe 'a' argument tells
a module cars. for car in gas_fleet:
class ElectricCar(Car):
Python you want to append to the end of an existing file.
next time they run your program. You can write text to my_cars.py car.fill_tank() for ecar in electric_fleet:
--snip--
files, and you can store Python structures such as Writing ecar.charge()
When you think an error may occur, you can write a
from carto__init__(self,
def an empty
import fileElectricCar
Car, make, model,
lists in data files. year): """Initialize an electric tryexcept block to handle the exception that might be raised.
filename = 'programming.txt' print("Gas
car."""
my_beetle super().__init__(make,
= Car('volkswagen', The try blockcars:", len(gas_fleet))
tells Python to try running some code, and the
Exceptions are special objects that help your with open(filename, 'w') as 'beetle', print("Electric cars:", len(electric_fleet))
model,
2016) year)
my_beetle.fill_tank() except block tells Python what to do if the code results in a
f:
programs respond to errors in appropriate ways. For my_beetle.drive()
f.write("I love programming!") particular kind of error.
example if your program tries to open a file that # Attribute specific to electric cars.
self.battery = Battery() Handling the ZeroDivisionError exception
doesn’t exist, you can use exceptions to display an Writing multiple lines to an empty file
my_tesla = ElectricCar('tesla', 'model s',
def
my_tesla.charge() try: print(5/0) except
informative error message instead of having the filename = 'programming.txt'
charge(self):
my_tesla.drive() ZeroDivisionError: print("You
program crash. with open(filename,
"""Fully charge 'w')
theasvehicle."""
f: can't divide by zero!")
self.battery.charge_level = 100
f.write("I
Importing entire love
an vehicle module programming!\n")
print("The is fully charged.")
f.write("I love creating new games.\n") Handling the FileNotFoundError exception
import car
To read from a file your program needs to open the file and Using the instance
then read the contents of the file. You can read the entire
Appending to a file f_name = 'siddhartha.txt' try: with
my_ecar
my_beetle = ElectricCar('tesla',
= car.Car( 'model x', 2016) open(f_name) as f_obj: lines =
contents of the file at once, or read the file line by line. The filename = 'programming.txt'
'volkswagen',
with open(filename, 'a') as 'beetle', 2016) f_obj.readlines() except FileNotFoundError:
with statement makes sure the file is closed properly when
my_ecar.charge()
my_beetle.fill_tank()
f: msg = "Can't find file {0}.".format(f_name)
the program has finished accessing the file.
my_beetle.drive()
print(my_ecar.battery.get_range())
f.write("I also love working with data.\n") print(msg)
Reading an entire file at once my_ecar.drive()
f.write("I love making apps as well.\n")
my_tesla = car.ElectricCar(
filename = 'siddhartha.txt' 'tesla', 'model s', 2016)
with open(filename) as my_tesla.charge()
f_obj: contents =
my_tesla.drive()
When Python runs the open() function, it looks for the file in
f_obj.read()
the same directory where the program that's being excuted
Importing all classes from a module It can be hard to know what kind of exception to handle
print(contents) is stored.
(Don’t do this,You
but can open itawhen
recognize file from a subfolder
you see it.) using a
relative path. You can also use an absolute path to open when writing
C code. Try writing your code without a try block,
from car
any file onimport *
your system. and make it generate an error. The traceback will tell you
what kind of exception your program needs to handle.
my_beetle = Car('volkswagen', 'beetle', 2016)
Reading line by line
The try block should only contain code that may cause an
Each line that's read from the file has a newline character at the
error.
end ofAny
thecode thatthe
line, and depends on the
print function try its
adds block
ownrunning
newline Sometimes you want your program to just continue running
successfully should be placed in the else block.
character. The rstrip() method gets rid of the the extra blank lines when it encounters an error, without reporting the error to
overs Python 3 and Python 2
this would result in when printing to the terminal. the user. Using the pass statement in an else block allows
Using an else block
you to do this.
filename = 'siddhartha.txt'
print("Enter two numbers. I'll divide them.")
with open(filename) as Using the pass statement in an else block
f_obj: for line in Opening a file from a subfolder
x = input("First number: ") y f_names = ['alice.txt', 'siddhartha.txt',
f_obj:
= input("Second number: ") 'moby_dick.txt',code
Exception-handling 'little_women.txt']
should catch specific exceptions
print(line.rstrip())
try: result = int(x) / int(y) for
that youf_name
expect in
to happen during your program's execution.
except ZeroDivisionError: Af_names:
bare except block will catch all exceptions, including
print("You can't divide by zero!") # Report
keyboard theand
interrupts length
systemofexits
each
youfile
might need when
else: print(result) found.a program
forcing try: to close. with open(f_name)
as f_obj: lines =
Iff_obj.readlines()
you want to use a try blockexcept
and you're not sure which
FileNotFoundError:
f_path to= catch,
exception "text_files/alice.txt"
use Exception. It will catch most
#butJust
still move
with open(f_path)
exceptions, on
as to
allow you the next
f_obj:
to interrupt programs
Preventing crashes from user input file. pass else:
Without the except block in the following example, the program
lines = f_obj.readlines()
intentionally.
num_lines
for line= in len(lines)
lines:
would crash if the user tries to divide by zero. As written, it will
Don’t use msg
bare=except
"{0} has
print(line.rstrip()) blocks
{1}
handle the error gracefully and keep running.
lines.".format( f_name,
try:
"""A simple calculator for division only.""" num_lines) print(msg)
# Do
something except:
print("Enter two numbers. I'll divide them.")
print("Enter 'q' to quit.") pass
while True: x = Use Exception instead
input("\nFirst number: ") if
x == 'q': break y = try: The json module allows you to dump simple Python data
input("Second number: ") if # Do something structures into a file, and load the data from that file the
y == 'q': break except Exception: next time the program runs. The JSON data format is not
try: result = int(x) / pass specific to Python, so you can share this kind of data with
int(y) except ZeroDivisionError: people who work in other languages as well.
print("You can't divide by zero!") Printing the exception
else: print(result) try: Knowing how to manage exceptions is important when
# Do something working with stored data. You'll usually want to make sure
except Exception as e: the data you're trying to load exists before working with it.
print(e, type(e)) Using json.dump() to store data
"""Store some numbers."""

import json

Well-written, properly tested code is not very prone to numbers = [2, 3, 5, 7, 11, 13]
internal errors such as syntax or logical errors. But every
time your program depends on something external such
filename = 'numbers.json' with
as user input or the existence of a file, there's a possibility
open(filename, 'w') as f_obj:
of an exception being raised.
json.dump(numbers, f_obj)
It's up to you how to communicate errors to your users. Using json.load() to read data
Sometimes users need to know if a file is missing;
sometimes it's better to handle the error silently. A little
experience will help you know how much to report. More cheat sheets available at
"""Load some previously stored numbers.""" Practice with exceptions
Take a program you've already written that prompts for
import json user input, and add some error-handling code to the
When you write a function or a class, you can also Building a testcase with one unit test program.
write tests for that code. Testing proves that your To build a test case, make a class that inherits from
filename = 'numbers.json' unittest.TestCase and write methods that begin with test_.
code
withworks as it's supposed
open(filename) to in the situations it's
as f_obj:
designed to handle, and also when people use your Save this as test_full_names.py More cheat sheets available at
numbers = json.load(f_obj)
programs in unexpected ways. Writing tests gives import unittest Running the test
from full_names import get_full_name When you change your code, it’s important to run your existing
you confidence that your code will work correctly as
print(numbers) tests. This will tell you whether the changes you made affected
more people begin to use your programs. You can class
existing behavior.
Making
also addsure
new the storedtodata
features yourexists
programs and know NamesTestCase(unittest.TestCase):
"""Tests for names.py.""" E
that you haven't
import json broken existing behavior.
def =============================================
test_first_last(self): === ERROR: test_first_last
Af_name
unit test= verifies that one specific aspect of your
'numbers.json' """Test names like Janis Joplin.""" (__main__.NamesTestCase)
code
try:works as it's supposed to. Aas
with open(f_name) test case is a
f_obj: full_name = get_full_name('janis', Test names like Janis Joplin.
collection of unit tests which verify your code's
numbers = json.load(f_obj) except 'joplin') ---------------------------------------------
FileNotFoundError:
behavior in a wide variety ofmsg = "Can’t find
situations. self.assertEqual(full_name, ---
{0}.".format(f_name) print(msg) else: 'Janis Joplin') Traceback (most recent call last):
print(numbers) File "test_full_names.py", line 10,
unittest.main() in test_first_last
Running the test 'joplin')
Python reports on each unit test in the test case. The dot reports a TypeError: get_full_name() missing 1 required
single passing test. Python informs us that it ran 1 test in less than positional argument: 'last'
0.001 seconds, and the OK lets us know that all unit tests in the
test case passed. ---------------------------------------------
. ---
--------------------------------------- Ran 1 test in 0.001s
Ran 1 test in 0.000s
FAILED (errors=1)
Python's unittest module provides tools for testing your OK
Fixing the code
code. To try it out, we’ll create a function that returns a full
name. We’ll use the function in a regular program, and then When a test fails, the code needs to be modified until the test
build a test case for the function. passes again. (Don’t make the mistake of rewriting your tests
Failing tests are important; they tell you that a change in the to fit your new code.) Here we can make the middle name
A function to test code has affected existing behavior. When a test fails, you optional. def get_full_name(first, last,
Save this as full_names.py need to modify the code so the existing behavior still works. middle=''): """Return a full name."""
def get_full_name(first, last): if middle: full_name = "{0} {1}
Modifying the function {2}".format(first,
"""Return a full name.""" We’ll modify get_full_name() so it handles middle names, but
full_name = "{0} {1}".format(first, last) middle, last) else: full_name =
we’ll do it in a way that breaks existing behavior.
return full_name.title() "{0} {1}".format(first,
def get_full_name(first, middle, last): last) return full_name.title() Running
Using the function """Return a full name."""
Save this as names.py
the test
full_name = "{0} {1} {2}".format(first, Now the test should pass again, which means our original
from full_names import get_full_name middle, last) return full_name.title() functionality is still intact.

.
janis = get_full_name('janis', 'joplin') Using the function ---------------------------------------
print(janis)
from full_names import get_full_name Ran 1 test in 0.000s
bob = get_full_name('bob', 'dylan')
O
C
print(bob) john = get_full_name('john', 'lee', 'hooker')
print(john) K

david = get_full_name('david', 'lee', 'roth')


print(david)
overs Python 3 and Python 2

More cheat sheets available at


You can add as many unit tests to a test case as you need. Testing a class is similar to testing a function, since you’ll When testing a class, you usually have to make an instance
To write a new test, add a new method to your test case mostly be testing your methods. of the class. The setUp() method is run before every test.
class. Any instances you make in setUp() are available in every
A class to test
Testing middle names test you write.
Save as accountant.py
We’ve shown that get_full_name() works for first and last Using setUp() to support multiple tests
names. Let’s test that it works for middle names as well. class Accountant(): The instance self.acc can be used in each new test.
"""Manage a bank account."""
import unittest def __init__(self, import unittest
from full_names import get_full_name balance=0): from accountant import Accountant class
class self.balance = balance TestAccountant(unittest.TestCase):
NamesTestCase(unittest.TestCase): def """Tests for the class Accountant."""
"""Tests for names.py.""" deposit(self, amount): def setUp(self):
def self.balance += amount self.acc = Accountant()
test_first_last(self): def def test_initial_balance(self):
"""Test names like Janis Joplin.""" # Default balance should be 0.
withdraw(self, amount):
full_name = get_full_name('janis', self.assertEqual(self.acc.balance, 0)
self.balance -= amount
'joplin') # Test non-default balance.
self.assertEqual(full_name, Building a testcase acc = Accountant(100)
For the first test, we’ll make sure we can start out with different self.assertEqual(acc.balance, 100)
'Janis Joplin')
initial balances. Save this as test_accountant.py. def
def
test_deposit(self): #
test_middle(self): import unittest Test single deposit.
"""Test names like David Lee Roth.""" from accountant import Accountant self.acc.deposit(100)
full_name = get_full_name('david', class self.assertEqual(self.acc.balance, 100)
'roth', 'lee') TestAccountant(unittest.TestCase):
self.assertEqual(full_name, """Tests for the class Accountant."""
'David Lee Roth') # Test multiple deposits.
def
self.acc.deposit(100)
test_initial_balance(self): #
unittest.main() self.acc.deposit(100)
Default balance should be 0.
self.assertEqual(self.acc.balance, 300)
acc = Accountant()
Running the tests def
self.assertEqual(acc.balance, 0)
The two dots represent two passing tests. test_withdrawal(self): #
Test single withdrawal.
.. # Test non-default balance. self.acc.deposit(1000)
--------------------------------------- acc = Accountant(100) self.acc.withdraw(100)
Ran 2 tests in 0.000s self.assertEqual(acc.balance, 100) self.assertEqual(self.acc.balance, 900)
unittest.main()
OK unittest.main()
Running the test
.
Python provides a number of assert methods you can use ---------------------------------------
to test your code. Ran 1 test in 0.000s
Running the tests
Verify that a==b, or a != b OK

C
assertEqual(a, b) ...
assertNotEqual(a, b) ---------------------------------------
Ran 3 tests in 0.001s
Verify that x is True, or x is False In general you shouldn’t modify a test once it’s written.
When a test fails it usually means new code you’ve written
assertTrue(x) has broken existing functionality, and you need to modify OK
assertFalse(x) the new code until all existing tests pass.
If your original requirements have changed, it may be
Verify an item is in a list, or not in a list
appropriate to modify some tests. This usually happens in
assertIn(item, list) the early stages of a project when desired behavior is still
assertNotIn(item, list) being sorted out.

Pygame is a framework for making games using Python. Making games is fun, and it’s a great way to expand your programming skills and knowledge. Pygame takes care of
many of the lower-level tasks in building games, which lets you focus on the aspects of your game that make it interesting.

Pygame runs on all systems, but setup is slightly different The following code sets up an empty game window, and
on each OS. The instructions here assume you’re using starts an event loop and a loop that continually refreshes Useful rect attributes
Python 3, and provide a minimal installation of Pygame. If the screen. Once you have a rect object, there are a number of attributes that
are useful when positioning objects and detecting relative positions
these instructions don’t work for your system, see the more
detailed notes at http://ehmatthes.github.io/pcc/.
An empty game window of objects. (You can find more attributes in the Pygame
documentation.)
Pygame on Linux # Individual x and y values:
screen_rect.left, screen_rect.right
$ sudo apt-get install python3-dev
screen_rect.top, screen_rect.bottom
mercurial libsdl-image1.2-dev libsdl2-
screen_rect.centerx, screen_rect.centery
dev libsdl-ttf2.0-dev $ pip install
screen_rect.width, screen_rect.height
--user
hg+http://bitbucket.org/pygame/pygame
# Tuples
Pygame on OS X screen_rect.center
This assumes you’ve used Homebrew to install Python 3. screen_rect.size
$ brew install hg sdl sdl_image sdl_ttf Creating a rect object
$ pip install --user You can create a rect object from scratch. For example a small rect
hg+http://bitbucket.org/pygame/pygame object that’s filled in can represent a bullet in a game. The Rect()
class takes the coordinates of the upper left corner, and the width
Pygame on Windows and height of the rect. The draw.rect() function takes a screen
Find an installer at object, a color, and a rect. This function fills the given rect with the
https://bitbucket.org/pygame/pygame/downloads/ or given color.
http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame that matches bullet_rect = pg.Rect(100, 100, 3, 15)
your version of Python. Run the installer file if it’s a .exe or .msi
color = (100, 100, 100)
file.
pg.draw.rect(screen, color, bullet_rect)

More cheat sheets available at


If it’s a .whl file, use pip to install Pygame: import sys
import pygame as pg
def
Many objects in a game are images that are moved around
run_game():
# Initialize and set up screen. the screen. It’s easiest to use bitmap (.bmp) image files, but
pg.init() screen = you can also configure your system to work with jpg, png,
> python –m pip install --user pygame- pg.display.set_mode((1200, 800)) and gif files as well.
1.9.2a0-cp35-none-win32.whl pg.display.set_caption("Alien Invasion") Loading an image
Testing your installation # Start main loop. ship = pg.image.load('images/ship.bmp')
To test your installation, open a terminal session and try to import
while True:
Pygame. If you don’t get any error messages, your installation was
# Start event loop. Getting the rect object from an image
successful.
for event in pg.event.get(): ship_rect = ship.get_rect()
$ python if event.type == pg.QUIT:
>>> import pygame sys.exit() Positioning an image
>>> With rects, it’s easy to position an image wherever you want on the
# Refresh screen. screen, or in relation to another object. The following code
pg.display.flip() positions a ship object at the bottom center of the screen.
ship_rect.midbottom = screen_rect.midbottom
run_game()
Setting a custom window size
The display.set_mode() function accepts a tuple that defines the
screen size.
screen_dim = (1200, 800)
screen = pg.display.set_mode(screen_dim)
Setting a custom background color
Colors are defined as a tuple of red, green, and blue values. Each
value ranges from 0-255.
bg_color = (230, 230, 230)
screen.fill(bg_color)

Many objects in a game can be treated as simple


rectangles, rather than their actual shape. This simplifies
code without noticeably affecting game play. Pygame has a
rect object that makes it easy to work with game objects.
Getting the screen rect object
We already have a screen object; we can easily access the rect
object associated with the screen.

screen_rect = screen.get_rect() Covers Python 3 and Python 2


Finding the center of the screen
Rect objects have a center attribute which stores the center point.

screen_center = screen_rect.center

C
Pygame watches for events such as key presses and Pygame
Pygame’shas a Group
event class which
loop registers makesany
an event working with a
time the You can detect when a single object collides with any
mouse actions. You can detect any event you care about in group of similar objects easier. A group is like a list,
mouse moves, or a mouse button is pressed or released. with member of a group. You can also detect when any member
Drawing
the an image
event loop, to the screen
and respond with any action that’s some extra functionality that’s helpful when building games. of one group collides with a member of another group.
Once an image is loaded and positioned, you can draw it to the
appropriate for your game. Responding to the mouse button
screen with the blit() method. The blit() method acts on the screen Making and filling a group Collisions between a single object and a group
for event in bepg.event.get(): if from Sprite. Removing an item from a group
Responding tothe
object, and takes key presses
image object and image rect as arguments. An object that will placed in a group must inherit The spritecollideany() function takes an object and a group, and
It’s important to delete elements that will never appear again in the
Pygame’s event.type == pg.MOUSEBUTTONDOWN: returns True if the object overlaps with any member of the group.
# Draw main
shipevent loop registers a KEYDOWN event any time a
to screen. from pygame.sprite import Sprite, Group game, so you don’t waste memory and resources.
key is pressed. When this happens, you can check for specific ship.fire_bullet()
screen.blit(ship, ship_rect) def if pg.sprite.spritecollideany(ship, aliens):
keys.
Finding the mouse position
Bullet(Sprite): ships_left -= 1
The blitme() method
for event in pg.event.get(): bullets.remove(bullet)
... position
The mouse defis returned as a tuple.
Game objects such as ships are often written as classes. Then a
if event.type == pg.KEYDOWN: draw_bullet(self): Collisions between two groups
blitme() method is usually defined, which draws the object to the
if event.key == pg.K_RIGHT: mouse_pos = pg.mouse.get_pos() The sprite.groupcollide() function takes two groups, and two
screen. ...
ship_rect.x += 1 booleans. The function returns a dictionary containing information
def blitme(self):
Clicking
defaupdate(self):
button about the members that have collided. The booleans tell Pygame
elif event.key == pg.K_LEFT: ...to know if the cursor is over an object such as a
You might want
"""Draw ship_rect.x
ship at current whether to delete the members of either group that have collided.
-= 1 location.""" button. The rect.collidepoint() method returns true when a point is
self.screen.blit(self.image,
elif event.key == pg.K_SPACE: self.rect) inside a rect=object. collisions =
bullets Group()
ship.fire_bullet() elif pg.sprite.groupcollide( bullets,
if button_rect.collidepoint(mouse_pos): aliens, True, True)
event.key == pg.K_q: new_bullet = Bullet()
start_game()
sys.exit() bullets.add(new_bullet)
Hiding the mouse score += len(collisions) * alien_point_value
Responding to released keys Looping through the items in a group
When the user releases a key, a KEYUP event is triggered. pg.mouse.set_visible(False) You can use text for a variety of purposes in a game. For
The sprites() method returns all the members of a group.
example you can share information with players, and you
if event.type == pg.KEYUP: for bullet in bullets.sprites(): can display a score. Displaying a message
if event.key == pg.K_RIGHT:
bullet.draw_bullet() The following code defines a message, then a color for the text and
ship.moving_right = False
the background color for the message. A font is defined using the
Calling update() on a group
default system font, with a font size of 48. The font.render() function is used to create an image of the message, and we get the rect object
Calling update() on a group automatically calls update() on each
associated with the image. We then center the image on the screen and display it. msg = "Play again?" msg_color = (100,
member of the group.
100, 100) bg_color = (230, 230, 230)
bullets.update()

f = pg.font.SysFont(None, 48)
msg_image = f.render(msg, True, msg_color,
The Pygame documentation is really helpful when building bg_color)
your own games. The home page for the Pygame project is msg_image_rect = msg_image.get_rect() at http://pygame.org/, and the home page for the msg_image_rect.center =
screen_rect.center documentation is at http://pygame.org/docs/. screen.blit(msg_image, msg_image_rect)
The most useful part of the documentation are the pages
about specific parts of Pygame, such as the Rect() class and the sprite module. You can find a list of these elements at the
top of the help pages.

Making a scatter plot


The scatter() function takes a list of x values and a list of y values, and a variety of optional arguments. The s=10 argument controls the size of each point.

More cheat sheets available at


import matplotlib.pyplot as plt

x_values = list(range(1000)) squares = [x**2 for x in x_values]

plt.scatter(x_values, squares, s=10) plt.show()

Plots can be customized in a wide variety of ways. Just


about any element of a plot can be customized. Emphasizing points
You can plot as much data as you want on one plot. Here we replot
Adding titles and labels, and scaling axes the first and last points larger to emphasize them.
import matplotlib.pyplot as plt import matplotlib.pyplot as plt

x_values = list(range(1000)) x_values = list(range(1000)) squares =


squares = [x**2 for x in x_values] [x**2 for x in x_values]
plt.scatter(x_values, squares, plt.scatter(x_values, squares, c=squares,
s=10) cmap=plt.cm.Blues, edgecolor='none',
s=10)
Data visualization involves exploring data through plt.scatter(x_values[0], squares[0], c='green',
plt.title("Square Numbers", fontsize=24)
visual representations. The matplotlib package helps plt.xlabel("Value", fontsize=18) edgecolor='none', s=100)
you make visually appealing representations of the plt.ylabel("Square of Value", fontsize=18) plt.scatter(x_values[-1], squares[-1], c='red',
data you’re working with. matplotlib is extremely plt.tick_params(axis='both', edgecolor='none', s=100)
flexible; these examples will help you get started with which='major',
labelsize=14) plt.axis([0, 1100, 0, plt.title("Square Numbers", fontsize=24)
a few simple visualizations.
1100000]) --snip--

plt.show()
Removing axes
matplotlib runs on all systems, but setup is slightly different Using a colormap You can customize or remove axes entirely. Here’s how to access
depending on your OS. If the minimal instructions here A colormap varies the point colors from one shade to another, each axis, and hide it.
don’t work for you, see the more detailed instructions at based on a certain value for each point. The value used to
determine the color of each point is passed to the c argument, and plt.axes().get_xaxis().set_visible(False)
http://ehmatthes.github.io/pcc/. You should also consider
the cmap argument specifies which colormap to use. plt.axes().get_yaxis().set_visible(False)
installing the Anaconda distrubution of Python from
The edgecolor='none' argument removes the black outline
https://continuum.io/downloads/, which includes matplotlib. from each point.
Setting a custom figure size
You can make your plot as big or small as you want. Before
matplotlib on Linux plt.scatter(x_values, squares, c=squares, plotting your data, add the following code. The dpi argument is
cmap=plt.cm.Blues, edgecolor='none', optional; if you don’t know your system’s resolution you can omit
$ sudo apt-get install python3-matplotlib
s=10) the argument and adjust the figsize argument accordingly.
matplotlib on OS X plt.figure(dpi=128, figsize=(10, 6))
Start a terminal session and enter import matplotlib to see if
it’s already installed on your system. If not, try this command: Saving a plot
The matplotlib viewer has an interactive save button, but you can
$ pip install --user matplotlib also save your visualizations programmatically. To do so, replace
plt.show() with plt.savefig(). The bbox_inches='tight'
matplotlib on Windows argument trims extra whitespace from the plot.
You first need to install Visual Studio, which you can do from
https://dev.windows.com/. The Community edition is free. Then go plt.savefig('squares.png', bbox_inches='tight')
to https://pypi.python.org/pypi/matplotlib/ or
http://www.lfd.uic.edu/~gohlke/pythonlibs/#matplotlib and download
an appropriate installer file. C
The matplotlib gallery and documentation are at
http://matplotlib.org/. Be sure to visit the examples, gallery,
Making a line graph and pyplot links.
import matplotlib.pyplot as plt

x_values = [0, 1, 2, 3, 4, 5]
squares = [0, 1, 4, 9, 16, 25]
Covers Python 3 and Python 2
plt.plot(x_values, squares)
plt.show()

You can make as many plots as you want on one figure. You can include as many individual graphs in one figure as
When you make multiple plots, you can emphasize Datetime formatting arguments
you want. This is useful, for example, when comparing
relationships in the data. For example you can fill the space The strftime() function generates a formatted string from a
datetime object, and the strptime() function genereates a
related datasets.
between two sets of data.
datetime object from a string. The following codes let you work with Sharing an x-axis
Plotting two sets of data dates exactly as you need to. The following code plots a set of squares and a set of cubes on
Here we use plt.scatter() twice to plot square numbers and %A Weekday name, such as Monday two separate graphs that share a common x-axis.
cubes on the same figure. The plt.subplots() function returns a figure object and a tuple
%B Month name, such as January
of axes. Each set of axes corresponds to a separate plot in the
import matplotlib.pyplot as plt %m Month, as a number (01 to 12) figure. The first two arguments control the number of rows and
%d Day of the month, as a number (01 to 31) columns generated in the figure.
x_values = list(range(11)) %Y Four-digit year, such as 2016 import matplotlib.pyplot as plt
squares = [x**2 for x in %y Two-digit year, such as 16
x_values] cubes = [x**3 for x in %H Hour, in 24-hour format (00 to 23) x_vals = list(range(11))
x_values] %I Hour, in 12-hour format (01 to 12) squares = [x**2 for x in
%p AM or PM x_vals] cubes = [x**3 for x in
plt.scatter(x_values, squares, c='blue', %M Minutes (00 to 59) x_vals]
edgecolor='none', s=20) plt.scatter(x_values, %S Seconds (00 to 61)
cubes, c='red', edgecolor='none', s=20) fig, axarr = plt.subplots(2, 1, sharex=True)
Converting a string to a datetime object
plt.axis([0, 11, 0, 1100]) new_years = dt.strptime('1/1/2017', '%m/%d/%Y') axarr[0].scatter(x_vals, squares)
plt.show() axarr[0].set_title('Squares')
Converting a datetime object to a string
Filling the space between data sets ny_string = dt.strftime(new_years, '%B %d, %Y')
The fill_between() method fills the space between two data axarr[1].scatter(x_vals, cubes, c='red')
print(ny_string) axarr[1].set_title('Cubes')
sets. It takes a series of x-values and two series of y-values. It also
takes a facecolor to use for the fill, and an optional alpha Plotting high temperatures
argument that controls the color’s transparency. The following code creates a list of dates and a corresponding list
plt.show()

plt.fill_between(x_values, cubes, squares, of high temperatures. It then plots the high temperatures, with the Sharing a y-axis
date labels displayed in a specific format. To share a y-axis, we use the sharey=True argument.
facecolor='blue', alpha=0.25)

More cheat sheets available at


from datetime import datetime as dt import matplotlib.pyplot as plt

import matplotlib.pyplot as plt from x_vals = list(range(11))


Many interesting data sets have a date or time as the matplotlib import dates as mdates squares = [x**2 for x in
xvalue. Python’s datetime module helps you work with this dates = [ dt(2016, 6, 21), x_vals] cubes = [x**3 for x in
kind of data. dt(2016, 6, 22), dt(2016, 6, x_vals]
Generating the current date 23), dt(2016, 6, 24),
The datetime.now() function returns a datetime object ] fig, axarr = plt.subplots(1, 2, sharey=True)
representing the current date and time. highs = [57, 68, 64, 59]
axarr[0].scatter(x_vals, squares)
from datetime import datetime as dt
fig = plt.figure(dpi=128, figsize=(10,6)) axarr[0].set_title('Squares')
plt.plot(dates, highs, c='red')
today = dt.now() plt.title("Daily High Temps", fontsize=24) axarr[1].scatter(x_vals, cubes, c='red')
date_string = dt.strftime(today, '%m/%d/%Y') plt.ylabel("Temp (F)", fontsize=16) axarr[1].set_title('Cubes')
print(date_string)
Generating a specific date x_axis = plt.axes().get_xaxis() plt.show()
You can also generate a datetime object for any date and time you x_axis.set_major_formatter(
want. The positional order of arguments is year, month, and day. mdates.DateFormatter('%B %d %Y')
The hour, minute, second, and microsecond arguments are )
optional. fig.autofmt_xdate()
from datetime import datetime as dt
plt.show()
new_years = dt(2017, 1, 1)
fall_equinox = dt(year=2016, month=9, day=22)

You can add as much data as you want when making a


Data visualization involves exploring data through Making a scatter plot
visualization.
visual representations. Pygal helps you make visually The data for a scatter plot needs to be a list containing tuples of
appealing representations of the data you’re working
the form (x, y). The stroke=False argument tells Pygal to make Plotting squares and cubes
an XY chart with no line connecting the points.
with. Pygal is particularly well suited for visualizations import pygal
import pygal
that will be presented online, because it supports
interactive elements. x_values = list(range(11))
squares = [ squares = [x**2 for x in
(0, 0), (1, 1), (2, 4), (3, 9), x_values] cubes = [x**3 for x in
(4, 16), (5, 25), x_values]
]
chart = pygal.XY(stroke=False) chart = pygal.Line()
chart.force_uri_protocol = 'http' chart.force_uri_protocol = 'http'
chart.add('x^2', squares) chart.title = "Squares and Cubes"
chart.render_to_file('squares.svg') chart.x_labels = x_values

Using a list comprehension for a scatter plot chart.add('Squares', squares)


Pygal can be installed using pip. A list comprehension can be used to effficiently make a dataset for chart.add('Cubes', cubes)
a scatter plot. chart.render_to_file('squares_cubes.svg')
Pygal on Linux and OS X
squares = [(x, x**2) for x in range(1000)] Filling the area under a data series
$ pip install --user pygal Pygal allows you to fill the area under or over each series of data.
The default isCto fill from the x-axis up, but you can fill from any
Making a bar graph
Pygal on Windows A bar graph requires a list of values for the bar sizes. To label the horizontal line using the zero argument.
bars, pass a list of the same length to x_labels.
> python –m pip install --user pygal
import pygal chart = pygal.Line(fill=True, zero=0)

outcomes = [1, 2, 3, 4, 5, 6]
To make a plot with Pygal, you specify the kind of plot and
frequencies = [18, 16, 18, 17, 18, 13]
then add the data.
Making a line graph chart = pygal.Bar()
To view the output, open the file squares.svg in a browser. chart.force_uri_protocol = 'http'
chart.x_labels = outcomes
import pygal chart.add('D6', frequencies)
chart.render_to_file('rolling_dice.svg')
x_values = [0, 1, 2, 3, 4, 5]
squares = [0, 1, 4, 9, 16, 25] Making a bar graph from a dictionary
Since each bar needs a label and a value, a dictionary is a great
way to store the data for a bar graph. The keys are used as the
chart = pygal.Line()
labels along the x-axis, and the values are used to determine the
chart.force_uri_protocol = 'http' The documentation for Pygal is available at
height of each bar.
chart.add('x^2', squares) http://www.pygal.org/.
import pygal
chart.render_to_file('squares.svg')
Adding labels and a title results = {
1:18, 2:16, 3:18, If you’re viewing svg output in a browser, Pygal needs to
--snip-- 4:17, 5:18, 6:13, render the output file in a specific way. The
chart = pygal.Line()
} force_uri_protocol attribute for chart objects needs to
chart.force_uri_protocol = 'http' chart = pygal.Bar()
chart.title = "Squares" be set to 'http'.
chart.force_uri_protocol = 'http'
chart.x_labels = x_values
chart.x_labels = results.keys() chart.add('D6',
chart.x_title = "Value"
chart.y_title = "Square of Value" results.values())
chart.add('x^2', squares) chart.render_to_file('rolling_dice.svg')
chart.render_to_file('squares.svg') Covers Python 3 and Python 2

More cheat sheets available at


Pygal lets you customize many elements of a plot. There Pygal can generate world maps, and you can add any data
are some excellent default themes, and many options for Configuration settings you want to these maps. Data is indicated by coloring, by
Some settings are controlled by a Config object.
labels, and by tooltips that show data when users hover
styling individual plot elements.
my_config = pygal.Config() over each country on the map.
Using built-in styles my_config.show_y_guides = False
To use built-in styles, import the style and make an instance of the
my_config.width = 1000 Installing the world map module
style class. Then pass the style object with the style argument The world map module is not included by default in Pygal 2.0. It
my_config.dots_size = 5
when you make the chart object. can be installed with pip:
import pygal chart = pygal.Line(config=my_config)
$ pip install --user pygal_maps_world
from pygal.style import LightGreenStyle --snip--
Making a world map
x_values = list(range(11)) Styling series The following code makes a simple world map showing the
squares = [x**2 for x in countries
You can give each series on a chart different of North
style America.
settings.
x_values] cubes = [x**3 for x in chart.add('Squares', squares, from pygal.maps.world import World
dots_size=2)
x_values] chart.add('Cubes', cubes, dots_size=3)
wm = World()
chart_style = LightGreenStyle() Styling individual data points
wm.force_uri_protocol = 'http'
chart = You can style individual data points as well. To do so, write a
wm.title = 'North America'
pygal.Line(style=chart_style) dictionary for each data point you want to customize. A 'value'
wm.add('North America', ['ca', 'mx', 'us'])
key is required, and other properies are optional.
chart.force_uri_protocol = 'http'
chart.title = "Squares and Cubes" import pygal wm.render_to_file('north_america.svg')
chart.x_labels = x_values
repos = [ Showing all the country codes
chart.add('Squares', squares) { In order to make maps, you need to know Pygal’s country codes.
chart.add('Cubes', cubes) 'value': 20506, The following example will print an alphabetical list of each country
chart.render_to_file('squares_cubes.svg') and its code.
'color': '#3333CC',
Parametric built-in styles from pygal.maps.world import COUNTRIES
'xlink': 'http://djangoproject.com/',
Some built-in styles accept a custom color, then generate a theme }, for code in
based on that color. 20054, sorted(COUNTRIES.keys()):
from pygal.style import LightenStyle 12607, print(code, COUNTRIES[code])
11827, Plotting numerical data on a world map
--snip-- chart_style = ] To plot numerical data on a map, pass a dictionary to add()
LightenStyle('#336688') chart = chart = pygal.Bar() instead of a list.
pygal.Line(style=chart_style) chart.force_uri_protocol = 'http'
chart.x_labels = [ from pygal.maps.world import World
--snip--
'django', 'requests', 'scikit-learn',
Customizing individual style properties 'tornado', populations =
Style objects have a number of properties you can set individually. ] { 'ca':
chart_style = LightenStyle('#336688') 34126000,
chart.y_title = 'Stars'
chart.add('Python Repos', repos) 'us': 309349000,
chart_style.plot_background = '#CCCCCC'
'mx': 113423000,
chart.render_to_file('python_repos.svg')
chart_style.major_label_font_size = 20
}
chart_style.label_font_size = 16
wm = World()
--snip--
wm.force_uri_protocol = 'http' wm.title
Custom style class = 'Population of North America'
You can start with a bare style class, and then set only the wm.add('North America', populations)
properties you care about.
chart_style = Style() wm.render_to_file('na_populations.svg')
chart_style.colors = [
'#CCCCCC', '#AAAAAA', '#888888'] C
chart_style.plot_background = '#EEEEEE'

chart = pygal.Line(style=chart_style)
--snip--
More cheat sheets available at

The data in a Django project is structured as a set of Users interact with a project through web pages, and a
models. project’s home page can start out as a simple page with no
data. A page usually needs a URL, a view, and a template.
Defining a model
To define the models for your app, modify the file models.py that Mapping a project’s URLs
was created in your app’s folder. The __str__() method tells The project’s main urls.py file tells Django where to find the urls.py
Django how to represent data objects based on this model. files associated with each app in the project.
from django.db import from django.conf.urls import include, url
Django is a web framework which helps you build models class from django.contrib import admin
Topic(models.Model):
interactive websites using Python. With Django you """A topic the user is learning about.""" urlpatterns = [
define the kind of data your site needs to work with, text = models.CharField(max_length=200) url(r'^admin/',
and you define the ways your users can work with date_added = include(admin.site.urls)), url(r'',
that data. models.DateTimeField( auto_now_add=
include('learning_logs.urls',
True)
namespace='learning_logs')), ]
def
__str__(self): Mapping an app’s URLs
It’s usualy best to install Django to a virtual environment, return self.text An app’s urls.py file tells Django which view to use for each URL in
where your project can be isolated from your other Python the app. You’ll need to make this file yourself, and save it in the
projects. Most commands assume you’re working in an
Activating a model app’s folder.
To use a model the app must be added to the tuple
active virtual environment. from django.conf.urls import url
INSTALLED_APPS, which is stored in the project’s settings.py file.
Create a virtual environment INSTALLED_APPS = ( from . import views
$ python –m venv ll_env --snip--
'django.contrib.staticfiles', urlpatterns = [
Activate the environment (Linux and OS X)
url(r'^$', views.index, name='index'),
$ source ll_env/bin/activate # My apps ]
'learning_logs',
Activate the environment (Windows) ) Writing a simple view
> ll_env\Scripts\activate A view takes information from a request and sends data to the
Migrating the database browser, often through a template. View functions are stored in an
Install Django to the active environment The database needs to be modified to store the kind of data that app’s views.py file. This simple view function doesn’t pull in any
the model represents. data, but it uses the template index.html to render the home page.
(ll_env)$ pip install Django
$ python manage.py makemigrations learning_logs from django.shortcuts import render
$ python manage.py migrate def
index(request):
Creating a superuser """The home page for Learning Log."""
To start a project we’ll create a new project, create a A superuser is a user account that has access to all aspects of the return render(request,
database, and start a development server. project.
'learning_logs/index.html')
Create a new project $ python manage.py createsuperuser

More cheat sheets available at


$ django-admin.py startproject learning_log . Registering a model
Most pages
You can in ayour
register project need
models with to present
Django’s datasite,
admin that’s specific
which
Create a database to the current
makes it easieruser.
to work with the data in your project. To do this,
The documentation for Django is available at
$ python manage.py migrate URL
modifyparameters
the app’s admin.py file. View the admin site at
http://docs.djangoproject.com/. The Django documentation
Ahttp://localhost:8000/admin/.
URL often needs to accept a parameter telling it which data to
View the project access is thorough and user-friendly, so check it out!
from from the database. The
django.contrib second admin
import URL pattern shown here
After issuing this command, you can view the project at looks for the ID of a specific topic and stores it in the parameter
http://localhost:8000/. topic_id.
from learning_logs.models import Topic
$ python manage.py runserver urlpatterns = [
url(r'^$', views.index, Covers Python 3 and Python 2
Create a new app admin.site.register(Topic)
name='index'), url(r'^topics/(?
A Django project is made up of one or more apps. P<topic_id>\d+)/$',
$ python manage.py startapp learning_logs views.topic, name='topic'), ]

A new model can use an existing model. The ForeignKey


attribute establishes a connection between instances of the
two related models. Make sure to migrate the database
Writing a simple
after adding template
a new model to your app.
A template sets up the structure for a page. It’s a mix of html and
Defining
template a model
code, with
which is like a foreign
Python but not key
powerful.
as Make a
folder called templates inside the project folder. Inside the
class folder
templates Entry(models.Model):
make another folder with the same name as the
"""Learning
app. This log entries
is where the template for
files should be a
saved.
Many elements of a web page are repeated on every page topic.""" topic =
in the site, or every page in a section of the site. By writing models.ForeignKey(Topic) text =
one parent template for the site, and one for each section, models.TextField() date_added =
you can easily modify the look and feel of your entire site. models.DateTimeField( auto_now
_add=True)
The parent template def __str__(self):
<p>Learning
in aLog</p>
The parent template defines the elements common to a set of return self.text[:50] + "..."
pages, and defines blocks that will be filled by individual pages.
Using data view
The view uses a parameter from the URL to pull the correct data
<p> <p>Learning
from the database.Log helps
In this exampleyou keepis sending
the view track a of your
context
<a href="{% url 'learning_logs:index' %}"> dictionary to the
learning, template,
for containing
any topic data thatlearning
you're should be displayed
on the page.
about.</p>
Learning Log
</a>
</p>

{% block content %}{% endblock content %}


The child template
The child template uses the {% extends %} template tag to pull in
the structure of the parent template. It then defines the content for You can explore the data in your project from the command
any blocks defined in the parent template. line. This is helpful for developing queries and testing code
{% extends 'learning_logs/base.html' %} snippets.
Start a shell session
{% block content %} def topic(request, topic_id):
$ python manage.py shell
<p> """Show a topic and all its entries."""
Learning Log helps you keep track topic = Topics.objects.get(id=topic_id) Access data from the project
of your learning, for any topic you're entries = topic.entry_set.order_by(
learning about. '-date_added') >>> from learning_logs.models import Topic
</p> context = { >>> Topic.objects.all()
C
{% endblock content %} 'topic': topic, [<Topic: Chess>, <Topic: Rock Climbing>]
Python code is usually indented by four spaces. In 'entries': entries, >>> topic = Topic.objects.get(id=1)
templates you’ll often see two spaces used for indentation, If you make a change to your project and the change >>> topic.text
}
because elements tend to be nested more deeply in doesn’t seem to have any effect, try restarting the 'Chess'
return render(request,
templates. server: $ python manage.py runserver
'learning_logs/topic.html', context)
Using data in a template
The data in the view function’s context dictionary is available within the template. This data is accessed using template variables, which
are indicated by doubled curly braces.
The vertical line after a template variable indicates a filter. In this case a filter called date formats date objects, and the filter linebreaks
renders paragraphs properly on a web page.

{% extends 'learning_logs/base.html' %}

{% block content %}

<p>Topic: {{ topic }}</p>

<p>Entries:</p>
<ul>
{% for entry in entries %}
<li>
<p>
{{ entry.date_added|date:'M d, Y H:i' }}
</p>
<p>
{{ entry.text|linebreaks }}
</p>
</li>
{% empty %}
<li>There are no entries yet.</li>
{% endfor %}
</ul>

{% endblock content %}

More cheat sheets available at

More cheat sheets available at


Defining the URLs Showing the current login status
Users will need to be able to log in, log out, and register. Make a You can modify the base.html template to show whether the user is
new urls.py file in the users app folder. The login view is a default currently logged in, and to provide a link to the login and logout
view provided by Django. pages. Django makes a user object available to every template,
and this template takes advantage of this object.
from django.conf.urls import url The user.is_authenticated tag allows you to serve specific
from django.contrib.auth.views import login content to users depending on whether they have logged in or not.
The {{ user.username }} property allows you to greet users
from . import views who have logged in. Users who haven’t logged in see links to
register or log in.
urlpatterns = [ <p>
url(r'^login/$', login, <a href="{% url 'learning_logs:index' %}">
Most web applications need to let users create {'template_name': 'users/login.html'}, Learning Log
accounts. This lets users create and work with their name='login'), </a>
own data. Some of this data may be private, and url(r'^logout/$', views.logout_view, {% if user.is_authenticated %}
some may be public. Django’s forms allow users to name='logout'), Hello, {{ user.username }}.
enter and modify their data. url(r'^register/$', views.register, <a href="{% url 'users:logout'
name='register'), %}"> log out </a>
] {% else %}
User accounts are handled by a dedicated app called The login template <a href="{% url 'users:register' %}">
users. Users need to be able to register, log in, and log The login view is provided by default, but you need to provide your register
own login template. The template shown here displays a simple </a> -
out. Django automates much of this work for you. login form, and provides basic error messages. Make a templates
<a href="{% url 'users:login'
Making a users app folder in the users folder, and then make a users folder in the
templates folder. Save this file as login.html. %}"> log in </a>
After making the app, be sure to add 'users' to INSTALLED_APPS
The tag {% csrf_token %} helps prevent a common type of {% endif %}
in the project’s settings.py file.
attack with forms. The {{ form.as_p }} element displays the </p>
$ python manage.py startapp users default login form in paragraph format. The <input> element
Including URLS for the users app named next redirects the user to the home page after a successful {% block content %}{% endblock content %}
Add a line to the project’s urls.py file so the users app’s URLs are login.
included in the project.
The logout view
urlpatterns = [ The logout_view() function uses Django’s logout() function
url(r'^admin/', and then redirects the user back to the home page. Since there is
include(admin.site.urls)), no logout page, there is no logout template. Make sure to write this
url(r'^users/', include('users.urls', code in the views.py file that’s stored in the users app folder.
namespace='users')), url(r'', from django.http import HttpResponseRedirect
include('learning_logs.urls', from django.core.urlresolvers import reverse
namespace='learning_logs')), ] from django.contrib.auth import logout
def logout_view(request):
"""Log the user out."""
logout(request)
return
HttpResponseRedirect( reverse('learning
_logs:index'))

C
{% extends "learning_logs/base.html" %}
The register
There view of ways to create forms and work with
are a number The register template Restricting access to logged-in users
them.
The Youview
register can needs
use Django’s
to displaydefaults, or completely
a blank registration form when The{% block
register content
template %} the registration form in paragraph
displays Some pages are only relevant to registered users. The views for
customize
the your
page is first forms. For
requested, and a simple
then waycompleted
process to let users enter {% if form.errors %}
formats. these pages canCovers Python
be protected by3theand Python 2
@login_required decorator.
registration
data based forms. A successful
on your models,registration logs the user
use a ModelForm. in and
This creates <p>
{% extends 'learning_logs/base.html' %} Any view with this decorator will automatically redirect non-logged
redirects
a form to theallows
that home page.
users to enter data that will populate the Your username and password didn't match. in users to an appropriate page. Here’s an example views.py file.
fields django.contrib.auth
from on a model. import login from Please
{% block try again.
content %} from django.contrib.auth.decorators import /
django.contrib.auth
The register view on theimport
back ofauthenticate
this sheet shows a </p> login_required
from
simpledjango.contrib.auth.forms
approach to form processing. Ifimport
the view\doesn’t {% endif %} --snip--
<form method='post'
UserCreationForm
receive data from a form, it responds with a blank form. If it
action="{% url 'users:register' %}">
def
receives POST data from a form, it validates the data and <form method="post" @login_required def
register(request):
then saves it to the database. action="{% url 'users:login' topic(request, topic_id):
Users will
{% have data that belongs
csrf_token %} to them. Any model%}">
that should
"""Register a new user.""" if """Show a topic and all its entries."""
{%
be connected csrf token
directly
{{ form.as_p }} %}
to a user needs a field connecting instances
request.method != 'POST': # of the model to a specific user.
{{ form.as_p }} Setting the redirect URL
Show blank registration form.
form = UserCreationForm() else: Making <button name="submit">log in</button>
a topicname='submit'>register</button>
<button belong to a user The @login_required decorator sends unauthorized users to the
# Process completed form. <input
Only type='hidden'
the highest-level data in aname='next'
hierarchy needs to be directly login page. Add the following line to your project’s settings.py file
form = UserCreationForm( connected <input
value="{% type="hidden"
to a user. Tourl
do this import name="next"
the User model, and add
'learning_logs:index' it
%}"/> so Django will know how to find your login page.
data=request.POST) as a foreignvalue="{% url
key on the data 'learning_logs:index' %}"/>
model. LOGIN_URL = '/users/login/'
if After modifying the model you’ll need to migrate the database.
</form>
</form>
form.is_valid(): You’ll need to choose a user ID to connect each existing instance Preventing inadvertent access
new_user = form.save() to. Some pages serve data based on a parameter in the URL. You
{%{%endblock
endblockcontent
content%}%}
can check that the current user owns the requested data, and
# Log in, redirect to home page. from django.db import models return a 404 error if they don’t. Here’s an example view.
pw = request.POST['password1'] from django.contrib.auth.models import User
authenticated_user = authenticate( Iffrom
you provide some initial
django.http importdata,Http404
Django generates a form
class with the user’s existing data. Users can then modify and
username=new_user.username,
Topic(models.Model): save their data.
password=pw --snip-- def topic(request,
"""A topic the user is learning
) topic_id):
about.""" text = Creating a form with initial data
login(request, authenticated_user) models.CharField(max_length=200) """Show a topic and all its entries."""
The instance parameter allows you to specify initial data for a form.
return topic = Topics.objects.get(id=topic_id)
date_added = models.DateTimeField(
HttpResponseRedirect( reverse(' if topic.owner
form != request.user:
= EntryForm(instance=entry)
auto_now_add=True) owner =
learning_logs:index')) raise Http404
models.ForeignKey(User) Modifying data before saving
--snip--
def The argument commit=False allows you to make changes before
context = {'form': form} __str__(self):
return render(request, writing data to the database.
Heroku lets you push your project to a live server, making it return self.text
available to'users/register.html', context)
anyone with an internet connection. Heroku new_topic = form.save(commit=False)
offers a free service level, which lets you learn the Querying data for the current user new_topic.owner = request.user
deployment process without any commitment. You’ll need In a view, the request object has a user attribute. You can use this new_topic.save()
to install a set of heroku tools, and use git to track the state attribute to query for the user’s data. The filter() function then
pulls the data that belongs to the current user.
of your project. See http://devcenter.heroku.com/, and click The django-bootstrap3 app allows you to use the Bootstrap
on the Python link. topics = library to make your project look visually appealing. The app
Topic.objects.filter( owner=req provides tags that you can use in your templates to style
individual elements on a page. Learn more at http://django- uest.user) bootstrap3.readthedocs.io/.

More cheat sheets available at


More cheat sheets available at

You might also like