Beginners Python Cheat Sheet Pcc All (2)
Beginners Python Cheat Sheet Pcc All (2)
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)
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"
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)
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
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.