loop iterations ignore spaces?

This is the place for queries that don't fit in any of the other categories.

loop iterations ignore spaces?

Postby Hypernova » Sat Jun 29, 2013 6:31 pm

Here's another problem for you helpful fellows;

My code takes a string that's been simply encrypted using an alphabetic character shift method, decodes it, and outputs the line in it's original form. So if the shift was -2, "d" would be "b" etc. Problem is when I use a forloop, it skips any spaces in a string. I need to output the code with the spaces, and splitting the string to keep the words separate seems like a really complicated way of doing it. Any hints? Thanks plenty in advance :)

here's my inadequate code with a forloop, at the moment;

Code: Select all
code= input()
s=1
def decode(code,s):
   a=""
   for i in range (len(code)):
      a+= chr(ord(code[i])-s)
   return a
print(decode(code,s))
Hypernova
 
Posts: 18
Joined: Mon Jun 10, 2013 12:23 am

Re: loop iterations ignore spaces?

Postby micseydel » Sat Jun 29, 2013 6:41 pm

If I were you, I'd switch to a regular for loop instead of one over the indexes
Code: Select all
for char in code:
    if char == ' ':
        continue
    #if we haven't continued, we can shift after this


Also, it's probably a good idea to create a list and then use str.join() on it rather than string concatenation in the for loop. Also, you code could shift letters into non-letter ASCII characters. Is this intentional? If not, you might want to look into str.translate() and string.maketrans().
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1262
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: loop iterations ignore spaces?

Postby Hypernova » Sat Jun 29, 2013 8:42 pm

micseydel wrote:If I were you, I'd switch to a regular for loop instead of one over the indexes
Code: Select all
for char in code:
    if char == ' ':
        continue
    #if we haven't continued, we can shift after this


Also, it's probably a good idea to create a list and then use str.join() on it rather than string concatenation in the for loop. Also, you code could shift letters into non-letter ASCII characters. Is this intentional? If not, you might want to look into str.translate() and string.maketrans().


I was actually using that type of loop initially, but I changed it to the index loop to see if that would stop it from skipping spaces, which it didn't, so I'll change it back as you suggest. Shifting to non-ASCII letters wasn't intentional, it's just something I hadn't got to addressing yet because the space skipping seems like it should be my first priority. I'll look into those methods too, but I want to code with my basic knowledge first before increasing my language "vocabulary" further just so there's more problems and things on which to practice on in the meantime.

I just fiddled about with it some more, and it seems my loop was ignoring spaces because whatever chr(ord(" ")-1) is, it returns as a stripping of the space. When I wrote chr(ord(" ")+1), it returned "!", so at least I understand what was going on there (and the length of the string remains the same).

So with the if condition, I can add that space to the string either by writing a str.join() or by concatenation before the continue statement, right?

Thanks tonnes for your input micseydel.
Hypernova
 
Posts: 18
Joined: Mon Jun 10, 2013 12:23 am

Re: loop iterations ignore spaces?

Postby ochichinyezaboombwa » Sun Jun 30, 2013 7:48 pm

Your loop was not ignoring spaces or anything: how could it without the if?!? (or without filter() or list comprehension, but that's a longer story).

It looked to you as spaces are skipped simply because chr(ord(" ")-1) is an invisible character (it is there for historical reasons mostly; search for "ascii table").

1) The usual idiom for filtering is something like this:
Code: Select all
for ch in smth:
    if cond1(ch): # add the ch itself to the result
    else: # add some_formula(ch) to the result

2) You can use string concatenation (as you do):
Code: Select all
def toupper1(s):
    r = ""
    for ch in s:
        r += ch.upper()
    return r

But it's considered a better technique to use list to obtain the same result:
Code: Select all
def toupper2(s):
    r = [] # list !
    for ch in s:
        r.append(ch.upper())
    return "".join(r) # join


This is (or at least should be) better for performance reasons.

3) what happens if the shift == 500? or -500?
What you probably (I am guessing but i bet I'm right that you are implementing a Caesar's cipher) need is:
a -> c, b -> d, ... , x -> z, y -> a, b -> c
right? Well your code doesn't do that.

Don't hesitate to ask more questions, but better don't rely just on us.
ochichinyezaboombwa
 
Posts: 200
Joined: Tue Jun 04, 2013 7:53 pm


Return to General Coding Help

Who is online

Users browsing this forum: Google [Bot] and 3 guests