### Thread: Learning python: question strings

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
10
Rep Power
0

#### Learning python: question strings

Hey all,

I'm reading the book "Think Python" to learn Python.
I'm at chapter 8 and I'm stuck.
Could someone explain this to me.

The exercise:
[CODE=exercise]The following example shows how to use concatenation (string addition) and a for loop to generate an abecedarian series (that is, in alphabetical order). 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.[/CODE]

My solution is this:
[CODE=solution]prefixes = 'JKLMNOPQ'
suffix = 'ack'
suffix2 = 'auck'
a = 0

while a < len(prefixes):
for letter in prefixes:
if letter == "O" or "Q":
print(letter + suffix2)
a = a + 1
else:
print(letter + suffix)
a = a + 1[/CODE]

This will result to this:
[CODE=result]Jauck
Kauck
Lauck
Mauck
Nauck
Oauck
Pauck
Qauck[/CODE]

I cant find what is rong and why he always prints "auck". Could someone explain what I'm doing wrong and how I could fix this?

I'm using Idle 3.3.0
Mac OS X Snow Leopard

Thank you very much!

Greetings,
Rhaiko
2. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Feb 2013
Posts
138
Rep Power
6
Here is the problem:

Code:
`if letter == "O" or "Q":`
This evaluates to:
Code:
`if (letter == "0") or ("Q"):`
And since "Q" is non-False, the if-statement above will always evaluate to True.

Since you're learning python, I will leave it to you to figure out the solution.

(Also, when I run your program I get 65 rows of output...)
3. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
10
Rep Power
0
Hey partoj,

I dont know why you get 65 rows of output because I only get 8...

When I use your script I get the same problem. But what I do saw was that if I use this script

[CODE=script2]while a < len(prefixes):
for letter in prefixes:
if (letter == "O"):
print(letter + suffix2)
a = a + 1
else:
print(letter + suffix)
a = a + 1[/CODE]
I get this
[CODE=result]Jack
Kack
Lack
Mack
Nack
Oauck
Pack
Qack[/CODE]

So the problem is the
or ("Q"):

Now I can do this:
[CODE=workingprogram]while a < len(prefixes):
for letter in prefixes:
if (letter == "O"):
print(letter + suffix2)
a = a + 1
elif (letter == "Q"):
print(letter + suffix2)
a = a + 1
else:
print(letter + suffix)
a = a + 1[/CODE]

But I thought I could use the or function.
Could you explain this to me?

Thank you very much.

Greetings,
Rhaiko
4. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Aug 2011
Posts
139
Rep Power
7

#### 0 OR'd with 1

In your 'if' statement, even if letter is unequal to 'O', the 'Q' is always evaluated as a true, or 1. so it is always 0 OR'd with 1. which is always 1, or true.

try: if letter == 'O' or letter == 'Q'

also, you could do without the 'while' statement and the 'a=a+1's, and the a=0.

also, shouldn't suffix2 = 'uack' ?

• Rhaiko agrees : This is what I was searching for, thanks
5. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
10
Rep Power
0
Hey WynnDeezl,

i see and understand it now.
Thank you very much!

And yes, suffix2 has to be uack. I made a typo there :P

Greetings,
Rhaiko
6. 0) how to refactor. a = a+1 always happens. Write the code so it's obvious.
Code:
```while a < len(prefixes):
letter = prefixes[a]
if (letter == "O"):
print(letter + suffix2)
elif (letter == "Q"):
print(letter + suffix2)
else:
print(letter + suffix)
a += 1```
1) how to use or operator:
if (letter == "O") or (letter == 'Q'):

2) how to use in operator:
if (letter in "OQ"):

3) refactoring yet again:
Code:
```suffixes = 'ack uack'.split()

leading_letter = ['{:c}'.format(c) for c in range(ord('J'),ord('Q')+1)]

print(letter + suffixes[letter in 'OQ'])```
7. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
10
Rep Power
0
Hey b49P23TIvg,

Thanks for the explaining.
I understand what you do with option 0, 1 and 2. It helped a lot!
I only dont understand point 3. But this is because I'm now that far yet (just starting). But I saved it so I could look at it back later when I'm done reading my first python book.

Greetings,
Rhaiko
8. print('\n'.join(c+('ack','uack')[c in'OQ']for c in'JKLMNOPQ'))

That's as short as I can write this today.
And in j (www.jsoftware.com) seeking short:

('ack',~(,'u'{.~e.&'OQ'))"0'JKLMNOPQ'

"append 'ack' to a string formed by letter followed by 'u' if the character is a member of 'OQ'"

, concatenates
e. tests membership
~ swaps arguments.

These verbs not arbitrarily named, they are easy to remember.

I admit the data flow takes some study, however, you'll find that forks work like you'd see in algebra,
(f + g)(x) means f(x) + g(x)
in j the operator (f + g) is written
(f + g)
j extends the notion to dyadic forks
x (f+g) y