Skip to content

Commit 3242b16

Browse files
authored
Merge pull request #358 from presnick/textbook_updates_May_2023
Textbook updates may 2023
2 parents f2fcb7f + 0eb8a04 commit 3242b16

24 files changed

+148
-112
lines changed

_sources/AdvancedFunctions/ChapterAssessment.rst

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,17 @@ Chapter Assessment
136136
:autograde: unittest
137137
:practice: T
138138

139-
We have provided the function ``checkingIfIn`` such that if the first input parameter is in the third, dictionary, input parameter, then the function returns that value, and otherwise, it returns ``False``. Follow the instructions in the active code window for specific variable assignmemts.
139+
We have provided a function below and the skeleton of three invocations of the function. Fill in the parameters of the invocations to produce the specified outputs
140140
~~~~
141-
def checkingIfIn(a, direction = True, d = {'apple': 2, 'pear': 1, 'fruit': 19, 'orange': 5, 'banana': 3, 'grapes': 2, 'watermelon': 7}):
142-
if direction == True:
143-
if a in d:
144-
return d[a]
145-
else:
146-
return False
147-
else:
148-
if a not in d:
149-
return True
150-
else:
151-
return d[a]
141+
def f(x, y = 3, z = 7):
142+
return ("{} {} {}".format(x, y, z))
152143

153-
# Call the function so that it returns False and assign that function call to the variable c_false
154-
155-
# Call the fucntion so that it returns True and assign it to the variable c_true
156-
157-
# Call the function so that the value of fruit is assigned to the variable fruit_ans
158-
159-
# Call the function using the first and third parameter so that the value 8 is assigned to the variable param_check
144+
# fill in just one parameter value to make val1 have the value "Hi 3 7"
145+
val1 = f()
146+
# fill in two parameter values to make val2 have the value "Hi Hi 7"
147+
val2 = f()
148+
# fill in two parameters to make vale have the value "Hi 3 Hi"
149+
val3 = f()
160150

161151
=====
162152

@@ -165,13 +155,12 @@ Chapter Assessment
165155
class myTests(TestCaseGui):
166156

167157
def testOne(self):
168-
self.assertEqual(c_false, False, "Testing that c_false has the correct value")
158+
self.assertEqual(val1, "Hi 3 7", "Testing that val1 has the correct value")
169159
def testTwo(self):
170-
self.assertEqual(c_true, True, "Testing that c_true has the correct value")
160+
self.assertEqual(val2, "Hi Hi 7", "Testing that val2 has the correct value")
171161
def testThree(self):
172-
self.assertEqual(fruit_ans, 19, "Testing that fruit_ans has the correct value")
173-
def testFour(self):
174-
self.assertEqual(param_check, 8, "Testing that param_check has the correct value")
175-
162+
self.assertEqual(val3, "Hi 3 Hi", "Testing that val3 has the correct value")
163+
### would be good to define additional tests that check to make sure student is only suppplying minimum number of parameter values
164+
176165

177166
myTests().main()

_sources/AdvancedFunctions/KeywordParameters.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ For example,
247247
:autograde: unittest
248248
:practice: T
249249

250-
**6.** Currently the function is supposed to take 1 required parameter, and 2 optional parameters, however the code doesn't work. Fix the code so that it passes the test. This should only require changing one line of code.
250+
**6.** Currently the function is supposed to take 1 required parameter, and 2 optional parameters, however the code doesn't work because a parameter name without a default value follows a parameter name with a default value. Fix the code so that it passes the test. This should only require changing one line of code.
251251
~~~~
252252
def waste(var = "Water", mar, marble = "type"):
253253
final_string = var + " " + marble + " " + mar

_sources/AdvancedFunctions/OptionalParameters.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@ call in on a string, ``int("100")``, the return value will be the integer 100.
2929

3030
That's the most common way programmers want to convert strings to integers. Sometimes, however, they
3131
are working with numbers in some other "base" rather than base 10. For example, in base 8, the rightmost
32-
digit is ones, the next digit to the left is 8s, and the one to the left of that is the 64s place (8**2).
32+
digit says how many ones, the next digit to the left says how many 8s, and the one to the left of that says how many 64s (64 is 8 squared).
33+
34+
.. note:: New Math
35+
36+
Some math educators believe that elementary school students will get a much deeper understanding
37+
of the place-value system, and set a foundation for learning algebra later, if they learn to do
38+
arithmetic not only in base-10 but also in base-8 and other bases. This was part of a movement
39+
called `New Math <https://en.wikipedia.org/wiki/New_Math>`_, though it's not so new now. It was popular in the 1960s and 1970s in the USA. One of the authors of this textbook (Resnick) had some version of it in elementary school and credits it with ruining his mind, in a good way. Tom
40+
Lehrer wrote a really funny song about it in 1965, and it's now set with visuals in several YouTube renditions. Try this very nice `lip-synched version <http://www.youtube.com/watch?v=DfCJgC2zezw>`_.
3341

3442
The int function provides an optional parameter for the base. When it is not specified, the number is
3543
converted to an integer assuming the original number was in base 10. We say that 10 is the default value.
@@ -42,15 +50,7 @@ supplying a different value.
4250
print(int("100", 10)) # same thing, 10 is the default value for the base
4351
print(int("100", 8)) # now the base is 8, so the result is 1*64 = 64
4452

45-
.. note:: Tom Lehrer's New Math
4653

47-
Some math educators believe that elementary school students will get a much deeper understanding
48-
of the place-value system, and set a foundation for learning algebra later, if they learn to do
49-
arithmetic not only in base-10 but also in base-8 and other bases. This was part of a movement
50-
called "The New Math", though it's not so new now (I had it when I was in elementary school!) Tom
51-
Lehrer made a really funny song about it, and it's set with visuals in several YouTube renditions
52-
now. Try this very nice `lip-synched version <http://www.youtube.com/watch?v=DfCJgC2zezw>`_.
53-
5454
When defining a function, you can specify a default value for a parameter. That parameter then becomes an
5555
optional parameter when the function is called. The way to specify a default value is with an assignment
5656
statement inside the parameter list. Consider the following code, for example.
@@ -76,7 +76,7 @@ specify a value for z without specifying a value for y.
7676

7777
.. note::
7878

79-
This is a second, related but slightly different use of = than we have seen previously. In a stand-alone assignment statement, not part of a function definition, ``x=3`` assigns 3 to the variable x. As part of specifying the parameters in a function definition, ``x=3`` says that 3 is the *default* value for x, used *only when* no value is provided during the function invocation.
79+
This is a second, related but slightly different use of = than we have seen previously. In a stand-alone assignment statement, not part of a function definition, ``y=3`` assigns 3 to the variable y. As part of specifying the parameters in a function definition, ``y=3`` says that 3 is the *default* value for y, used *only when* no value is provided during the function invocation.
8080

8181
There are two tricky things that can confuse you with default values. The first is that the default
8282
value is determined at the time that the function is defined, not at the time that it is invoked. So
@@ -96,7 +96,7 @@ value 7 when f is invoked without specifying a value for z.
9696

9797
The second tricky thing is that if the default value is set to a mutable object, such as a list or a dictionary,
9898
that object will be shared in all invocations of the function. This can get very confusing, so I suggest that you
99-
never set a default value that is a mutable object. For example, follow the exceution of this one carefully.
99+
never set a default value that is a mutable object. For example, follow the execution of this one carefully.
100100

101101
.. codelens:: opt_params_4
102102
:python: py3

_sources/Dictionaries/AccumulatingtheBestKey.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ but you'll learn more if you try to write it yourself first.
7272
:autograde: unittest
7373
:practice: T
7474

75-
**1.** Create a dictionary called ``d`` that keeps track of all the characters in the string ``placement`` and notes how many times each character was seen. Then, find the key with the lowest value in this dictionary and assign that key to ``min_value``.
75+
**1.** Create a dictionary called ``d`` that keeps track of all the characters in the string ``placement`` and notes how many times each character was seen. Then, find the key with the lowest value in this dictionary and assign that key to ``key_with_min_value``.
7676
~~~~
7777
placement = "Beaches are cool places to visit in spring however the Mackinaw Bridge is near. Most people visit Mackinaw later since the island is a cool place to explore."
7878

@@ -86,7 +86,7 @@ but you'll learn more if you try to write it yourself first.
8686
self.assertEqual(sorted(d.keys()), sorted(['B', 'e', 'a', 'c', 'h', 's', ' ', 'r', 'o', 'l', 'p', 't', 'v', 'i', 'n', 'g', 'w', 'M', 'k', 'd', '.', 'x']), "Testing the keys were created correctly")
8787
self.assertEqual(sorted(d.values()), sorted([2, 17, 12, 8, 4, 10, 27, 7, 10, 8, 6, 8, 3, 13, 7, 2, 3, 3, 2, 2, 2, 1]), "Testing the values were created correctly")
8888
def testTwo(self):
89-
self.assertEqual(min_value, "x", "Testing that min_value has been correctly assigned")
89+
self.assertEqual(key_with_min_value, "x", "Testing that key_with_min_value has been correctly assigned")
9090

9191
myTests().main()
9292

@@ -95,7 +95,7 @@ but you'll learn more if you try to write it yourself first.
9595
:autograde: unittest
9696
:practice: T
9797

98-
**5.** Create a dictionary called ``lett_d`` that keeps track of all of the characters in the string ``product`` and notes how many times each character was seen. Then, find the key with the highest value in this dictionary and assign that key to ``max_value``.
98+
**5.** Create a dictionary called ``lett_d`` that keeps track of all of the characters in the string ``product`` and notes how many times each character was seen. Then, find the key with the highest value in this dictionary and assign that key to ``key_with_max_value``.
9999
~~~~
100100
product = "iphone and android phones"
101101

@@ -108,6 +108,6 @@ but you'll learn more if you try to write it yourself first.
108108
def testOne(self):
109109
self.assertEqual(sorted(lett_d.items()), sorted([('h', 2), ('a', 2), (' ', 3), ('n', 4), ('d', 3), ('o', 3), ('i', 2), ('p', 2), ('e', 2), ('r', 1), ('s', 1)]), "Testing that lett_d has been created correctly.")
110110
def testTwo(self):
111-
self.assertEqual(max_value, "n", "Testing that max_value has been correctly assigned")
111+
self.assertEqual(key_with_max_value, "n", "Testing that key_with_max_value has been correctly assigned")
112112

113113
myTests().main()

_sources/Dictionaries/ChapterAssessment.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ Assessment - Dictionaries
173173
:practice: T
174174
:topics: Dictionaries/intro-Dictionaries
175175

176-
Provided is a dictionary called ``US_medals`` which has the first 70 metals that the United States has won in 2016, and in which category they have won it in. Using dictionary mechanics, assign the value of the key ``"Fencing"`` to a variable ``fencing_value``. Remember, do not hard code this.
176+
Provided is a dictionary called ``US_medals`` which has the first 70 medals that the United States has won in 2016, and in which category they have won it in. Using dictionary mechanics, assign the value of the key ``"Fencing"`` to a variable ``fencing_value``. Remember, do not hard code this.
177177
~~~~
178178
US_medals = {"Swimming": 33, "Gymnastics": 6, "Track & Field": 6, "Tennis": 3, "Judo": 2, "Rowing": 2, "Shooting": 3, "Cycling - Road": 1, "Fencing": 4, "Diving": 2, "Archery": 2, "Cycling - Track": 1, "Equestrian": 2, "Golf": 1, "Weightlifting": 1}
179179

_sources/Dictionaries/Dictionarymethods.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ a key, ``get`` returns 0 (instead of None).
245245
:autograde: unittest
246246
:practice: T
247247

248-
**5.** We have a dictionary of the specific events that Italy has won medals in and the number of medals they have won for each event. Assign to the variable ``events`` a list of the keys from the dictionary ``medal_events``. Do not hard code this.
248+
**5.** We have a dictionary of the specific events that Italy has won medals in and the number of medals they have won for each event. Assign to the variable ``events`` a list of the keys from the dictionary ``medal_events``. Use a dictionary method and cast to a list; do not hard code or accumulate a list via iteration.
249249

250250
~~~~
251251
medal_events = {'Shooting': 7, 'Fencing': 4, 'Judo': 2, 'Swimming': 3, 'Diving': 2}
@@ -259,7 +259,7 @@ a key, ``get`` returns 0 (instead of None).
259259
def testOne(self):
260260
self.assertEqual(type(events), list, "Testing that events is a list")
261261
self.assertEqual(sorted(events), sorted(medal_events), "Testing that events was created correctly")
262-
self.assertNotIn('[', self.getEditorText(), "No hard coding")
262+
self.assertNotIn('[', self.getEditorText(), "Hard coding or accumulation detected; use a dictionary method instead")
263263

264264
myTests().main()
265265

_sources/Dictionaries/intro-Dictionaries.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ The key ``'two'`` yields the value ``'dos'``. The key ``one`` yields the value `
130130
:autograde: unittest
131131
:practice: T
132132

133-
**4.** You are keeping track of olympic medals for Italy in the 2016 Rio Summer Olympics! At the moment, Italy has 7 gold medals, 8 silver metals, and 6 bronze medals. Create a dictionary called ``olympics`` where the keys are the types of medals, and the values are the number of that type of medals that Italy has won so far.
133+
**4.** You are keeping track of olympic medals for Italy in the 2016 Rio Summer Olympics! At the moment, Italy has 7 gold medals, 8 silver medals, and 6 bronze medals. Create a dictionary called ``olympics`` where the keys are the types of medals, and the values are the number of that type of medals that Italy has won so far.
134134
~~~~
135135

136136
=====

_sources/Files/Iteratingoverlinesinafile.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,21 @@ file as a string of characters. The general pattern for processing each line of
3333
statement2
3434
...
3535

36-
To process all of our olypmics data, we will use a *for* loop to iterate over the lines of the file. Using
36+
To process all of our olympics data, we will use a *for* loop to iterate over the lines of the file. Using
3737
the ``split`` method, we can break each line into a list containing all the fields of interest about the
3838
athlete. We can then take the values corresponding to name, team and event to
3939
construct a simple sentence.
4040

4141
.. activecode:: ac9_5_1
4242
:nocodelens:
4343

44-
olypmicsfile = open("olypmics.txt", "r")
44+
olympicsfile = open("olympics.txt", "r")
4545

46-
for aline in olypmicsfile.readlines():
46+
for aline in olympicsfile.readlines():
4747
values = aline.split(",")
4848
print(values[0], "is from", values[3], "and is on the roster for", values[4])
4949

50-
olypmicsfile.close()
50+
olympicsfile.close()
5151

5252
To make the code a little simpler, and to allow for more efficient processing, Python provides a built-in way to
5353
iterate through the contents of a file one line at a time, without first reading them all into a list. Some students find this confusing initially, so we don't recommend doing it this way, until you get a
@@ -57,17 +57,17 @@ to read it. And when you start dealing with big files, you may notice the effici
5757
.. activecode:: ac9_5_2
5858
:nocodelens:
5959

60-
olypmicsfile = open("olypmics.txt", "r")
60+
olympicsfile = open("olympics.txt", "r")
6161

62-
for aline in olypmicsfile:
62+
for aline in olympicsfile:
6363
values = aline.split(",")
6464
print(values[0], "is from", values[3], "and is on the roster for", values[4])
6565

66-
olypmicsfile.close()
66+
olympicsfile.close()
6767

6868
.. raw:: html
6969

70-
<pre hidden id="olypmics.txt">
70+
<pre hidden id="olympics.txt">
7171
Name,Sex,Age,Team,Event,Medal
7272
A Dijiang,M,24,China,Basketball,NA
7373
A Lamusi,M,23,China,Judo,NA
@@ -127,6 +127,6 @@ to read it. And when you start dealing with big files, you may notice the effici
127127

128128
def testOne(self):
129129
self.assertEqual(num_lines, 7, "Testing that num_lines was assigned to the correct value.")
130-
self.assertNotIn('len', self.getEditorText(), "Testing your code (Don't worry about actual and expected values).")
130+
self.assertNotIn('len', self.getEditorText(), "Checking that you didn't use the len function.")
131131

132132
myTests().main()

_sources/Files/ReadingCSVFiles.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Once we have parsed the lines into their separate values, we can use those value
4646

4747
Note that the trick of splitting the text for each row based on the presence of commas only works because commas are not used in any of the field values. Suppose that some of our events were more specific, and used commas. For example, "Swimming, 100M Freestyle". How will a program processing a .csv file know when a comma is separating columns, and when it is just part of the text string giving a value within a column?
4848

49-
The CSV format is actually a little more general than we have described and has a couple of solutions for that problem. One alternative format uses a different column separator, such as | or a tab (\t). Sometimes, when a tab is used, the format is called tsv, for tab-separated values). If you get a file using a different separator, you can just call the ``.split('|')`` or ``.split('\\t')``.
49+
The CSV format is actually a little more general than we have described and has a couple of solutions for that problem. One alternative format uses a different column separator, such as | or a tab (\\t). Sometimes, when a tab is used, the format is called tsv, for tab-separated values). If you get a file using a different separator, you can just call the ``.split('|')`` or ``.split('\t')``.
5050

5151
The other advanced CSV format uses commas to separate but encloses all values in double quotes.
5252

_sources/Functions/Functionscancallotherfunctions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Also notice that when ``square`` is called (at Step 8, for example), there are t
5858
``square`` and one for ``sum_of_squares``. Each group of local variables is called a **stack frame**. The variables
5959
``x``, and ``y`` are local variables in both functions. These are completely different variables, even though they
6060
have the same name. Each function invocation creates a new frame, and variables are looked up in that frame. Notice
61-
that at step 9, y has the value 25 is one frame and 2 in the other.
61+
that at step 11 of the execution, y has the value 25 in one frame and 2 in the other.
6262

6363
What happens when you to refer to variable y on line 3? Python looks up the value of y in the stack frame for the
6464
``square`` function. If it didn't find it there, it would go look in the global frame.

0 commit comments

Comments
 (0)