def convert(number):
sounds = ''
drops = ("i", 3), ("a", 5), ("o", 7)
for vowel, factor in drops:
if number % factor == 0:
sounds += f'Pl{vowel}ng'
return sounds or str(number)
This approach loops through the drops tuple
(although any iterable sequence(s) can be used), unpacking each vowel
and factor
.
If the input number is evenly divisible by the factor (modulus == 0), the corresponding vowel is inserted into the f-string
for that factor.
The f-string
is then concatenated to sounds string via +
.
Sounds is returned if it is not empty.
Otherwise, a string version of the input number is returned.
This takes O(1)
time and O(1)
space.
It is a very efficient and clever way of building up the return string, since only one vowel is changing per 'drop'. However, it might take a moment for others reading the code to understand what exactly is going on. It also (may) create maintenance difficulties should there be future factors and sounds that do not conform to the pattern of only changing the vowel in the sound.
A much less exciting (but perhaps easier to maintain) rewrite would be to store the whole drop sound and build up the return string out of whole drops:
def convert(number):
sounds = (3, 'Pling'), (5, 'Plang'), (7, 'Plong')
output = ''
for factor, sound in sounds:
if number % factor == 0:
output += sound
return output or str(number)
This has the same time and space complexity as the first variation.