Letter replacer - suggestions?

dn PythonList at DancesWithMice.info
Mon Dec 7 18:08:28 EST 2020


> word = input('input word you want to change letters in: ')
> 
> chars = tuple(word)
> change_this = input('Enter the letters you want to change: ')
> replace_with = input('Enter the letters to replace with: ')
> 
> if len(change_this) != len(replace_with):
>      raise RuntimeError(
>          "Letters to replace must be equals in number to letters you want " +
>          "to change"
>      )
> 
> change_chars = tuple(change_this)
> replace_chars = tuple(replace_with)
> 
> new_chars = []
> 
> for ch in chars:
>      try:
>          i = change_chars.index(ch)
>      except ValueError:
>          new_chars.append(ch)
>      else:
>          new_chars.append(replace_chars[i])


There are two 'phases' to this program:

1 collecting the input-data, and
2 performing a translation.

The second and third inputs must be the same length - hence the first 
if-condition (above).


Phase 1:

More user-friendly (considerate) ways to do this include:

- (if short strings) input the character-pairs as a unit:-

     while ... # decide upon a sentinel/loop-terminator
         in = input( "A character and its replacement" )
         source_character, replacement_character = in.split( ... )
         # insert appropriate criteria as ...
         source_list.append( source_character )
         replacement_list.append( replacement_character )

- (existing practice) alter the input() "prompt-strings" to be the same 
length, and thus assist the user to *see* that his/her two inputs [must] 
also 'match' in length! eg

Source  characters? abcdef↵
Encoded characters? zyxwuv↵


Phase 2:

The translation phase is most easily achieved with the built-in 
str.translate() - and likely faster! First the translation-table must be 
built, then the source-text(s) translated:

     source_str = "".join( source_list )
     replacement_str = "".join( replacement_list )
     # have to join (above) lists into strings for next line
     translation_table = str.maketrans( source_str, replacement_str )
     translation = word.translate( translation_table )

NB because maketrans() is a static method (of the str[ing] class) we 
must use the "str.".

NBB because str.maketrans() checks the length of the two 
translation-strings, wrapping that with try...except might be considered 
more 'pythonic' than the "first if-condition" (although "explicit is 
better...", Zen of Python)


For extra credit/re-factoring further:
(after learning the above 'straight-line' approaches and code constructs)

str.maketrans() will accept a single dict[ionary]. Accordingly, instead 
of collecting the translation data as two lists - which must then be 
converted into strings; (no matter which approach to 'phase 1' is 
preferred); consider building a translation-dictionary wherein each 
entry has the 'letter to be changed' as its "key", and its "data" is 
'the letter to replace [it] with'. Refactoring from the above:

     source_character, replacement_character = in.split( ... )
     translation_dict[ source_character ] = replacement_character
     translation_table = str.maketrans( translation_dict )
     translation = word.translate( translation_table )


Trust this adds to your 'adventures' in learning Python!


Web.Refs:
https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str
https://www.askpython.com/python/string/python-string-translate
-- 
Regards =dn


More information about the Python-list mailing list