Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
300884b
olypmics --> olympics and better feedback on test case
presnick Apr 29, 2023
aa1e21b
fixed escaping of \t tab character in text
presnick Apr 29, 2023
71235d2
improve exercise instructions
presnick Apr 30, 2023
4e9fed9
metals --> medals
presnick Apr 30, 2023
a81ba47
change variable name to make goal of exercise clearer
presnick Apr 30, 2023
ae215b1
corrected text; step 9 --> 11
presnick Apr 30, 2023
329d44c
deleted stop_at_four exercise; poorly worded and risk of infinite loo…
presnick Apr 30, 2023
0c090e3
remove spurious print that doesn't print out until end of while loop …
presnick Apr 30, 2023
ce90eb1
move infinite loop to CodeLens so students can see execution instead …
presnick Apr 30, 2023
4869923
allow for loop instead of while loop in challenge problem
presnick Apr 30, 2023
28e1b42
update the introduction of base 64 and reference to New Math
presnick Apr 30, 2023
7578589
small fixes to exposition in optional parameters
presnick Apr 30, 2023
aeaef62
clarify wording of ac15_2_4
presnick Apr 30, 2023
7407991
replaced exercise on invoking functions with optional and keyword params
presnick Apr 30, 2023
2273ecc
small wording fix
presnick May 1, 2023
bf91ba9
fix one typo
presnick May 1, 2023
a1a6404
expand type annotations
presnick May 23, 2023
d070dbc
Improvements to TestCases chapter
presnick May 23, 2023
7062066
add destination for internal rst link
presnick May 27, 2023
0eb8a04
Merge remote-tracking branch 'upstream/master' into textbook_updates_…
presnick May 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions _sources/AdvancedFunctions/ChapterAssessment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,27 +136,17 @@ Chapter Assessment
:autograde: unittest
:practice: T

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.
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
~~~~
def checkingIfIn(a, direction = True, d = {'apple': 2, 'pear': 1, 'fruit': 19, 'orange': 5, 'banana': 3, 'grapes': 2, 'watermelon': 7}):
if direction == True:
if a in d:
return d[a]
else:
return False
else:
if a not in d:
return True
else:
return d[a]
def f(x, y = 3, z = 7):
return ("{} {} {}".format(x, y, z))

# Call the function so that it returns False and assign that function call to the variable c_false

# Call the fucntion so that it returns True and assign it to the variable c_true

# Call the function so that the value of fruit is assigned to the variable fruit_ans

# Call the function using the first and third parameter so that the value 8 is assigned to the variable param_check
# fill in just one parameter value to make val1 have the value "Hi 3 7"
val1 = f()
# fill in two parameter values to make val2 have the value "Hi Hi 7"
val2 = f()
# fill in two parameters to make vale have the value "Hi 3 Hi"
val3 = f()

=====

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

def testOne(self):
self.assertEqual(c_false, False, "Testing that c_false has the correct value")
self.assertEqual(val1, "Hi 3 7", "Testing that val1 has the correct value")
def testTwo(self):
self.assertEqual(c_true, True, "Testing that c_true has the correct value")
self.assertEqual(val2, "Hi Hi 7", "Testing that val2 has the correct value")
def testThree(self):
self.assertEqual(fruit_ans, 19, "Testing that fruit_ans has the correct value")
def testFour(self):
self.assertEqual(param_check, 8, "Testing that param_check has the correct value")

self.assertEqual(val3, "Hi 3 Hi", "Testing that val3 has the correct value")
### would be good to define additional tests that check to make sure student is only suppplying minimum number of parameter values


myTests().main()
2 changes: 1 addition & 1 deletion _sources/AdvancedFunctions/KeywordParameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ For example,
:autograde: unittest
:practice: T

**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.
**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.
~~~~
def waste(var = "Water", mar, marble = "type"):
final_string = var + " " + marble + " " + mar
Expand Down
22 changes: 11 additions & 11 deletions _sources/AdvancedFunctions/OptionalParameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ call in on a string, ``int("100")``, the return value will be the integer 100.

That's the most common way programmers want to convert strings to integers. Sometimes, however, they
are working with numbers in some other "base" rather than base 10. For example, in base 8, the rightmost
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).
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).

.. note:: New Math

Some math educators believe that elementary school students will get a much deeper understanding
of the place-value system, and set a foundation for learning algebra later, if they learn to do
arithmetic not only in base-10 but also in base-8 and other bases. This was part of a movement
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
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>`_.

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

.. note:: Tom Lehrer's New Math

Some math educators believe that elementary school students will get a much deeper understanding
of the place-value system, and set a foundation for learning algebra later, if they learn to do
arithmetic not only in base-10 but also in base-8 and other bases. This was part of a movement
called "The New Math", though it's not so new now (I had it when I was in elementary school!) Tom
Lehrer made a really funny song about it, and it's set with visuals in several YouTube renditions
now. Try this very nice `lip-synched version <http://www.youtube.com/watch?v=DfCJgC2zezw>`_.

When defining a function, you can specify a default value for a parameter. That parameter then becomes an
optional parameter when the function is called. The way to specify a default value is with an assignment
statement inside the parameter list. Consider the following code, for example.
Expand All @@ -76,7 +76,7 @@ specify a value for z without specifying a value for y.

.. note::

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.
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.

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

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

.. codelens:: opt_params_4
:python: py3
Expand Down
8 changes: 4 additions & 4 deletions _sources/Dictionaries/AccumulatingtheBestKey.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ but you'll learn more if you try to write it yourself first.
:autograde: unittest
:practice: T

**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``.
**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``.
~~~~
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."

Expand All @@ -86,7 +86,7 @@ but you'll learn more if you try to write it yourself first.
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")
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")
def testTwo(self):
self.assertEqual(min_value, "x", "Testing that min_value has been correctly assigned")
self.assertEqual(key_with_min_value, "x", "Testing that key_with_min_value has been correctly assigned")

myTests().main()

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

**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``.
**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``.
~~~~
product = "iphone and android phones"

Expand All @@ -108,6 +108,6 @@ but you'll learn more if you try to write it yourself first.
def testOne(self):
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.")
def testTwo(self):
self.assertEqual(max_value, "n", "Testing that max_value has been correctly assigned")
self.assertEqual(key_with_max_value, "n", "Testing that key_with_max_value has been correctly assigned")

myTests().main()
2 changes: 1 addition & 1 deletion _sources/Dictionaries/ChapterAssessment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Assessment - Dictionaries
:practice: T
:topics: Dictionaries/intro-Dictionaries

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.
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.
~~~~
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}

Expand Down
4 changes: 2 additions & 2 deletions _sources/Dictionaries/Dictionarymethods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ a key, ``get`` returns 0 (instead of None).
:autograde: unittest
:practice: T

**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.
**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.

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

myTests().main()

Expand Down
2 changes: 1 addition & 1 deletion _sources/Dictionaries/intro-Dictionaries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ The key ``'two'`` yields the value ``'dos'``. The key ``one`` yields the value `
:autograde: unittest
:practice: T

**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.
**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.
~~~~

=====
Expand Down
18 changes: 9 additions & 9 deletions _sources/Files/Iteratingoverlinesinafile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ file as a string of characters. The general pattern for processing each line of
statement2
...

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

.. activecode:: ac9_5_1
:nocodelens:

olypmicsfile = open("olypmics.txt", "r")
olympicsfile = open("olympics.txt", "r")

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

olypmicsfile.close()
olympicsfile.close()

To make the code a little simpler, and to allow for more efficient processing, Python provides a built-in way to
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
Expand All @@ -57,17 +57,17 @@ to read it. And when you start dealing with big files, you may notice the effici
.. activecode:: ac9_5_2
:nocodelens:

olypmicsfile = open("olypmics.txt", "r")
olympicsfile = open("olympics.txt", "r")

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

olypmicsfile.close()
olympicsfile.close()

.. raw:: html

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

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

myTests().main()
2 changes: 1 addition & 1 deletion _sources/Files/ReadingCSVFiles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Once we have parsed the lines into their separate values, we can use those value

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?

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')``.
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')``.

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

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

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
``square`` function. If it didn't find it there, it would go look in the global frame.
Expand Down
Loading