1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 1 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb Part 2 Permissible resources: You may freely use lectures notes and videos; any pre-existing online resources; Google; etc. Impermissible resources: You may not collaborate with each other or solicit help from any in- person or online resources. Example: browsing an online Python forum is fine; posting on the forum is not. Submission Expectations Each of the two notebooks should be submitted as .pdf files following the usual submission format. You should also include comments and docstrings in your class and function definitions unless stated otherwise. Partial Credit Let us give you partial credit! 1. Are you completely stuck on Part (A)? Can't get your code to run? Breathe, and write down (as a comment or "docstring") your approach. What is your idea? What have you tried so far? What is your best guess for what's not working? We will give you partial credit for these notes. 2. Being stuck on Part (A) doesn't mean you can't do Part (B)! Do your best, and again write down everything you can think of that is relevant. Write the code that you would expect to run if part (A) were working. Explicitly state that you are unable to test your code in (B) because you couldn't get (A) to run. If your answers fully demonstrate understanding of the problem, then you can receive up to full credit this way. 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 2 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb Part A (25 points) Review your solution (or the posted solution) to Problem 4 of Homework 1. Repurpose this code to implement a random_walk class. This class should: 1. Possess a self.step() method that causes the walk to move forward or backward. 2. Possess a self.multistep(k_steps=1) method that causes the walk to take k_steps consecutively. 3. Possess a self.plot() method that plots the walk using the plot() function of matplotlib.pyplot . You will need to import this module -- check the HW1 solutions to see how. 4. Possess instance variables that collect the full history of the positions and step directions of the walk. It is not necessary to incorporate upper and lower bounds this time. Test your class by running the following code and showing the result. rw = random_walk() rw.multistep(1000000) rw.plot() Don't forget comments and docstrings! Your Solution 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 3 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb In [39]: # class definition here import random from matplotlib import pyplot as plt class random_walk: """ an object-oriented approach to random walks. Stores current position, a log of previous positions, and a log of steps. """ def __init__(self): self.p = 0 self.positions = [self.p] self.steps = [] def step(self): """ increment the current position by either -1 or 1 with equal probability append the direction of movement to self.steps and the position to self.positions """ # pick a random direction s = random.choice([-1, 1]) # update steps, current position, and position log self.steps.append(s) self.p += s self.positions.append(self.p) def multistep(self, k_steps=1): """ take a user-specified number of self.step()'s """ for i in range(k_steps): self.step() def plot(self): """ visualize the walk using the plot() function of matplotlib.pyplot """ plt.plot(self.positions) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 4 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb In [27]: # test code -- run but do not modify rw = random_walk() rw.multistep(1000000) rw.plot() 1 2 3 4 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 5 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb Part B (10 points) Copy/paste your solution from above into the code block below. Implement self.__iter__() and any additional required methods or classes in order to add support for iteration through the positions visited by the walk. For example, the following code should work. rw = random_walk() rw.multistep(5) for i in rw: print(i) 0 -1 -2 -1 0 1 The printed numbers are the 6 total positions visited by the walk when calling rw.multistep(5) (including the initial position of 0). Since we are working with random numbers, your exactly outputs may look different from mine. Test your solution by running the four lines of code below the cell for your class definition. Note: because it's a random walk, you won't get exactly the same numbers -- that's ok! It is possible to obtain full credit on this part, even if you did not completely solve Part A. Note: There is a long way and a short way to solve this problem. Short solutions will receive full credit; long solutions can receive up to 8/10 points. Your Solution 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 6 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb In [3]: In [4]: 0 -1 0 1 2 1 # class definition here import random from matplotlib import pyplot as plt class random_walk: """ See previous part for example docstrings and comments """ def __init__(self): self.p = 0 self.positions = [self.p] self.steps = [] def step(self): s = random.choice([-1, 1]) self.steps.append(s) self.p += s self.positions.append(self.p) def multistep(self, k_steps=1): for i in range(k_steps): self.step() def plot(self): plt.plot(self.positions) # new code begins here, could alternatively implement a # custom iterator class with `__next__()` # or implement __next__() within this class # for partial credit. def __iter__(self): return iter(self.positions) # test code -- run this, do not modify rw = random_walk() rw.multistep(5) for i in rw: print(i) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1 2 3 4 5 6 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 7 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb Part C (10 points) Now, write a generator called rw_generator that achieves the same looping behavior as your iteration solution for the random_walk class. You should be able to use your generator like this: for pos in rw_generator(5): print(pos) 0 1 0 -1 -2 -3 That is, when looping through rw_generator(5) , the initial value 0 is always returned. Then, the next value is either one more or one less than the previous value, and these two cases each have 50% probability. Mathematically, this is the same behavior as the object-oriented approach above. As usual, your exact numbers are likely to differ from the above due to randomness. Your generator should be independent of the random_walk class (that is, you would be able to use it even if that class were not defined). Additionally, the code for your generator should be much shorter than the object-oriented approach. It is possible to obtain full credit on this part, even if you did not completely solve Parts A and B. Comments and docstrings are not required in this part. In [5]: In [6]: 0 1 0 1 2 3 # define your generator here def rw_generator(n_steps): pos = 0 yield pos for i in range(n_steps): pos += random.choice([-1, 1]) yield pos # test your generator by running this block for pos in rw_generator(5): print(pos) 1 2 3 4 5 6 7 1 2 3 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 8 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb Part D (0 points) Generators can be converted into lists via the list constructor. This makes it easy to plot the random walk from the generator in the previous part. If you like, you are welcome to see your generator in action for a large random walk by running the code below. In [33]: Out[33]: [
] plt.plot(list(rw_generator(500000)))1 1/29/22, 8:47 PMF20-midterm-P2-sol - Jupyter Notebook Page 9 of 9http://localhost:8888/notebooks/F20-midterm-P2-sol.ipynb 欢迎咨询51作业君