Beginners Python

Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

Beginner's Python

Lists (cont.) Dictionaries


List comprehensions Dictionaries store connections between pieces of
information. Each item in a dictionary is a key-value pair.

Cheat Sheet
squares = [x**2 for x in range(1, 11)]
A simple dictionary
Slicing a list
alien = {'color': 'green', 'points': 5}
finishers = ['sam', 'bob', 'ada', 'bea']
first_two = finishers[:2] Accessing a value
Variables and Strings
Copying a list print(f"The alien's color is {alien['color']}.")
Variables are used to assign labels to values. A string is a
series of characters, surrounded by single or double quotes. copy_of_bikes = bikes[:] Adding a new key-value pair
Python's f-strings allow you to use variables inside strings to
alien['x_position'] = 0
build dynamic messages.
Tuples
Hello world Looping through all key-value pairs
Tuples are similar to lists, but the items in a tuple can't be
print("Hello world!") modified. fav_numbers = {'eric': 7, 'ever': 4, 'erin': 47}

Hello world with a variable Making a tuple for name, number in fav_numbers.items():
dimensions = (1920, 1080) print(f"{name} loves {number}.")
msg = "Hello world!"
print(msg) resolutions = ('720p', '1080p', '4K')
Looping through all keys
f-strings (using variables in strings) If statements fav_numbers = {'eric': 7, 'ever': 4, 'erin': 47}
first_name = 'albert' If statements are used to test for particular conditions and for name in fav_numbers.keys():
last_name = 'einstein' respond appropriately. print(f"{name} loves a number.")
full_name = f"{first_name} {last_name}"
print(full_name) Conditional tests Looping through all the values
equal x == 42
fav_numbers = {'eric': 7, 'ever': 4, 'erin': 47}
Lists not equal x != 42
A list stores a series of items in a particular order. You greater than x > 42
for number in fav_numbers.values():
or equal to x >= 42
access items using an index, or within a loop. print(f"{number} is a favorite.")
less than x < 42
Make a list or equal to x <= 42
User input
bikes = ['trek', 'redline', 'giant'] Conditional tests with lists Your programs can prompt the user for input. All input is
Get the first item in a list 'trek' in bikes stored as a string.
'surly' not in bikes
first_bike = bikes[0] Prompting for a value
Assigning boolean values name = input("What's your name? ")
Get the last item in a list
game_active = True print(f"Hello, {name}!")
last_bike = bikes[-1]
can_edit = False
Prompting for numerical input
Looping through a list
A simple if test age = input("How old are you? ")
for bike in bikes: age = int(age)
if age >= 18:
print(bike)
print("You can vote!")
Adding items to a list pi = input("What's the value of pi? ")
If-elif-else statements pi = float(pi)
bikes = []
if age < 4:
bikes.append('trek')
ticket_price = 0
bikes.append('redline')
bikes.append('giant')
elif age < 18:
ticket_price = 10 Python Crash Course
Making numerical lists elif age < 65: A Hands-on, Project-Based
ticket_price = 40 Introduction to Programming
squares = [] else:
for x in range(1, 11): ticket_price = 15 nostarch.com/pythoncrashcourse2e
squares.append(x**2)
While loops Classes Working with files
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. While loops are especially useful when you information an object can store. The information in a class are opened in read mode by default, but can also be opened
can't know ahead of time how many times a loop should run. is stored in attributes, and functions that belong to a class in write mode and append mode.
are called methods. A child class inherits the attributes and
A simple while loop Reading a file and storing its lines
methods from its parent class.
current_value = 1 filename = 'siddhartha.txt'
while current_value <= 5: Creating a dog class with open(filename) as file_object:
print(current_value) class Dog: lines = file_object.readlines()
current_value += 1 """Represent a dog."""
for line in lines:
Letting the user choose when to quit def __init__(self, name): print(line)
msg = '' """Initialize dog object."""
while msg != 'quit': self.name = name Writing to a file
The variable referring to the file object is often shortened to f.
msg = input("What's your message? ")
print(msg) def sit(self): filename = 'journal.txt'
"""Simulate sitting.""" with open(filename, 'w') as f:
Functions print(f"{self.name} is sitting.") f.write("I love programming.")
Functions are named blocks of code, designed to do one my_dog = Dog('Peso') Appending to a file
specific job. Information passed to a function is called an
filename = 'journal.txt'
argument, and information received by a function is called a print(f"{my_dog.name} is a great dog!") with open(filename, 'a') as f:
parameter. my_dog.sit() f.write("\nI love making games.")
A simple function Inheritance
def greet_user(): class SARDog(Dog):
Exceptions
"""Display a simple greeting.""" """Represent a search dog.""" Exceptions help you respond appropriately to errors that are
print("Hello!") likely to occur. You place code that might cause an error in
def __init__(self, name): the try block. Code that should run in response to an error
greet_user() """Initialize the sardog.""" goes in the except block. Code that should run only if the try
Passing an argument super().__init__(name) block was successful goes in the else block.

def greet_user(username): Catching an exception


def search(self):
"""Display a personalized greeting.""" """Simulate searching.""" prompt = "How many tickets do you need? "
print(f"Hello, {username}!") print(f"{self.name} is searching.") num_tickets = input(prompt)

greet_user('jesse') my_dog = SARDog('Willie') try:


num_tickets = int(num_tickets)
Default values for parameters print(f"{my_dog.name} is a search dog.") except ValueError:
def make_pizza(topping='pineapple'): my_dog.sit() print("Please try again.")
"""Make a single-topping pizza.""" my_dog.search() else:
print(f"Have a {topping} pizza!") print("Your tickets are printing.")
Infinite Skills
make_pizza() Zen of Python
make_pizza('mushroom') If you had infinite programming skills, what would you build?
Simple is better than complex
As you're learning to program, it's helpful to think
Returning a value If you have a choice between a simple and a complex
about the real-world projects you'd like to create. It's a
def add_numbers(x, y): good habit to keep an "ideas" notebook that you can solution, and both work, use the simple solution. Your
"""Add two numbers and return the sum.""" code will be easier to maintain, and it will be easier
return x + y
refer to whenever you want to start a new project.
If you haven't done so already, take a few minutes for you and others to build on that code later on.
sum = add_numbers(3, 5) and describe three projects you'd like to create. As
print(sum) you're learning you can write mall sprograms that
relate to these ideas, so you can get practice writing More cheat sheets available at
code relevant to topics you're interested in. ehmatthes.github.io/pcc_2e/
Beginner's Python
Adding elements Sorting a list
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. This allows you to modify The sorted() function returns a copy of the list, leaving the

Cheat Sheet - Lists existing lists, or start with an empty list and then add items to
it as the program develops.
Adding an element to the end of the list
original list unchanged.
You can sort the items in a list in alphabetical order, or
reverse alphabetical order. You can also reverse the original
order of the list. Keep in mind that lowercase and uppercase
What are lists? users.append('amy') letters may affect the sort order.
A list stores a series of items in a particular order. Lists Starting with an empty list Sorting a list permanently
allow you to store sets of information in one place, users = [] users.sort()
whether you have just a few items or millions of items. users.append('amy')
Lists are one of Python's most powerful features users.append('val') Sorting a list permanently in reverse alphabetical order
readily accessible to new programmers, and they tie users.append('bob') users.sort(reverse=True)
together many important concepts in programming. users.append('mia')
Sorting a list temporarily
Inserting elements at a particular position
Defining a list print(sorted(users))
users.insert(0, 'joe') print(sorted(users, reverse=True))
Use square brackets to define a list, and use commas to users.insert(3, 'bea')
separate individual items in the list. Use plural names for Reversing the order of a list
lists, to make it clear that the variable represents more than
one item. Removing elements users.reverse()
You can remove elements by their position in a list, or by the
Making a list value of the item. If you remove an item by its value, Python Looping through a list
users = ['val', 'bob', 'mia', 'ron', 'ned'] removes only the first item that has that value. Lists can contain millions of items, so Python provides an
Deleting an element by its position efficient way to loop through all the items in a list. When
Accessing elements you set up a loop, Python pulls each item from the list one
del users[-1] at a time and assigns it to a temporary variable, which
Individual elements in a list are accessed according to their
position, called the index. The index of the first element is 0, Removing an item by its value you provide a name for. This name should be the singular
the index of the second element is 1, and so forth. Negative version of the list name.
users.remove('mia') The indented block of code makes up the body of the
indices refer to items at the end of the list. To get a particular
element, write the name of the list and then the index of the loop, where you can work with each individual item. Any
element in square brackets. Popping elements lines that are not indented run after the loop is completed.
If you want to work with an element that you're removing Printing all items in a list
Getting the first element from the list, you can "pop" the item. If you think of the list as
first_user = users[0] a stack of items, pop() takes an item off the top of the stack. for user in users:
By default pop() returns the last element in the list, but print(user)
Getting the second element you can also pop elements from any position in the list. Printing a message for each item, and a separate
second_user = users[1] message afterwards
Pop the last item from a list
Getting the last elements most_recent_user = users.pop() for user in users:
newest_user = users[-1] print(most_recent_user) print(f"\nWelcome, {user}!")
print("We're so glad you joined!")
Pop the first item in a list
Modifying individual items first_user = users.pop(0) print("\nWelcome, we're glad to see you all!")
Once you've defined a list, you can change the value of print(first_user)
individual elements in the list. You do this by referring to the
index of the item you want to modify.
List length
Changing an element The len() function returns the number of items in a list. Python Crash Course
users[0] = 'valerie' A Hands-on, Project-Based
Find the length of a list
users[1] = 'robert' Introduction to Programming
users[-2] = 'ronald' num_users = len(users)
print(f"We have {num_users} users.") nostarch.com/pythoncrashcourse2e
The range() function Copying a list Tuples
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
numbers efficiently. The range() function starts at 0 by ends at the last item. If you try to copy a list without using in a 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 a
it. You can use the list() function to efficiently generate a the original list as well. program. Tuples are usually designated by parentheses.
large list of numbers. You can overwrite an entire tuple, but you can't change
Making a copy of a list
the values of individual elements.
Printing the numbers 0 to 1000 finishers = ['kai', 'abe', 'ada', 'gus', 'zoe']
for number in range(1001): copy_of_finishers = finishers[:] Defining a tuple
print(number) dimensions = (800, 600)
Printing the numbers 1 to 1000 List comprehensions Looping through a tuple
You can use a loop to generate a list based on a range of
for number in range(1, 1001): for dimension in dimensions:
numbers or on another list. This is a common operation,
print(number) print(dimension)
so 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 Overwriting a tuple
the for loop approach until you're ready to start using
numbers = list(range(1, 1000001)) dimensions = (800, 600)
comprehensions.
print(dimensions)
To write a comprehension, define an expression for the
Simple statistics values you want to store in the list. Then write a for loop to dimensions = (1200, 900)
There are a number of simple statistical operations you can generate input values needed to make the list. print(dimensions)
run on a list containing numerical data.
Using a loop to generate a list of square numbers
Finding the minimum value in a list squares = [] Visualizing your code
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2, 77] for x in range(1, 11): When you're first learning about data structures such as
youngest = min(ages) square = x**2 lists, it helps to visualize how Python is working with the
squares.append(square) information in your program. Python Tutor is a great tool for
Finding the maximum value seeing how Python keeps track of the information in a list.
Using a comprehension to generate a list of square
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2, 77] Try running the following code on pythontutor.com, and then
oldest = max(ages) numbers run your own code.
squares = [x**2 for x in range(1, 11)]
Finding the sum of all values Build a list and print the items in the list
ages = [93, 99, 66, 17, 85, 1, 35, 82, 2, 77] Using a loop to convert a list of names to upper case dogs = []
total_years = sum(ages) names = ['kai', 'abe', 'ada', 'gus', 'zoe'] dogs.append('willie')
dogs.append('hootz')
Slicing a list upper_names = [] dogs.append('peso')
for name in names: dogs.append('goblin')
You can work with any subset of elements from a list. A
upper_names.append(name.upper())
portion of a list is called a slice. To slice a list start with the for dog in dogs:
index of the first item you want, then add a colon and the Using a comprehension to convert a list of names to print(f"Hello {dog}!")
index after the last item you want. Leave off the first index upper case print("I love these dogs!")
to start at the beginning of the list, and leave off the second
index to slice through the end of the list. names = ['kai', 'abe', 'ada', 'gus', 'zoe']
print("\nThese were my first two dogs:")
old_dogs = dogs[:2]
Getting the first three items upper_names = [name.upper() for name in names]
for old_dog in old_dogs:
finishers = ['kai', 'abe', 'ada', 'gus', 'zoe'] print(old_dog)
first_three = finishers[:3] Styling your code
Readability counts del dogs[0]
Getting the middle three items dogs.remove('peso')
middle_three = finishers[1:4] Follow common Python formatting conventions: print(dogs)
• Use four spaces per indentation level.
Getting the last three items • Keep your lines to 79 characters or fewer.
last_three = finishers[-3:] • Use single blank lines to group parts of your
program visually. More cheat sheets available at
ehmatthes.github.io/pcc_2e/
Beginner's Python
Adding new key-value pairs Looping through a dictionary
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 a loop through all the key-value pairs, all the keys, or all the

Cheat Sheet - new key-value pair to an existing dictionary give the name of
the dictionary and the new key in square brackets, and set it
equal to the new value.
values.
Dictionaries keep track of the order in which key-value
pairs are added. If you want to process the information in a

Dictionaries
This also allows you to start with an empty dictionary and different order, you can sort the keys in your loop, using the
add key-value pairs as they become relevant. sorted() function.
Adding a key-value pair Looping through all key-value pairs
What are dictionaries? alien_0 = {'color': 'green', 'points': 5} # Store people's favorite languages.
fav_languages = {
Python's dictionaries allow you to connect pieces of alien_0['x'] = 0 'jen': 'python',
related information. Each piece of information in a alien_0['y'] = 25 'sarah': 'c',
dictionary is stored as a key-value pair. When you alien_0['speed'] = 1.5 'edward': 'ruby',
provide a key, Python returns the value associated 'phil': 'python',
Starting with an empty dictionary }
with that key. You can loop through all the key-value
alien_0 = {}
pairs, all the keys, or all the values. # Show each person's favorite language.
alien_0['color'] = 'green'
alien_0['points'] = 5 for name, language in fav_languages.items():
Defining a dictionary print(f"{name}: {language}")
Use curly braces to define a dictionary. Use colons to
connect keys and values, and use commas to separate
Modifying values Looping through all the keys
individual key-value pairs. You can modify the value associated with any key in a # Show everyone who's taken the survey.
dictionary. To do so give the name of the dictionary and the for name in fav_languages.keys():
Making a dictionary key in square brackets, then provide the new value for that print(name)
alien_0 = {'color': 'green', 'points': 5} key.
Looping through all the values
Modifying values in a dictionary
Accessing values alien_0 = {'color': 'green', 'points': 5}
# Show all the languages that have been chosen.
for language in fav_languages.values():
To access the value associated with an individual key give print(alien_0) print(language)
the name of the dictionary and then place the key in a set
of square brackets. If the key you provided is not in the # Change the alien's color and point value. Looping through all the keys in reverse order
dictionary, an error will occur. alien_0['color'] = 'yellow'
# Show each person's favorite language,
You can also use the get() method, which returns alien_0['points'] = 10
# in reverse order by the person's name.
None instead of an error if the key doesn't exist. You can print(alien_0)
for name in sorted(fav_languages.keys(),
also specify a default value to use if the key is not in the reverse=True):
dictionary. Removing key-value pairs language = fav_languages[name]
Getting the value associated with a key You can remove any key-value pair you want from a print(f"{name}: {language}")
dictionary. To do so use the del keyword and the dictionary
alien_0 = {'color': 'green', 'points': 5}
name, followed by the key in square brackets. This will Dictionary length
print(alien_0['color']) delete the key and its associated value. You can find the number of key-value pairs in a dictionary
print(alien_0['points']) Deleting a key-value pair using the len() function.
Getting the value with get() alien_0 = {'color': 'green', 'points': 5} Finding a dictionary's length
print(alien_0) num_responses = len(fav_languages)
alien_0 = {'color': 'green'}
del alien_0['points']
alien_color = alien_0.get('color')
alien_points = alien_0.get('points', 0)
print(alien_0)
Python Crash Course
alien_speed = alien_0.get('speed') A Hands-on, Project-Based
Visualizing dictionaries
print(alien_color) Introduction to Programming
Try running some of these examples on pythontutor.com,
print(alien_points) and then run one of your own programs that uses nostarch.com/pythoncrashcourse2e
print(alien_speed) dictionaries.
Nesting - A list of dictionaries Nesting - Lists in a dictionary Dictionary Comprehensions
It's sometimes useful to store a number of dictionaries in a Storing a list inside a dictionary allows you to associate more A comprehension is a compact way of generating a
list; this is called nesting. than one value with each key. dictionary, similar to a list comprehension. To make a
dictionary comprehension, define an expression for the
Storing dictionaries in a list Storing lists in a dictionary
key-value pairs you want to make. Then write a for loop to
# Start with an empty list. # Store multiple languages for each person. generate the values that will feed into this expression.
users = [] fav_languages = { The zip() function matches each item in one list to each
'jen': ['python', 'ruby'], item in a second list. It can be used to make a dictionary
# Make a new user, and add them to the list. 'sarah': ['c'], from two lists.
new_user = { 'edward': ['ruby', 'go'],
'last': 'fermi', 'phil': ['python', 'haskell'], Using a loop to make a dictionary
'first': 'enrico', } squares = {}
'username': 'efermi', for x in range(5):
} # Show all responses for each person. squares[x] = x**2
users.append(new_user) for name, langs in fav_languages.items():
print(f"{name}: ") Using a dictionary comprehension
# Make another new user, and add them as well. for lang in langs:
squares = {x:x**2 for x in range(5)}
new_user = { print(f"- {lang}")
'last': 'curie', Using zip() to make a dictionary
'first': 'marie', Nesting - A dictionary of dictionaries
'username': 'mcurie', group_1 = ['kai', 'abe', 'ada', 'gus', 'zoe']
} You can store a dictionary inside another dictionary. In this group_2 = ['jen', 'eva', 'dan', 'isa', 'meg']
users.append(new_user) case each value associated with a key is itself a dictionary.
pairings = {name:name_2
Storing dictionaries in a dictionary for name, name_2 in zip(group_1, group_2)}
# Show all information about each user.
print("User summary:") users = {
for user_dict in users: 'aeinstein': { Generating a million dictionaries
for k, v in user_dict.items(): 'first': 'albert',
You can use a loop to generate a large number of
print(f"{k}: {v}") 'last': 'einstein',
'location': 'princeton', dictionaries efficiently, if all the dictionaries start out with
print("\n") similar data.
},
You can also define a list of dictionaries directly, A million aliens
without using append(): 'mcurie': {
'first': 'marie', aliens = []
# Define a list of users, where each user 'last': 'curie',
# is represented by a dictionary. 'location': 'paris', # Make a million green aliens, worth 5 points
users = [ }, # each. Have them all start in one row.
{ } for alien_num in range(1_000_000):
'last': 'fermi', new_alien = {
'first': 'enrico', for username, user_dict in users.items(): 'color': 'green',
'username': 'efermi', full_name = f"{user_dict['first']} " 'points': 5,
}, full_name += user_dict['last'] 'x': 20 * alien_num,
{ 'y': 0
'last': 'curie', location = user_dict['location'] }
'first': 'marie',
'username': 'mcurie', print("\nUsername: " + username) aliens.append(new_alien)
}, print(f"\tFull name: {full_name.title()}")
] print(f"\tLocation: {location.title()}") # Prove the list contains a million aliens.
num_aliens = len(aliens)
# Show all information about each user.
print("User summary:") Levels of nesting print("Number of aliens created:")
for user_dict in users: Nesting is extremely useful in certain situations. However, print(num_aliens)
for k, v in user_dict.items(): be aware of making your code overly complex. If you're
print(f"{k}: {v}") nesting items much deeper than what you see here there
print("\n") are probably simpler ways of managing your data, such as More cheat sheets available at
using classes. ehmatthes.github.io/pcc_2e/
Beginner's Python
Numerical comparisons If statements
Testing numerical values is similar to testing string values. Several kinds of if statements exist. Your choice of which to
use depends on the number of conditions you need to test.
Testing equality and inequality
Cheat Sheet - >>> age = 18
>>> age == 18
You can have as many elif blocks as you need, and the
else block is always optional.
Simple if statement

If Statements
True
>>> age != 18 age = 19
False

and While Loops


if age >= 18:
Comparison operators print("You're old enough to vote!")
>>> age = 19
>>> age < 21 If-else statements
True age = 17
What are if statements? What are while >>> age <= 21
loops? True if age >= 18:
>>> age > 21 print("You're old enough to vote!")
Python's if statements allow you to examine the False else:
current state of a program and respond appropriately >>> age >= 21 print("You can't vote yet.")
to that state. You can write a simple if statement that False
checks one condition, or you can create a complex The if-elif-else chain
series of statements that identify the exact conditions Checking multiple conditions age = 12
you're interested in. You can check multiple conditions at the same time. The and
While loops run as long as certain conditions remain operator returns True if all the conditions listed are true. The if age < 4:
price = 0
true. You can use while loops to let your programs run or operator returns True if any condition is true.
elif age < 18:
as long as your users want them to. Using and to check multiple conditions price = 25
else:
Conditional Tests >>> age_0 = 22
price = 40
>>> age_1 = 18
A conditional test is an expression that can be evaluated
>>> age_0 >= 21 and age_1 >= 21
as true or false. Python uses the values True and False print(f"Your cost is ${price}.")
False
to decide whether the code in an if statement should be >>> age_1 = 23
executed. >>> age_0 >= 21 and age_1 >= 21 Conditional tests with lists
Checking for equality True You can easily test whether a certain value is in a list. You
A single equal sign assigns a value to a variable. A double equal can also test whether a list is empty before trying to loop
Using or to check multiple conditions
sign checks whether two values are equal. through the list.
If your conditional tests aren't doing what you expect them to, >>> age_0 = 22
make sure you're not accidentally using a single equal sign. >>> age_1 = 18 Testing if a value is in a list
>>> car = 'bmw' >>> age_0 >= 21 or age_1 >= 21 >>> players = ['al', 'bea', 'cyn', 'dale']
>>> car == 'bmw' True >>> 'al' in players
True >>> age_0 = 18 True
>>> car = 'audi' >>> age_0 >= 21 or age_1 >= 21 >>> 'eric' in players
>>> car == 'bmw' False False
False Testing if two values are in a list
Boolean values
Ignoring case when making a comparison >>> 'al' in players and 'cyn' in players
A boolean value is either True or False. Variables with
>>> car = 'Audi' boolean values are often used to keep track of certain
>>> car.lower() == 'audi'
True
conditions within a program.
Simple boolean values
Python Crash Course
Checking for inequality A Hands-on, Project-Based
game_active = True Introduction to Programming
>>> topping = 'mushrooms' is_valid = True
>>> topping != 'anchovies' can_edit = False nostarch.com/pythoncrashcourse2e
True
Conditional tests with lists (cont.) While loops (cont.) While loops (cont.)
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', 'dee'] prompt = "\nTell me something, and I'll " banned_users = ['eve', 'fred', 'gary', 'helen']
user = 'erin' prompt += "repeat it back to you."
prompt += "\nEnter 'quit' to end the program. " prompt = "\nAdd a player to your team."
if user not in banned_users: prompt += "\nEnter 'quit' when you're done. "
print("You can play!") message = ""
while message != 'quit': players = []
Checking if a list is empty message = input(prompt) while True:
An empty list evaluates as False in an if statement. player = input(prompt)
players = [] if message != 'quit':
print(message) if player == 'quit':
if players: break
Using a flag elif player in banned_users:
for player in players:
Flags are most useful in long-running programs where code from print(f"{player} is banned!")
print(f"Player: {player.title()}")
other parts of the program might need to end the loop. continue
else:
print("We have no players yet!") prompt = "\nTell me something, and I'll " else:
prompt += "repeat it back to you." players.append(player)
prompt += "\nEnter 'quit' to end the program. "
Accepting input print("\nYour team:")
You can allow your users to enter input using the input() active = True for player in players:
function. All input is initially stored as a string. If you want to while active: print(player)
accept numerical input, you'll need to convert the input string message = input(prompt)
value to a numerical type. Avoiding infinite loops
Simple input if message == 'quit':
Every while loop needs a way to stop running so it won't
active = False
name = input("What's your name? ") else: continue to run forever. If there's no way for the condition
print(f"Hello, {name}.") print(message) to become false, the loop will never stop running. You can
usually press Ctrl-C to stop an infinite loop.
Accepting numerical input using int() Using break to exit a loop
An infinite loop
age = input("How old are you? ") prompt = "\nWhat cities have you visited?"
age = int(age) while True:
prompt += "\nEnter 'quit' when you're done. "
name = input("\nWho are you? ")
if age >= 18: print(f"Nice to meet you, {name}!")
while True:
print("\nYou can vote!") city = input(prompt)
else: Removing all instances of a value from a list
print("\nSorry, you can't vote yet.") if city == 'quit': The remove() method removes a specific value from a
break list, but it only removes the first instance of the value you
Accepting numerical input using float() else: provide. You can use a while loop to remove all instances of
tip = input("How much do you want to tip? ") print(f"I've been to {city}!") a particular value.
tip = float(tip)
print(f"Tipped ${tip}.") Removing all cats from a list of pets
Accepting input with Sublime Text
Sublime Text, and a number of other text editors can't run pets = ['dog', 'cat', 'dog', 'fish', 'cat',
While loops programs that prompt the user for input. You can use these 'rabbit', 'cat']
A while loop repeats a block of code as long as a condition editors to write programs that prompt for input, but you'll print(pets)
is true. need to run them from a terminal.
while 'cat' in pets:
Counting to 5 pets.remove('cat')
Breaking out of loops
current_number = 1
You can use the break statement and the continue print(pets)
while current_number <= 5: statement with any of Python's loops. For example you can
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 More cheat sheets available at
when looping through a list or dictionary as well. ehmatthes.github.io/pcc_2e/
Beginner's Python
Positional and keyword arguments Return values
The two main kinds of arguments are positional and keyword A function can return a value or a set of values. When a
arguments. When you use positional arguments Python function returns a value, the calling line should provide

Cheat Sheet - matches the first argument in the function call with the first
parameter in the function definition, and so forth.
With keyword arguments, you specify which parameter
a variable which the return value can be assigned to. A
function stops running when it reaches a return statement.
Returning a single value

Functions
each argument should be assigned to in the function
call. When you use keyword arguments, the order of the def get_full_name(first, last):
arguments doesn't matter. """Return a neatly formatted full name."""
full_name = f"{first} {last}"
Using positional arguments return full_name.title()
What are functions?
def describe_pet(animal, name):
Functions are named blocks of code designed to do """Display information about a pet.""" musician = get_full_name('jimi', 'hendrix')
one specific job. Functions allow you to write code print(f"\nI have a {animal}.") print(musician)
once that can then be run whenever you need to print(f"Its name is {name}.")
Returning a dictionary
accomplish the same task.
describe_pet('hamster', 'harry') def build_person(first, last):
Functions can take in the information they need,
describe_pet('dog', 'willie') """Return a dictionary of information
and return the information they generate. Using about a person.
functions effectively makes your programs easier to Using keyword arguments """
write, read, test, and fix. def describe_pet(animal, name): person = {'first': first, 'last': last}
"""Display information about a pet.""" return person
Defining a function print(f"\nI have a {animal}.")
The first line of a function is its definition, marked by the print(f"Its name is {name}.") musician = build_person('jimi', 'hendrix')
keyword def. The name of the function is followed by a set print(musician)
of parentheses and a colon. A docstring, in triple quotes, describe_pet(animal='hamster', name='harry')
Returning a dictionary with optional values
describes what the function does. The body of a function is describe_pet(name='willie', animal='dog')
indented one level. def build_person(first, last, age=None):
Default values """Return a dictionary of information
To call a function, give the name of the function followed
about a person.
by a set of parentheses. You can provide a default value for a parameter. When """
Making a function function calls omit this argument the default value will be person = {'first': first, 'last': last}
used. Parameters with default values must be listed after if age:
def greet_user(): parameters without default values in the function's definition person['age'] = age
"""Display a simple greeting.""" so positional arguments can still work correctly.
print("Hello!")
Using a default value return person
greet_user() def describe_pet(name, animal='dog'): musician = build_person('jimi', 'hendrix', 27)
"""Display information about a pet.""" print(musician)
Passing information to a function print(f"\nI have a {animal}.")
Information that's passed to a function is called an argument; print(f"Its name is {name}.") musician = build_person('janis', 'joplin')
information that's received by a function is called a print(musician)
parameter. Arguments are included in parentheses after the describe_pet('harry', 'hamster')
describe_pet('willie')
function's name, and parameters are listed in parentheses in Visualizing functions
the function's definition. Using None to make an argument optional Try running some of these examples, and some of your own
Passing a simple argument def describe_pet(animal, name=None): programs that use functions, on pythontutor.com.
def greet_user(username): """Display information about a pet."""
print(f"\nI have a {animal}.")
"""Display a simple greeting."""
print(f"Hello, {username}!") if name: Python Crash Course
print(f"Its name is {name}.")
A Hands-on, Project-Based
greet_user('jesse') Introduction to Programming
greet_user('diana') describe_pet('hamster', 'harry')
greet_user('brandon') describe_pet('snake') nostarch.com/pythoncrashcourse2e
Passing a list to a function Passing an arbitrary number of arguments Modules
You can pass a list as an argument to a function, and the Sometimes you won't know how many arguments a function You can store your functions in a separate file called a
function can work with the values in the list. Any changes the will need to accept. Python allows you to collect an arbitrary module, and then import the functions you need into the
function makes to the list will affect the original list. You can number of arguments into one parameter using the * file containing your main program. This allows for cleaner
prevent a function from modifying a list by passing a copy of operator. A parameter that accepts an arbitrary number of program files. Make sure your module is stored in the same
the list as an argument. arguments must come last in the function definition. This directory as your main program.
parameter is often named *args.
Passing a list as an argument Storing a function in a module
The ** operator allows a parameter to collect an arbitrary
File: pizza.py
def greet_users(names): number of keyword arguments. These are stored as a
"""Print a simple greeting to everyone.""" dictionary with the parameter names as keys, and the def make_pizza(size, *toppings):
for name in names: arguments as values. This is often named **kwargs. """Make a pizza."""
msg = f"Hello, {name}!" print(f"\nMaking a {size} pizza.")
print(msg) Collecting an arbitrary number of arguments print("Toppings:")
def make_pizza(size, *toppings): for topping in toppings:
usernames = ['hannah', 'ty', 'margot'] """Make a pizza.""" print(f"- {topping}")
greet_users(usernames) print(f"\nMaking a {size} pizza.")
Importing an entire module
Allowing a function to modify a list File: making_pizzas.py Every function in the module is available in
print("Toppings:")
The following example sends a list of models to a function for the program file.
printing. The first list is emptied, and the second list is filled.
for topping in toppings:
print(f"- {topping}") import pizza
def print_models(unprinted, printed):
"""3d print a set of models.""" # Make three pizzas with different toppings. pizza.make_pizza('medium', 'pepperoni')
while unprinted: make_pizza('small', 'pepperoni') pizza.make_pizza('small', 'bacon', 'pineapple')
current_model = unprinted.pop() make_pizza('large', 'bacon bits', 'pineapple')
print(f"Printing {current_model}") make_pizza('medium', 'mushrooms', 'peppers', Importing a specific function
printed.append(current_model) 'onions', 'extra cheese') Only the imported functions are available in the program file.
from pizza import make_pizza
# Store some unprinted designs, Collecting an arbitrary number of keyword arguments
# and print each of them. def build_profile(first, last, **user_info): make_pizza('medium', 'pepperoni')
unprinted = ['phone case', 'pendant', 'ring'] """Build a dictionary for a user.""" make_pizza('small', 'bacon', 'pineapple')
printed = [] user_info['first'] = first
print_models(unprinted, printed) user_info['last'] = last Giving a module an alias
import pizza as p
print(f"\nUnprinted: {unprinted}") return user_info
print(f"Printed: {printed}") p.make_pizza('medium', 'pepperoni')
Preventing a function from modifying a list # Create two users with different kinds p.make_pizza('small', 'bacon', 'pineapple')
# of information.
The following example is the same as the previous one, except the Giving a function an alias
original list is unchanged after calling print_models().
user_0 = build_profile('albert', 'einstein',
location='princeton') from pizza import make_pizza as mp
def print_models(unprinted, printed):
"""3d print a set of models.""" user_1 = build_profile('marie', 'curie', mp('medium', 'pepperoni')
while unprinted: location='paris', field='chemistry') mp('small', 'bacon', 'pineapple')
current_model = unprinted.pop()
print(f"Printing {current_model}") print(user_0) Importing all functions from a module
printed.append(current_model) print(user_1) Don't do this, but recognize it when you see it in others' code. It can
result in naming conflicts, which can cause errors.
# Store some unprinted designs,
# and print each of them.
What's the best way to structure a function? from pizza import *
original = ['phone case', 'pendant', 'ring'] There are many ways to write and call a function. When
printed = [] you're starting out, aim for something that simply works. As make_pizza('medium', 'pepperoni')
you gain experience you'll develop an understanding of the make_pizza('small', 'bacon', 'pineapple')
print_models(original[:], printed) subtle advantages of different structures such as positional
print(f"\nOriginal: {original}") and keyword arguments, and the various approaches to
print(f"Printed: {printed}") importing functions. For now if your functions do what you More cheat sheets available at
need them to, you're doing well. ehmatthes.github.io/pcc_2e/
Beginner's Python
Creating and using a class (cont.) Class inheritance
Creating an instance from a class If the class you're writing is a specialized version of another
class, you can use inheritance. When one class inherits

Cheat Sheet - Classes


my_car = Car('audi', 'a4', 2021)
from another, it automatically takes on all the attributes
Accessing attribute values and methods of the parent class. The child class is free
to introduce new attributes and methods, and override
print(my_car.make)
attributes and methods of the parent class.
print(my_car.model)
What are classes? print(my_car.year)
To inherit from another class include the name of the
parent class in parentheses when defining the new class.
Classes are the foundation of object-oriented
Calling methods The __init__() method for a child class
programming. Classes represent real-world things
you want to model in your programs such as dogs, my_car.fill_tank() class ElectricCar(Car):
cars, and robots. You use a class to make objects, my_car.drive() """A simple model of an electric car."""
which are specific instances of dogs, cars, and robots. Creating multiple instances
A class defines the general behavior that a whole def __init__(self, make, model, year):
my_car = Car('audi', 'a4', 2021) """Initialize an electric car."""
category of objects can have, and the information that my_old_car = Car('subaru', 'outback', 2015) super().__init__(make, model, year)
can be associated with those objects. my_truck = Car('toyota', 'tacoma', 2018)
Classes can inherit from each other – you can write my_old_truck = Car('ford', 'ranger', 1999) # Attributes specific to electric cars.
a class that extends the functionality of an existing # Battery capacity in kWh.
class. This allows you to code efficiently for a wide Modifying attributes self.battery_size = 85
variety of situations. Even if you don't write many You can modify an attribute's value directly, or you can
# Charge level in %.
of your own classes, you'll frequently find yourself write methods that manage updating values more carefully.
self.charge_level = 0
working with classes that others have written. Methods like these can help validate the kinds of changes
that are being made to an attribute. Adding new methods to the child class
Creating and using a class Modifying an attribute directly class ElectricCar(Car):
Consider how we might model a car. What information would --snip--
my_new_car = Car('audi', 'a4', 2021)
we associate with a car, and what behavior would it have?
my_new_car.fuel_level = 5
The information is assigned to variables called attributes, def charge(self):
and the behavior is represented by functions. Functions that Writing a method to update an attribute's value """Fully charge the vehicle."""
are part of a class are called methods. self.charge_level = 100
def update_fuel_level(self, new_level):
print("The vehicle is fully charged.")
The Car class """Update the fuel level."""
if new_level <= self.fuel_capacity: Using child methods and parent methods
class Car:
self.fuel_level = new_level
"""A simple attempt to model a car.""" my_ecar = ElectricCar('tesla', 'model s', 2021)
else:
print("The tank can't hold that much!")
def __init__(self, make, model, year): my_ecar.charge()
"""Initialize car attributes.""" Writing a method to increment an attribute's value my_ecar.drive()
self.make = make
self.model = model def add_fuel(self, amount):
self.year = year """Add fuel to the tank.""" Finding your workflow
if (self.fuel_level + amount There are many ways to model real world objects and
# Fuel capacity and level in gallons. <= self.fuel_capacity): situations in code, and sometimes that variety can feel
self.fuel_capacity = 15 self.fuel_level += amount overwhelming. Pick an approach and try it – if your first
self.fuel_level = 0 print("Added fuel.") attempt doesn't work, try a different approach.
else:
def fill_tank(self): print("The tank won't hold that much.")
"""Fill gas tank to capacity."""
self.fuel_level = self.fuel_capacity Naming conventions Python Crash Course
print("Fuel tank is full.") In Python class names are written in CamelCase and object A Hands-on, Project-Based
names are written in lowercase with underscores. Modules Introduction to Programming
def drive(self): that contain classes should be named in lowercase with
"""Simulate driving.""" underscores. nostarch.com/pythoncrashcourse2e
print("The car is moving.")
Class inheritance (cont.) Importing classes Storing objects in a list
Overriding parent methods Class files can get long as you add detailed information and A list can hold as many items as you want, so you can make
functionality. To help keep your program files uncluttered, a large number of objects from a class and store them in a
class ElectricCar(Car):
you can store your classes in modules and import the list.
--snip--
classes you need into your main program. Here's an example showing how to make a fleet of rental
cars, and make sure all the cars are ready to drive.
def fill_tank(self): Storing classes in a file
"""Display an error message.""" car.py A fleet of rental cars
print("This car has no fuel tank!")
"""Represent gas and electric cars.""" from car import Car, ElectricCar

Instances as attributes class Car: # Make lists to hold a fleet of cars.


A class can have objects as attributes. This allows classes to """A simple attempt to model a car.""" gas_fleet = []
work together to model more complex real-world things and --snip— electric_fleet = []
concepts.
class Battery: # Make 250 gas cars and 500 electric cars.
A Battery class """A battery for an electric car.""" for _ in range(250):
class Battery: --snip-- car = Car('ford', 'escape', 2021)
"""A battery for an electric car.""" gas_fleet.append(car)
class ElectricCar(Car): for _ in range(500):
def __init__(self, size=85): """A simple model of an electric car.""" ecar = ElectricCar('nissan', 'leaf', 2021)
"""Initialize battery attributes.""" --snip-- electric_fleet.append(ecar)
# Capacity in kWh, charge level in %.
Importing individual classes from a module # Fill the gas cars, and charge electric cars.
self.size = size
my_cars.py for car in gas_fleet:
self.charge_level = 0
from car import Car, ElectricCar car.fill_tank()
def get_range(self): for ecar in electric_fleet:
"""Return the battery's range.""" my_beetle = Car('volkswagen', 'beetle', 2019) ecar.charge()
if self.size == 85: my_beetle.fill_tank()
return 390 my_beetle.drive() print(f"Gas cars: {len(gas_fleet)}")
elif self.size == 100: print(f"Electric cars: {len(electric_fleet)}")
return 415 my_tesla = ElectricCar('tesla', 'model s',
Using an instance as an attribute
2021) Understanding self
my_tesla.charge()
People often ask what the self variable represents. The
class ElectricCar(Car): my_tesla.drive()
self variable is a reference to an object that's been created
--snip-- from the class.
Importing an entire module
The self variable provides a way to make other variables
def __init__(self, make, model, year): import car
and objects available everywhere in a class. The self
"""Initialize an electric car."""
variable is automatically passed to each method that's called
super().__init__(make, model, year) my_beetle = car.Car(
'volkswagen', 'beetle', 2019) through an object, which is why you see it listed first in every
# Attribute specific to electric cars. my_beetle.fill_tank() method definition. Any variable attached to self is available
self.battery = Battery() my_beetle.drive() everywhere in the class.

def charge(self): my_tesla = car.ElectricCar( Understanding __init__()


"""Fully charge the vehicle.""" 'tesla', 'model s', 2021) The __init__() method is a function that's part of a class,
self.battery.charge_level = 100 my_tesla.charge() just like any other method. The only special thing about
print("The vehicle is fully charged.") my_tesla.drive() __init__() is that it's called automatically every time
Using the instance Importing all classes from a module you make a new instance from a class. If you accidentally
(Don’t do this, but recognize it when you see it.) misspell __init__(), the method won't be called and your
my_ecar = ElectricCar('tesla', 'model s', 2021) object may not be created correctly.
from car import *
my_ecar.charge()
print(my_ecar.battery.get_range()) my_beetle = Car('volkswagen', 'beetle', 2019)
my_ecar.drive() my_tesla = ElectricCar('tesla', 'model s', More cheat sheets available at
2021) ehmatthes.github.io/pcc_2e/
Beginner's Python
Reading from a file (cont.) File paths (cont.)
Storing the lines in a list Opening a file using an absolute path

Cheat Sheet -
filename = 'siddhartha.txt' f_path = "/home/ehmatthes/books/alice.txt"

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


lines = f_obj.readlines() lines = f.readlines()

Files and Exceptions for line in lines:


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

Cheat Sheet - TestCase and write methods that begin with test_. Save this as
test_full_names.py
import unittest
tests. This will tell you whether the changes you made affected
existing behavior.
E

Testing Your Code from full_names import get_full_name

class NamesTestCase(unittest.TestCase):
================================================
ERROR: test_first_last (__main__.NamesTestCase)
Test names like Janis Joplin.
"""Tests for names.py.""" ------------------------------------------------
Why test your code? Traceback (most recent call last):
def test_first_last(self): File "test_full_names.py", line 10,
When you write a function or a class, you can also """Test names like Janis Joplin.""" in test_first_last
write tests for that code. Testing proves that your code full_name = get_full_name('janis', 'joplin')
works as it's supposed to in the situations it's designed 'joplin') TypeError: get_full_name() missing 1 required
to handle, and also when people use your programs in self.assertEqual(full_name, positional argument: 'last'
unexpected ways. Writing tests gives you confidence 'Janis Joplin')
that your code will work correctly as more people ------------------------------------------------
if __name__ == '__main__': Ran 1 test in 0.001s
begin to use your programs. You can also add new unittest.main()
features to your programs and know whether or not FAILED (errors=1)
you've broken existing behavior by running your tests. Running the test
A unit test verifies that one specific aspect of your Python reports on each unit test in the test case. The dot represents Fixing the code
a single passing test. Python informs us that it ran 1 test in less than When a test fails, the code needs to be modified until the test
code works as it's supposed to. A test case is a 0.001 seconds, and the OK lets us know that all unit tests in the test passes again. Don’t make the mistake of rewriting your tests to fit
collection of unit tests which verify that your code's case passed. your new code, otherwise your code will break for anyone who's
behavior is correct in a wide variety of situations. .
using it the same way it's being used in the failing test. Here we can
make the middle name optional.
---------------------------------------
Testing a function: a passing test Ran 1 test in 0.000s def get_full_name(first, last, middle=''):
Python's unittest module provides tools for testing your """Return a full name."""
code. To try it out, we’ll create a function that returns a full OK
name. We’ll use the function in a regular program, and then if middle:
build a test case for the function. full_name = f"{first} {middle} {last}"
Testing a function: A failing test else:
A function to test Failing tests are important; they tell you that a change in the full_name = f"{first} {last}"
Save this as full_names.py code has affected existing behavior. When a test fails, you
def get_full_name(first, last): need to modify the code so the existing behavior still works. return full_name.title()
"""Return a full name.""" Modifying the function Running the test
We’ll modify get_full_name() so it handles middle names, but Now the test should pass again, which means our original
full_name = f"{first} {last}" we’ll do it in a way that breaks existing behavior. functionality is still intact.
return full_name.title()
def get_full_name(first, middle, last): .
Using the function """Return a full name.""" ---------------------------------------
Save this as names.py full_name = f"{first} {middle} {last}" Ran 1 test in 0.000s
return full_name.title()
from full_names import get_full_name
Using the function OK
janis = get_full_name('janis', 'joplin')
print(janis) from full_names import get_full_name

bob = get_full_name('bob', 'dylan') john = get_full_name('john', 'lee', 'hooker')


print(john)
Python Crash Course
print(bob) A Hands-on, Project-Based
david = get_full_name('david', 'lee', 'roth') Introduction to Programming
print(david) nostarch.com/pythoncrashcourse2e
Adding new tests Testing a class The setUp() method
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 names.
class Accountant(): Using setUp() to support multiple tests
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, amount): """Tests for the class Accountant."""
self.balance += amount
def test_first_last(self): def setUp(self):
"""Test names like Janis Joplin.""" def withdraw(self, amount): self.acc = Accountant()
full_name = get_full_name('janis', self.balance -= amount
'joplin') def test_initial_balance(self):
self.assertEqual(full_name, Building a testcase # Default balance should be 0.
'Janis Joplin') For the first test, we’ll make sure we can start out with different initial self.assertEqual(self.acc.balance, 0)
balances. Save this as test_accountant.py.
def test_middle(self): import unittest # Test non-default balance.
"""Test names like David Lee Roth.""" from accountant import Accountant acc = Accountant(100)
full_name = get_full_name('david', self.assertEqual(acc.balance, 100)
'roth', 'lee') class TestAccountant(unittest.TestCase):
self.assertEqual(full_name, """Tests for the class Accountant.""" def test_deposit(self):
'David Lee Roth') # Test single deposit.
def test_initial_balance(self): self.acc.deposit(100)
if __name__ == '__main__': # Default balance should be 0. self.assertEqual(self.acc.balance, 100)
unittest.main() acc = Accountant()
self.assertEqual(acc.balance, 0) # Test multiple deposits.
Running the tests self.acc.deposit(100)
The two dots represent two passing tests.
# Test non-default balance. self.acc.deposit(100)
.. acc = Accountant(100) self.assertEqual(self.acc.balance, 300)
--------------------------------------- self.assertEqual(acc.balance, 100)
Ran 2 tests in 0.000s def test_withdrawal(self):
OK if __name__ == '__main__': # Test single withdrawal.
unittest.main() self.acc.deposit(1000)
self.acc.withdraw(100)
A variety of assert methods Running the test self.assertEqual(self.acc.balance, 900)
Python provides a number of assert methods you can use to
.
test your code. --------------------------------------- if __name__ == '__main__':
Verify that a==b, or a != b Ran 1 test in 0.000s unittest.main()
OK
assertEqual(a, b) Running the tests
assertNotEqual(a, b) ...
When is it okay to modify tests?
Verify that x is True, or x is False ---------------------------------------
In general you shouldn’t modify a test once it’s written. When Ran 3 tests in 0.001s
assertTrue(x) a test fails it usually means new code you’ve written has
assertFalse(x) broken existing functionality, and you need to modify the new OK
code until all existing tests pass.
Verify an item is in a list, or not in a list If your original requirements have changed, it may be
assertIn(item, list) appropriate to modify some tests. This usually happens in
assertNotIn(item, list) the early stages of a project when desired behavior is still More cheat sheets available at
being sorted out, and no one is using your code yet. ehmatthes.github.io/pcc_2e/
Beginner's Python
Starting a game (cont.) Pygame rect objects (cont.)
Setting a custom window size Creating a rect object
The display.set_mode() function accepts a tuple that defines the You can create a rect object from scratch. For example a small rect

Cheat Sheet - Pygame screen size.


screen_dim = (1500, 1000)
object that’s filled in can represent a bullet in a game. The Rect()
class takes the coordinates of the upper left corner, and the width
and height of the rect. The draw.rect() function takes a screen
self.screen = pygame.display.set_mode( object, a color, and a rect. This function fills the given rect with the
screen_dim)
What is Pygame? given color.

Pygame is a framework for making games using Setting a custom background color bullet_rect = pygame.Rect(100, 100, 3, 15)
Colors are defined as a tuple of red, green, and blue values. Each color = (100, 100, 100)
Python. Making games is fun, and it’s a great way value ranges from 0-255. The fill() method fills the screen with the
to expand your programming skills and knowledge. color you specify, and should be called before you add any other pygame.draw.rect(screen, color, bullet_rect)
Pygame takes care of many of the lower-level tasks in elements to the screen.
building games, which lets you focus on the aspects of def __init__(self): Working with images
your game that make it interesting. --snip-- Many objects in a game are images that are moved around
self.bg_color = (225, 225, 225) the screen. It’s easiest to use bitmap (.bmp) image files, but
Installing Pygame you can also configure your system to work with jpg, png,
Pygame runs on all systems, and you should be able to def run_game(self):
and gif files as well.
install it in one line. while True:
for event in pygame.event.get(): Loading an image
Installing Pygame --snip--
ship = pygame.image.load('images/ship.bmp')
$ python -m pip install --user pygame
self.screen.fill(self.bg_color) Getting the rect object from an image
pygame.display.flip()
Starting a game ship_rect = ship.get_rect()
The following code sets up an empty game window, and
Pygame rect objects Positioning an image
starts an event loop and a loop that continually refreshes the With rects, it’s easy to position an image wherever you want on
screen. Many objects in a game can be treated as simple rectangles,
rather than their actual shape. This simplifies code without the screen, or in relation to another object. The following code
An empty game window positions a ship at the bottom center of the screen, by matching the
noticeably affecting game play. Pygame has a rect object
midbottom of the ship with the midbottom of the screen.
import sys that makes it easy to work with game objects.
import pygame ship_rect.midbottom = screen_rect.midbottom
Getting the screen rect object
We already have a screen object; we can easily access the rect Drawing an image to the screen
class AlienInvasion: object associated with the screen. Once an image is loaded and positioned, you can draw it to the
screen with the blit() method. The blit() method acts on
def __init__(self): self.screen_rect = self.screen.get_rect()
the screen object, and takes the image object and image rect as
pygame.init() arguments.
Finding the center of the screen
self.screen = pygame.display.set_mode(
Rect objects have a center attribute which stores the center point. # Draw ship to screen.
(1200, 800))
pygame.display.set_caption( screen_center = self.screen_rect.center screen.blit(ship, ship_rect)
"Alien Invasion") Transforming an image
Useful rect attributes
Once you have a rect object, there are a number of attributes The transform module allows you to make changes to an image
def run_game(self): such as rotation and scaling.
while True: that are useful when positioning objects and detecting relative
positions of objects. (You can find more attributes in the Pygame rotated_image = pygame.transform.rotate(
for event in pygame.event.get():
documentation. The self variable has been left off for clarity.) ship.image, 45)
if event.type == pygame.QUIT:
sys.exit() # Individual x and y values:
screen_rect.left, screen_rect.right
pygame.display.flip() screen_rect.top, screen_rect.bottom
screen_rect.centerx, screen_rect.centery Python Crash Course
if __name__ == '__main__': screen_rect.width, screen_rect.height A Hands-on, Project-Based
ai = AlienInvasion()
Introduction to Programming
ai.run_game() # Tuples
screen_rect.center nostarch.com/pythoncrashcourse2e
screen_rect.size
Working with images (cont.) Responding to mouse events Pygame groups (cont.)
The blitme() method Pygame’s event loop registers an event any time the mouse Removing an item from a group
Game objects such as ships are often written as classes. Then a moves, or a mouse button is pressed or released. It’s important to delete elements that will never appear again in the
blitme() method is usually defined, which draws the object to the game, so you don’t waste memory and resources.
Responding to the mouse button
screen.
for event in pygame.event.get(): bullets.remove(bullet)
def blitme(self):
if event.type == pygame.MOUSEBUTTONDOWN:
"""Draw ship at current location.""" Detecting collisions
ship.fire_bullet()
self.screen.blit(self.image, self.rect)
You can detect when a single object collides with any
Finding the mouse position
member of a group. You can also detect when any member
Responding to keyboard input The mouse position is returned as a tuple.
of one group collides with a member of another group.
Pygame watches for events such as key presses and mouse mouse_pos = pygame.mouse.get_pos()
actions. You can detect any event you care about in the Collisions between a single object and a group
event loop, and respond with any action that’s appropriate Clicking a button The spritecollideany() function takes an object and a group,
You might want to know if the cursor is over an object such as a and returns True if the object overlaps with any member of the
for your game.
button. The rect.collidepoint() method returns True when a group.
Responding to key presses point overlaps a rect object.
if pygame.sprite.spritecollideany(ship, aliens):
Pygame’s main event loop registers a KEYDOWN event any time a key if button_rect.collidepoint(mouse_pos): ships_left -= 1
is pressed. When this happens, you can check for specific keys.
start_game()
for event in pygame.event.get(): Collisions between two groups
if event.type == pygame.KEYDOWN: Hiding the mouse The sprite.groupcollide() function takes two groups, and two
if event.key == pygame.K_RIGHT: booleans. The function returns a dictionary containing information
pygame.mouse.set_visible(False)
about the members that have collided. The booleans tell Pygame
ship_rect.x += 1
whether to delete the members of either group that have collided.
elif event.key == pygame.K_LEFT:
ship_rect.x -= 1
Pygame groups collisions = pygame.sprite.groupcollide(
elif event.key == pygame.K_SPACE: Pygame has a Group class which makes working with a bullets, aliens, True, True)
ship.fire_bullet() group of similar objects easier. A group is like a list, with
elif event.key == pygame.K_q: some extra functionality that’s helpful when building games. score += len(collisions) * alien_point_value
sys.exit() Making and filling a group
Responding to released keys An object that will be placed in a group must inherit from Sprite. Rendering text
When the user releases a key, a KEYUP event is triggered. from pygame.sprite import Sprite, Group You can use text for a variety of purposes in a game. For
example you can share information with players, and you
for event in pygame.event.get():
class Bullet(Sprite): can display a score.
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT: ... Displaying a message
ship.moving_right = False def draw_bullet(self): The following code defines a message, then a color for the text
... and the background color for the message. A font is defined using
def update(self): the default system font, with a font size of 48. The font.render()
The game is an object ... function is used to create an image of the message, and we get the
In the overall structure shown here (under Starting a Game), rect object associated with the image. We then center the image on
the entire game is written as a class. This makes it possible bullets = Group() the screen and display it.
to write programs that play the game automatically, and
msg = "Play again?"
it also means you can build an arcade with a collection of new_bullet = Bullet()
msg_color = (100, 100, 100)
games. bullets.add(new_bullet)
bg_color = (230, 230, 230)
Looping through the items in a group
Pygame documentation The sprites() method returns all the members of a group. f = pygame.font.SysFont(None, 48)
The Pygame documentation is really helpful when building msg_image = f.render(msg, True, msg_color,
for bullet in bullets.sprites(): bg_color)
your own games. The home page for the Pygame project is
bullet.draw_bullet() msg_image_rect = msg_image.get_rect()
at pygame.org/, and the home page for the documentation is
at pygame.org/docs/. Calling update() on a group msg_image_rect.center = screen_rect.center
The most useful part of the documentation are the screen.blit(msg_image, msg_image_rect)
Calling update() on a group automatically calls update() on each
pages about specific parts of Pygame, such as the Rect() member of the group.
class and the sprite module. You can find a list of these
bullets.update() More cheat sheets available at
elements at the top of the help pages. ehmatthes.github.io/pcc_2e/
Beginner's Python
Customizing plots Customizing plots (cont.)
Plots can be customized in a wide variety of ways. Just Emphasizing points
about any element of a plot can be modified. You can plot as much data as you want on one plot. Here we replot

Cheat Sheet - Using built-in styles


Matplotlib comes with a number of built-in styles, which you can use
with one additional line of code. The style must be specified before
the first and last points larger to emphasize them.
import matplotlib.pyplot as plt

Matplotlib you create the figure.


import matplotlib.pyplot as plt
x_values = list(range(1000))
squares = [x**2 for x in x_values]

x_values = list(range(1000)) fig, ax = plt.subplots()


What is Matplotlib? squares = [x**2 for x in x_values] ax.scatter(x_values, squares, c=squares,
cmap=plt.cm.Blues, s=10)
Data visualization involves exploring data through
visual representations. The Matplotlib library helps you plt.style.use('seaborn')
fig, ax = plt.subplots() ax.scatter(x_values[0], squares[0], c='green',
make visually appealing representations of the data ax.scatter(x_values, squares, s=10) s=100)
you’re working with. Matplotlib is extremely flexible; ax.scatter(x_values[-1], squares[-1], c='red',
these examples will help you get started with a few plt.show() s=100)
simple visualizations.
Seeing available styles ax.set_title('Square Numbers', fontsize=24)
--snip--
Installing Matplotlib You can see all available styles on your system. This can be done in
a terminal session.
Matplotlib runs on all systems, and you should be able to Removing axes
install it in one line. >>> import matplotlib.pyplot as plt You can customize or remove axes entirely. Here’s how to access
>>> plt.style.available each axis, and hide it.
Installing Matplotlib ['seaborn-dark', 'seaborn-darkgrid', ...
ax.get_xaxis().set_visible(False)
$ python -m pip install --user matplotlib Adding titles and labels, and scaling axes ax.get_yaxis().set_visible(False)
import matplotlib.pyplot as plt Setting a custom figure size
Line graphs and scatter plots
You can make your plot as big or small as you want by using the
Making a line graph x_values = list(range(1000)) figsize argument. The dpi argument is optional; if you don’t know
The fig object represents the entire figure, or collection of plots; ax squares = [x**2 for x in x_values] your system’s resolution you can omit the argument and adjust the
represents a single plot in the figure. This convention is used even figsize argument accordingly.
when there's only one plot in the figure. # Set overall style to use, and plot data.
fig, ax = plt.subplots(figsize=(10, 6),
import matplotlib.pyplot as plt plt.style.use('seaborn')
dpi=128)
fig, ax = plt.subplots()
x_values = [0, 1, 2, 3, 4, 5] ax.scatter(x_values, squares, s=10) Saving a plot
squares = [0, 1, 4, 9, 16, 25] The Matplotlib viewer has a save button, but you can also save
# Set chart title and label axes. your visualizations programmatically by replacing plt.show() with
fig, ax = plt.subplots() ax.set_title('Square Numbers', fontsize=24) plt.savefig(). The bbox_inches argument reduces the amount of
ax.plot(x_values, squares) ax.set_xlabel('Value', fontsize=14) whitespace around the figure.
ax.set_ylabel('Square of Value', fontsize=14)
plt.savefig('squares.png', bbox_inches='tight')
plt.show()
# Set scale of axes, and size of tick labels.
Making a scatter plot ax.axis([0, 1100, 0, 1_100_000]) Online resources
scatter() takes a list of x and y values; the s=10 argument ax.tick_params(axis='both', labelsize=14) The matplotlib gallery and documentation are at
controls the size of each point. matplotlib.org/. Be sure to visit the examples, gallery, and
plt.show() pyplot links.
import matplotlib.pyplot as plt
Using a colormap
x_values = list(range(1000))
squares = [x**2 for x in x_values]
A colormap varies the point colors from one shade to another, based
on a certain value for each point. The value used to determine Python Crash Course
the color of each point is passed to the c argument, and the cmap A Hands-on, Project-Based
fig, ax = plt.subplots() argument specifies which colormap to use. Introduction to Programming
ax.scatter(x_values, squares, s=10)
ax.scatter(x_values, squares, c=squares, nostarch.com/pythoncrashcourse2e
plt.show()
cmap=plt.cm.Blues, s=10)
Multiple plots Working with dates and times (cont.) Multiple plots in one figure
You can make as many plots as you want on one figure. Datetime formatting arguments You can include as many individual graphs in one figure as
When you make multiple plots, you can emphasize The strptime() function generates a datetime object from a you want.
relationships in the data. For example you can fill the space string, and the strftime() method generates a formatted string
Sharing an x-axis
between two sets of data. from a datetime object. The following codes let you work with dates
The following code plots a set of squares and a set of cubes on
exactly as you need to.
Plotting two sets of data two separate graphs that share a common x-axis. The plt.
Here we use ax.scatter() twice to plot square numbers and %A Weekday name, such as Monday subplots() function returns a figure object and a tuple of axes.
cubes on the same figure. %B Month name, such as January Each set of axes corresponds to a separate plot in the figure.
%m Month, as a number (01 to 12) The first two arguments control the number of rows and columns
import matplotlib.pyplot as plt %d Day of the month, as a number (01 to 31) generated in the figure.
%Y Four-digit year, such as 2021 import matplotlib.pyplot as plt
x_values = list(range(11)) %y Two-digit year, such as 21
squares = [x**2 for x in x_values] %H Hour, in 24-hour format (00 to 23)
cubes = [x**3 for x in x_values] x_values = list(range(11))
%I Hour, in 12-hour format (01 to 12) squares = [x**2 for x in x_values]
%p AM or PM cubes = [x**3 for x in x_values]
plt.style.use('seaborn') %M Minutes (00 to 59)
fig, ax = plt.subplots() %S Seconds (00 to 61) fig, axs = plt.subplots(2, 1, sharex=True)
ax.scatter(x_values, squares, c='blue', s=10) Converting a string to a datetime object
ax.scatter(x_values, cubes, c='red', s=10) axs[0].scatter(x_values, squares)
new_years = dt.strptime('1/1/2021', '%m/%d/%Y') axs[0].set_title('Squares')
plt.show() Converting a datetime object to a string axs[1].scatter(x_values, cubes, c='red')
Filling the space between data sets ny_string = new_years.strftime('%B %d, %Y') axs[1].set_title('Cubes')
The fill_between() method fills the space between two data sets. print(ny_string)
It takes a series of x-values and two series of y-values. It also takes plt.show()
a facecolor to use for the fill, and an optional alpha argument that Plotting high temperatures
controls the color’s transparency. The following code creates a list of dates and a corresponding list of Sharing a y-axis
high temperatures. It then plots the high temperatures, with the date To share a y-axis, we use the sharey=True argument.
ax.fill_between(x_values, cubes, squares, labels displayed in a specific format.
facecolor='blue', alpha=0.25) import matplotlib.pyplot as plt
from datetime import datetime as dt
x_values = list(range(11))
Working with dates and times import matplotlib.pyplot as plt squares = [x**2 for x in x_values]
Many interesting data sets have a date or time as the x from matplotlib import dates as mdates cubes = [x**3 for x in x_values]
value. Python’s datetime module helps you work with this
kind of data. dates = [ plt.style.use('seaborn')
dt(2020, 6, 21), dt(2020, 6, 22), fig, axs = plt.subplots(1, 2, sharey=True)
Generating the current date dt(2020, 6, 23), dt(2020, 6, 24),
The datetime.now() function returns a datetime object ] axs[0].scatter(x_values, squares)
representing the current date and time.
axs[0].set_title('Squares')
from datetime import datetime as dt highs = [56, 57, 57, 64]
axs[1].scatter(x_values, cubes, c='red')
today = dt.now() fig, ax = plt.subplots() axs[1].set_title('Cubes')
date_string = today.strftime('%m/%d/%Y') ax.plot(dates, highs, c='red')
print(date_string) plt.show()
ax.set_title("Daily High Temps", fontsize=24)
Generating a specific date ax.set_ylabel("Temp (F)", fontsize=16)
You can also generate a datetime object for any date and time you x_axis = ax.get_xaxis()
want. The positional order of arguments is year, month, and day. x_axis.set_major_formatter(
The hour, minute, second, and microsecond arguments are optional. mdates.DateFormatter('%B %d %Y')
from datetime import datetime as dt )
fig.autofmt_xdate()
new_years = dt(2021, 1, 1)
fall_equinox = dt(year=2021, month=9, day=22) plt.show()
More cheat sheets available at
ehmatthes.github.io/pcc_2e/
Beginner's Python
Line graphs, scatter plots, and bar graphs Multiple plots
(cont.) You can include as many data series as you want in a
visualization. To do this, create one dictionary for each
Making a bar graph
Cheat Sheet - Plotly To make a bar graph, pass your data to the Bar() graph object.
from plotly.graph_objs import Bar
data series, and put these dictionaries in the data list. Each
of these dictionaries is referred to as a trace in the Plotly
documentation.
--snip--
Plotting squares and cubes
What is Plotly? Here we use the 'name' attribute to set the label for each trace.
data = [Bar(x=x_values, y=squares)]
Data visualization involves exploring data through from plotly.graph_objs import Scatter
visual representations. Plotly helps you make visually # Pass the data and a filename to plot(). from plotly import offline
appealing representations of the data you’re working offline.plot(data, filename='squares.html')
with. Plotly is particularly well suited for visualizations x_values = list(range(11))
that will be presented online, because it supports Adding a title and labels squares = [x**2 for x in x_values]
interactive elements. cubes = [x**3 for x in x_values]
Using layout objects
The Layout class allows you to specify titles, labels, and other data = [
Installing Plotly formatting directives for your visualizations. {
Plotly runs on all systems, and can be installed in one line. from plotly.graph_objs import Scatter, Layout # Trace 1: squares
Installing Plotly from plotly import offline 'type': 'scatter',
'x': x_values,
$ python -m pip install --user plotly x_values = list(range(11)) 'y': squares,
squares = [x**2 for x in x_values] 'name': 'Squares',
Line graphs, scatter plots, and bar graphs },
data = [Scatter(x=x_values, y=squares)] {
To make a plot with Plotly, you specify the data and then
# Trace 2: cubes
pass it to a graph object. The data is stored in a list, so you
# Add a title, and a label for each axis. 'type': 'scatter',
can add as much data as you want to any graph. In offline
title = 'Square Numbers' 'x': x_values,
mode, the output should open automatically in a browser 'y': cubes,
x_axis_config = {'title': 'x'}
window. 'name': 'Cubes',
y_axis_config = {'title': 'Square of x'}
Making a line graph },
A line graph is a scatter plot where the points are connected. Plotly my_layout = Layout(title=title, ]
generates JavaScript code to render the plot file. If you're curious to xaxis=x_axis_config, yaxis=y_axis_config)
see the code, open the squares.html file in a text editor after running offline.plot(data,
this program. offline.plot( filename='squares_cubes.html')
from plotly.graph_objs import Scatter {'data': data, 'layout': my_layout},
from plotly import offline filename='squares.html') Online resources
The Plotly documentation is extensive and well-organized.
# Define the data. Specifying complex data Start with the overview at plotly.com/python/. Here you can
x_values = list(range(11)) see an example of all the basic chart types, and click on any
Data as a dictionary
squares = [x**2 for x in x_values] example to see a relevant tutorial.
Plotly is highly customizable, and most of that flexibility comes from
representing data and formatting directives as a dictionary. Here is Then take a look at the Python Figure Reference, at
# Pass the data to a graph object, and store it the same data from the previous examples, defined as a dictionary. plotly.com/python/reference/. Check out the Figure Data
# in a list. Defining the data as a dictionary also allows you to specify more Structure in Python page as well, at plotly.com/python/figure-
data = [Scatter(x=x_values, y=squares)] information about each series. Anything that pertains to a specific structure/.
data series such as markers, lines, and point labels, goes in the
# Pass the data and a filename to plot(). data dictionary. Plotly has several ways of specifying data, but
offline.plot(data, filename='squares.html') internally all data is represented in this way.

Making a scatter plot data = [{


'type': 'scatter',
Python Crash Course
To make a scatter plot, use the mode='markers' argument to tell
Plotly to only display the markers. 'x': x_values, A Hands-on, Project-Based
'y': squares, Introduction to Programming
data = [Scatter(x=x_values, y=squares, 'mode': 'markers',
mode='markers')] nostarch.com/pythoncrashcourse2e
}]
Specifying complex layouts Specifying complex layouts (cont.) Plotting global datasets
You can also specify the layout of your visualization as a Using a colorscale Plotly has a variety of mapping tools. For example, if you
dictionary, which gives you much more control of the overall Colorscales are often used to show variations in large datasets. In have a set of points represented by latitude and longitude,
layout. Plotly, colorscales are set in the marker dictionary, nested inside a you can create a scatter plot of those points overlaying a
data dictionary. map.
Layout as a dictionary
Here is the same layout we used earlier, written as a dictionary. data = [{ The scattergeo chart type
Simple elements such as the title of the chart are just key-value 'type': 'scatter', Here's a map showing the location of three of the higher peaks in
pairs. More complex elements such as axes, which can have many 'x': x_values, North America. If you hover over each point, you'll see its location
of their own settings, are nested dictionaries. 'y': squares, and the name of the mountain.
my_layout = { 'mode': 'markers',
from plotly import offline
'title': 'Square Numbers', 'marker': {
'xaxis': { 'colorscale': 'Viridis',
# Points in (lat, lon) format.
'title': 'x', 'color': squares,
peak_coords = [
}, 'colorbar': {'title': 'Value'},
(63.069, -151.0063),
'yaxis': { },
(60.5671, -140.4055),
'title': 'Square of x', }]
(46.8529, -121.7604),
}, ]
} Using Subplots
It's often useful to have multiple plots share the same axes. # Make matching lists of lats, lons,
A more complex layout # and labels.
Here is a layout for the same data, with more specific formatting
This is done using the subplots module.
lats = [pc[0] for pc in peak_coords]
directives in the data and layout dictionaries. Adding subplots to a figure lons = [pc[1] for pc in peak_coords]
from plotly.graph_objs import Scatter To use the subplots module, make a figure to hold all the charts peak_names = ['Denali', 'Mt Logan',
from plotly import offline that will be made. Then use the add_trace() method to add each 'Mt Rainier']
data series to the overall figure.
For more help, see the documentation at plot.ly/python/subplots/.
x_values = list(range(11)) data = [{
squares = [x**2 for x in x_values] from plotly.subplots import make_subplots 'type': 'scattergeo',
from plotly.graph_objects import Scatter 'lon': lons,
data = [{ from plotly import offline 'lat': lats,
'type': 'scatter', 'marker': {
'x': x_values, x_values = list(range(11)) 'size': 20,
'y': squares, squares = [x**2 for x in x_values] 'color': '#227722',
'mode': 'markers', cubes = [x**3 for x in x_values] },
'marker': { 'text': peak_names,
'size': 10, # Make two subplots, sharing a y-axis. }]
'color': '#6688dd', fig = make_subplots(rows=1, cols=2,
}, shared_yaxes=True) my_layout = {
}] 'title': 'Selected High Peaks',
data = { 'geo': {
my_layout = { 'type': 'scatter', 'scope': 'north america',
'title': 'Square Numbers', 'x': x_values, 'showland': True,
'xaxis': { 'y': squares, 'showocean': True,
'title': 'x', } 'showlakes': True,
'titlefont': {'family': 'monospace'}, fig.add_trace(data, row=1, col=1) 'showrivers': True,
}, },
'yaxis': { data = { }
'title': 'Square of x', 'type': 'scatter',
'titlefont': {'family': 'monospace'}, 'x': x_values, offline.plot(
}, 'y': cubes, {'data': data, 'layout': my_layout},
} } filename='peaks.html')
fig.add_trace(data, row=1, col=2)
offline.plot(
{'data': data, 'layout': my_layout}, offline.plot(fig, filename='subplots.html') More cheat sheets available at
filename='squares.html')
ehmatthes.github.io/pcc_2e/

You might also like