-
There are two problems with contrived examples. The first is code that the students can't understand because it simply makes no sense. The second is most of these contrived examples are badly written Python. We want to show the students well written Python only. I would even go so far as to say if you can't think of a well written Python example maybe you should skip what you want to show them entirely. Showing the students how to traverse a list using In Unit 4 lesson 2 we show them this code: for i in range(len(numbers)):
numbers[i] = numbers[i] * 2 The correct way to do that is this: doubled_numbers = [n * 2 for n in numbers] We also show them this code: def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i + 1
j = j - 1
return True
print(is_reverse('pots', 'stop')) The correct way to do that is this: def is_reverse(word_a, word_b):
return word_a == word_b[::-1]
print(is_reverse('pots', 'stop')) Here are my new examples. I am going to show 4. One each for the major traversals (map, filter, reduce) and one for using range. Traversing a list to transform it. (map) def strings(list):
all_strings = []
for item in list:
all_strings.append(str(item))
return all_strings Traversing a list to summarize the items. (reduce) def sum(numbers):
"""Return a total of the numbers"""
total = 0
for number in numbers:
total = total + number
return total Using a traversal to filter a list. (filter) def only_primes(numbers):
"""Return a list of the primes in the numbers list"""
primes = []
for n in numbers:
if is_prime(n):
primes.append(n)
return primes Using range() to generate a list for traversal. def is_prime(n):
for divisor in range(2, n):
if n % divisor == 0:
return False
return True |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Well... this post might open up some interesting philosophical discussions. I'm not sure anyone is playing the part of high-level architect for this course, who could give an official ruling on whether all of these replacements are a good idea or not. But on a first reading -- and without reading through the entire set of lessons up to Unit 4 again -- I'd be fairly worried that showing these technically "correct" ways of doing things at this point in the course would be more confusing than helpful. I taught from the 2nd-semester course material last year, and as I went along I tried to repair the things that really made no sense at all, or absolutely didn't work. (There were quite a few broken code snippets in the PowerPoint presentations, but not nearly as many in the HTML notes.) But I was very careful not to touch code like the above examples that was written in a sub-optimal way, since it was often written that way very deliberately -- because the key concepts that would allow a rewrite hadn't been introduced yet. In other words, some of these examples don't look like "badly written Python" to me -- they're just "Python written with reduced syntax options". The course design, as far as I understood it -- it made a little more sense once I'd gotten through the whole thing -- was to be very careful to avoid throwing too much syntax at students all at once. There was even a point where Booleans were introduced before "if" statements... not sure how successful that particular decision was, but it was deliberately done and it made for a consistent step-by-step flow through the concepts. So I really don't have any quarrel with
at this point in the course -- because that's the only syntax for the "for" command that they've been introduced to up to this point. At least in my experience, while it would be easy to show students a code example like
and say that that's "the correct way", it would then be really painful to get students to generate new code similar to that as an answer to a homework assignment. It doesn't line up with what they've experienced so far, either in Snap! or in previous units' use of for loops. So they would put in parentheses instead of square brackets, or try to put the "for" keyword first, or try to call pluralize() first and then return the results -- and when you're done explaining all those "mistakes", they won't necessarily understand why "the correct way" works. If you instead break down the problem and solve it using the tools that the course has provided to students so far, you get something along the lines of the lab solution. Also, if the lab spec says that the function is supposed to modify the list of words, then returning a new list is not a solution at all, because it doesn't follow the spec. I actually think it's much more important to emphasize that solutions should precisely match the spec, than to emphasize using "correct Python" no matter what. It's certainly possible to change the spec along with the solution -- but my sense is that if you really want students to be able to use list comprehensions to solve Unit 4 labs, you will really have to rewrite the whole course. Somewhat similarly,
might be acceptable if that specific slice syntax has been covered thoroughly back in Unit 2, so that students can look at "[::-1]" and recognize immediately that that means "reverse word_b". I don't recall that Unit 2 got quite that far with slice syntax -- this is only an introductory course, and there just isn't time to give students a thorough grounding in every possible syntax detail. I think the key idea of the course's current design is that after students have gone through the effort of writing some working code using limited-syntax Python, they'll be much more prepared to understand and appreciate the "syntactic sugar" available from list comprehensions, advanced slicing, and so on. |
Beta Was this translation helpful? Give feedback.
-
I think I didn't explain that idea well. In your example match means the same thing. Let's say you have a text monster game and on one floor I disagree with your statement "a decent example of the use of a for loop to iterate through a string". I am planning on skipping that slide as there is no reason to debug it because it shouldn't even exist. (I am moving Zork to Unit 6.) Changing what is in a room doesn't change the meaning of the variable. It is still the room contents. I suppose that is an exception that I don't mind because the side affect can be clearly labeled in the function name and is expected. The Principle of Least Astonishment may apply here. Here is my version of the slide show. https://docs.google.com/presentation/d/1z4Z__2BsOlwLVtnZQHf379zJ_K2VYl-C_DRYZVIo-xc/edit?usp=sharing |
Beta Was this translation helpful? Give feedback.
-
I ended up replacing 4.04 with list comprehensions as described here #370 List comprehensions are important. |
Beta Was this translation helpful? Give feedback.
I think I didn't explain that idea well. In your example match means the same thing. Let's say you have a text monster game and on one floor
match
is True if you have a match to light your lantern. On another floormatch
is used to tell if you won your boxing match with a goblin. The difference isn't in which boolean it holds, but rather the meaning. Doubling all the numbers is a transformation of that list into something else. It needs a different name because it isn't the same list anymore.I disagree with your statement "a decent example of the use of a for loop to iterate through a string". I am planning on skipping that slide as there is no reason to debug it because it shouldn't eve…