0% found this document useful (0 votes)
17 views27 pages

Beginners Python Cheat Sheet Pcc All (2)

The document provides an overview of various Python programming concepts, including data structures like lists, dictionaries, and tuples, as well as control flow statements such as if statements and loops. It explains how to manipulate these structures, perform operations, and handle user input, along with examples of functions, classes, and file handling. Additionally, it emphasizes the importance of simplicity in coding and offers tips for beginners on project planning and utilizing resources like pythontutor.com.

Uploaded by

razafiza1971
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views27 pages

Beginners Python Cheat Sheet Pcc All (2)

The document provides an overview of various Python programming concepts, including data structures like lists, dictionaries, and tuples, as well as control flow statements such as if statements and loops. It explains how to manipulate these structures, perform operations, and handle user input, along with examples of functions, classes, and file handling. Additionally, it emphasizes the importance of simplicity in coding and offers tips for beginners on project planning and utilizing resources like pythontutor.com.

Uploaded by

razafiza1971
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 27

Dictionaries store connections between pieces of

List comprehensions information. Each item in a dictionary is a key-value pair.


squares = [x**2 for x in range(1, 11)] A simple dictionary
Slicing a list alien = {'color': 'green', 'points': 5}
finishers = ['sam', 'bob', 'ada', Accessing a value
'bea'] first_two = finishers[:2]
print("The alien's color is " +
Variables are used to store values. A string is a series of Copying a list alien['color'])
characters, surrounded by single or double quotes.
copy_of_bikes = bikes[:] Adding a new key-value pair
Hello world
alien['x_position'] = 0
print("Hello world!")
Looping through all key-value pairs
Hello world with a variable Tuples are similar to lists, but the items in a tuple can't be
modified. fav_numbers = {'eric': 17, 'ever':
msg = "Hello world!" 4} for name, number in
print(msg) Making a tuple fav_numbers.items():
print(name + ' loves ' + str(number))
Concatenation (combining strings) dimensions = (1920, 1080)
Looping through all keys
first_name = 'albert'
last_name = 'einstein' fav_numbers = {'eric': 17, 'ever':
full_name = first_name + ' ' + last_name 4} for name in fav_numbers.keys():
If statements are used to test for particular conditions and
print(full_name) print(name + ' loves a number')
respond appropriately.
Conditional tests Looping through all the values
equals x == 42 fav_numbers = {'eric': 17, 'ever':
A list stores a series of items in a particular order. You not equal x != 42 4} for number in
access items using an index, or within a loop. greater than x > 42 fav_numbers.values():
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 <= stored as a string.
Get the first item in a list
42 Prompting for a value
first_bike = bikes[0]
Conditional test with lists
name = input("What's your name? ")
Get the last item in a list 'trek' in bikes print("Hello, " + name + "!")
last_bike = bikes[-1] 'surly' not in
bikes Prompting for numerical input
Looping through a list
Assigning boolean values age = input("How old are you?
for bike in bikes: ") age = int(age)
game_active = True
print(bike)
can_edit = False
pi = input("What's the value of pi?
Adding items to a list ") pi = float(pi)
A simple if test
bikes = []
if age >= 18:
bikes.append('trek')
print("You can vote!")
bikes.append('redline')
bikes.append('giant') If-elif-else statements
Making numerical lists if age < 4: Covers Python 3 and Python 2
ticket_price = 0
squares = []
elif age < 18:
for x in range(1, 11):
ticket_price = 10
squares.append(x**2)
else:
ticket_price = 15
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
methods from its parent class. Reading a file and storing its lines
current_value = 1
while current_value <= 5: Creating a dog class filename = 'siddhartha.txt'
print(current_value) with open(filename) as file_object:
current_value += 1 class Dog(): lines = file_object.readlines()
"""Represent a dog."""
Letting the user choose when to quit for line in lines:
msg = '' def init (self, name): print(line)
while msg != 'quit': """Initialize dog object."""
self.name = name Writing to a file
msg = input("What's your message? ")
print(msg) filename = 'journal.txt'
def sit(self): with open(filename, 'w') as file_object:
"""Simulate sitting.""" file_object.write("I love programming.")
print(self.name + " is sitting.")
Functions are named blocks of code, designed to do one Appending to a file
specific job. Information passed to a function is called an my_dog = Dog('Peso')
argument, and information received by a function is called a filename = 'journal.txt'
parameter. with open(filename, 'a') as file_object:
print(my_dog.name + " is a great dog!") file_object.write("\nI love making
A simple function my_dog.sit() games.")
def greet_user(): Inheritance
"""Display a simple greeting.""" class SARDog(Dog):
print("Hello!") """Represent a search dog.""" Exceptions help you respond appropriately to errors that
are likely to occur. You place code that might cause an
greet_user() def init (self, name): error in the try block. Code that should run in response to
"""Initialize the sardog.""" an error goes in the except block. Code that should run
Passing an argument only if the try block was successful goes in the else block.
super(). init (name)
def greet_user(username): Catching an exception
"""Display a personalized greeting.""" def search(self):
print("Hello, " + username + "!") """Simulate prompt = "How many tickets do you need? "
searching.""" num_tickets = input(prompt)
greet_user('jesse') print(self.name + " is
try:
Default values for parameters searching.") my_dog = SARDog('Willie') num_tickets = int(num_tickets)
def make_pizza(topping='bacon'): except ValueError:
"""Make a single-topping print(my_dog.name + " is a search print("Please try again.")
pizza.""" dog.") my_dog.sit() else:
print("Have a " + topping + " pizza!") my_dog.search() print("Your tickets are printing.")
make_pizza()
make_pizza('pepperoni') If you had infinite programming skills, what would you
Returning a value build? Simple is better than complex

def add_numbers(x, y): As you're learning to program, it's helpful to If you have a choice between a simple and a
"""Add two numbers and return the think about the real-world projects you'd like complex solution, and both work, use the
sum.""" return x + y to create. It's a good habit to keep an "ideas" simple solution. Your code will be easier to
notebook that you can refer to whenever you maintain, and it will be easier for you and
sum = add_numbers(3, 5) want to start a new project. If you haven't others to build on that code later on.
print(sum) done so already, take a few minutes and
describe three projects you'd like to create. More cheat sheets available at
You can add elements to the end of a list, or you can insert The sort() method changes the order of a list permanently.
them wherever you like in a list. The sorted() function returns a copy of the list, leaving the
original list unchanged. You can sort the items in a list in
Adding an element to the end of the list alphabetical order, or reverse alphabetical order. You can
users.append('amy') also reverse the original order of the list. Keep in mind that
lowercase and uppercase letters may affect the sort order.
Starting with an empty list
Sorting a list permanently
A list stores a series of items in a particular users = []
users.append('val') users.sort()
order. Lists allow you to store sets of
users.append('bob') Sorting a list permanently in reverse
information in one place, whether you have users.append('mia')
just a few items or millions of items. Lists are alphabetical order
one of Python's most powerful features readily Inserting elements at a particular position users.sort(reverse=True)
accessible to new programmers, and they tie users.insert(0, 'joe')
together many important concepts in users.insert(3, 'bea') Sorting a list temporarily
programming. print(sorted(users))
print(sorted(users,
reverse=True))
You can remove elements by their position in a list, or by
Use square brackets to define a list, and use commas to
the value of the item. If you remove an item by its value, Reversing the order of a list
separate individual items in the list. Use plural names
Python removes only the first item that has that value.
for lists, to make your code easier to read. users.reverse()
Making a list Deleting an element by its position
users = ['val', 'bob', 'mia', 'ron', 'ned'] del users[-1] Lists can contain millions of items, so Python provides an
efficient way to loop through all the items in a list. When
Removing an item by its value you set up a loop, Python pulls each item from the list one
users.remove('mia') at a time and stores it in a temporary variable, which you
Individual elements in a list are accessed according to their provide a name for. This name should be the singular
position, called the index. The index of the first element is version of the list name.
0, the index of the second element is 1, and so forth. The indented block of code makes up the body of the
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
a particular element, write the name of the list and then from the list, you can "pop" the element. If you think of the lines that are not indented run after the loop is completed.
the index of the element in square brackets. list as a stack of items, pop() takes an item off the top of the
Printing all items in a list
Getting the first element stack. By default pop() returns the last element in the list,
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
most_recent_user = users.pop()
second_user = users[1] print(most_recent_user) separate message afterwards
Getting the last element Pop the first item in a list for user in users:
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 len() function returns the number of items in a list.
the item you want to modify.
Find the length of a list
Covers Python 3 and Python 2
Changing an element num_users = len(users)
users[0] = print("We have " + str(num_users) + "
'valerie' users[- users.")
2] = 'ronald'
You can use the range() function to work with a set of To copy a list make a slice that starts at the first item and A tuple is like a list, except you can't change the values in a
numbers efficiently. The range() function starts at 0 by ends at the last item. If you try to copy a list without using tuple once it's defined. Tuples are good for storing
default, and stops one number below the number passed to this approach, whatever you do to the copied list will affect information that shouldn't be changed throughout the life of
it. You can use the list() function to efficiently generate a the original list as well. a program. Tuples are designated by parentheses instead
large list of numbers. of square brackets. (You can overwrite an entire tuple, but
Making a copy of a list you can't change the individual elements in a tuple.)
Printing the numbers 0 to 1000
finishers = ['kai', 'abe', 'ada', 'gus',
for number in range(1001): 'zoe'] copy_of_finishers = finishers[:] Defining a tuple
print(number) dimensions = (800, 600)
Printing the numbers 1 to 1000 Looping through a tuple
for number in range(1, 1001): You can use a loop to generate a list based on a range of
print(number) for dimension in dimensions:
numbers or on another list. This is a common operation, so
print(dimension)
Python offers a more efficient way to do it. List
Making a list of numbers from 1 to a million comprehensions may look complicated at first; if so, use the Overwriting a tuple
numbers = list(range(1, 1000001)) for loop approach until you're ready to start using
comprehensions. dimensions = (800, 600)
To write a comprehension, define an expression for the print(dimensions)
values you want to store in the list. Then write a for loop to
There are a number of simple statistics you can run on a list generate input values needed to make the list. dimensions = (1200, 900)
containing numerical data.
Using a loop to generate a list of square
Finding the minimum value in a list
numbers
squares = []
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2, When you're first learning about data structures such as
for x in range(1, 11):
77] lists, it helps to visualize how Python is working with the
square = x**2
youngest = min(ages) information in your program. pythontutor.com is a great tool
squares.append(square)
for seeing how Python keeps track of the information in a
Finding the maximum value list. Try running the following code on pythontutor.com, and
Using a comprehension to generate a list of
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2, square numbers then run your own code.
77] Build a list and print the items in the list
oldest = max(ages) squares = [x**2 for x in range(1, 11)]
dogs = []
Finding the sum of all values Using a loop to convert a list of names to upper dogs.append('willie')
case dogs.append('hootz')
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2,
names = ['kai', 'abe', 'ada', 'gus', 'zoe'] dogs.append('peso')
77]
total_years = sum(ages) dogs.append('goblin')
upper_names = []
for name in for dog in dogs:
names: print("Hello " + dog + "!")
You can work with any set of elements from a list. A portion print("I love these dogs!")
of a list is called a slice. To slice a list start with the index of Using a comprehension to convert a list of
the first item you want, then add a colon and the index after names to upper case
print("\nThese were my first two dogs:")
the last item you want. Leave off the first index to start at names = ['kai', 'abe', 'ada', 'gus', 'zoe'] old_dogs = dogs[:2]
the beginning of the list, and leave off the last index to slice for old_dog in old_dogs:
through the end of the list. upper_names = [name.upper() for name in print(old_dog)
Getting the first three items names]
finishers = ['kai', 'abe', 'ada', 'gus', del dogs[0]
'zoe'] first_three = finishers[:3] dogs.remove('peso')
Readability counts print(dogs)
Getting the middle three items  Use four spaces per indentation level.
middle_three = finishers[1:4]  Keep your lines to 79 characters or fewer.
Getting the last three items  Use single blank lines to group parts More cheat sheets available at
of your program visually.
last_three = finishers[-3:]
You can store as many key-value pairs as you want in a You can loop through a dictionary in three ways: you can
dictionary, until your computer runs out of memory. To add loop through all the key-value pairs, all the keys, or all the
a new key-value pair to an existing dictionary give the values.
name of the dictionary and the new key in square brackets, A dictionary only tracks the connections between keys
and set it equal to the new value. and values; it doesn't track the order of items in the
This also allows you to start with an empty dictionary and dictionary. If you want to process the information in order,
add key-value pairs as they become relevant. you can sort the keys in your loop.
Adding a key-value pair Looping through all key-value pairs
alien_0 = {'color': 'green', 'points': 5} # Store people's favorite languages.
fav_languages = {
Python's dictionaries allow you to connect alien_0['x'] = 0 'jen': 'python',
pieces of related information. Each piece of alien_0['y'] = 25 'sarah': 'c',
information in a dictionary is stored as a key- alien_0['speed'] = 1.5 'edward': 'ruby',
value pair. When you provide a key, Python 'phil': 'python',
Adding to an empty dictionary }
returns the value associated with that key.
You can loop through all the key-value pairs, alien_0 = {}
alien_0['color'] = # Show each person's favorite language.
all the keys, or all the values. for name, language in
'green' alien_0['points']
= 5 fav_languages.items(): print(name + ":
" + language)
Use curly braces to define a dictionary. Use colons to Looping through all the keys
connect keys and values, and use commas to separate
individual key-value pairs. You can modify the value associated with any key in a # Show everyone who's taken the
dictionary. To do so give the name of the dictionary and survey. for name in
Making a dictionary enclose the key in square brackets, then provide the new fav_languages.keys():
alien_0 = {'color': 'green', 'points': 5} value for that key. print(name)
Modifying values in a dictionary Looping through all the values
alien_0 = {'color': 'green', 'points': 5} # Show all the languages that have been
To access the value associated with an individual key give print(alien_0) chosen. for language in
the name of the dictionary and then place the key in a set fav_languages.values():
of square brackets. If the key you're asking for is not in the # Change the alien's color and point print(language)
dictionary, an error will occur. value. alien_0['color'] = 'yellow'
You can also use the get() method, which returns alien_0['points'] = 10
Looping through all the keys in order
None instead of an error if the key doesn't exist. You can print(alien_0) # Show each person's favorite
also specify a default value to use if the key is not in the language, # in order by the
dictionary. person's name.
Getting the value associated with a key for name in sorted(fav_languages.keys()):
You can remove any key-value pair you want from a print(name + ": " + language)
alien_0 = {'color': 'green', 'points': 5} dictionary. To do so use the del keyword and the dictionary
name, followed by the key in square brackets. This will
print(alien_0['color']) delete the key and its associated value.
print(alien_0['points']) Deleting a key-value pair You can find the number of key-value pairs in a dictionary.
Getting the value with get() alien_0 = {'color': 'green', 'points': 5} Finding a dictionary's length
print(alien_0)
alien_0 = {'color': 'green'} num_responses = len(fav_languages)
del alien_0['points']
alien_color = alien_0.get('color')
print(alien_0)
alien_points = alien_0.get('points', 0)

print(alien_color)
print(alien_points) Try running some of these examples on pythontutor.com. Covers Python 3 and Python 2
It's sometimes useful to store a set of dictionaries in a list; Storing a list inside a dictionary alows you to associate Standard Python dictionaries don't keep track of the order
this is called nesting. more than one value with each key. in which keys and values are added; they only preserve the
association between each key and its value. If you want to
Storing dictionaries in a list Storing lists in a dictionary preserve the order in which keys and values are added,
# Start with an empty # Store multiple languages for each use an OrderedDict.
list. users = [] person. fav_languages = { Preserving the order of keys and values
'jen': ['python', 'ruby'],
# Make a new user, and add them to the 'sarah': ['c'], from collections import OrderedDict
list. new_user = { 'edward': ['ruby', 'go'],
'last': 'fermi', 'phil': ['python', 'haskell'], # Store each person's languages,
'first': 'enrico', } keeping # track of who respoded
'username': first. fav_languages = OrderedDict()
'efermi', # Show all responses for each person.
} for name, langs in fav_languages.items(): fav_languages['jen'] = ['python', 'ruby']
users.append(new_user) print(name + ": ") fav_languages['sarah'] = ['c']
for lang in langs: fav_languages['edward'] = ['ruby', 'go']
# Make another new user, and add them as print("- " + fav_languages['phil'] = ['python',
well. new_user = { lang) 'haskell']
'last': 'curie',
'first': 'marie', # Display the results, in the same order
'username': they # were entered.
'mcurie', You can store a dictionary inside another dictionary. In this for name, langs in fav_languages.items():
} case each value associated with a key is itself a dictionary. print(name + ":")
users.append(new_user) for lang in langs:
Storing dictionaries in a dictionary print("- " +
# Show all information about each users = {
user. for user_dict in users: 'aeinstein':
for k, v in user_dict.items(): { 'first': You can use a loop to generate a large number of
print(k + ": " + v) 'albert', dictionaries efficiently, if all the dictionaries start out with
print("\n") 'last': 'einstein', similar data.
You can also define a list of dictionaries 'location': 'princeton', A million aliens
directly, without using append(): },
'mcurie': { aliens = []
# Define a list of users, where each 'first': 'marie',
user # is represented by a 'last': 'curie', # Make a million green aliens, worth 5
dictionary. 'location': 'paris', points # each. Have them all start in
users = [ }, one row.
{ } for alien_num in range(1000000):
'last': 'fermi', new_alien = {}
'first': 'enrico', for username, user_dict in new_alien['color'] = 'green'
'username': 'efermi', users.items(): print("\nUsername: new_alien['points'] = 5
}, " + username) full_name = new_alien['x'] = 20 *
{ user_dict['first'] + " " full_name alien_num new_alien['y'] = 0
'last': 'curie', += user_dict['last'] location = aliens.append(new_alien)
'first': 'marie', user_dict['location']
'username': 'mcurie', # Prove the list contains a million
}, print("\tFull name: " + aliens. num_aliens = len(aliens)
] full_name.title()) print("\tLocation: "
+ location.title()) print("Number of aliens created:")
# Show all information about each print(num_aliens)
user. for user_dict in users:
for k, v in user_dict.items(): More cheat sheets available at
print(k + ": " + v) Nesting is extremely useful in certain situations. However,
print("\n") be aware of making your code overly complex. If you're
Testing numerical values is similar to testing string values. Several kinds of if statements exist. Your choice of which
Testing equality and inequality to use depends on the number of conditions you need to
test. You can have as many elif blocks as you need, and
>>> age = 18 the else block is always optional.
>>> age == 18 Simple if statement
True
>>> age != 18 age = 19
False
if age >= 18:
Comparison operators print("You're old enough to vote!")
>>> age = 19 If-else statements
>>> age < 21
True age = 17
>>> age <= 21
True if age >= 18:
If statements allow you to examine the >>> age > 21 print("You're old enough to
False vote!") else:
current state of a program and respond
>>> age >= 21 print("You can't vote yet.")
appropriately to that state. You can write a
False
simple if statement that checks one The if-elif-else chain
condition, or you can create a complex age = 12
series of if statements that idenitfy the exact
conditions you're looking for. You can check multiple conditions at the same time. The if age < 4:
and operator returns True if all the conditions listed are price =
While loops run as long as certain conditions True. The or operator returns True if any condition is True. 0
remain true. You can use while loops to let Using and to check multiple conditions elif age < 18:
your programs run as long as your users price = 5
>>> age_0 = 22 else:
want them to.
>>> age_1 = 18 price = 10
>>> age_0 >= 21 and age_1 >=
21 False print("Your cost is $" + str(price) + ".")
A conditional test is an expression that can be evaluated >>> age_1 = 23
as True or False. Python uses the values True and False >>> age_0 >= 21 and age_1 >=
to decide whether the code in an if statement should be 21 True
executed. You can easily test whether a certain value is in a list. You
Using or to check multiple conditions can also test whether a list is empty before trying to loop
Checking for equality through the list.
A single equal sign assigns a value to a variable. A double >>> age_0 = 22
equal sign (==) checks whether two values are equal. >>> age_1 = 18 Testing if a value is in a list
>>> car = 'bmw' >>> age_0 >= 21 or age_1 >= >>> players = ['al', 'bea', 'cyn', 'dale']
>>> car == 'bmw' 21 True >>> 'al' in
True >>> age_0 = 18 players True
>>> car = 'audi' >>> age_0 >= 21 or age_1 >= >>> 'eric' in players
>>> car == 'bmw' 21 False False
False
Ignoring case when making a comparison
>>> car = 'Audi' A boolean value is either True or False. Variables
with boolean values are often used to keep track of
>>> car.lower() ==
certain conditions within a program.
'audi' True Covers Python 3 and Python 2
Simple boolean values
Checking for inequality
game_active = True
>>> topping = 'mushrooms' can_edit = False
>>> topping !=
Testing if a value is not in a list Letting the user choose when to quit Using continue in a loop
banned_users = ['ann', 'chad', prompt = "\nTell me something, and I'll " banned_users = ['eve', 'fred', 'gary',
'dee'] user = 'erin' prompt += "repeat it back to you." 'helen']
prompt += "\nEnter 'quit' to end the
if user not in banned_users: program. " prompt = "\nAdd a player to your team."
print("You can play!") prompt += "\nEnter 'quit' when you're
message = "" done. "
Checking if a list is empty
while message != 'quit':
players = [] message = input(prompt) players = []
while True:
if players: if message != 'quit': player =
for player in players: print(message) input(prompt) if
print("Player: " + player.title()) player == 'quit':
else: Using a flag break
print("We have no players yet!") elif player in banned_users:
prompt = "\nTell me something, and I'll "
print(player + " is banned!")
prompt += "repeat it back to you."
continue
prompt += "\nEnter 'quit' to end the
else:
program. "
You can allow your users to enter input using the input() players.append(player)
statement. In Python 3, all input is stored as a string. active =
print("\nYour team:")
Simple input True while
for player in
active:
name = input("What's your name? ") players:
message = input(prompt)
print("Hello, " + name + ".") print(player)

Accepting numerical input if message == 'quit':


active = False
age = input("How old are you? else: Every while loop needs a way to stop running so it won't
") age = int(age) print(message) continue to run forever. If there's no way for the condition to
become False, the loop will never stop running.
if age >= 18: Using break to exit a loop
An infinite loop
print("\nYou can vote!") prompt = "\nWhat cities have you visited?"
else: while True:
prompt += "\nEnter 'quit' when you're
print("\nYou can't vote yet.") name = input("\nWho are you? ")
done. "
print("Nice to meet you, " + name +
Accepting input in Python 2.7 "!")
Use raw_input() in Python 2.7. This function interprets all input as a while True:
string, just as input() does in Python 3. city = input(prompt)
name = raw_input("What's your name? ") if city == The remove() method removes a specific value from a list,
print("Hello, " + name + ".") but it only removes the first instance of the value you
provide. You can use a while loop to remove all instances
Sublime Text doesn't run programs that prompt the user for of a particular value.
input. You can use Sublime Text to write programs that
A while loop repeats a block of code as long as a condition prompt for input, but you'll need to run these programs from Removing all cats from a list of pets
is True. a terminal. pets = ['dog', 'cat', 'dog', 'fish', 'cat',
Counting to 5 'rabbit', 'cat']
print(pets)
current_number = 1
You can use the break statement and the continue while 'cat' in pets:
while current_number <= 5: statement with any of Python's loops. For example you can pets.remove('cat')
print(current_number) use break to quit a for loop that's working through a list or a
current_number += 1 dictionary. You can use continue to skip over certain items print(pets)
when looping through a list or dictionary as well.
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
Using positional arguments name.""" full_name = first + ' ' + last
return full_name.title()
def describe_pet(animal, name):
Functions are named blocks of code designed """Display information about a musician = get_full_name('jimi',
to do one specific job. Functions allow you to pet.""" print("\nI have a " + 'hendrix') print(musician)
write code once that can then be run animal + ".") print("Its name is "
+ name + ".") Returning a dictionary
whenever you need to accomplish the same
task. Functions can take in the information def build_person(first, last):
describe_pet('hamster', 'harry') """Return a dictionary of information
they need, and return the information they
describe_pet('dog', 'willie') about a person.
generate. Using functions effectively makes
your programs easier to write, read, test, and Using keyword arguments """
person = {'first': first, 'last':
fix. def describe_pet(animal, name): last} return person
"""Display information about a
pet.""" print("\nI have a " + musician = build_person('jimi',
The first line of a function is its definition, marked by the animal + ".") print("Its name is " 'hendrix') print(musician)
keyword def. The name of the function is followed by a set + name + ".")
of parentheses and a colon. A docstring, in triple quotes, Returning a dictionary with optional values
describes what the function does. The body of a function is describe_pet(animal='hamster',
name='harry') describe_pet(name='willie', def build_person(first, last, age=None):
indented one level. """Return a dictionary of information
To call a function, give the name of the function followed animal='dog')
about a person.
by a set of parentheses.
"""
Making a function person = {'first': first, 'last':
You can provide a default value for a parameter. When last} if age:
def greet_user(): function calls omit this argument the default value will be
"""Display a simple greeting.""" person['age'] = age
used. Parameters with default values must be listed after return person
print("Hello!") parameters without default values in the function's definition
so positional arguments can still work correctly. musician = build_person('jimi', 'hendrix',
greet_user()
Using a default value 27) print(musician)
def describe_pet(name, animal='dog'):
musician = build_person('janis',
"""Display information about a pet."""
Information that's passed to a function is called an 'joplin') print(musician)
print("\nI have a " + animal + ".")
argument; information that's received by a function is called print("Its name is " + name + ".")
a parameter. Arguments are included in parentheses after
the function's name, and parameters are listed in
describe_pet('harry', 'hamster') Try running some of these examples on pythontutor.com.
parentheses in the function's definition.
describe_pet('willie')
Passing a single argument
Using None to make an argument optional
def greet_user(username):
"""Display a simple def describe_pet(animal, name=None):
greeting.""" """Display information about a
print("Hello, " + username + "!") pet.""" print("\nI have a " + Covers Python 3 and Python 2
animal + ".") if name:
greet_user('jesse') print("Its name is " + name + ".")
greet_user('diana')
greet_user('brandon') describe_pet('hamster', 'harry')
You can pass a list as an argument to a function, and the Sometimes you won't know how many arguments a You can store your functions in a separate file called a
function can work with the values in the list. Any changes function will need to accept. Python allows you to collect an module, and then import the functions you need into the
the function makes to the list will affect the original list. You arbitrary number of arguments into one parameter using file containing your main program. This allows for cleaner
can prevent a function from modifying a list by passing a the program files. (Make sure your module is stored in the
copy of the list as an argument. * operator. A parameter that accepts an arbitrary number of same directory as your main program.)
arguments must come last in the function definition.
Passing a list as an argument The ** operator allows a parameter to collect an arbitrary Storing a function in a module
number of keyword arguments. File: pizza.py
def greet_users(names):
"""Print a simple greeting to Collecting an arbitrary number of arguments def make_pizza(size, *toppings):
everyone.""" for name in names: """Make a pizza."""
def make_pizza(size, print("\nMaking a " + size + "
msg = "Hello, " + name +
*toppings): """Make a pizza.") print("Toppings:")
"!" print(msg)
pizza.""" for topping in
print("\nMaking a " + size + " pizza.") toppings: print("-
usernames = ['hannah', 'ty',
print("Toppings:") " + topping)
'margot'] greet_users(usernames)
for topping in
Allowing a function to modify a list toppings: print("- Importing an entire module
The following example sends a list of models to a function for " + topping) File: making_pizzas.py
printing. The original list is emptied, and the second list is filled. Every function in the module is available in the program file.
# Make three pizzas with different import pizza
def print_models(unprinted,
toppings. make_pizza('small', 'pepperoni')
printed): """3d print a set of
make_pizza('large', 'bacon bits', pizza.make_pizza('medium', 'pepperoni')
models.""" while unprinted:
'pineapple') make_pizza('medium', pizza.make_pizza('small', 'bacon',
current_model = unprinted.pop()
'mushrooms', 'peppers', 'pineapple')
print("Printing " + current_model)
'onions', 'extra cheese')
printed.append(current_model)
Collecting an arbitrary number of keyword Importing a specific function
Only the imported functions are available in the program file.
# Store some unprinted arguments
designs, # and print each def build_profile(first, last, from pizza import make_pizza
of them. **user_info): """Build a user's
unprinted = ['phone case', 'pendant', profile dictionary.""" # Build a make_pizza('medium', 'pepperoni')
'ring'] printed = [] dict with the required keys. profile make_pizza('small', 'bacon', 'pineapple')
print_models(unprinted, printed) = {'first': first, 'last': last}
Giving a module an alias
print("\nUnprinted:", unprinted) # Add any other keys and import pizza as p
print("Printed:", printed) values. for key, value in
Preventing a function from modifying a list user_info.items(): p.make_pizza('medium', 'pepperoni')
The following example is the same as the previous one, except the profile[key] = value p.make_pizza('small', 'bacon',
original list is unchanged after calling print_models(). 'pineapple')
return profile
def print_models(unprinted, Giving a function an alias
printed): """3d print a set of
# Create two users with different from pizza import make_pizza as mp
models.""" while unprinted:
kinds # of information.
current_model = unprinted.pop()
user_0 = build_profile('albert', mp('medium', 'pepperoni')
print("Printing " + current_model)
'einstein', location='princeton') mp('small', 'bacon',
printed.append(current_model)
user_1 = build_profile('marie', 'curie', 'pineapple')
location='paris', field='chemistry')
# Store some unprinted Importing all functions from a module
designs, # and print each Don't do this, but recognize it when you see it in others' code. It
print(user_0)
of them. can result in naming conflicts, which can cause errors.
print(user_1)
original = ['phone case', 'pendant',
'ring'] printed = [] from pizza import *

As you can see there are many ways to write and call a More cheat sheets available at
print_models(original[:], printed)
print("\nOriginal:", original) function. When you're starting out, aim for something that
print("Printed:", printed) simply works. As you gain experience you'll develop an
If the class you're writing is a specialized version of another
Creating an object from a class class, you can use inheritance. When one class inherits
my_car = Car('audi', 'a4', 2016) from another, it automatically takes on all the attributes and
methods of the parent class. The child class is free to
Accessing attribute values introduce new attributes and methods, and override
attributes and methods of the parent class.
print(my_car.make)
To inherit from another class include the name of the
print(my_car.model)
parent class in parentheses when defining the new class.
print(my_car.year)
Classes are the foundation of object-oriented The init () method for a child class
Calling methods
programming. Classes represent real-world
class ElectricCar(Car):
things you want to model in your programs: for my_car.fill_tank()
"""A simple model of an electric car."""
example dogs, cars, and robots. You use a my_car.drive()
class to make objects, which are specific Creating multiple objects def init (self, make, model, year):
instances of dogs, cars, and robots. A class """Initialize an electric car."""
defines the general behavior that a whole my_car = Car('audi', 'a4', 2016) super(). init (make, model, year)
my_old_car = Car('subaru', 'outback', 2013)
category of objects can have, and the
my_truck = Car('toyota', 'tacoma', 2010) # Attributes specific to electric
information that can be associated with those
objects. cars. # Battery capacity in kWh.
self.battery_size = 70
Classes can inherit from each other – you
# Charge level in %.
can write a class that extends the functionality You can modify an attribute's value directly, or you can
self.charge_level = 0
of an existing class. This allows you to code write methods that manage updating values more carefully.
Modifying an attribute directly Adding new methods to the child class
Consider how we might model a car. What information class ElectricCar(Car):
my_new_car = Car('audi', 'a4', 2016)
would we associate with a car, and what behavior would it --snip--
my_new_car.fuel_level = 5
have? The information is stored in variables called def charge(self):
attributes, and the behavior is represented by functions. Writing a method to update an attribute's value """Fully charge the
Functions that are part of a class are called methods. vehicle.""" self.charge_level
def update_fuel_level(self, new_level): = 100
The Car class """Update the fuel level.""" print("The vehicle is fully
if new_level <= charged.")
class Car():
self.fuel_capacity:
"""A simple attempt to model a car.""" Using child methods and parent methods
self.fuel_level = new_level
else: my_ecar = ElectricCar('tesla', 'model s',
def init (self, make, model, year):
print("The tank can't hold that 2016)
"""Initialize car attributes."""
much!")
self.make = make
self.model = model Writing a method to increment an attribute's my_ecar.charge()
self.year = year value
def add_fuel(self, amount):
# Fuel capacity and level in """Add fuel to the There are many ways to model real world objects and
gallons. self.fuel_capacity = 15 tank.""" if situations in code, and sometimes that variety can feel
self.fuel_level = 0 (self.fuel_level + amount overwhelming. Pick an approach and try it – if your first
<= self.fuel_capacity): attempt doesn't work, try a different approach.
def fill_tank(self): self.fuel_level += amount
"""Fill gas tank to capacity.""" print("Added fuel.")
self.fuel_level =
self.fuel_capacity print("Fuel
tank is full.")
In Python class names are written in CamelCase and object Covers Python 3 and Python 2
names are written in lowercase with underscores. Modules
def drive(self): that contain classes should still be named in lowercase with
"""Simulate underscores.
driving."""
print("The car is moving.")
Class files can get long as you add detailed information and functionality. To help keep your program files uncluttered, you can
store Overriding
your classes inparent
modulesmethods
and import the classes you need into your main program. Classes should inherit from object
class ElectricCar(Car):
Storing classes in a file class ClassName(object):
--snip-- car.py
def fill_tank(self): The Car class in Python 2.7
"""Display an error message.""" """Represent gas and electric cars.""" class Car(object):
print("This car has no fuel
tank!") class Car(): Child class init () method is different
A class can have objects as attributes. This allows classes """A simple attempt to model a car."""
class
to work together to model complex situations. --snip—
ChildClassName(ParentClass):
A Battery class def init (self):
class Battery():
super(ClassName, self). init ()
"""A battery for an electric car."""
class Battery(): The ElectricCar class in Python 2.7
--snip--
"""A battery for an electric car."""
class ElectricCar(Car):
class ElectricCar(Car): def init (self, make, model, year):
def init (self, size=70):
"""A simple model of an electric car.""" super(ElectricCar, self). init (
"""Initialize battery
--snip-- make, model, year)
attributes.""" # Capacity in kWh,
charge level in %. self.size = Importing individual classes from a module
size my_cars.py
self.charge_level = 0
from car import Car, ElectricCar A list can hold as many items as you want, so you can
make a large number of objects from a class and store
def get_range(self):
my_beetle = Car('volkswagen', 'beetle', them in a list.
"""Return the battery's
my_beetle.fill_tank Here's an example showing how to make a fleet of
range.""" if self.size == 70:
()
2016) my_beetle.drive() rental cars, and make sure all the cars are ready to drive.
return 240
elif self.size == 85: A fleet of rental cars
return 270 my_tesla = ElectricCar('tesla', 'model s',
2016 from car import Car, ElectricCar
Using an instance as an attribute )
my_tesla.charge()
my_tesla.drive() # Make lists to hold a fleet of cars.
class ElectricCar(Car): gas_fleet = []
--snip-- Importing an entire module electric_fleet = []
def init (self, make, model, year): import car
# Make 500 gas cars and 250 electric
"""Initialize an electric car."""
my_beetle = car.Car( cars. for _ in range(500):
super(). init (make, model, year)
'volkswagen', 'beetle', car = Car('ford', 'focus', 2016)
2016) my_beetle.fill_tank() gas_fleet.append(car)
# Attribute specific to electric for _ in range(250):
cars. self.battery = Battery() my_beetle.drive()
ecar = ElectricCar('nissan', 'leaf',
my_tesla = 2016) electric_fleet.append(ecar)
def charge(self):
"""Fully charge the vehicle.""" car.ElectricCar( 'tesla'
, 'model s', 2016) # Fill the gas cars, and charge electric
self.battery.charge_level = 100 cars. for car in gas_fleet:
print("The vehicle is fully my_tesla.charge()
my_tesla.drive() car.fill_tank()
charged.") for ecar in electric_fleet:
Using the instance Importing all classes from a module ecar.charge()
(Don’t do this, but recognize it when you see it.)
my_ecar = ElectricCar('tesla', 'model x', print("Gas cars:", len(gas_fleet))
from car import *
2016) print("Electric cars:",
my_beetle = Car('volkswagen', 'beetle', 2016) len(electric_fleet))
my_ecar.charge()
More cheat sheets available at
Storing the lines in a list Opening a file using an absolute path
filename = 'siddhartha.txt' f_path = "/home/ehmatthes/books/alice.txt"

with open(filename) as f_obj: with open(f_path) as


lines = f_obj.readlines() f_obj: lines =
f_obj.readlines()
for line in lines: Opening a file on Windows
print(line.rstrip()) Windows will sometimes interpret forward slashes incorrectly. If
you run into this, use backslashes in your file paths.

Your programs can read information in from f_path = "C:\Users\ehmatthes\books\alice.txt"


files, and they can write data to files. Reading Passing the 'w' argument to open() tells Python you want
to write to the file. Be careful; this will erase the contents of with open(f_path) as
from files allows you to work with a wide
the file if it already exists. Passing the 'a' argument tells f_obj: lines =
variety of information; writing to files allows f_obj.readlines()
Python you want to append to the end of an existing file.
users to pick up where they left off the next
Writing to an empty file
time they run your program. You can write text
to files, and you can store Python structures filename = 'programming.txt' When you think an error may occur, you can write a try-
such as lists in data files. except block to handle the exception that might be raised.
with open(filename, 'w') as f: The try block tells Python to try running some code, and the
Exceptions are special objects that help your f.write("I love programming!") except block tells Python what to do if the code results in a
programs respond to errors in appropriate Writing multiple lines to an empty file particular kind of error.
ways. For example if your program tries to Handling the ZeroDivisionError exception
filename = 'programming.txt'
open a file that doesn’t exist, you can use
try:
exceptions to display an informative error with open(filename, 'w') as f: print(5/0)
message instead of having the program crash. f.write("I love programming!\ except ZeroDivisionError:
n") print("You can't divide by zero!")
f.write("I love creating new games.\n")
To read from a file your program needs to open the file Handling the FileNotFoundError exception
Appending to a file
and then read the contents of the file. You can read the f_name = 'siddhartha.txt'
entire contents of the file at once, or read the file line by filename = 'programming.txt'
line. The with statement makes sure the file is closed try:
properly when the program has finished accessing the file. with open(filename, 'a') as f: with open(f_name) as f_obj:
Reading an entire file at once f.write("I also love working with data.\ lines =
n") f.write("I love making apps as f_obj.readlines()
filename = 'siddhartha.txt' well.\n") except FileNotFoundError:
msg = "Can't find file
with open(filename) as f_obj: {0}.".format(f_name) print(msg)
contents = f_obj.read()
When Python runs the open() function, it looks for the file
in the same directory where the program that's being
print(contents)
excuted is stored. You can open a file from a subfolder It can be hard to know what kind of exception to handle
Reading line by line using a relative path. You can also use an absolute path to when writing code. Try writing your code without a try block,
Each line that's read from the file has a newline character at the open any file on your system. and make it generate an error. The traceback will tell you
end of the line, and the print function adds its own newline Opening a file from a subfolder
character. The rstrip() method gets rid of the the extra blank
lines this would result in when printing to the terminal. f_path = "text_files/alice.txt"
filename = 'siddhartha.txt'
with open(f_path) as f_obj: Covers Python 3 and Python 2
lines = f_obj.readlines()
with open(filename) as
f_obj: for line in f_obj:
for line in lines:
print(line.rstrip())
print(line.rstrip())
The try block should only contain code that may cause an Sometimes you want your program to just continue running The json module allows you to dump simple Python data
error. Any code that depends on the try block running when it encounters an error, without reporting the error to structures into a file, and load the data from that file the
successfully should be placed in the else block. the user. Using the pass statement in an else block allows next time the program runs. The JSON data format is not
you to do this. specific to Python, so you can share this kind of data with
Using an else block people who work in other languages as well.
Using the pass statement in an else block
print("Enter two numbers. I'll divide
them.") f_names = ['alice.txt', 'siddhartha.txt', Knowing how to manage exceptions is important when
'moby_dick.txt', 'little_women.txt'] working with stored data. You'll usually want to make sure
x = input("First number: the data you're trying to load exists before working with it.
") y = input("Second for f_name in f_names: Using json.dump() to store data
number: ") # Report the length of each file
found. try: """Store some numbers."""
try: with open(f_name) as f_obj:
result = int(x) / int(y) lines = import json
except ZeroDivisionError: f_obj.readlines()
print("You can't divide by zero!") except FileNotFoundError: numbers = [2, 3, 5, 7, 11, 13]
else: # Just move on to the next
print(result) file. pass filename = 'numbers.json'
Preventing crashes from user input else: with open(filename, 'w') as f_obj:
Without the except block in the following example, the program num_lines = len(lines) json.dump(numbers, f_obj)
would crash if the user tries to divide by zero. As written, it will msg = "{0} has {1}
handle the error gracefully and keep running. lines.".format( f_name,
Using json.load() to read data
num_lines) """Load some previously stored numbers."""
"""A simple calculator for division
only."""
import json
Exception-handling code should catch specific exceptions
print("Enter two numbers. I'll divide that you expect to happen during your program's execution.
them.") print("Enter 'q' to quit.") filename = 'numbers.json'
A bare except block will catch all exceptions, including with open(filename) as
keyboard interrupts and system exits you might need when f_obj:
while True: forcing a program to close.
x = input("\nFirst number: numbers = json.load(f_obj)
") if x == 'q': If you want to use a try block and you're not sure which
break print(numbers)
exception to catch, use Exception. It will catch most
y = input("Second number: exceptions, but still allow you to interrupt programs Making sure the stored data exists
") if y == 'q': intentionally. import json
break
Don’t use bare except blocks
f_name = 'numbers.json'
try: try:
result = int(x) / # Do something try:
int(y) except except: with open(f_name) as f_obj:
ZeroDivisionError: pass numbers = json.load(f_obj)
print("You can't divide by
except FileNotFoundError:
zero!") else: Use Exception instead msg = "Can’t find {0}.".format(f_name)
print(result)
try: print(msg)
# Do something else:
except Exception: print(numbers)
Well-written, properly tested code is not very prone to pass
internal errors such as syntax or logical errors. But every Practice with exceptions
time your program depends on something external such as Printing the exception Take a program you've already written that prompts for
user input or the existence of a file, there's a possibility of try: user input, and add some error-handling code to the
an exception being raised. # Do something program.
except Exception as
It's up to you how to communicate errors to your users. e: More cheat sheets available at
Sometimes users need to know if a file is missing; print(e, type(e))
Building a testcase with one unit test Running the test
To build a test case, make a class that inherits from When you change your code, it’s important to run your existing
unittest.TestCase and write methods that begin with test_. tests. This will tell you whether the changes you made
Save this as test_full_names.py affected existing behavior.

import unittest E
from full_names import get_full_name =============================================
===
class NamesTestCase(unittest.TestCase): ERROR: test_first_last ( main
"""Tests for names.py.""" .NamesTestCase) Test names like Janis
Joplin.
def test_first_last(self):
When you write a function or a class, you can """Test names like Janis Joplin.""" Traceback (most recent call last):
also write tests for that code. Testing proves full_name = get_full_name('janis', File "test_full_names.py", line
that your code works as it's supposed to in 'joplin') 10,
the situations it's designed to handle, and self.assertEqual(full_name, in test_first_last
also when people use your programs in 'Janis Joplin') 'joplin')
unexpected ways. Writing tests gives you TypeError: get_full_name() missing 1
confidence that your code will work correctly unittest.main() required positional argument: 'last'
as more people begin to use your programs. Running the test ---------------------------------------------
You can also add new features to your Python reports on each unit test in the test case. The dot reports a ---
programs and know that you haven't broken single passing test. Python informs us that it ran 1 test in less than
Ran 1 test in 0.001s
existing behavior. 0.001 seconds, and the OK lets us know that all unit tests in the
test case passed.
FAILED (errors=1)
A unit test verifies that one specific aspect of .
Fixing the code
your code works as it's supposed to. A test ---------------------------------------
When a test fails, the code needs to be modified until the test
case is a collection of unit tests which verify Ran 1 test in 0.000s passes again. (Don’t make the mistake of rewriting your tests to fit
your code's behavior in a wide variety of your new code.) Here we can make the middle name optional.
OK
situations. def get_full_name(first, last,
middle=''): """Return a full
name."""
Python's unittest module provides tools for testing your Failing tests are important; they tell you that a change in the if middle:
code. To try it out, we’ll create a function that returns a full code has affected existing behavior. When a test fails, you full_name = "{0} {1}
name. We’ll use the function in a regular program, and then need to modify the code so the existing behavior still works. {2}".format(first,
build a test case for the function. Modifying the function middle, last)
A function to test We’ll modify get_full_name() so it handles middle names, but else:
Save this as full_names.py
we’ll do it in a way that breaks existing behavior. full_name = "{0} {1}".format(first,
last)
def get_full_name(first, def get_full_name(first, middle, last):
return full_name.title()
last): """Return a full """Return a full name."""
full_name = "{0} {1} {2}".format(first, Running the test
name.""" Now the test should pass again, which means our original
full_name = "{0} {1}".format(first, middle, last)
return full_name.title() functionality is still intact.
last) return full_name.title()
.
Using the function Using the function
---------------------------------------
Save this as names.py
from full_names import get_full_name
from full_names import get_full_name
john = get_full_name('john', 'lee',
janis = get_full_name('janis', 'joplin') 'hooker') print(john) Covers Python 3 and Python 2
print(janis)
david = get_full_name('david', 'lee',
bob = get_full_name('bob', 'dylan') 'roth') print(david)
print(bob)
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 test you write.
Testing middle names Save as accountant.py
We’ve shown that get_full_name() works for first and last
class Accountant(): Using setUp() to support multiple tests
names. Let’s test that it works for middle names as well. The instance self.acc can be used in each new test.
"""Manage a bank account."""
import unittest import unittest
from full_names import get_full_name def init (self, balance=0): from accountant import Accountant
self.balance = balance
class NamesTestCase(unittest.TestCase): class TestAccountant(unittest.TestCase):
"""Tests for names.py.""" def deposit(self, """Tests for the class Accountant."""
amount):
def test_first_last(self): self.balance += def setUp(self):
"""Test names like Janis Joplin.""" amount self.acc = Accountant()
full_name = get_full_name('janis',
'joplin') def withdraw(self, amount): def test_initial_balance(self):
self.assertEqual(full_name, self.balance -= amount # Default balance should be 0.
'Janis Joplin') self.assertEqual(self.acc.balance,
Building a testcase 0)
def test_middle(self): For the first test, we’ll make sure we can start out with different
initial balances. Save this as test_accountant.py.
"""Test names like David Lee # Test non-default
Roth.""" full_name = import unittest balance. acc =
get_full_name('david', from accountant import Accountant Accountant(100)
'roth', 'lee') self.assertEqual(acc.balance, 100)
self.assertEqual(full_name, class TestAccountant(unittest.TestCase):
'David Lee Roth') """Tests for the class Accountant.""" def test_deposit(self):
# Test single deposit.
unittest.main() def test_initial_balance(self): self.acc.deposit(100)
Running the tests # Default balance should be self.assertEqual(self.acc.balance,
The two dots represent two passing tests. 0. acc = Accountant() 100)
self.assertEqual(acc.balance,
.. 0) # Test multiple deposits.
---------------------------------------
self.acc.deposit(100)
Ran 2 tests in 0.000s # Test non-default self.acc.deposit(100)
balance. acc = self.assertEqual(self.acc.balance,
OK Accountant(100) 300)
self.assertEqual(acc.balance, 100)
def test_withdrawal(self):
Python provides a number of assert methods you can use unittest.main() # Test single withdrawal.
to test your code. self.acc.deposit(1000)
Running the test
Verify that a==b, or a != b self.acc.withdraw(100)
. self.assertEqual(self.acc.balance,
assertEqual(a, b) --------------------------------------- 900)
assertNotEqual(a, b) Ran 1 test in
unittest.main()
Verify that x is True, or x is False
0.000s OK Running the tests
assertTrue(x)
assertFalse(x) ...

Verify an item is in a list, or not in a list In general you shouldn’t modify a test once it’s written. Ran 3 tests in
When a test fails it usually means new code you’ve written
assertIn(item, list) has broken existing functionality, and you need to modify 0.001s OK
assertNotIn(item, list) the new code until all existing tests pass.
If your original requirements have changed, it may be
appropriate to modify some tests. This usually happens in
the early stages of a project when desired behavior is still
being sorted out.
The following code sets up an empty game window, and
starts an event loop and a loop that continually Useful rect attributes
Once you have a rect object, there are a number of attributes that
refreshes the screen.
are useful when positioning objects and detecting relative positions
An empty game window of objects. (You can find more attributes in the Pygame
documentation.)
import sys
# Individual x and y values:
import pygame as pg
screen_rect.left, screen_rect.right
Pygame is a framework for making games using def run_game():
screen_rect.top, screen_rect.bottom
Python. Making games is fun, and it’s a great screen_rect.centerx,
# Initialize and set up screen.
way to expand your programming skills and screen_rect.centery
pg.init()
knowledge. screen_rect.width, screen_rect.height
screen = pg.display.set_mode((1200,
Pygame takes care of many of the lower- 800)) pg.display.set_caption("Alien
# Tuples
level tasks in building games, which lets you Invasion")
screen_rect.center
focus on the aspects of your game that make screen_rect.size
it interesting. # Start main loop.
while True: Creating a rect object
# Start event loop. You can create a rect object from scratch. For example a small
for event in rect object that’s filled in can represent a bullet in a game. The
Pygame runs on all systems, but setup is slightly different Rect() class takes the coordinates of the upper left corner, and the
pg.event.get(): if width and height of the rect. The draw.rect() function takes a
on each OS. The instructions here assume you’re using event.type == pg.QUIT: screen object, a color, and a rect. This function fills the given rect
Python 3, and provide a minimal installation of Pygame. If sys.exit() with the given color.
these instructions don’t work for your system, see the
more detailed notes at http://ehmatthes.github.io/pcc/. # Refresh screen. bullet_rect = pg.Rect(100, 100, 3, 15)
Pygame on Linux pg.display.flip() color = (100, 100, 100)
pg.draw.rect(screen, color, bullet_rect)
$ sudo apt-get install python3-dev
run_game()
mercurial libsdl-image1.2-dev
libsdl2-dev Setting a custom window size
libsdl-ttf2.0-dev The display.set_mode() function accepts a tuple that defines the Many objects in a game are images that are moved around
screen size. the screen. It’s easiest to use bitmap (.bmp) image files, but
$ pip install --user
hg+http://bitbucket.org/pygame/pygame screen_dim = (1200, 800) you can also configure your system to work with jpg, png,
screen = pg.display.set_mode(screen_dim) and gif files as well.
Pygame on OS X
This assumes you’ve used Homebrew to install Python 3. Loading an image
Setting a custom background color
$ brew install hg sdl sdl_image sdl_ttf Colors are defined as a tuple of red, green, and blue values. Each ship = pg.image.load('images/ship.bmp')
$ pip install --user value ranges from 0-255.
Getting the rect object from an image
hg+http://bitbucket.org/pygame/pygame bg_color = (230, 230, 230)
screen.fill(bg_color) ship_rect = ship.get_rect()
Pygame on Windows
Find an installer at Positioning an image
https://bitbucket.org/pygame/pygame/downloads/ or With rects, it’s easy to position an image wherever you want on
http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame that matches the screen, or in relation to another object. The following code
your version of Python. Run the installer file if it’s a .exe or .msi file. Many objects in a game can be treated as simple positions a ship object at the bottom center of the screen.
If it’s a .whl file, use pip to install Pygame: rectangles, rather than their actual shape. This simplifies
code without noticeably affecting game play. Pygame has a ship_rect.midbottom = screen_rect.midbottom
> python –m pip install --user
rect object that makes it easy to work with game objects.
pygame-1.9.2a0-cp35-none-win32.whl
Getting the screen rect object
Testing your installation We already have a screen object; we can easily access the rect
To test your installation, open a terminal session and try to import object associated with the screen.
Pygame. If you don’t get any error messages, your installation was
successful. screen_rect = screen.get_rect() Covers Python 3 and Python 2
$ python Finding the center of the screen
>>> import pygame Rect objects have a center attribute which stores the center point.
>>> screen_center = screen_rect.center
Pygame’s event loop registers an event any time the
Drawing an image to the screen mouse moves, or a mouse button is pressed or released. Removing an item from a group
Once an image is loaded and positioned, you can draw it to the It’s important to delete elements that will never appear again in the
screen with the blit() method. The blit() method acts on the screen Responding to the mouse button game, so you don’t waste memory and resources.
object, and takes the image object and image rect as arguments.
for event in pg.event.get(): bullets.remove(bullet)
# Draw ship to screen. if event.type == pg.MOUSEBUTTONDOWN:
screen.blit(ship, ship_rect) ship.fire_bullet()
The blitme() method Finding the mouse position You can detect when a single object collides with any
Game objects such as ships are often written as classes. Then The mouse position is returned as a tuple. member of a group. You can also detect when any member
a blitme() method is usually defined, which draws the object to of one group collides with a member of another group.
the screen. mouse_pos = pg.mouse.get_pos()
Collisions between a single object and a group
def blitme(self): Clicking a button The spritecollideany() function takes an object and a group, and
"""Draw ship at current location.""" You might want to know if the cursor is over an object such as a returns True if the object overlaps with any member of the group.
self.screen.blit(self.image, self.rect) button. The rect.collidepoint() method returns true when a point is
if pg.sprite.spritecollideany(ship, aliens):
inside a rect object.
ships_left -= 1
if button_rect.collidepoint(mouse_pos):
start_game() Collisions between two groups
Pygame watches for events such as key presses and The sprite.groupcollide() function takes two groups, and two
mouse actions. You can detect any event you care about in Hiding the mouse booleans. The function returns a dictionary containing information
the event loop, and respond with any action that’s about the members that have collided. The booleans tell Pygame
appropriate for your game. pg.mouse.set_visible(False) whether to delete the members of either group that have collided.
Responding to key presses collisions =
Pygame’s main event loop registers a KEYDOWN event any time pg.sprite.groupcollide( bull
a key is pressed. When this happens, you can check for specific
ets, aliens, True, True)
keys. Pygame has a Group class which makes working with a
for event in pg.event.get(): group of similar objects easier. A group is like a list, with
score += len(collisions) * alien_point_value
some extra functionality that’s helpful when building games.
if event.type == pg.KEYDOWN:
if event.key == pg.K_RIGHT: Making and filling a group
ship_rect.x += 1 An object that will be placed in a group must inherit from Sprite. You can use text for a variety of purposes in a game. For
elif event.key == pg.K_LEFT: example you can share information with players, and
ship_rect.x -= 1 from pygame.sprite import Sprite, Group
you can display a score.
elif event.key == pg.K_SPACE:
def Bullet(Sprite): Displaying a message
ship.fire_bullet()
... The following code defines a message, then a color for the text
elif event.key == pg.K_q: and the background color for the message. A font is defined using
sys.exit() def draw_bullet(self):
the 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
Responding to released keys def update(self): the rect object associated with the image. We then center the
When the user releases a key, a KEYUP event is triggered. ... image on the screen and display it.
if event.type == pg.KEYUP: msg = "Play again?"
bullets = Group()
if event.key == pg.K_RIGHT: msg_color = (100, 100,
ship.moving_right = False 100)
new_bullet = Bullet()
bullets.add(new_bullet) bg_color = (230, 230, 230)

Looping through the items in a group f = pg.font.SysFont(None, 48)


The Pygame documentation is really helpful when building The sprites() method returns all the members of a group. msg_image = f.render(msg, True, msg_color,
your own games. The home page for the Pygame project is
at http://pygame.org/, and the home page for the for bullet in bullets.sprites(): bg_color)
documentation is at http://pygame.org/docs/. bullet.draw_bullet() msg_image_rect = msg_image.get_rect()
The most useful part of the documentation are the pages msg_image_rect.center = screen_rect.center
about specific parts of Pygame, such as the Rect() class Calling update() on a group screen.blit(msg_image, msg_image_rect)
Calling update() on a group automatically calls update() on each
and the sprite module. You can find a list of these elements
at the top of the help pages.
member of the group. More cheat sheets available at
bullets.update()
Making a scatter plot Emphasizing points
The scatter() function takes a list of x values and a list of y values, You can plot as much data as you want on one plot. Here we re-
and a variety of optional arguments. The s=10 argument controls plot the first and last points larger to emphasize them.
the size of each point.
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
x_values = list(range(1000))
x_values = list(range(1000)) squares = [x**2 for x in
squares = [x**2 for x in x_values]
x_values] plt.scatter(x_values, squares, c=squares,
cmap=plt.cm.Blues, edgecolor='none',
Data visualization involves exploring data plt.scatter(x_values, squares, s=10) s=10)
through visual representations. The matplotlib plt.show()
package helps you make visually appealing plt.scatter(x_values[0], squares[0],
representations of the data you’re working c='green', edgecolor='none', s=100)
Plots can be customized in a wide variety of ways. Just plt.scatter(x_values[-1], squares[-1],
with. matplotlib is extremely flexible; these
about any element of a plot can be customized. c='red', edgecolor='none', s=100)
examples will help you get started with a few
simple visualizations. Adding titles and labels, and scaling axes
plt.title("Square Numbers", fontsize=24)
import matplotlib.pyplot as plt --snip--
Removing axes
matplotlib runs on all systems, but setup is slightly different x_values = list(range(1000)) You can customize or remove axes entirely. Here’s how to access
depending on your OS. If the minimal instructions here squares = [x**2 for x in each axis, and hide it.
don’t work for you, see the more detailed instructions at x_values]
http://ehmatthes.github.io/pcc/. You should also consider plt.scatter(x_values, squares, s=10) plt.axes().get_xaxis().set_visible(False)
installing the Anaconda distrubution of Python from plt.axes().get_yaxis().set_visible(False)
https://continuum.io/downloads/, which includes matplotlib. plt.title("Square Numbers", fontsize=24) Setting a custom figure size
matplotlib on Linux plt.xlabel("Value", fontsize=18) You can make your plot as big or small as you want. Before
plt.ylabel("Square of Value", fontsize=18) plotting your data, add the following code. The dpi argument is
$ sudo apt-get install python3-matplotlib plt.tick_params(axis='both', which='major', optional; if you don’t know your system’s resolution you can omit
labelsize=14) the argument and adjust the figsize argument accordingly.
matplotlib on OS X
Start a terminal session and enter import matplotlib to plt.axis([0, 1100, 0, 1100000]) plt.figure(dpi=128, figsize=(10, 6))
see if it’s already installed on your system. If not, try this
command: plt.show() Saving a plot
The matplotlib viewer has an interactive save button, but you can
$ pip install --user matplotlib Using a colormap
also save your visualizations programmatically. To do so, replace
A colormap varies the point colors from one shade to another,
matplotlib on Windows plt.show() with plt.savefig(). The
based on a certain value for each point. The value used to
You first need to install Visual Studio, which you can do from bbox_inches='tight' argument trims extra whitespace from
determine the color of each point is passed to the c argument,
https://dev.windows.com/. The Community edition is free. Then go the plot.
and the cmap argument specifies which colormap to use.
to https://pypi.python.org/pypi/matplotlib/ or The edgecolor='none' argument removes the black outline plt.savefig('squares.png',
http://www.lfd.uic.edu/~gohlke/pythonlibs/#matplotlib and download from each point. bbox_inches='tight')
an appropriate installer file.
plt.scatter(x_values, squares, c=squares,
cmap=plt.cm.Blues, edgecolor='none',
s=10) 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
The strftime() function generates a formatted string from a
relationships in the data. For example you can fill the space related datasets.
datetime object, and the strptime() function genereates a
between two sets of data. datetime object from a string. The following codes let you work Sharing an x-axis
Plotting two sets of data with 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
%B Month name, such as January tuple of axes. Each set of axes corresponds to a separate plot in
import matplotlib.pyplot as plt %m Month, as a number (01 to 12) the 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
%y Two-digit year, such as 16 import matplotlib.pyplot as plt
squares = [x**2 for x in
x_values] cubes = [x**3 for x %H Hour, in 24-hour format (00 to 23)
%I Hour, in 12-hour format (01 to 12) x_vals = list(range(11))
in x_values]
%p AM or PM squares = [x**2 for x in x_vals]
%M Minutes (00 to 59) cubes = [x**3 for x in x_vals]
plt.scatter(x_values, squares, c='blue',
edgecolor='none', s=20) %S Seconds (00 to 61)
fig, axarr = plt.subplots(2, 1,
plt.scatter(x_values, cubes, c='red',
Converting a string to a datetime object sharex=True)
edgecolor='none', s=20)
new_years = dt.strptime('1/1/2017', '%m/%d/%Y')
axarr[0].scatter(x_vals, squares)
plt.axis([0, 11, 0, 1100])
Converting a datetime object to a string axarr[0].set_title('Squares')
plt.show()
Filling the space between data sets ny_string = dt.strftime(new_years, '%B %d, axarr[1].scatter(x_vals, cubes, c='red')
The fill_between() method fills the space between two data %Y') 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 plt.show()
list of high temperatures. It then plots the high temperatures, with Sharing a y-axis
plt.fill_between(x_values, cubes, squares, the date labels displayed in a specific format. To share a y-axis, we use the sharey=True argument.
facecolor='blue', alpha=0.25)
from datetime import datetime as dt import matplotlib.pyplot as plt

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


Many interesting data sets have a date or time as the x- from matplotlib import dates as mdates squares = [x**2 for x in x_vals]
value. Python’s datetime module helps you work with this cubes = [x**3 for x in x_vals]
kind of data. dates = [
Generating the current date dt(2016, 6, 21), dt(2016, 6, 22), fig, axarr = plt.subplots(1, 2,
The datetime.now() function returns a datetime object dt(2016, 6, 23), dt(2016, 6, 24), sharey=True)
representing the current date and time. ]
from datetime import datetime as dt axarr[0].scatter(x_vals, squares)
highs = [57, 68, 64, 59] axarr[0].set_title('Squares')
today = dt.now() fig = plt.figure(dpi=128, figsize=(10,6))
date_string = dt.strftime(today, axarr[1].scatter(x_vals, cubes, c='red')
plt.plot(dates, highs, c='red') axarr[1].set_title('Cubes')
'%m/%d/%Y') print(date_string) plt.title("Daily High Temps", fontsize=24)
Generating a specific date plt.ylabel("Temp (F)", fontsize=16) plt.show()
You can also generate a datetime object for any date and time you
want. The positional order of arguments is year, month, and day. x_axis = plt.axes().get_xaxis()
The hour, minute, second, and microsecond arguments are x_axis.set_major_formatter(
optional. mdates.DateFormatter('%B %d %Y')
from datetime import datetime as dt )
fig.autofmt_xdate()
new_years = dt(2017, 1, 1)
fall_equinox = dt(year=2016, month=9, plt.show() More cheat sheets available at
day=22)
You can add as much data as you want when making a
Making a scatter plot visualization.
The data for a scatter plot needs to be a list containing tuples of
the form (x, y). The stroke=False argument tells Pygal to Plotting squares and cubes
make an XY chart with no line connecting the points.
import pygal
import pygal
x_values = list(range(11))
squares = [ squares = [x**2 for x in
Data visualization involves exploring data (0, 0), (1, 1), (2, 4), (3, 9), x_values] cubes = [x**3 for x
(4, 16), (5, 25), in x_values]
through visual representations. Pygal helps
]
you make visually appealing representations of
chart = pygal.Line()
the data you’re working with. Pygal is chart = pygal.XY(stroke=False) chart.force_uri_protocol =
particularly well suited for visualizations that chart.force_uri_protocol = 'http' 'http' chart.title = "Squares
will be presented online, because it supports chart.add('x^2', squares) and Cubes" chart.x_labels =
interactive elements. chart.render_to_file('squares.svg') x_values
Using a list comprehension for a scatter plot
A list comprehension can be used to effficiently make a dataset
chart.add('Squares', squares)
Pygal can be installed using pip. for a scatter plot. chart.add('Cubes', cubes)
Pygal on Linux and OS X chart.render_to_file('squares_cubes.svg')
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.
Making a bar graph
A bar graph requires a list of values for the bar sizes. To label The default is to fill from the x-axis up, but you can fill from any
Pygal on Windows horizontal line using the zero argument.
the bars, pass a list of the same length to x_labels.
> python –m pip install --user pygal chart = pygal.Line(fill=True, zero=0)
import pygal

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.s
x_values = [0, 1, 2, 3, 4, 5] vg')
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
chart = pygal.Line() way to store the data for a bar graph. The keys are used as the The documentation for Pygal is available at
chart.force_uri_protocol = 'http' labels along the x-axis, and the values are used to determine http://www.pygal.org/.
chart.add('x^2', squares) the height of each bar.
chart.render_to_file('squares.svg')
import pygal
Adding labels and a title If you’re viewing svg output in a browser, Pygal needs to
results = { render the output file in a specific way. The
--snip-- 1:18, 2:16, 3:18, force_uri_protocol attribute for chart objects needs
chart = pygal.Line() 4:17, 5:18, 6:13, to be set to 'http'.
chart.force_uri_protocol = }
'http' chart.title = "Squares"
chart.x_labels = x_values chart = pygal.Bar()
chart.x_title = "Value" chart.force_uri_protocol = 'http' Covers Python 3 and Python 2
chart.y_title = "Square of chart.x_labels = results.keys()
Value" chart.add('x^2', squares) chart.add('D6', results.values())
chart.render_to_file('squares.svg chart.render_to_file('rolling_dice.s
') vg')
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 Configuration settings you want to these maps. Data is indicated by coloring, by
Some settings are controlled by a Config object.
for styling individual plot elements. labels, and by tooltips that show data when users hover
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 Installing the world map module
style class. Then pass the style object with the style argument my_config.width = 1000 The world map module is not included by default in Pygal 2.0. It
when you make the chart object. my_config.dots_size = 5 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
You can give each series on a chart different style settings. countries of North America.
squares = [x**2 for x in
x_values] cubes = [x**3 for x chart.add('Squares', squares, dots_size=2) from pygal.maps.world import World
in x_values] chart.add('Cubes', cubes, dots_size=3)
wm = World()
chart_style = LightGreenStyle() Styling individual data points wm.force_uri_protocol =
chart = You can style individual data points as well. To do so, write a 'http' wm.title = 'North
pygal.Line(style=chart_style) dictionary for each data point you want to customize. A 'value' America'
chart.force_uri_protocol = 'http' key is required, and other properies are optional. wm.add('North America', ['ca', 'mx', 'us'])
chart.title = "Squares and Cubes" import pygal
chart.x_labels = x_values wm.render_to_file('north_america.svg')
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') 'color': '#3333CC', and its code.
Parametric built-in styles 'xlink': 'http://djangoproject.com/', from pygal.maps.world import
Some built-in styles accept a custom color, then generate a theme }, COUNTRIES
based on that color. 20054,
from pygal.style import LightenStyle 12607, for code in sorted(COUNTRIES.keys()):
11827, print(code, COUNTRIES[code])
--snip-- ]
Plotting numerical data on a world map
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') chart.y_title = 'Stars' 34126000,
chart_style.plot_background = '#CCCCCC' chart.add('Python Repos', repos) 'us': 309349000,
chart_style.major_label_font_size = 20 chart.render_to_file('python_repos.sv 'mx': 113423000,
chart_style.label_font_size = 16 g') }
--snip--
wm = World()
Custom style class wm.force_uri_protocol =
You can start with a bare style class, and then set only the 'http'
properties you care about. wm.title = 'Population of North America'
chart_style = Style() wm.add('North America', populations)
chart_style.colors = [
'#CCCCCC', '#AAAAAA', '#888888'] wm.render_to_file('na_populations.svg')
chart_style.plot_background = '#EEEEEE'
More cheat sheets available at
chart = pygal.Line(style=chart_style)
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 models from django.conf.urls import include,
url from django.contrib import admin
Django is a web framework which helps you class Topic(models.Model):
build interactive websites using Python. With """A topic the user is learning urlpatterns = [
Django you define the kind of data your site about.""" text = url(r'^admin/',
needs to work with, and you define the ways models.CharField(max_length=200) include(admin.site.urls)), url(r'',
your users can work with that data. date_added = models.DateTimeField( include('learning_logs.urls',
auto_now_add=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
where your project can be isolated from your other Python
projects. Most commands assume you’re working in an Activating a model in the app. You’ll need to make this file yourself, and save it in the
To use a model the app must be added to the tuple app’s folder.
active virtual environment.
INSTALLED_APPS, which is stored in the project’s settings.py file.
from django.conf.urls import url
Create a virtual environment
INSTALLED_APPS = (
$ python –m venv ll_env --snip-- from . import views
'django.contrib.staticfiles',
Activate the environment (Linux and OS X) urlpatterns = [
$ source ll_env/bin/activate # My apps url(r'^$', views.index, name='index'),
'learning_logs', ]
Activate the environment (Windows) )
Writing a simple view
> ll_env\Scripts\activate Migrating the database A view takes information from a request and sends data to the
The database needs to be modified to store the kind of data that browser, often through a template. View functions are stored in an
Install Django to the active environment the model represents. app’s views.py file. This simple view function doesn’t pull in any
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):
To start a project we’ll create a new project, create a Creating a superuser """The home page for Learning Log."""
database, and start a development server. A superuser is a user account that has access to all aspects of the
project.
return render(request,
Create a new project 'learning_logs/index.html')
$ python manage.py createsuperuser
$ django-admin.py startproject learning_log
. Registering a model
Create a database You can register your models with Django’s admin site, which
makes it easier to work with the data in your project. To do this, The documentation for Django is available at
$ python manage.py migrate modify the app’s admin.py file. View the admin site at http://docs.djangoproject.com/. The Django documentation
http://localhost:8000/admin/. is thorough and user-friendly, so check it out!
View the project
After issuing this command, you can view the project at from django.contrib import admin
http://localhost:8000/.
from learning_logs.models import Topic
$ python manage.py runserver
Covers Python 3 and Python 2
Create a new app admin.site.register(Topic)
A Django project is made up of one or more apps.

$ python manage.py startapp learning_logs


A new model can use an existing model. The ForeignKey
Writing a simple template Using data in a template
attribute establishes a connection between instances of the
A template sets up the structure for a page. It’s a mix of html and The data in the view function’s context dictionary is available
template code, which is like Python but not as powerful. Make a two related models. Make sure to migrate the database within the template. This data is accessed using template
folder called templates inside the project folder. Inside the after adding a new model to your app. variables, which are indicated by doubled curly braces.
templates folder make another folder with the same name as the The vertical line after a template variable indicates a filter. In this
app. This is where the template files should be saved.
Defining a model with a foreign key case a filter called date formats date objects, and the filter
class Entry(models.Model): linebreaks renders paragraphs properly on a web page.
<p>Learning Log</p>
"""Learning log entries for a {% extends 'learning_logs/base.html' %}
<p>Learning Log helps you keep track of topic.""" topic =
your learning, for any topic you're models.ForeignKey(Topic) {% block content %}
learning about.</p> text = models.TextField()
date_added = <p>Topic: {{ topic }}</p>
models.DateTimeField(
auto_now_add=True) <p>Entries:</p>
Many elements of a web page are repeated on every page <ul>
in the site, or every page in a section of the site. By writing def str (self): {% for entry in entries %}
one parent template for the site, and one for each section, <li>
you can easily modify the look and feel of your entire site. <p>
Most pages in a project need to present data that’s specific
{{ entry.date_added|date:'M d, Y H:i'
The parent template to the current user.
The parent template defines the elements common to a set of }}
pages, and defines blocks that will be filled by individual pages. URL parameters </p>
A URL often needs to accept a parameter telling it which data to <p>
<p> access from the database. The second URL pattern shown here {{ entry.text|linebreaks }}
<a href="{% url 'learning_logs:index' looks for the ID of a specific topic and stores it in the parameter </p>
%}"> Learning Log topic_id. </li>
</a> {% empty %}
urlpatterns = [
</p> <li>There are no entries yet.</li>
url(r'^$', views.index,
name='index'), url(r'^topics/(? {% endfor %}
{% block content %}{% endblock content %} </ul>
P<topic_id>\d+)/$',
The child template views.topic, name='topic'),
The child template uses the {% extends %} template tag to pull ] {% endblock content %}
in the structure of the parent template. It then defines the content
for any blocks defined in the parent template. Using data in a view
The view uses a parameter from the URL to pull the correct data
{% extends 'learning_logs/base.html' %} from the database. In this example the view is sending a context You can explore the data in your project from the command
dictionary to the template, containing data that should be displayed line. This is helpful for developing queries and testing code
{% block content %} on the page. snippets.
<p> def topic(request, topic_id): Start a shell session
Learning Log helps you keep track """Show a topic and all its
of your learning, for any topic you're $ python manage.py shell
entries.""" topic =
learning about. Topics.objects.get(id=topic_id) Access data from the project
</p> entries = topic.entry_set.order_by(
{% endblock content %} >>> from learning_logs.models import Topic
'-
>>> Topic.objects.all()
date_added') context
[<Topic: Chess>, <Topic: Rock Climbing>]
= {
>>> topic = Topic.objects.get(id=1)
'topic': topic,
>>> topic.text
'entries': entries,
'Chess'
}

Python code is usually indented by four spaces. In


templates you’ll often see two spaces used for indentation, If you make a change to your project and the change More cheat sheets available at
because elements tend to be nested more deeply in doesn’t seem to have any effect, try restarting the server:
templates. $ python manage.py runserver
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
new urls.py file in the users app folder. The login view is a is currently logged in, and to provide a link to the login and logout
default 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
from django.contrib.auth.views import specific content to users depending on whether they have logged
in or not. The {{ user.username }} property allows you to
login from . import views greet users who have logged in. Users who haven’t logged in see
links to register or log in.
urlpatterns = <p>
[ url(r'^login/$', <a href="{% url 'learning_logs:index'
Most web applications need to let users login, %}"> Learning Log
create accounts. This lets users create and {'template_name': </a>
work with their own data. Some of this data 'users/login.html'}, name='login'), {% if user.is_authenticated
may be private, and some may be public. url(r'^logout/$', %} Hello, {{ user.username
Django’s forms allow users to enter and views.logout_view, }}.
modify their data. name='logout'), <a href="{% url 'users:logout'
url(r'^register/$', %}"> log out
views.register, </a>
User accounts are handled by a dedicated app called name='register'), {% else %}
users. Users need to be able to register, log in, and log ] <a href="{% url 'users:register' %}">
out. Django automates much of this work for you. The login template register
The login view is provided by default, but you need to provide your </a> -
Making a users app own login template. The template shown here displays a simple <a href="{% url 'users:login'
After making the app, be sure to add 'users' to login form, and provides basic error messages. Make a templates
INSTALLED_APPS %}"> log in
folder in the users folder, and then make a users folder in the
in the project’s settings.py file. templates folder. Save this file as login.html. </a>
$ python manage.py startapp users The tag {% csrf_token %} helps prevent a common type of {% endif %}
attack with forms. The {{ form.as_p }} element displays the </p>
Including URLS for the users app default login form in paragraph format. The <input> element
Add a line to the project’s urls.py file so the users app’s URLs are named next redirects the user to the home page after a {% block content %}{% endblock content %}
included in the project. successful login.
The logout view
urlpatterns = [ {% extends "learning_logs/base.html" %} The logout_view() function uses Django’s logout()
url(r'^admin/', function and then redirects the user back to the home page. Since
there is no logout page, there is no logout template. Make sure to
include(admin.site.urls)), {% block content %}
write this code in the views.py file that’s stored in the users app
url(r'^users/', include('users.urls', {% if form.errors %} folder.
namespace='users')), <p>
from django.http import
url(r'', include('learning_logs.urls', Your username and password didn't match.
HttpResponseRedirect from
namespace='learning_logs')), Please try again.
django.core.urlresolvers import reverse
] </p>
from django.contrib.auth import logout
{% endif %}
def logout_view(request):
There are a number of ways to create forms and work with <form method="post"
"""Log the user
them. You can use Django’s defaults, or completely action="{% url 'users:login' %}">
out."""
customize your forms. For a simple way to let users enter {% csrf token %}
logout(request)
data based on your models, use a ModelForm. This {{ form.as_p }}
creates a form that allows users to enter data that will <button name="submit">log in</button>
populate the fields on a model.
The register view on the back of this sheet shows a <input type="hidden" name="next"
value="{% url 'learning_logs:index'
Covers Python 3 and Python 2
simple approach to form processing. If the view doesn’t
receive data from a form, it responds with a blank form. If it %}"/>
receives POST data from a form, it validates the data and </form>
then saves it to the database.
{% endblock content %}
The register view The register template Restricting access to logged-in users
The register view needs to display a blank registration form when The register template displays the registration form in paragraph Some pages are only relevant to registered users. The views for
the page is first requested, and then process completed formats. these pages can be protected by the @login_required
registration forms. A successful registration logs the user in and decorator. Any view with this decorator will automatically redirect
redirects to the home page. {% extends 'learning_logs/base.html' %} non-logged in users to an appropriate page. Here’s an example
views.py file.
from django.contrib.auth import login {% block content %} from django.contrib.auth.decorators import
from django.contrib.auth import
/ login_required
authenticate from django.contrib.auth.forms <form method='post' --snip--
import \ action="{% url 'users:register' %}">
UserCreationForm
@login_required
{% csrf_token %} def topic(request, topic_id):
def register(request): {{ form.as_p }} """Show a topic and all its entries."""
"""Register a new
user.""" if <button name='submit'>register</button> Setting the redirect URL
request.method != 'POST': <input type='hidden' name='next' The @login_required decorator sends unauthorized users to
# Show blank registration form. value="{% url 'learning_logs:index' the login page. Add the following line to your project’s settings.py
form = UserCreationForm() %}"/> file so Django will know how to find your login page.
else: LOGIN_URL = '/users/login/'
# Process completed </form>
form. form = Preventing inadvertent access
UserCreationForm( {% endblock content %} Some pages serve data based on a parameter in the URL. You
data=request.POST) can check that the current user owns the requested data, and
return a 404 error if they don’t. Here’s an example view.
if form.is_valid(): Users will have data that belongs to them. Any model that should from django.http import Http404
new_user = be connected directly to a user needs a field connecting instances
form.save() of the model to a specific user.
--snip--
# Log in, redirect to home Making a topic belong to a user def topic(request, topic_id):
page. pw = Only the highest-level data in a hierarchy needs to be directly """Show a topic and all its
request.POST['password1'] connected to a user. To do this import the User model, and add it entries.""" topic =
authenticated_user = as a foreign key on the data model. Topics.objects.get(id=topic_id) if
authenticate( After modifying the model you’ll need to migrate the database. topic.owner != request.user:
username=new_user.username, You’ll need to choose a user ID to connect each existing instance
to.
raise Http404
password=pw --snip--
) from django.db import models
login(request, from django.contrib.auth.models import User
authenticated_user) return
HttpResponseRedirect( class Topic(models.Model): If you provide some initial data, Django generates a form
reverse('learning_logs:index') """A topic the user is learning with the user’s existing data. Users can then modify and
) about.""" text = save their data.
models.CharField(max_length=200) Creating a form with initial data
context = {'form': form} date_added = models.DateTimeField( The instance parameter allows you to specify initial data for a form.
return render(request, auto_now_add=True) form = EntryForm(instance=entry)
'users/register.html', context) owner =
models.ForeignKey(User) Modifying data before saving
The argument commit=False allows you to make changes before
def str (self): writing data to the database.
The django-bootstrap3 app allows you to use the Bootstrap
library to make your project look visually appealing. The return self.text new_topic = form.save(commit=False)
app provides tags that you can use in your templates to new_topic.owner = request.user
Querying data for the current user
style individual elements on a page. Learn more at In a view, the request object has a user attribute. You can use this new_topic.save()
http://django-bootstrap3.readthedocs.io/. attribute to query for the user’s data. The filter() function then
pulls the data that belongs to the current user. More cheat sheets available at
topics = Topic.objects.filter(
Heroku lets you push your project to a live server, making owner=request.user)

You might also like