@hoola: Die Aufgabenstellung sagt das man die Satzzeichen *nicht* beachten muss.  Schau Dir einfach mal das Beispiel in der Aufgabe an — da sind die Satzzeichen auch einfach raus gefallen.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import defaultdict
from datetime import date as Date
from itertools import chain
# 
# 1 a)
# 
# Commenting that code would be stating the obvious, i.e. repeating what the
# code does in the comment.  That is not what comments are meant for.  So I pass
# on this one.  :-þ
# 
# 
# 1 b)
# 
def get_unique_characters(string):
    """
    >>> get_unique_characters('')
    ''
    >>> get_unique_characters('baabcad')
    'abcd'
    >>> get_unique_characters('mississippi')
    'imps'
    >>> get_unique_characters('python')
    'hnopty'
    """
    return ''.join(sorted(set(string)))
# 
# 2 a)
# 
def make_histogram(sexes, allowed_sexes=('w', 'm')):
    """
    >>> sexes = list('wwmwmwmmswwwwmm')
    >>> sexes
    ['w', 'w', 'm', 'w', 'm', 'w', 'm', 'm', 's', 'w', 'w', 'w', 'w', 'm', 'm']
    >>> female_count, male_count, error_count = make_histogram(sexes)
    >>> female_count, male_count, error_count
    (8, 6, 1)
    >>> sexes
    ['w', 'w', 'm', 'w', 'm', 'w', 'm', 'm', None, 'w', 'w', 'w', 'w', 'm', 'm']
    >>> male_count == sexes.count('m')
    True
    >>> female_count == sexes.count('w')
    True
    >>> error_count == sexes.count(None)
    True
    """
    histogram = defaultdict(int)
    for i, sex in enumerate(sexes):
        sex = sexes[i] = sex if sex in allowed_sexes else None
        histogram[sex] += 1
    return tuple(histogram[k] for k in chain(allowed_sexes, [None]))
# 
# 2 b)
# 
# The input functions should be separate.
# 
def input_non_empty(prompt):
    """Repeats the `prompt` until the user inputs a non empty string."""
    while True:
        result = raw_input(prompt + ': ')
        if result:
            return result
def input_choice(prompt, choices):
    """Repeats the `prompt` until the user inputs one of the given `choices`.
    
    Input is case insensitive and returned as lower case and `choices` are
    displayed in lower case too.
    """
    choices = [c.lower() for c in choices]
    while True:
        result = raw_input('%s (%s): ' % (prompt, '/'.join(choices))).lower()
        if result in choices:
            return result
# 
# It should be possible to leave the name field empty and to input at least
# an unknown sex for a newborn because both cases may happen in the field.
# 
def input_child():
    return (
        input_non_empty('Bitte Nachnamen eingeben'),
        raw_input('Bitte Vornamen eingeben'),
        input_choice('Bitte Geschlecht eingeben', ['m', 'w', '?'])
    )
def new_child(children):
    children.append(input_child())
    return children     # XXX Stupid API.
# 
# 3
# 
def shorten_words(text, length=5):
    return ' '.join(w[:length] for w in text.split())
def test_shorten_words():
    source = (
        u'Die ersten Buchstaben eines Wortes sind die Träger der Bedeutung.'
        u' Die Verständlichkeit eines Satzes ist auch gegeben, wenn von jedem'
        u' Wort die ersten fünf Buchstaben geschrieben werden.'
    )
    expected = (
        u'Die erste Buchs eines Worte sind die Träge der Bedeu Die Verst eines'
        u' Satze ist auch gegeb wenn von jedem Wort die erste fünf Buchs gesch'
        u' werde'
    )
    assert shorten_words(source) == expected
# 
# 4 a)
# 
# Maps unique ISBN to rest of data.  This makes it easy to ensure there is
# just one entry per ISBN.
# ISBN is a string because it is semantically no number.  You do not calculate
# with ISBN like adding them up or dividing them by another number.
# For calculating the checksum it is easier to work with the single digits when
# the ISBN is in string form.
# 
# The other choices for types should be obvious.
# 
# In a serious application a Books container class and a Book class for
# single entries might be more appropriate than accessing „fields” by index.
# 
PRICE_INDEX = 3
COUNT_INDEX = 4
ISBN_TO_BOOK = {
    '9783768825825': [
        'Delius Klasing', 'MV - Bornholm', Date(2009, 1, 1), 54.90, 2
    ],
    '9783768832021': [
        'Delius Klasing', 'MV - Bornholm', Date(2011, 3, 1), 54.90, 13
    ],
    '9783892255598': [
        'Edition Maritim', 'Rund Rügen', Date(2008, 3, 1), 29.90, 15
    ],
    '9783892252368': [
        'Delius Klasing', 'Küstenhandbuch MV', Date(2006, 3, 1), 29.90, 3
    ],
    '9783980672016': [
        'Quick Maritim Medien',
        'Törnplaner/-atlas Peene, Oder, Bodden',
        Date(2006, 4, 1),
        25.00,
        5
    ],
    '9783768831017': [
        'Delius Klasing',
        'Kieler Bucht und Rund Fünen (2010)',
        Date(2010, 3, 1),
        69.90,
        17
    ],
}
def sum_total_worth(isbn2book):
    """
    >>> sum_total_worth(ISBN_TO_BOOK)
    2675.0
    """
    return sum(b[PRICE_INDEX] * b[COUNT_INDEX] for b in isbn2book.itervalues())