List problems in C code ported to Python

Bengt Richter bokr at oz.net
Tue Jan 18 14:00:49 CET 2005


On Mon, 17 Jan 2005 15:28:56 GMT, Lucas Raab <pythongnome at hotmail.com> wrote:

>Lucas Raab wrote:
>> I'm done porting the C code, but now when running the script I 
>> continually run into problems with lists. I tried appending and 
>> extending the lists, but with no avail. Any help is much appreciated 
>> Please see both the Python and C code at 
>> http://home.earthlink.net/~lvraab. The two files are ENIGMA.C and engima.py
>> 
>> TIA
>
>OK, here's the Python code and the corresponding C code:
>
>def init_mach():
>	import string
>	#setup rotor data
>	i=1
>	j=0
>	for j in j<26, j+1:
I urge you to explore interactively. And do it line by line
(and even expression by expression when you get mystifying results) until you
are more familiar with the language.

E.g., what do you think the values of j will be here?
 >>> j=0
 >>> for j in j<26, j+1: print j,
 ...
 True 1

Surprised?

 >>> j<26, j+1
 (True, 2)

Hm, surprised at the 2 here?

 >>> j=0
 >>> j<26, j+1
 (True, 1)

IOW, your 'for' line was equivalent to iterating through a length-2 tuple
       for j in (True, 1):  # since if j is 0, j<26 is True, and j+1 is 1
What you probably wanted was j starting with 0 and ending with 25, which you get by

 >>> for j in xrange(26): print j,
 ...
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

(The comma at the end of the print statement is to get a space before
 the next output instead of a newline).
       
>		data[4],[j] = (ref_rotor[j] - 'A'+26) % 26
Had you tried an interactive experiment, you would have had some real questions to ask ;-)

 >>> j=0
 >>> for j in xrange(26):
 ...     data[4],[j] = (ref_rotor[j] - 'A'+26) % 26
 ...
 Traceback (most recent call last):
   File "<stdin>", line 2, in ?
 NameError: name 'ref_rotor' is not defined

Ok, fix that with something
 >>> ref_rotor = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'  # something legal
 >>> j=0
 >>> for j in xrange(26):
 ...     data[4],[j] = (ref_rotor[j] - 'A'+26) % 26
 ...
 Traceback (most recent call last):
   File "<stdin>", line 2, in ?
 TypeError: unsupported operand type(s) for -: 'str' and 'str'

You might have had to ask at this point what that meant, but you could get closer by
trying the expressions and their terms:

 >>> (ref_rotor[j] - 'A'+26) % 26
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for -: 'str' and 'str'

Pare it down

 >>> (ref_rotor[j] - 'A'+26)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for -: 'str' and 'str'

Check pieces
 >>> j
 0
 >>> ref_rotor[j]
 'A'

Substitute to make painfully clear

 >>> ('A' - 'A'+26)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for -: 'str' and 'str'
 >>> ('A' - 'A')
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for -: 'str' and 'str'

What is 'A' ?
 >>> type('A')
 <type 'str'>

Hm, characters are strings, not char types that are directly type compatible
with int. It takes a conversion. To get from single-char string to its integer code
and back:

 >>> ord('A')
 65
 >>> chr(65)
 'A'

Another experiment:

 >>> ord('AB')
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: ord() expected a character, but string of length 2 found


Now you are in a position to use ord, and get a little further:

 >>> j=0
 >>> for j in xrange(26):
 ...     data[4],[j] = (ord(ref_rotor[j]) - ord('A')+26) % 26
 ...
 Traceback (most recent call last):
   File "<stdin>", line 2, in ?
 TypeError: unpack non-sequence

Was the right hand side a problem?
 >>> j
 0
 >>> (ord(ref_rotor[j]) - ord('A')+26) % 26
 0

Apparently not, so what it was trying to do was

 >>> data[4],[j] = 0
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unpack non-sequence

What was it trying to unpack? And why?
Well, you might have known if you had been through the tutorial, but at least
you would have had a specific question about a specific error at this point.

Note:
 >>> a, b = 0
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unpack non-sequence

I.e., when you have commas (or even one) on the left hand side of an assignment,
that is asking python to unpack a sequence on the right hand side and assign to
corresponding items on the left. So e.g.,

 >>> a, b = 0, 1
will unpack the tuple formed by 0, 1
 >>> a
 0
 >>> b
 1
You can unpack any sequence of the same length, and strings happen to be sequences:

 >>> a,b = 'XY'
 >>> a
 'X'
 >>> b
 'Y'

Ok, enough of that. The comma was obviously a problem so, try it without:


 >>> data[4][j] = 0
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 NameError: name 'data' is not defined

I could go on, but IMO if you expect help, you should do your part, and at least
post code that you have tried and which compiles or runs up to the point where
it shows an error that you need help with.

And show a verbatim copy/paste from your interactive session, not uncompilable
and obviously totally untested stuff.

>		
>	for i in i<4, i+1:
>		step[i-1] = step_data[order[i-1]]
>		for j in j<26, j+1:
>			data[i],[j] = (rotor[order[i-1]],[j]-'A'+26)%26
>			data[8-i],[data[i],[j]] = j
>
>
>void
>init_mach( void )
>{
>   int i, j;
>   int ds;
>   int u, v;
>
>   /* setup rotor data */
>   for (j=0;j<26;j++)
>     data[4][j] = ((int)ref_rotor[j]-'A'+26)%26;
>
>   for (i=1;i<4;i++)
>     {
>       step[i-1] = step_data[order[i-1]];
>       for (j=0;j<26;j++)
>	{
>	  data[i][j] = ((int)(rotor[order[i-1]][j])-'A' + 26) % 26;
>	  data[8-i][data[i][j]] = j;
>	}
>     }
>
>Now, do I need to start boning up on lists and how to use them or am I 
>missing the bigger picture?? Again, for the complete code see 
>http://home.earthlink.net/~lvraab. I'm not asking you to do it for me, 
>just some pointers on going about this.

You are obviously not yet familiar with python, but a few hours with the
introduction and tutorials should help a lot. Then post something that
compiles. Or a snippet that does something you don't understand.

This is about all I have patience for this time. I really have other stuff to do.

Regards,
Bengt Richter



More information about the Python-list mailing list