Add Chapter 11 Exercises

This commit is contained in:
lolabird 2023-10-27 15:50:13 -06:00
commit cddc649b7f
10 changed files with 890 additions and 0 deletions

View file

@ -0,0 +1,481 @@
# Exercises
This lesson only had five problems, and thank goodness for that, because problem 4 really threw me for a loop. I've included all 5 here, because there are so few problems and because I genuinely found them all to be interesting problems. 
Also I kept getting tripped up with how I interpreted the numbers from the files vs how Python interpreted them. Because they were coming from a file, those numbers were interpreted as strings, not numbers. You'd think that after my first encounter with this, I'd understand that, but I was literally still struggling with that on problem 5 lol. 
Anyway, enough talk. Let's go through the exercises. 
Student Data
------------
The following three questions uses the following file as a reference:
![](Exercises/image.png)
### Problem 1
> The following sample file called `studentdata.txt` contains one line for each student in an imaginary class. The student’s name is the first thing on each line, followed by some exam scores. The number of scores might be different for each student.
>
> \[studentdata.txt\]
>
> Using the text file `studentdata.txt` write a program that prints out the names of students that have more than six quiz scores.
My solution:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 1
sdfile = open("studentdata.txt", "r")
for line in sdfile:
student = line.split()
if len(student[1:]) > 6:
print(student[0])
sdfile.close()
```
Result:
![](Exercises/1_image.png)
### Problem 2
> Using the text file `studentdata.txt` (shown in exercise 1) write a program that calculates the average grade for each student, and print out the student’s name along with their average grade.
My solution:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 2
sdfile = open("studentdata.txt", "r")
for line in sdfile:
student = line.split()
sum = 0
avg = 0
count = len(student[1:])
for grade in student:
if grade != student[0]:
sum += int(grade)
avg = sum/count
print(student[0], "-", avg)
sdfile.close()
```
Result:
![](Exercises/2_image.png)
### Problem 3
> Using the text file `studentdata.txt` (shown in exercise 1) write a program that calculates the minimum and maximum score for each student. Print out their name as well.
My first attempt at this problem, did not get the right results, even though my logic was right. The issue was that I needed to convert the grades from strings to numbers before comparing them. Once I figured that out, everything was gucci. Here's the final code:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 3
sdfile = open("studentdata.txt", "r")
for line in sdfile:
student = line.split()
mingrade = student[1]
maxgrade = student[1]
for grade in student:
if grade != student[0]:
if int(grade) < int(mingrade):
mingrade = grade
if int(grade) > int(maxgrade):
maxgrade = grade
outputText = "{} - minimum score:{}; maximum score:{}".format(student[0], mingrade, maxgrade)
print(outputText)
sdfile.close()
```
Result:
![](Exercises/3_image.png)
Problem 4
---------
> Here is a file called `labdata.txt` that contains some sample data from a lab experiment.
>
> ![](Exercises/5_image.png)
>
> Interpret the data file `labdata.txt` such that each line contains a an x,y coordinate pair. Write a function called `plotRegression` that reads the data from this file and uses a turtle to plot those points and a best fit line according to the following formulas:
>
> \\(y = \\bar{y} + m(x - \\bar{x})\\)
>
> \\(m = \\frac{\\sum{x\_iy\_i - n\\bar{x}\\bar{y}}}{\\sum{x\_i^2}-n\\bar{x}^2}\\)
>
> where \\(\\bar{x}\\) is the mean of the x-values, \\(\\bar{y}\\) is the mean of the y- values and is the number of points. If you are not familiar with the mathematical \\(\\sum\\) it is the sum operation. For example \\(\\sum{x\_i}\\) means to add up all the x values.
>
> Your program should analyze the points and correctly scale the window using `setworldcoordinates` so that that each point can be plotted. Then you should draw the best fit line, in a different color, through the points.
Mkay… this one was kind of a pain in the ass, from formatting the instructions above, to refreshing myself on how sums worked, to actually structuring the solution. But I got through it. 
First attempt:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 4
import turtle
with open('labdata.txt') as lab:
def plotRegression():
sumx = 0
sumy = 0
sumxy = 0
sumxsq = 0
count = 0
meanx = 0
meany = 0
'''this is basically a normal linear line except with average values'''
for line in lab:
x = int(line[0])
y = int(line[1])
sumx += x
sumy += y
sumxy += x*y
sumxsq += x**2
count += 1
meanx = sumx/count
meany = sumy/count
#meanxsq = meanx**2
slope = (sumxy - (count*meanx*meany))/(sumxsq - (count*meanx**2)) #m
for line in lab:
plot = meany + slope(line[0] - meanx) #y
plotTurtle(line[0], line[1], plot)
def plotTurtle(x, y, plot):
wn = turtle.Screen()
ella = turtle.Turtle() #points from the labdata.txt
#maya = turtle.Turtle() #line of best fit (y)
ella.up()
ella.goto(x,y)
ella.down()
ella.stamp()
ella.up()
wn.exitonclick()
plotRegression()
```
I forgot to split each line, so of course I was getting an error. 
Next, needed to figure out accurately getting the values needed for the equations.
I ended up separating the calculation of slope from the calculation of the regression line into two separate functions decided to send the list of x and y values, the mean x and y, and the slope through as parameters to the `plotRegression` function. 
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 4
import turtle
def slope():
xlist = []
ylist = []
sumx = 0
sumy = 0
sumxy = 0
sumxsq = 0
count = 0 #n
meanx = 0
meany = 0
slope = 0 #m
with open('labdata.txt') as lab:
for line in lab:
values = line.split()
xlist += [int(values[0])]
ylist += [int(values[1])]
x = int(values[0])
y = int(values[1])
sumx += x
sumy += y
sumxy += x*y
sumxsq += x**2
count += 1
meanx = sumx / count
meany = sumy / count
slope = (sumxy - count*meanx*meany) / (sumxsq - count*meanx**2)
plotRegression(xlist, ylist, meanx, meany, slope)
def plotRegression(xlist, ylist, meanx, meany, slope):
for x in xlist:
yplot = meany + slope*(x - meanx)
plotTurtle(x, yplot)
def plotTurtle(x, y):
wn = turtle.Screen()
ella = turtle.Turtle() #points from the labdata.txt
#maya = turtle.Turtle() #line of best fit (y)
ella.up()
ella.goto(x,y)
ella.down()
ella.stamp()
ella.up()
wn.exitonclick()
slope()
```
This helped clean up the code a bit, but I still had the issue of exactly how I was going to plot the line and the x and y value pairs at the same time. I knew that I couldn't just do a simple nested loop. That would result in one of those values being referenced too many times. I needed to find a way to go through both `xlist` and `ylist` at the same time.
So I didn't need a _simple_ nested loop, but I _did_ need a nested loop. What I figured out was that I needed two new variables: one to use as a binary and another to use an index for one of the lists. 
The binary variable was there to keep the value from the first list from being repeated and the index was there to make sure the right value from the second list was being sent to `plotTurtle`. This is what `plotRegression` ended up looking like once I figured that out:
```text-x-python
def plotRegression(xlist, ylist, meanx, meany, slope):
i = 0
for x in xlist:
j = 0
yplot = meany + slope*(x - meanx)
while not j:
plotTurtle(x, ylist[i], yplot)
j += 1
i += 1
```
Now I needed to figure out getting my turtles to draw a line from `yplot` rather than just a series of points. 
Because of the way I was feeding points to `plotTurtle`, the turtles would go back to their starting point, before going back to their respective, (x,y) positions. This is fine for the turtle plotting the original x and y value pairs, but not fine for the turtle plotting the line of best fit. I needed to make sure that the second turtle stayed where it was when it got fed the next plot point.
Turns out the solution to making it stay where it was, was just to have the turtles in the the same function where `yplot` was being calculated. Now all that was left was to get the world coordinates to scale (and change up the colors, just because).
Here's te final code:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 4
import turtle
def slope():
xlist = []
ylist = []
sumx = 0
sumy = 0
sumxy = 0
sumxsq = 0
count = 0 #n
meanx = 0
meany = 0
slope = 0 #m
with open('labdata.txt') as lab:
for line in lab:
values = line.split()
xlist += [int(values[0])]
ylist += [int(values[1])]
x = int(values[0])
y = int(values[1])
sumx += x
sumy += y
sumxy += x*y
sumxsq += x**2
count += 1
meanx = sumx / count
meany = sumy / count
slope = (sumxy - count*meanx*meany) / (sumxsq - count*meanx**2)
plotRegression(xlist, ylist, meanx, meany, slope)
def plotRegression(xlist, ylist, meanx, meany, slope):
#set world coordinates
minx = xlist[0]
miny = ylist[0]
maxx = xlist[0]
maxy = ylist[0]
count = len(xlist)
num = 0
while num < count:
if xlist[num] < minx:
minx = xlist[num]
if xlist[num] > maxx:
maxx = xlist[num]
if ylist[num] < miny:
miny = ylist[num]
if ylist[num] > maxy:
maxy = ylist[num]
num += 1
turtle.setworldcoordinates(minx-10, miny-10, maxx+10, maxy+10)
#plot points
i = 0
wn = turtle.Screen()
wn.bgcolor("#222")
ella = turtle.Turtle() #points from the labdata.txt
ella.color("pink")
maya = turtle.Turtle() #line of best fit (yplot)
maya.color("lightblue")
for x in xlist:
j = 0
yplot = meany + slope*(x - meanx)
while not j:
ella.up()
ella.goto(x, ylist[i])
ella.dot()
if i != 0:
maya.goto(x, yplot)
else:
maya.up()
maya.goto(x, yplot)
maya.down()
j += 1
i += 1
wn.exitonclick()
slope()
```
Result:
![](Exercises/4_image.png)
Problem 5
---------
> At the bottom of this page is a very long file called `mystery.txt` The lines of this file contain either the word UP or DOWN or a pair of numbers. UP and DOWN are instructions for a turtle to lift up or put down its tail. The pairs of numbers are some x,y coordinates. Write a program that reads the file `mystery.txt` and uses the turtle to draw the picture described by the commands and the set of points.
It's long so, I'll just link to the data in `mystery.txt` [here](Exercises/mystery.txt.md). 
Drawing the image was relatively straightforward. It was getting the world coordinates that was challenging, even though I literally just did the same thing in the previous problem. 
The challenge was that this time, just splitting the data into x and y coordinates was not that simple. I now had to contend with strings `“UP”` and `“DOWN”`, as well. 
What also threw me for a loop was that the program was expecting me to initialize the min/max variables before what I thought of as the actual initialization (assigning the variables to the first numbers in the file). My guess is that I had to go through this extra step, because unlike in the previous problem, I was pulling the numbers directly from the file insteadAnd  an array. 
Anywho, here's my solution:
```text-x-python
# Runestone.Academy thinkcspy course
# Chapter 11
# Problem 5
 import turtle
def getMinMax():
#get world coordinates
minx = 0
miny = 0
maxx = 0
maxy = 0
with open('mystery.txt') as data:
for line in data:
values = line.split()
if values[0] != "UP" and values[0] != "DOWN":
minx = int(values[0])
miny = int(values[1])
maxx = int(values[0])
maxy = int(values[1])
break
for line in data:
values = line.split()
if values[0] != "UP" and values[0] != "DOWN":
if int(values[0]) < minx:
minx = int(values[0])
if int(values[0]) > maxx:
maxx = int(values[0])
if int(values[1]) < miny:
miny = int(values[1])
if int(values[1]) > maxy:
maxy = int(values[1])
draw(minx, miny, maxx, maxy)
def draw(minx, miny, maxx, maxy):
turtle.setworldcoordinates(minx-10, miny-10, maxx+10, maxy+10)
wn = turtle.Screen()
wn.bgcolor("#e0e0e0")
ella = turtle.Turtle()
ella.color("brown")
with open('mystery.txt') as data:
for line in data:
values = line.split()
if values[0] == "UP":
ella.up()
elif values[0] == "DOWN":
ella.down()
else:
x = int(values[0])
y = int(values[1])
ella.goto(x,y)
getMinMax()
```
Result:
![](Exercises/6_image.png)
It's a dinosaur!
And here's a gif of Python actually generating the image from the instructions. Figured that'd be more interesting than a static image:
![](Exercises/mystery-2023-10-27_15.00.35.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

View file

@ -0,0 +1,409 @@
# mystery.txt
```text-plain
UP
-218 185
DOWN
-240 189
-246 188
-248 183
-246 178
-244 175
-240 170
-235 166
-229 163
-220 158
-208 156
-203 153
-194 148
-187 141
-179 133
-171 119
-166 106
-163 87
-161 66
-162 52
-164 44
-167 28
-171 6
-172 -15
-171 -30
-165 -46
-156 -60
-152 -67
-152 -68
UP
-134 -61
DOWN
-145 -66
-152 -78
-152 -94
-157 -109
-157 -118
-151 -128
-146 -135
-146 -136
UP
-97 -134
DOWN
-98 -138
-97 -143
-96 -157
-96 -169
-98 -183
-104 -194
-110 -203
-114 -211
-117 -220
-120 -233
-122 -243
-123 -247
-157 -248
-157 -240
-154 -234
-154 -230
-153 -229
-149 -226
-146 -223
-145 -219
-143 -214
-142 -210
-141 -203
-139 -199
-136 -192
-132 -184
-130 -179
-132 -171
-133 -162
-134 -153
-138 -145
-143 -137
-143 -132
-142 -124
-138 -112
-134 -104
-132 -102
UP
-97 -155
DOWN
-92 -151
-91 -147
-89 -142
-89 -135
-90 -129
-90 -128
UP
-94 -170
DOWN
-83 -171
-68 -174
-47 -177
-30 -172
-15 -171
-11 -170
UP
12 -96
DOWN
9 -109
9 -127
7 -140
5 -157
9 -164
22 -176
37 -204
40 -209
49 -220
55 -229
57 -235
57 -238
50 -239
49 -241
51 -248
53 -249
63 -245
70 -243
57 -249
62 -250
71 -250
75 -250
81 -250
86 -248
86 -242
84 -232
85 -226
81 -221
77 -211
73 -205
67 -196
62 -187
58 -180
51 -171
47 -164
46 -153
50 -141
53 -130
54 -124
57 -112
56 -102
55 -98
UP
48 -164
DOWN
54 -158
60 -146
64 -136
64 -131
UP
5 -152
DOWN
1 -150
-4 -145
-8 -138
-14 -128
-19 -119
-17 -124
UP
21 -177
DOWN
14 -176
7 -174
-6 -174
-14 -170
-19 -166
-20 -164
UP
-8 -173
DOWN
-8 -180
-5 -189
-4 -201
-2 -211
-1 -220
-2 -231
-5 -238
-8 -241
-9 -244
-7 -249
6 -247
9 -248
16 -247
21 -246
24 -241
27 -234
27 -226
27 -219
27 -209
27 -202
28 -193
28 -188
28 -184
UP
-60 -177
DOWN
-59 -186
-57 -199
-56 -211
-59 -225
-61 -233
-65 -243
-66 -245
-73 -246
-81 -246
-84 -246
-91 -245
-91 -244
-88 -231
-87 -225
-85 -218
-85 -211
-85 -203
-85 -193
-88 -185
-89 -180
-91 -175
-92 -172
-93 -170
UP
-154 -93
DOWN
-157 -87
-162 -74
-168 -66
-172 -57
-175 -49
-178 -38
-178 -26
-178 -12
-177 4
-175 17
-172 27
-168 36
-161 48
-161 50
UP
-217 178
DOWN
-217 178
-217 177
-215 176
-214 175
-220 177
-223 178
-223 178
-222 178
UP
-248 185
DOWN
-245 184
-240 182
-237 181
-234 179
-231 177
-229 176
-228 175
-226 174
-224 173
-223 173
-220 172
-217 172
-216 171
-214 170
-214 169
UP
-218 186
DOWN
-195 173
-183 165
-175 159
-164 151
-158 145
-152 139
-145 128
-143 122
-139 112
-138 105
-134 95
-131 88
-129 78
-126 67
-125 62
-125 54
-124 44
-125 38
-126 30
-125 27
-125 8
-126 5
-125 -9
-122 -15
-115 -25
-109 -32
-103 -39
-95 -42
-84 -45
-72 -47
-56 -48
-41 -47
-31 -46
-18 -45
-1 -44
9 -43
34 -45
50 -52
67 -61
83 -68
95 -80
112 -97
142 -115
180 -132
200 -146
227 -159
259 -175
289 -185
317 -189
349 -190
375 -191
385 -192
382 -196
366 -199
352 -204
343 -204
330 -205
315 -209
296 -212
276 -214
252 -208
237 -202
218 -197
202 -193
184 -187
164 -179
147 -173
128 -168
116 -164
102 -160
88 -158
78 -159
69 -162
57 -164
56 -165
51 -165
UP
68 -144
DOWN
83 -143
96 -141
109 -139
119 -146
141 -150
161 -155
181 -163
195 -169
208 -179
223 -187
241 -191
247 -193
249 -194
UP
-6 -141
DOWN
-15 -146
-29 -150
-42 -154
-51 -153
-60 -152
-60 -152
UP
-90 -134
DOWN
-85 -131
-79 -128
-78 -123
-80 -115
-82 -106
-80 -101
-76 -101
UP
-81 -132
DOWN
-76 -130
-71 -126
-72 -124
UP
43 -118
DOWN
44 -125
47 -135
41 -156
37 -160
40 -166
47 -171
47 -171
UP
-106 -153
DOWN
-107 -167
-106 -178
-109 -192
-114 -198
-116 -201
```