Genotype as input, give the phenotype I want to write a Python script where the input is a genotype (e.g. "CCDd") based upon the following Punnett square. The output should be the phenotype (e.g. "seal").



My code works, but doesn't look that 'pythonic' at all.

def colour(input):

    if len(set(input)) == 2 and input[0] != 'C' and input[2] != 'D':
        return('lilac')
    elif len(set(input[2::])) == 1 and input[2] != 'D':
        return('blue')
    elif len(set(input[0:2])) == 1 and input[0] != 'C':
        return('chocolate')
    else:
        return('seal')
You correctly identified that you need to count the number of lowercase c and d. But using a set to do so is not the right tool. Instead, I suggest using collections.Counter:

from collections import Counter


def color(genotype):
    assert len(genotype) == 4

    count = Counter(genotype)
    blue = count['d'] == 2
    chocolate = count['c'] == 2

    if blue and chocolate:
        return 'lilac'
    if blue:
        return 'blue'
    if chocolate:
        return 'chocolate'
    return 'seal'


I also added a debug check to ensure that the length of the input sequence is always four.



Given the mini debate that occured in the comments, pertaining to variable names, you may consider this slight variation:

from collections import Counter


def color(genotype):
    assert len(genotype) == 4

    count = Counter(genotype)
    recessive_traits = [count[gene] == 2 for gene in 'cd']

    if all(recessive_traits):
        return 'lilac'
    if recessive_traits[0]:
        return 'blue'
    if recessive_traits[1]:
        return 'chocolate'
    return 'seal'


It may be more expressive as to what you're testing, and why.