Shaken_not_stirred.
Shaken_not_stirred.

Reputation: 516

'while' loop with characters converted to ASCII code (intermediate level)

I'm working through examples where I have to convert 'for' loops into 'while' loops, and this one has me stumped. The problem for me is that 'for' loops are perfectly designed to iterate over each character in a string, and then that character can be easily cast as 'ord' to get its ASCII code. But converting this to a 'while' loop is giving me issues when I try to retrieve the 'ord' part of this. I've attempted it using split() and trying to find each letter using an index, but it isn't working so far.

Please note that the code itself is just rubbish code that doesn't produce anything useful - it is purely just for practising 'while' loops. Thanks!

Supplied problem to be converted into a 'while' loop:

def convert(string):
    """take string and return an int that is the unicode version"""
    num = 0
    for char in string:
        if ord(char) > 20:
            num = ord(char) - 10
        else:
            num = ord(char) * 2
    return num
print(convert('Test this string'))

My attempt at the 'while' loop version:

def convert(string):
    """take string and return an int that is the unicode version"""
    char_value = string.split()
    num = 0
    char_index = 0
    while char_index < len(string):
        if ord(char_value[char_index]) > 20:
            num = char_value - 10
        else:
            num = char_value * 2
        char_index += 1    
    return num
print(convert('Test this string'))

EDIT: here is the working solution as adapted after NPE's suggestion (just in case beginners want to see the full solution):

def convert(string):
    """take string and return an int that is the unicode version"""
    num = 0
    char_index = 0
    while char_index < len(string):
        char = string[char_index]
        if ord(char) > 20:
            num = ord(char) - 10
        else:
            num = ord(char) * 2
        char_index += 1    
    return num
print(convert('Test this string'))

Upvotes: 1

Views: 2112

Answers (2)

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17434

I'd propose a more elegant and even more equivalent way to write that loop:

def convert(string):
    """take string and return an int that is for sure not any kind of Unicode version, whatever that's supposed to be"""
    it = iter(string)
    while True:
        char = next(it, None)
        if char is None:
            break
        if ord(char) > 20:
            num = ord(char) - 10
        else:
            num = ord(char) * 2
    return num
print(convert('Test this string'))

Why is the iterator approach more elegant, you may ask. A few simple reasons:

  • This works with any sequence, even one that is not indexable.
  • You don't have to compute the sequence's length in advance why may require loading it into memory first.
  • You could use this with a sequence who's length is infinite (this particular algorithm would loop endlessly then) or one who's length is unknown (think user input).

Upvotes: 1

NPE
NPE

Reputation: 500773

You don't need to use split. You can index into the string directly with a character index.

A straightforward way to rewrite the for as a while is shown below:

    char_index = 0
    while char_index < len(string):
        char = string[char_index]
        ...
        char_index += 1    

(The ... part can be exactly as the body of the for loop.)

Upvotes: 2

Related Questions