# Workshop 19¶

## Pickle¶

Write the following program.

The user inputs integer numbers into the program. The numbers are saved into a list. If the user inputs 0, it is a sign that the input has ended. The number 0 itself shouldn't be included into the list. The list is empty at the start.

The program should be persistent: once the user runs it again, it should load all the previously inputted numbers and append the new ones at the end of the list.

To achieve this, pickle the list at the end and unpickle it at the beginning of the program. When you run the program for the first time, the pickled file from "the last time" wouldn't exist. Write an exception handler to output a notice message "New file" in this case, then append the numbers to an empty list and pickle the list.

### Saving data to a file with pickle¶

In [ ]:
import pickle

# An arbitrary collection of objects supported by pickle.
data = {
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': {None, True, False}
}

with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)


### Loading data from a file with pickle¶

In [ ]:
import pickle

with open('data.pickle', 'rb') as f:
# The protocol version used is detected automatically, so we do not
# have to specify it.
print(data)

{'a': [1, 2.0, 3, (4+6j)], 'b': ('character string', b'byte string'), 'c': {None, True, False}}


## Module random¶

Module random provides ways to generate random numbers.

In [ ]:
# generating a float in range [0, 1).
import random
x = random.random()
print(x)

0.709248465584801

In [ ]:
# generating a float in range [start, end]
start = 10
end = 20

y = random.uniform(start, end)
# y = start + random.random()*(end - start)

print(y)

14.32524306038929

In [ ]:
# generating an int
# includes last number
z = random.randint(10, 20)
print(z)

20

In [ ]:
# generating an int
# behaves like range(), does not include last number
z = random.randrange(10, 20)
print(z)

15


Additionally, it provides ways of working with random objects in general and making random choices.

In [ ]:
# choosing a random value from a list
animals = ['cat', 'dog', 'bunny', 'hamster']
random_animal = random.choice(animals)
print(random_animal)

hamster

In [ ]:
# randomly rearranging a list
number_list = list(range(20))
random.shuffle(number_list)
print(number_list)

[17, 12, 2, 10, 11, 9, 1, 0, 4, 3, 16, 13, 5, 8, 15, 7, 18, 6, 19, 14]


### Example 1¶

In [ ]:
import math

total_counter = 10000
in_circle_counter = 0

for i in range(total_counter):

# generate a random dot in square from [-1 -1] to [1 1]
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)

# get distance to the origin
distance = math.hypot(x, y)

# check if the dot is inside the circle with radius 1
if distance < 1:
in_circle_counter += 1

ratio = in_circle_counter / total_counter
print('Ratio of numbers in circle is:', ratio)
estimated_pi = ratio * 4
print('Estimated pi:', estimated_pi)

Ratio of numbers in circle is: 0.78387
Estimated pi: 3.13548


Function chr(code) allows you to turn ASCII code of a symbol into the symbol itself. For example, chr(97) will return the string 'a'.

Use this function to write a program that generates a password of 8 random characters with codes from 33 to 126.

In [ ]:
code = 97
print(chr(code))


Write a program that simulates coin flips by generating random numbers. Generate a sequence of coin flips until you get either heads or tails 3 times in a row.

Run the simulation 15 times. Compute the average number of flips it takes to get the same result 3 times in a row.

##### Example output¶
H T H T T T (6 flips)
H H T H H T H H H (9 flips)
T T T (3 flips)
...
T H H H (4 flips)
Average: 8.1 flips
In [ ]: