This section is included to assist you in performing the activities present in the book. It includes detailed steps that are to be performed by the students to complete and achieve the objectives of the book.
Solution:
x = 14
x += 1
(x/5) ** 2
You should get the following output:
9.0
With this activity, you have learned how to perform multiple mathematical operations on a variable. This is very common in Python. For example, in machine learning, covered in Chapter 11, Machine Learning, the input may be a matrix, X, and multiple mathematical operations will be performed on the X matrix until predictive results are obtained. Although the mathematics behind machine learning is more sophisticated, the core ideas are the same.
Solution:
"""
This document determines the Pythagorean Distance
between three given points
"""
# Initialize variables
x, y, z = 2, 3, 4
# Pythagorean Theorem in 3 dimensions
w_squared = x**2 + y**2 + z**2
# The square root gives the distance
w = w_squared ** 0.5
#Show the distance
w
You should get the following output:
5.385164807134504
In this activity, you have written a mini program that determines the Pythagorean distance between three points. Significantly, you have added a docstring and comments to clarify the code. There is never a correct answer for comments. It's up to the writer to determine how much information to give. A general goal is to be terse but informative. Comprehension is the most important thing. Adding comments and docstrings will always make your code look more professional and easier to read.
Congratulations on making it through the first topic in your Python journey! You are well on your way to becoming a developer or data scientist.
Solution:
# Choose a question to ask
print('How would you rate your day on a scale of 1 to 10?')
# Set a variable equal to input()
day_rating = input()
You should get the following output:
# Select an appropriate output.
print('You feel like a ' + day_rating + ' today. Thanks for letting me know')
You should get the following output:
In this activity, you prompted the user for a number and used that number to display a statement back to the user that includes the number. Communicating directly with users depending upon their input is a core developer skill.
Solution:
# Find the Least Common Multiple of Two Divisors
first_divisor = 24
second_divisor = 36
counting = True
i = 1
while counting:
if i % first_divisor == 0 and i % second_divisor == 0:
break
i += 1
print('The Least Common Multiple of', first_divisor, 'and', second_divisor, 'is', i, '.')
The aforementioned code snippet prints the results.
You should get the following output:
The Least Common Multiple of 24 and 36 is 72.
In this activity, you used a while loop to run a program that computes the LCM of two numbers. Using while loops to complete tasks is an essential ability for all developers.
Solution:
For the first bot, the solution is as follows:
print('What is your name?')
name = input()
print('Fascinating.', name, 'is my name too.')
You should get the following output:
Once you enter the value, in this case, your name, the output will be as follows:
print('Have you thought about black holes today?')
You should get the following output:
Have you thought about black holes today?
yes_no = input()
print('I am so glad you said', yes_no, '. I was thinking the same thing.')
You should get the following output:
Once you enter the value, in this case, your name, the output will be as follows:
print('We're kindred spirits,', name, '. Talk later.')
You should get the following output:
We're kindred spirits, Corey.Talk later.
Now, moving on to the second bot:
print('How intelligent are you? 0 is very dumb. And 10 is a genius')
smarts = input()
smarts = int(smarts)
if smarts <= 3:
print('I don't believe you.')
print('How bad of a day are you having? 0 is the worst, and 10 is the best.')
day = input()
day = int(day)
if day <= 5:
print('If I was human, I would give you a hug.')
else:
print('Maybe I should try your approach.')
elif smarts <= 6:
print('I think you're actually smarter.')
print('How much time do you spend online? 0 is none and 10 is 24 hours a day.')
hours = input()
hours = int(hours)
if hours <= 4:
print('That's the problem.')
else:
print('And I thought it was only me.')
elif smarts <= 8:
print('Are you human by chance? Wait. Don't answer that.')
print('How human are you? 0 is not at all and 10 is human all the way.')
human = input()
human = int(human)
if human <= 5:
print('I knew it.')
else:
print('I think this courtship is over.')
else:
print('I see... How many operating systems do you run?')
os = input()
os = int(os)
if os <= 2:
print('Good thing you're taking this course.')
else:
print('What is this? A competition?')
You should get the following output:
Congratulations! By completing this activity, you have created two conversational bots using nested conditionals and if-else loops where we also used changing types, using the input() function to get values from the user and then respectively displaying the output.
Solution:
employees = [['John Mckee', 38, 'Sales'], ['Lisa Crawford', 29, 'Marketing'], ['Sujan Patel', 33, 'HR']]
print(employees)
You should get the following output:
for employee in employees:
print(employee)
for employee in employees:
print("Name:", employee[0])
print("Age:", employee[1])
print("Department:", employee[2])
print('-' * 20)
employee = employees[1]
print(employee)
print("Name:", employee[0])
print("Age:", employee[1])
print("Department:", employee[2])
print('-' * 20)
Having successfully completed this activity, you will be able to work with lists and nested lists. As mentioned in the activity, this is just one instance where this concept could come in handy, that is, to store data in lists and then access them as required.
Solution:
employees = [
{"name": "John Mckee", "age":38, "department":"Sales"},
{"name": "Lisa Crawford", "age":29, "department":"Marketing"},
{"name": "Sujan Patel", "age":33, "department":"HR"}
]
print(employees)
You should get the following output:
In step 1, we created a list, employee, and added values to it, such as name, age, and department.
for employee in employees:
print("Name:", employee['name'])
print("Age:", employee['age'])
print("Department:", employee['department'])
print('-' * 20)
You should get the following output:
Note
You can compare this method with the previous activity, where we printed from a nested list. Using a dictionary gives us a more concise syntax, as we access the data using a key instead of a positional index. This is particularly helpful when we are dealing with objects with many keys.
for employee in employees:
if employee['name'] == 'Sujan Patel':
print("Name:", employee['name'])
print("Age:", employee['age'])
print("Department:", employee['department'])
print('-' * 20)
You should get the following output:
Having completed this activity, you are able to work with lists and dictionaries. As you have seen, lists are very useful for storing and accessing data, which very often comes in handy in the real world when handling data in Python. Using dictionaries along with lists proves to be very useful, as you have seen in this activity.
Solution:
In the following, you will find the solution code to Activity 8, What's the Time?
To make it easier to understand, the code has been broken down with explanations:
current_time.py:
"""
This script returns the current system time.
"""
import datetime
time = datetime.datetime.now().time()
if __name__ == '__main__':
print(time)
You should get the following output:
At the end of this activity, you are able to import the datetime module and execute the Python script to tell the time. Additionally, you are able to import the time to use it elsewhere in your code if necessary.
Solution:
The customer.py file should look like the steps mentioned below. Note that there are many different valid ways to write this function:
def format_customer(first, last, location=None):
full_name = '%s %s' % (first, last)
if location:
return '%s (%s)' % (full_name, location)
else:
return full_name
By the end of this activity, you are able to create a function that takes in various arguments for names and returns a string as you require.
Solution:
def fibonacci_iterative(n):
previous = 0
current = 1
for i in range(n - 1):
current_old = current
current = previous + current
previous = current_old
return current
from fibonacci import fibonacci_iterative
fibonacci_iterative(3)
You should get the following output:
2
Let's try another example:
fibonacci_iterative(10)
You should get the following output:
55
In this activity, you were able to work with iterations and return the nth value in the Fibonacci sequence.
Solution:
def fibonacci_recursive(n):
if n == 0 or n == 1:
return n
else:
return fibonacci_recursive(n - 2) + fibonacci_recursive(n - 1)
from fibonacci import fibonacci_recursive
fibonacci_recursive(3)
You should get the following output:
2
You can now work with recursive functions. We implemented this on our fibonnacci.py file to get the expected output. Recursive functions are helpful in many cases in order to reduce the lines of code that you will be using if it is repetitive.
Solution:
stored = {0: 0, 1: 1} # We set the first 2 terms of the Fibonacci sequence here.
def fibonacci_dynamic(n):
if n in stored:
return stored[n]
else:
stored[n] = fibonacci_dynamic(n - 2) + fibonacci_dynamic(n - 1)
return stored[n]
from fibonacci import fibonacci_recursive
fibonacci_dynamic(100)
You should get the following output:
354224848179261915075
In this activity, we used a function with dynamic programming that takes a single positional argument representing the number term in the sequence that we want to return.
Solution
import csv
lines = []
with open('titanic_train.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for line in csv_reader:
lines.append(line)
data = lines[1:]
passengers = []
headers = lines[0]
for d in data:
p = {}
for i in range(0,len(headers)):
key = headers[i]
value = d[i]
p[key] = value
passengers.append(p)
survived = [p['Survived'] for p in passengers]
pclass = [p['Pclass'] for p in passengers]
age = [float(p['Age']) for p in passengers if p['Age'] != '']
gender_survived = [p['Sex'] for p in passengers if int(p['Survived']) == 1]
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from collections import Counter
plt.title("Survived")
plt.pie(Counter(survived).values(), labels=Counter(survived).keys(), autopct='%1.1f%%',
colors=['lightblue', 'lightgreen', 'yellow'])
plt.show()
Execute the cell twice, and you should get the following output:
plt.title("surviving passengers count by gender")
plt.bar(Counter(gender_survived).keys(), Counter(gender_survived).values())
plt.show()
You should get the following output:
In this activity, we have used the interesting Titanic dataset to visualize data. We imported the dataset and stored the data in a list. Then, we used the matplotlib, seaborn, and numpy libraries to plot the various data and get the outputs as needed using the two plotting techniques: pie charts and bar plots.
class Polygon():
"""A class to capture common utilities for dealing with shapes"""
def __init__(self, side_lengths):
self.side_lengths = side_lengths
def __str__(self):
return 'Polygon with %s sides' % self.num_sides
class Polygon():
"""A class to capture common utilities for dealing with shapes"""
def __init__(self, side_lengths):
self.side_lengths = side_lengths
def __str__(self):
return 'Polygon with %s sides' % self.num_sides
@property
def num_sides(self):
return len(self.side_lengths)
@property
def perimeter(self):
return sum(self.side_lengths)
class Rectangle(Polygon):
def __init__(self, height, width):
super().__init__([height, width, height, width])
@property
def area(self):
return self.side_lengths[0] * self.side_lengths[1]
r = Rectangle(1, 5)
r.area, r.perimeter
You should get the following output:
(5, 12)
class Square(Rectangle):
def __init__(self, height):
super().__init__(height, height)
s = Square(5)
s.area, s.perimeter
You should get the following output:
(25, 20)
Solution:
import random
import time
start = time.time()
l = [random.randint(1, 999) for _ in range(10 * 3)]
end = time.time()
print(end - start)
You should get the following output:
0.0019025802612304688
start = time.time_ns()
l = [random.randint(1, 999) for _ in range(10 * 3)]
end = time.time_ns()
print(end - start)
You should get the following output:
187500
Note
This is a good solution when using the time module and for common applications.
Solution:
The line, compile("1" + "+1" * 10 ** 6, "string", "exec"), will crash the interpreter; we will need to run it with the following code:
import sys
import subprocess
code = 'compile("1" + "+1" * 10 ** 6, "string", "exec")'
result = subprocess.run([
sys.executable,
"-c", code
])
The preceding code takes a code line, which compiles Python code that will crash and runs it in a subprocess by executing the same interpreter (retrieved via sys.executable) with the -c option to run Python code inline.
print(result.returncode)
The output will be as follows:
-11
This line of code just prints the return code of the subprocess call.
In this activity, we have executed a small program that can run the requested code line and checked whether it would crash without breaking the current process. It did end up crashing, hence outputting the value -11, which corresponded to an abort in the program.
Solution:
You need to explore the functools module and realize a specific helper for methods, which can be used as explained in the following steps:
Now, to fix this, let's check for an alternative by observing the following steps.
import functools
class Hero:
DEFAULT_NAME = "Superman"
def __init__(self):
self.name = Hero.DEFAULT_NAME
def rename(self, new_name):
self.name = new_name
reset_name = functools.partial(rename, DEFAULT_NAME)
def __repr__(self):
return f"Hero({self.name!r})"
The code makes use of a different version of partial, partialmethod, which allows the creation of partial for a method class. By using this utility on the rename method and setting the name to the default name, we can create partial, which will be used as a method. The name of the method is the one that is set in the scope of the Hero class definition, which is reset_name.
Solution:
names = ["Magnus Carlsen", "Fabiano Caruana", "Yifan Hou", "Wenjun Ju"]
fixtures = [f"{p1} vs. {p2}" for p1 in names for p2 in names if p1 != p2]
print(fixtures)
You should get the following output:
In this activity, we used list comprehension to sort out players and create a fixture that was in the form of a string.
Solution:
students = ["Vivian", "Rachel", "Tom", "Adrian"]
points = [70, 82, 80, 79]
Now build the dictionary. The comprehension is actually using the third collection; that is, the range of integers from 0 to 100.
scores = { students[i]:points[i] for i in range(4) }
print(scores)
You should get the following output:
In this activity, we worked on dictionary comprehension and multiple lists. We executed the code to print out a scorecard with two separate lists of names and scores and outputted their values.
Solution:
import math
import random
def approximate_pi():
total_points = 0
within_circle = 0
for i in range (10001):
Here, x and y are random numbers between 0 and 1, which, together, represent a point in the unit square (you can refer to Figure 7.25):
x = random.random()
y = random.random()
total_points += 1
distance = math.sqrt(x**2+y**2)
if distance < 1:
If the distance is less than 1, then this point is both inside the square and inside a circle of radius 1, centered on the origin. You can refer to Figure 7.25:
within_circle += 1
if total_points % 1000 == 0:
pi_estimate = 4 * within_circle / total_points
if total_points == 10000:
return pi_estimate
else:
Yield successive approximations to π:
yield pi_estimate
estimates = [estimate for estimate in approximate_pi()]
errors = [estimate - math.pi for estimate in estimates]
print(estimates)
print(errors)
You should get the following output:
By completing this activity, you are now able to explain the working of generators. You successfully generated a plot of points, using which you were able to calculate the value of π. In the following section, we will learn about regular expressions.
Solution:
names = ["Xander Harris", "Jennifer Smith", "Timothy Jones", "Amy Alexandrescu", "Peter Price", "Weifung Xu"]
winners = [name for name in names if re.search("[Xx]", name)]
print(winners)
You should get the following output:
In this activity, we used regular expressions and Python's re module to find customers from a list whose name contains the value of Xx.
Solution:
DEFAULT_INITIAL_BASKET = ["orange", "apple"]
def create_picnic_basket(healthy, hungry, initial_basket=DEFAULT_INITIAL_BASKET):
basket = initial_basket
if healthy:
basket.append("strawberry")
else:
basket.append("jam")
if hungry:
basket.append("sandwich")
return basket
For the first step, the code creates a list of food that is based on an initial list that can be passed as an argument. There are then some flags that control what gets added. When healthy is true, a strawberry will get added. On the other hand, if it is false, the jam will be added instead. Finally, if the hungry flag is set to true, a sandwich will be added as well.
# Reproducer
print("First basket:", create_picnic_basket(True, False))
print("Second basket:", create_picnic_basket(False, True, ["tea"]))
print("Third basket:", create_picnic_basket(True, True))
You should get the following output:
def create_picnic_basket(healthy, hungry, basket=None):
if basket is None:
basket = ["orange", "apple"]
if healthy:
basket.append("strawberry")
else:
basket.append("jam")
if hungry:
basket.append("sandwich")
return basket
Note that default values in functions should not be mutable, as the modifications will persist across calls. The default basket should be set to None in the function declaration, and the constant should be used within the function. This is a great exercise to debug.
The debugged output is as follows:
In this activity, you have implemented debugging to understand the source code, after which you were able to print the test cases (reproducers) and find the issue. You were then able to debug the code and fix it to achieve the desired output.
Solution
conda create -n my_env
You should get the following output:
conda activate my_env
conda install numpy
You should get the following output:
conda install jupyter
jupyter notebook
import threading
import queue
import cProfile
import itertools
import numpy as np
in_queue = queue.Queue()
out_queue = queue.Queue()
def random_number_threading():
while True:
n = in_queue.get()
if n == 'STOP':
return
random_numbers = np.random.rand(n)
out_queue.put(random_numbers)
def generate_random_numbers(show_output, up_to):
thread = threading.Thread(target=random_number_threading)
thread.start()
for i in range(up_to):
in_queue.put(i)
random_nums = out_queue.get()
if show_output:
print(random_nums)
in_queue.put('STOP')
thread.join()
generate_random_numbers(True, 10)
You should get the following output:
cProfile.run('generate_random_numbers(False, 20000)')
You should get the following output:
Having completed this activity, you now know how to execute programs in a conda virtual environment and get the final output as a set amount of time to execute the code. You also used CProfiling to analyze the time taken by various parts of your code, giving you the opportunity to diagnose which parts of your code were the least efficient.
Solution
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
# Set up seaborn dark grid
sns.set()
statistics_df = pd.read_csv('UKStatistics.csv')
statistics_df.head()
The output will be as follows:
statistics_df.shape
The output will be as follows:
(51, 19)
plt.hist(statistics_df['Actual Pay Floor (£)'])
plt.show()
The output will be as follows:
x = statistics_df['Salary Cost of Reports (£)']
y = statistics_df['Actual Pay Floor (£)']
plt.scatter(x, y)
plt.show()
The output will be as follows:
x = statistics_df['Salary Cost of Reports (£)']
y = statistics_df['Actual Pay Floor (£)']
plt.boxplot(x)
plt.show()
The output will be as follows:
In this activity, we compared two specific pieces of data from the dataset, that is, Salary Cost of Reports (£) and Actual Pay Floor (£). We then used various graphs and observed the vast difference between Salary cost reports and Actual Pay Floor. The box plot graph clearly shows us that there are three outliers in the data of x and y that make it prone to inconsistencies with regard to pay from the government.
Solution:
Import the necessary pandas and numpy libraries to begin with:
import pandas as pd
import numpy as np
df = pd.read_csv('CHURN.csv')
df.head()
You should get the following output:
df.info()
You should get the following output:
df['Churn'] = df['Churn'].replace(to_replace=['No', 'Yes'], value=[0, 1])
X = df.iloc[:,1:-1]
y = df.iloc[:, -1]
X = pd.get_dummies(X)
from sklearn.model_selection import cross_val_score
def clf_model (model, cv=3):
clf = model
scores = cross_val_score(clf, X, y, cv=cv)
print('Scores:', scores)
print('Mean score', scores.mean())
By using logistic regression:
from sklearn.linear_model import LogisticRegression
clf_model(LogisticRegression())
You should get the following output:
By using KNeighborsClassifier:
from sklearn.neighbors import KNeighborsClassifier
clf_model(KNeighborsClassifier())
You should get the following output:
By using GaussianNB:
from sklearn.naive_bayes import GaussianNB
clf_model(GaussianNB())
You should get the following output:
By using RandomForestClassifier:
from sklearn.ensemble import RandomForestClassifier
clf_model(RandomForestClassifier())
You should get the following output:
By using AdaBoostClassifier:
from sklearn.ensemble import AdaBoostClassifier
clf_model(AdaBoostClassifier())
You should get the following output:
You may or may not have the same warning as us in your notebook files. Generally speaking, warnings that do not interfere with code are okay. They are often used to warn the developer of future changes. The top three performing models, in this case, are AdaBoostClassifer, RandomForestClassifier, and Logistic Regression.
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
X_train, X_test ,y_train, y_test = train_test_split(X, y, test_size = 0.25)
def confusion(model):
clf = model
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print('Confusion Matrix:', confusion_matrix(y_test, y_pred))
print('Classfication Report:', classification_report(y_test, y_pred))
return clf
confusion(AdaBoostClassifier())
You should get the following output:
Confusion matrix using RandomForestClassifier:
confusion(RandomForestClassifier())
You should get the following output:
Confusion matrix using LogisticRegression:
confusion(LogisticRegression())
You should get the following output:
confusion(AdaBoostClassifier(n_estimators=250))
You should get the following output:
confusion(AdaBoostClassifier(n_estimators=25))
You should get the following output:
confusion(AdaBoostClassifier(n_estimators=15))
You should get the following output:
As you will see by the end of this activity, when it comes to predicting user churn, AdaBoostClassifier(n_estimators = 25) gives the best predictions.
18.118.198.138