2

The assignment is:

Your task is correcting the errors in the digitized text. You only have to handle the following mistakes:

  • S is misinterpreted as 5
  • O is misinterpreted as 0
  • I is misinterpreted as 1

My code:

def correct(string):
    for i in string:
        if '5' in string:
           string = string.replace('5','S') 
        elif '0' in string:
          string = string.replace('0','O')
        elif '1' in string:
            string = string.replace('1','I')
    return string 

I know this solution will not work for a word like:

Test.assert_equals(correct("51NGAP0RE"),"SINGAPORE");

Does anyone have tips on how to make this a more general function that will work for every word?

ilim
  • 4,477
  • 7
  • 27
  • 46
Steve
  • 353
  • 3
  • 12
  • 1
    Why do you have a for loop, and the `if in` checks? Just doing the replacements would work better. – internet_user Apr 13 '18 at 15:48
  • On a small number of replacements, @internet_user is correct. See also [string.translate](https://docs.python.org/3.6/library/stdtypes.html#str.translate) for more flexibilty – Reid Ballard Apr 13 '18 at 15:51
  • This is task from CodeWars: https://www.codewars.com/kata/577bd026df78c19bca0002c0 – Denis Rasulev Apr 13 '18 at 15:53
  • 1
    Are you sure your code doesn't work? It's not as efficient as it could be, but it should still give the correct answer. – Barmar Apr 13 '18 at 15:55
  • 1
    Possible duplicate of [Multiple character replace with Python](https://stackoverflow.com/questions/3411771/multiple-character-replace-with-python) – Keyur Potdar Apr 13 '18 at 16:03
  • 1
    Don't name your variable `string` as it conflicts with the `string` library- if you're using python2, it would make a difference for the solution given by chrisz – pault Apr 13 '18 at 16:07

4 Answers4

5

You can use str.replace directly.

def correct(string):
    return string.replace('5','S').replace('0','O').replace('1','I')
Rakesh
  • 81,458
  • 17
  • 76
  • 113
5

Why don't you make use of str.maketrans and str.translate:

>>> "51NGAP0RE".translate(str.maketrans('501', 'SOI'))
'SINGAPORE'

Wrapped in a function:

def correct(s):
    return s.translate(str.maketrans('501', 'SOI'))
user3483203
  • 50,081
  • 9
  • 65
  • 94
  • 4
    In python2, this is in the [`string`](https://docs.python.org/2/library/string.html#string.translate) library. A great reason not to use `string` as a variable name! – pault Apr 13 '18 at 16:06
  • Thanks for the answer! However it needs to work for every word :) – Steve Apr 13 '18 at 19:13
  • @DaphneCornelisse You did not understand the answer. This works for every word, not only 501. This is just the way the maketrans function works. – Olivier Melançon Apr 13 '18 at 19:13
  • @OlivierMelançon my bad! I just meant that it had to be a function. – Steve Apr 13 '18 at 19:19
  • 1
    Well then just put that line into a function, it really isn't hard. Plus, this is the best way to go with the kind of problem you are trying to solve. `def correct(s): return s.translate(str.maketrans('501', 'SOI'))` – Olivier Melançon Apr 13 '18 at 19:20
2

Don't use elif, since that only does a test if the previous one failed. Change them all to ordinary if and the code will work correctly.

But as mentioned in the comments, there's no need for any of the tests. If the letter isn't in the string, replace() will just return the original string, so there's no harm.

string = string.replace('5', 'S').replace('0', 'O').replace('1', 'I')
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • My initial thought too but OP is iterating over each character in the string, so the `elif`/`if` shouldn't make a difference. – pault Apr 13 '18 at 15:52
  • 1
    Good point. If the string is at least 3 characters long it should perform all the replacements. – Barmar Apr 13 '18 at 15:53
  • 1
    And if it's shorter, it can't need all the replacements. – Barmar Apr 13 '18 at 15:54
2

Here's another method using list comprehension:

def correct(str_, replacements = {'5': 'S', '0': 'O', '1': 'I'}):
    return "".join(replacements.get(c, c) for c in str_)
print(correct("51NGAP0RE"))
#'SINGAPORE'
pault
  • 41,343
  • 15
  • 107
  • 149