If the version of your code on github does not run, it is considered non-functioning. If it does not run on your personal computer WITHOUT CHANGES, it is considered non-functioning.
WARNING: Graders will not grade any part of your code that does not execute.
TOTAL: 30 points
main()
, i.e. no global variablesIn this lab, you will practice
font
and transform
libraryAn example of indefinite iteration is the 3n+1 sequence. The rule for creating the sequence is as follows:
Below is Python for generating the sequence given some positive number:
def threenp1(n):
while n > 1.0:
if n % 2 == 0:
n = int(n / 2)
else:
n = int(3 * n + 1)
return None
What’s so interesting about this sequence:
In other words, every number tried so far has converged on 1, but there is no mathematical proof that says all numbers will
One of the interesting questions about the 3n+1 sequence is:
How many numbers are in the sequence for a particular starting value?
To determine this, we will need to count them.
Write a function that refactors the previous function as follows:
count
.0
before you begin the while
loop.while
loop, you will need to +1 to count (increment), so that you can keep track of the number of iterationscount = count + 1
1
), return the value of count
.
count
contains the total number of times the loop body executed.It is very important that you put these statements in the right place with the correct indentation.
Now that we have an algorithm that can return the number of iterations required to get to 1
, we can use it to check a wide range of starting values. In fact, instead of just doing one value at a time, we can use a loop get the number of iterations for a range of values.
Let's keep track of the 3n+1 iterations for each positive integer value between 2
and <upper_limit>
. Write a function:
def threenp1range(upper_limit):
that takes a upper_limit
as an argument.
You can store each value and the resulting number of iterations in a dictionary, objs_in_sequence = {}
, where each entry is formatted as n : iters
.
The final algorithm is as follows:
for
loop using an iteration variable called that goes from 2
up to (and including) upper_limit
range()
because the default of 0 will cause an infinite loopfor
loop, call your threenp1()
function to determine the number of 3n+1 iterations for that value in the range[2-10]
:threenplus1_iters_dict = {2: 1, 3: 7, 4: 2, 5: 5, 6: 8, 7: 16, 8: 3, 9: 19, 10: 6}
Write a main()
to call your function to test it.
Scanning the list of results in the dictionary causes us to ask the following question:
Which value between
1
andupper_limit
produces the largestcount
of iterations?
Let's use pygame to draw a line graph based on your results, which will allows us to see the number of iterations for each value.
Write another function that graphs a point for each value/iterations
pair in the range.
We will also add some text to display the current maximum number of iterations (i.e. current state) as you work your way through the range.
As an argument, your function should take a dictionary of values and iterations:
def graph_coordinates(threenplus1_iters_dict):
You will need to use the following pygame modules for graphing:
coordinates = [(2,1), (3,7), … ]
[(key, value)]
formnew_display = pygame.transform.flip(display, False, True)
pygame.transform
library can help with that too:
width, height = new_display.get_size()
new_display = pygame.transform.scale(new_display, (width * <factor>, height * <factor>))
factor=5
to work well, but you can adjust as needed.display.blit(new_display, (0, 0))
(0,0)
, to place the top left corner of the new screenFinally, create a variable that will keep track of the largest number of iterations for a value seen so far: max_so_far
n:iters
dictionary pairs (coordinate points), we want to find the highest value for iters
(the y-values)Use a for loop to find largest number of iterations for any value in the range and save it in max_so_far
.
After graphing the coordinates, write a message on screen with the current max_so_far
value in the top left of the screen.
You will need to do this after you have transformed the screen but before you display it.
To write a message on screen, use the pygame font library
You must create a font object before you can write text on the screen
font = pygame.font.Font(font_name, size)
font_name
: the name of the font you want to use
None
to get pygame to use a default font (recommendedsize
: font sizeSince pygame displays images, not text, it has to convert your text to an image it can display
msg = font.render(msg, antialias, color)
msg
: a string you want to displayantialias
: a boolean (True
/False
) if the text should be antialiased (display more smoothly, but less efficiently).color
: the text color (choose any color you like)Add the new text image to the display
display.blit(msg, pos)
msg
: the result from calling font.render()pos
: the location, as a tuple of (x, y), to place the image.
(10, 10)
gives a little space between your text and the edge of the display, but feel free to adjust however you like.In your main()
use the result form your threenp1range()
as the argument for your graph_coordinates()
function.
Although there are many ways to complete this, below is one basic algorithm for the entire program from start to finish:
main()
threenp1range()
function with your upper limit
graph_coordinates()
functionthreenp1range()
:
2
and upper_limit
:
threenplus1
algorithm to get the number of iterationsx:y
result to your dictionarygraph_coordinates
to graph the results:
pygame.draw.lines()
main.py
Complete your submission by making a commit and push using either the Source Control tab in VSCode or the command line in the shell.
That's it! You've completed the work for this lab.