Reputation: 673
I'm having some trouble solving the problem below (My thinking on how I might solve it is directly beneath the problem)
"In Robert McCloskey’s book Make Way for Ducklings, the names of the ducklings are Jack, Kack, Lack, Mack, Nack, Ouack, Pack, and Quack."
This loop outputs these names in order:
prefixes = 'JKLMNOPQ'
suffix = 'ack'
for letter in prefixes:
print letter + suffix
The output is:
Jack
Kack
Lack
Mack
Nack
Oack
Pack
Qack
Of course, that’s not quite right because “Ouack” and “Quack” are misspelled.
Exercise 8.2 Modify the program to fix this error."
So prefix + suffix yields 4 characters in its current form. Ouack and Quack are 5 characters. In the prior section, we used 'while' to transverse a string to create a condition where if the index is equal to the length of the string, the condition is false, and the body of the loop is not executed. I'm thinking I need to modify the for loop so that if the output character count is less than the original string value inputted, it adds the letter 'U'. How do I go about relating the length of the string value inputted for each name and the 'prefixes'?
I'm not sure how I'd go about doing this, or if I should persue a different strategy.
I apologize in advance I've butchered any of the terminology, I'm two days into this book, and I have no prior computer science background.
Upvotes: 2
Views: 10477
Reputation: 13
Same as other answers here, going through the book, solved it then came here to compare answers. My solution is to only change the prefixes to a list and no other changes:
prefixes = ["J", "K", "L", "M", "N", "Ou", "P", "Qu"] #originally "JKLMNOPQ"
suffix = "ack"
for letter in prefixes:
print(letter + suffix)
Upvotes: 0
Reputation: 71
prefixes = "JKLMNOPQ"
suffix = "ack"
for l in prefixes:
if l == "Q" or l == "O":
print(l + "u" + suffix)
else:
print(l + suffix)
Try this!
Upvotes: 0
Reputation: 11
I just came across this question myself, and then checked the web to see how others did. Mine looked like this:
prefixes = "JKLMNOPQ"
prefixes = list(prefixes)
prefixes[5] = "Ou"
prefixes[7] = "Qu"
suffix = "ack"
for p in prefixes:
print(p + suffix)
Upvotes: 1
Reputation: 1
It works but other code using if
looks nicer:
prefixes = 'JKLMNP'
prefixess = 'OQ'
suffix = 'ack'
for letter in prefixes:
print(letter + suffix)
for letter in prefixess:
print (letter + 'u' + suffix)
Upvotes: 0
Reputation: 31
I just did this exercise and came here to see how others did it. In my 2nd edition this was part of a chapter on indexing and the string module, so I used them heavily in my nutso solution. Basically I added the "u"s to the prefix string and wrote an if statement to check for lowercase in the string.
import string
def ducks():
prefixes = "JKLMNOuPQu"
suffix = "ack"
index = 0
while index < len(prefixes)-1:
if prefixes[index+1] in string.lowercase:
prefix = prefixes[index:index+2]
print prefix + suffix
index += 1
elif prefixes[index] in string.lowercase:
index += 1
else:
prefix = prefixes[index]
print prefix + suffix
index +=1
Upvotes: 3
Reputation: 1097
suffix = 'ack'
prefixes = list('JKLMNP')
prefixes += ['Qu', 'Ou']
prefixes.sort()
for prefix in prefixes:
print prefix + suffix
Upvotes: 1
Reputation: 5599
My solution would be:
prefixes = list('JKLMNP')
prefixes.extend(['Ou', 'Qu'])
suffix = 'ack'
for pref in prefixes:
print pref + suffix
It is compact and contains very few modifications of the original.
Upvotes: 4
Reputation: 2668
I prefer the Gordian Knot approach:
print '\n'.join(['Jack', 'Kack', 'Lack', 'Mack', 'Nack', 'Ouack', 'Pack', 'Quack'])
Strictly speaking, that's just a (somewhat radical) modification.
Stuff that, Perl guy.
All kidding aside, you could do it as the others have mentioned by special casing the "O" and "Q". A (very) slightly more general approach is to think of the extra vowels not as a special case but rather as the only "visible" members of a general case:
suffixes = ['ack'] * 8
prefixes = 'JKLMNOPQ'
infixes = ',,,,,u,,u'.split(',')
The split of the infixes string returns empty strings surrounding the consecutive commas, so the 'u's are the only non-empty elements and they fall in the right places for the final result.
This makes three iterables (think lists, but strings count too) where all of the parts are lined up in the correct slots. This is enough of a shift that you can trade the old loop for a zip, which is probably not the intent of the exercise but is still a pythonic technique. Now you just need to run a zipper down the three, which is what the zip function is for, of course.
The only wrinkle is that zip gives you a out a list of string pairs and we want whole strings, which is what a ''.join is for. They are processed by a list comprehension, which you will definitely want to learn if you don't already know:
result = [''.join(pair) for pair in zip(infixes, suffixes)]
result = [''.join(pair) for pair in zip(prefixes, result)]
All that is left is to print:
print '\n'.join(result)
To paraphrase a great man, my disclaimer: In theory, I can prove the correctness of this code, but I have not run it, so there may be bugs.
Upvotes: 1
Reputation: 3897
Being a Perl guy I couldn't help but give you a shorter solution than everyone else's :p
prefixes = 'JKLMNOPQ'
suffix = 'ack'
for letter in prefixes:
if letter in ('O','Q'):
letter+="u"
print letter+suffix
PS: I take it that the exercise was to modify the given code rather than to revamp it, otherwise there are ways of shrinking it further, within the confines of PEP8 that is:)
Upvotes: 1
Reputation: 123473
I like data-driven code:
endings = ['ack', 'uack']
specials = ['O','Q']
prefixes = 'JKLMNOPQ'
suffixes = dict(zip(prefixes, [endings[p in specials] for p in prefixes]))
for letter in prefixes:
print letter + suffixes[letter]
Upvotes: 1
Reputation: 131677
>>> for letter in prefixes:
if letter in ('O', 'Q'): # if the letter is O or Q
print letter + 'u' + suffix
else:
print letter + suffix
Jack
Kack
Lack
Mack
Nack
Ouack
Pack
Quack
Upvotes: 6
Reputation: 599620
I think you're overthinking this. You just need to check within the loop if the current letter is O or Q, and if so add a U.
Upvotes: 2