[Tutor] Homework problem

Steven D'Aprano steve at pearwood.info
Thu Jul 21 03:11:27 CEST 2011


Ken Baclig wrote:
> Hi,
> 
> I'm trying to make a function that receives text (a string) as an argument and returns the same text (as string), but with 1 added to each word that is a number.


What counts as a number? In the string:

"Hello world 1234 ham spam"

which of these do you expect to get back?

"Hello world 2345 ham spam"  # Add one to each digit.
"Hello world 1235 ham spam"  # Add one to each number.

What about strings without spaces like "foo123bar"?

I'm going to assume that you mean to add 1 to any digit, not just to 
complete numbers.



> I need help getting started.
> 
> So far, I have:
> 
> def FindNumbers(a_string):
> 
>     for index, char in enumerate(a_string):
>         if char.isdigit():
> a_string[index] = 



This can't work, because strings are immutable. They cannot be changed 
in place. You have to form a new string.

The approach I would take is something like this. Here's a version which 
doesn't actually add one to each digit, but merely turns any digit into 
an asterisk. Your job is to make it do what it is supposed to do.


def add_one_to_digits(a_string):
     # Give the function a name that says what it does. It doesn't
     # just FindNumbers, that name is completely inappropriate.
     result = []  # Holder to build up a new string.
     for char in a_string:
         if char.isdigit():
             char = "*"
         # Anything else gets passed through unchanged.
         result.append(char)
     # Assemble the characters into a string.
     return ''.join(result)




> def Test():
>     sometext = "I got 432 when I counted, but Jim got 433 which is a lot foronly 6 cats, or were there 12 cats?"
>     FindNumbers(sometext)
> 
> Test()


Test functions should actually test something. Try this instead:


def test():
     source = ("I got 432 when I counted, but Jim got 433 which "
               "is a lot for only 6 cats, or were there 12 cats?")
     expected = ("I got 543 when I counted, but Jim got 544 which "
               "is a lot for only 7 cats, or were there 23 cats?")
     actual = add_one_to_digits(source)
     if actual == expected:
         print("Test passes!")
     else:
         print("Test fails!")
         print("Expected '%s'" % expected)
         print("but actually got '%s'" % actual)



By the way, the test case is not very good, because there is one digit 
which is special compared to the others, and it doesn't get tested. 
Think about it... out of the 10 possible digits, 9 of them are obvious: 
0 -> 1
1 -> 2
2 -> 3 etc.

but one digit is not obvious. Can you see which one? So you need to 
include that digit in the test case, so you know it gets handled correctly.




-- 
Steven


More information about the Tutor mailing list