Libraries and Random Values Lesson Notes
Based on the lesson by Prasith, Chinmay, Vyaan, Chris, and Emaad.
FOR GRADERS
I combined my notes, challenges, and homework completion from both lessons into this one document, so it's pretty big and bulky. Here is what I completed (and you can verify by finding these things on the blog's table of contents):
Basic Expectations
Libraries (3.14):
- Fill-in-the-blank notes
- Additional notes
- Challenges 1-3 fully completed (see each in the TOC for proof)
- Homework "Option 1" (draws a shape with a given random number of sides with Turtle)
- Homework "Option 2" (finds the difference between two dates, at least one random)
Random Values (3.15):
- Additional notes
- Fill-in-the-blank random examples list
- Challenge 1 (coin flip function)
- Binary homework
Extras
- Fully incorporated user input for Libraries Homework "Option 1" and "Option 2"
- Working failsafe code on Libraries Homework "Option 2"
- Random Values Challenge 1 "EXTRA": Card Generator and Royal Flush Detector
- Random Values Homework "EXTRA": Decimal-to-Hexadecimal Converter
Libraries
Okay, so we've learned a lot of code, and all of you now can boast that you can code at least some basic programs in python. But, what about more advanced stuff? What if there's a more advanced program you don't know how to make? Do you need to make it yourself? Well, not always.
You've already learned about functions that you can write to reuse in your code in previous lessons. But,there are many others who code in python just like you. So why would you do again what someone has already done, and is available for any python user?
Packages allow a python user to import methods from a library, and use the methods in their code. Most libraries come with documentation on the different methods they entail and how to use them, and they can be found with a quick Google search. methods are used with the following:
Note: a method from a package can only be used after the import statement.
Some libraries are always installed, such as those with the list methods which we have previously discussed. But others require a special python keyword called `import`. We will learn different ways to import in Challenge 1.
Sometimes we only need to import a single method from the package. We can do that with the word "from", followed by the package name, then the word "import", then the method. This will alllow you to use the method without mentioning the package's name, unlike what we did before, however other methods from that package cannot be used. To get the best of both worlds you can use "*".
To import a method as an easier name, just do what we did first, add the word "as", and write the name you would like to use that package as.
Additional Notes
Here are some extra notes I took for the sake of completion.
- Some libraries need to be installed before use. Some, however, are innate.
- Some libraries require the features of other libraries. For example, Turtle relies on Tkinter features to open a window for a canvas.
- Importing with the format
from [library] import *
negates the need to specify[library].function()
each time.
Challenge 1: Basic Libraries
- Find a Python package on the internet and import it
- Choose a method from the package and import only the method
- import the package as a more convenient name.
from time import *
from IPython.display import clear_output as clr
#i used them to make an ASCII animation
def base():
print(" | | ")
print("-----")
def startpos():
print(" O ")
print(" /|\ ")
def waveup():
print(" O /")
print(" /| ")
def wavemid():
print(" O| ")
print(" /| ")
i = 0
while i < 30:
clr(wait=True)
if i == 0:
startpos()
base()
else:
if i % 2 == 0:
wavemid()
base()
else:
waveup()
base()
i += 1
sleep(.2)
For this challenge, I imported the whole time
module using *
, which allowed me to call sleep()
rather than time.sleep()
. I also imported clear_output
and renamed it "clr
" for simplicity. Try copying and running this yourself for a little animation.
Challenge 2: Turtle
Turtle is a Python drawing package which allows you to draw all kinds of different shapes. It's ofter used to teach beginning python learners, but is really cool to use anywhere. Turtle employs a graphics package to display what you've done, but unfortunately it's kind of annoying to make work with VSCode.
My Image
This is what I created with Turtle. I'm no artist, but I tried to at least show I could use the program from a code perspective.

Here's the code I used for it. See the code comments for where I satisfied the expectations of this challenge.
import turtle
t = turtle.Turtle()
ts = t.getscreen()
# vvv FOUND THIS ONE MYSELF vvv
ts.bgcolor('pink') #here's me changing a canvas function
t.pensize(5) #here's me changing the pen settings
t.speed('fastest') #more pen/canvas settings
t.color('yellow')
# vvv FOUND THIS ONE MYSELF vvv
t.circle(65) #here's a unique function i used
t.left(90)
t.color('pink')
t.forward(90)
t.left(90)
t.forward(10)
t.left(90)
t.color('black')
t.forward(20)
t.color('pink')
t.left(90)
t.forward(20)
t.left(90)
t.color('black')
t.forward(20)
t.color('pink')
t.left(90)
t.forward(10)
t.left(90)
t.forward(70)
t.color('black')
t.left(90)
i = 0
while i < 50:
t.forward(1)
t.left(1)
i += 1
t.color('pink')
t.setpos(20, -100) #trying out more functions
i = 0
t.color('green', 'red')
# vvv FOUND THIS ONE MYSELF vvv
t.begin_fill()
while i < 25:
t.forward(150)
t.right(130)
i += 1
# vvv FOUND THIS ONE MYSELF vvv
t.end_fill()
Challenge 3: Math
The math package allows for some really cool mathematical methods!
Methods | Action |
---|---|
ceil(x) | rounds to the largest integer greater than or equal to x |
floor(x) | rounds to largest integer less than or equal to x |
factorial(x) | takes the factorial of x |
gcd(x,y) | returns the greatest common denominator of x and y |
lcm(x,y) | returns the least common multiple of x and y |
Challenge: Create a program which asks for a user input of two numbers, and returns the following:
- each number rounded up
- each number rounded down
- the lcm of the rounded down numbers
- the gcf of the rounded up numbers
- the factorial of each number
- something else using the math package!
I decided to use sqrt
.
from math import *
def smorgas(x, y):
info = []
for num in [x, y]:
info.append(ceil(num)) #rounding x and y up
info.append(floor(num)) #rounding x and y down
info.append(lcm(floor(x), floor(y))) #the lcm of x and y rounded down
info.append(gcd(ceil(x), ceil(y))) #the gcd of x and y rounded up
info.append(factorial(x)) #same as x factorial
info.append(factorial(y)) #same as y factorial
info.append(floor(sqrt(x))) #extra: finding and rounding the square root of x
info.append(floor(sqrt(y))) #extra: square root of y
return info #returned as list to be called later
i1 = 3
i2 = 5
info = smorgas(i1, i2)
print(i1, "rounded up:", info[0])
print(i1, "rounded down:", info[1])
print(i2, "rounded up:", info[2])
print(i2, "rounded down:", info[3])
print("Least common multiple of", i1, "and", str(i2) + ":", info[4])
print("Greatest common denominator of", i1, "and", str(i2) + ":", info[5])
print("Factorial of", str(i1) + ":", info[6])
print("Factorial of", str(i2) + ":", info[7])
print("Rounded square root of", str(i1) + ":", info[8])
print("Rounded square root of", str(i2) + ":", info[9])
import turtle
def userInp():
print("How many sides do you want on the polygon?")
rsp = input("Please input an integer.")
rsp = int(rsp)
return rsp
t = turtle.Turtle()
t.speed('fastest')
i = 0
sides = userInp()
while i < sides:
angle = 180 - (((sides - 2) * 180) / sides)
t.forward(360/sides)
t.left(angle)
i += 1
And here's code that makes a polygon for a random number of sides from 1 to 10. (1 is just a straight line.)

And here's the code again.
import turtle
from random import *
t = turtle.Turtle()
t.speed('fastest')
i = 0
sides = randint(1, 10)
print("Number of sides on polygon:", sides)
while i < sides:
angle = 180 - (((sides - 2) * 180) / sides)
t.forward(360/sides)
t.left(angle)
i += 1
Option 2 ("Libraries HW")
Here is the program that finds the distance between two dates using the datetime
package. One set of instructions says to use a user input and a random date while the other says to use two completely random dates, so I made both.
Here's the one that takes one user input and then generates the second randomly:
from datetime import date
from random import *
days_dictionary = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31,
9: 30,10: 31, 11: 30, 12: 31
}
def getUserDate(): #really long because of a bunch of failsafes
yr = False
mh = False
dy = False
while yr == False:
print("What year do you want?")
useryr = input("Input any year. Must be a positive integer.")
try:
useryr = abs(int(useryr))
yr = True
except:
print('Please input a valid integer.')
while mh == False:
print("What month do you want?")
usermh = input("Input a month. Must be an integer 1 through 12.")
try:
usermh = abs(int(usermh))
if 1 <= usermh <= 12:
mh = True
else:
print('Please input a valid integer within the range.')
except:
print('Please input a valid integer.')
while dy == False:
print("What day do you want?")
userdy = input("Input a day. Must be within the amount of days per year (Feb. with 28).")
try:
userdy = abs(int(userdy))
if 1 <= userdy <= days_dictionary[usermh]:
dy = True
else:
print('Please input a valid day.')
except:
print('Please input a valid integer.')
return date(useryr, usermh, userdy)
def randomDate():
randyear = randint(1500, 3000) #only from the years 1500 to 3000
randmonth = randint(1, 12) #limited to 1-12, January-December
randday = randint(1, days_dictionary[randmonth])
return date(randyear, randmonth, randday)
date1 = getUserDate()
date2 = randomDate()
delta = abs(date2 - date1)
diff = delta.days
print("User Date:", date1)
print("Random Date:", date2)
print('The number of days between these two dates is', diff, 'days.')
And then here's the one that has two random dates:
date1 = randomDate()
date2 = randomDate()
delta = abs(date2 - date1)
diff = delta.days
print("Random Date 1:", date1)
print("Random Date 2:", date2)
print('The number of days between these two dates is', diff, 'days.')
Random Values
This is the start of the 3.15 - Random Values notes section.
Additional Notes
- Good for cryptography and games
- Using the import statements we learned about in the last lesson, you can import Python's
random
module for various random packages - Later in the lesson, we can use
random
to check if a function works in all cases - There are multiple ways to use
random
: choose from a list, select an integer in a range, shuffle a list, etc.
What are Random Values?
Random Values are a number generated using a large set of numbers and a mathematical algorithm which gives equal probability to all number occuring.
Each result from randomization is equally likely to occur. Using random number generation in a program means each execution may produce a different result.
What are examples of (psuedo-)random outputs in the world? Add a few you can think of.
- Marbles
- Card game hands
- Weather
- APCSP teacher grades
Why Do We Need Random Values for Code?
Adding elements of randomness helps us to simulate these real-world "random" scenarios.
import random
random_number = random.randint(1,100)
print(random_number)
def randomlist():
list = ["apple", "banana", "cherry", "blueberry"]
element = random.choice(list)
print(element)
randomlist()
Here's a code version of a dice roll.
import random
for i in range(3):
roll = random.randint(1,6)
print("Roll " + str(i + 1) + ":", str(roll))
def coinflip():
result = random.choice(['heads', 'tails'])
return result
print("The result was... " + coinflip() + "!")
print("The result was... " + coinflip() + "!")
import random
#initializing
suits = ['Hearts', 'Spades', 'Clubs', 'Diamonds']
cards = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
deck = []
for suit in suits:
for card in cards:
info = ((card + ' of ' + suit), card, suit)
deck.append(info)
random.shuffle(deck)
def flush():
global deck
flush = ['10', 'Jack', 'Queen', 'King', 'Ace'] #the card conditions for flush
hand = [deck[0], deck[1], deck[2], deck[3], deck[4]] #already shuffled
print('Your hand:', hand[0][0] + ",", hand[1][0]+ ",", hand[2][0]+ ",", hand[3][0]+ ",", hand[4][0])
base = hand[0][2]
for name, card, suit in hand:
if suit == base: #if every card has the same suit
if card in flush: #if the card is in a royal flush set
pass
else:
print('Your hand is NOT a Royal Flush!')
return
else:
print('Your hand is NOT a Royal Flush!')
return
print('Your hand is a Royal Flush!') #if all conditions pass, it's a flush
return
flush()
def DecimalToBinary(num):
i = 7
binary = ""
while i >= 0:
if num % (2**i) == num:
binary += "0"
i -= 1
else:
binary += "1"
num -= 2**i
i -= 1
return binary
x = random.randint(0, 255)
print("Initial decimal number:", x)
print("Binary conversion:", DecimalToBinary(x))
def DecimalToHexa(num):
hexalist = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
hexa = []
hexadec = ''
while num > 0:
num, ind = divmod(num, 16)
hexa.append(hexalist[ind])
i = (len(hexa) - 1)
while i >= 0:
hexadec += hexa[i]
i -= 1
return hexadec
y = random.randint(0, 16777215)
print("Initial decimal number:", y)
print("Hexadecimal conversion:", DecimalToHexa(y))