if statements

Raindrops
Raindrops in Python
def convert(num):
    sounds = ''
    
    if num % 3 == 0: sounds += 'Pling'
    if num % 5 == 0: sounds += 'Plang'
    if num % 7 == 0: sounds += 'Plong'
        
    return sounds or str(num)

This approach is the most straightforward or 'naive' - it replicates in code what the instructions say, using if statements to check the modulo for each factor. If the number is evenly divisible by the factor (modulo == 0), the corresponding string is concatenated to sounds via the + operator. Sounds is returned if it is not empty (see Truth Value Testing for more info). Otherwise, a str version of the input number is returned.

This, of course incurs the 'penalty' of string concatenation. But since there are only three factors to check and the strings are small, the concatenation is at a minimum.

In fact, this solution - and most others described in the approaches here - are O(1) time complexity. There are a constant number of factors to iterate through, and the work that is done never increases, even as the input numbers get bigger. This holds true for space complexity as well.

The compact form for the if statements might be harder to read for some people. These can be re-written to be nested, and the return can be re-written to use a ternary expression:

def convert(num):
    sounds = ''
    
    if num % 3 == 0: 
        sounds += 'Pling'
    if num % 5 == 0: 
        sounds += 'Plang'
    if num % 7 == 0: 
        sounds += 'Plong'
        
    return sounds if sounds else str(num)

While this solution is nicely readable and to-the-point, it will grow in length and get harder to read if many more factors are added or business logic changes. Other solutions using data structures to hold factors might be a better option in 'high change' situations.

20th Nov 2024 · Found it useful?

Other Approaches to Raindrops in Python

Other ways our community solved this exercise
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)
Loop and f-string

Loop through a tuple and assemble output via an f-string.

def convert(number):
    drops = ["Pling","Plang","Plong"]
    factors = [3,5,7]
    sounds = ''.join(drops[index] for
                     index, factor in
                     enumerate(factors) if (number % factor == 0))

    return sounds or str(number)
Sequence(s) with str.join()

Use one or more sequences and str.join() with a generator-expression.

def convert(number):
    threes = '' if number % 3 else 'Pling'
    fives =  '' if number % 5 else 'Plang'
    sevens = '' if number % 7 else 'Plong'

    return f'{threes}{fives}{sevens}' or str(number)
Truthy and Falsey Values with f-strings

Use ternaries to build words and an f-string to assemble the result.

def convert(number):
    sounds = {3: 'Pling', 5: 'Plang', 7: 'Plong'}

    results = ''.join(sounds[divisor] for
                      divisor in sounds.keys()
                      if number % divisor == 0)

    return results or str(number)
Dict and str.join()

Use a dict to hold factors:values and str.join() with a generator-expression.

from itertools import compress

def convert(number):
    sounds ='Pling','Plang','Plong'
    mask =  ((number % factor) == 0 for factor in (3,5,7))
    return ''.join(compress(sounds, mask)) or str(number)
itertools.compress

Use itertools.compress() with a list mask.

from functools import reduce

def convert(number):
    sounds = ('Pling','Plang','Plong')
    factors = ((number % factor) == 0 for factor in (3,5,7))
    result = reduce(lambda sound, item : sound + (item[0] * item[1]), zip(sounds, factors), '')

    return result or str(number)
functools.reduce

Use functools.reduce() and zip().