Freitag, 29. März 2013

SimpleCode 2

Ich habe eine eigene Version von SimpleCode in PHP programmiert. Das ging überraschend einfach, wenn auch der Aufwand es zu coden exorbitant war. Ganz verstanden habe ich das Problem noch nicht...
<?PHP

  echo("Hallo Welt!");

?>
Das eigentliche Problem ist, dass ich noch nicht weiß, ob meine Version wirklich schon völlig funktioniert. Der Test hier sagt: Es funktioniert. Wenn ich den PHP-Code direkt posten würde, dann würde er in Blogger nicht angezeigt werden.

Sonntag, 24. März 2013

Die Funktion header()

Ich fange gerade erst an das erste PHP-Tutorial durchzuarbeiten, bin aber in die Verlegenheit gekommen, eine Umleitung zu programmieren. Ich möchte verhindern, dass ein Benutzer auf ein PHP-Skript zugreift, dass Daten eines anderen Skripts verarbeitet und ausgibt.

Im Augenblick behelfe ich mir mit folgendem Code:

if (empty($_POST)){
  header('Location: skript_1.php');
 };

Wahrscheinlich ist das so nicht direkt im Sinne des Erfinders, aber es funktioniert erst einmal.

Sonntag, 10. März 2013

Morse Code Palindrome

Das „Morse Code Palindrome“-Problem gehört zum „HP Code wars“-Wettbewerb 2013 und war eher sehr einfach zu lösen. Einmal galt es eine Botschaft in Morsecode zu übersetzen und dann die Botschaft auf ihre Palindrom-Eigenschaft hin zu untersuchen:
# HP Code wars 2013
# problem 12
# Morse Code Palindrome
# 6 points


def botschaft_decodieren(botschaft):
    """ Bekommt eine Botschaft und setzt sie
    in Morsezeichen um. Leerzeichen und Satzzeichen
    werden ignoriert. Kleinbuchstaben werden nicht
    erwartet oder beachtet.

    """
    morsecode = {"A": "•-", 
                 "B": "-•••",
                 "C": "-•-•",
                 "D": "-••",
                 "E": "•",
                 "F": "••-•",
                 "G": "--•",
                 "H": "••••",
                 "I": "••",
                 "J": "•---",
                 "K": "-•-",
                 "L": "•-••",
                 "M": "--",
                 "N": "-•",
                 "O": "---",
                 "P": "•--•",
                 "Q": "--•-",
                 "R": "•-•",
                 "S": "••••",
                 "T": "-",
                 "U": "••-",
                 "V": "•••-",
                 "W": "•--",
                 "X": "-••-",
                 "Y": "-•--",
                 "Z": "--••"}
    codierte_botschaft = []
    for a in botschaft:
        codierte_botschaft.append(morsecode.get(a,""))
    return "".join(codierte_botschaft)


def palindrom_testen(datensatz):
    """ Testet auf ein Palindrom und
    schickt den Datensatz dazu zum decodieren

    """
    botschaft = botschaft_decodieren(datensatz)
    if botschaft == botschaft[::-1]:
        return True
    else:
        return False


data = """ELEGIZED 
QUIRKILY 
MERCURY 
FACE A WINE 
HAPPY DAY 
FEVER REBEL 
SOPRANOS 
EMIT OLD UFO TIME 
PROTEIN POWDER 
ANNEXING 
ENJOIN 
. """


datensaetze = data.split("\n")
for datensatz in datensaetze:
    datensatz = datensatz.strip(" ")

    if not datensatz == ".":

        if palindrom_testen(datensatz):
            print ("{} is a MCP".format(datensatz))
        else:
            print("{} is *not* a MCP".format(datensatz))
Anders als einige andere Aufgaben des diesjährigen Wettbewerbs eher keine Herausforderung.

Webcrawler zur Websitenanalyse

Bei einer gestrigen Besprechung kam das Problem der Website-Wartung, der Behandlung toter Weblinks, des Aufspürens inzwischen falscher E-Mail-Adressen und - ich ergänze - defekter (Bild–)Dateien auf die Tagesordnung. Das Problem scheint „ungelöst“, jedenfalls wenn man dem Wikipedia-Artikel zu „Toten Weblinks“ glauben darf.

Erste Überlegungen

Ich hatte mir gestern überlegt an drei Stellen ansetzen zu können:
  1. Datenbank-Dump zur Website als CSV-Datei oder als SQL-Datei.
    Vorteil: Die Prüfung erfasst alle Seiten und nicht nur die, die öffentlich zugänglich sind, sondern auch die, die einst zugänglich waren und vielleicht noch von jemandem über ein Lesezeichen besucht werden.

    Nachteil: Per Hand muss zunächst ein Datenbank-Dump erzeugt werden. 
  2. Website im Laufenden Betrieb parsen.
    Vorteil: Ich erfasst die vollständig zugängliche Website und brauche keinen Datenbankzugriff.
    Nachteil: Einige Seiten werden übersehen.
  3. Ich generiere spezielle 404-Seiten, die eine Meldung per E-Mail an den Webadmin absetzen und zeitnah über einen möglichen Fehler der Seite informieren.
Tja.

Ausgabe eines Protokolls
Prüfung der Bilddateien auf dem Rechner
Prüfung der E-Mail-Adressen durch Test-E-Mail und Information an den Empfänger.
Prüfung der Links über Protokoll (Liste) zur manuellen Prüfung und automatischen Prüfung über Test auf 404- oder weitere Fehlerseiten...

Samstag, 9. März 2013

Family tree

Eigentlich könnte „Family tree“ ein schönes Problem sein, müsste man nicht eine durchaus komplexe Datenstruktur aufbauen, die sowohl aufsteigend, als auch absteigend durchsucht werden kann. Ich denke daran die Datenstruktur in ein Dictionary zu packen und die Auf- bzw. Abwärtssuche dann gesondert zu implementieren.

Ein- und Ausgabe

Ich erhalte als Eingabe folgende Datensätze:
9 
A + B : C , D , E . 
F + G : H . 
I + J : K , L . 
C + H : M , N . 
D + K : O . 
L + E : P , Q , R , S . 
N + Q : T , U , V . 
O + S : W , X . 
Y + H : Z . 
7 
K > O ? 
F > W ? 
B ^ U ? 
O ^ V ? 
A > Z ? 
F > Z ? 
X ^ Z ?

Die Ausgabe soll folgendermaßen aussehen:
K > O ? TRUE 
F > W ? FALSE 
B ^ U ? FALSE 
O ^ V ? TRUE 
A > Z ? FALSE 
F > Z ? TRUE 
X ^ Z ? FALSE 

Das Problem

Eine Visualisierung dient der ersten Orientierung:

Ein Stammbaum erzeugt aus den Anweisungen

Also gehen wir es an.

Room for an argument

Room for an argument“ war Problem 11 bei HP Code wars 2013 und es gab hierfür insgesamt 5 Punkte, was mir recht hoch erscheint, wenn man sich das Problem vergegenwärtigt. Insgesamt galt es bei einer Reihe von Texten aus „is“ ein „is not“ zu machen und umgekehrt.

Aus meiner Sicht ließ sich das mit Stringoperationen erledigen ohne jede Zeile gesondert zu parsen, womit ich direkt einen Gedankenfehler gemacht habe, weil ich dabei z. B. „This“ übersehen hatte. Folglich muss doch jede Zeile gesondert geparst werden bzw. müssen die Ersetzungen angepasst werden.
data = """7 
This is not an argument. 
An argument is an intellectual process. 
It is fair if you do not go. 
The ferris wheel is not working. 
A butterfly is beautiful, but litter is not. 
A lady discerns that which is not elegant from that which is. 
A lemur is a monkey and a grivet is a monkey but a chimp is not. """

for i, line in enumerate(data.split("\n")):
    if not i == 0:

        print(line)
        
        line = line.strip(" ")
        line = line.replace(" is not"," ")
        line = line.replace(" is"," is not")
        line = line.replace(" "," is")
        
        print(line,"\n")
Ob die es sich so gedacht haben? Alternativ müsste man jede Zeile in eine Liste aufsplitten und dann jedes Element und ggf. sein Folgeelement einzeln parsen und Änderungen auf einer Liste vornehmen. Die Lösung hier scheint mit vertretbar.

Dienstag, 5. März 2013

Hot Pad

Das „Hot Pad“-Problem von HP Codewars für 9 Punkte besteht eigentlich aus 2 Problemen. Im Rahmen des Problems erhalte ich von einem Keypad die Temperaturen je Taste und muss eine Liste der möglichen Kombinationen ausgegeben, die ein Anwender getippt haben könnte.

Problem

Die beiden Probleme sind folglich:

  1. Lies die Temperaturwerte ein und stelle fest, welche Taste einmal und welche ggf. zweimal gedrückt wurde. Es gibt eine durchschnittliche Temperatur und die Taste # muss zwingend zum Absenden gedrückt sein.
  2. Für die ermittelten Tasten muss ich anschließend alle möglichen Kombinationen ausgeben. Das ist ein Problem der Kombinatorik, wenn ich mich nicht irre.

Erste Annäherung

Beachten muss ich, dass die eingegebenen Codes eine Länge von 4 Ziffern haben und mit einem # abgeschlossen werden. Das Keypad sieht so aus:

1 2 3
4 5 6
7 8 9
* 0 #

Die Temperaturwerte für das Pad sehen u. a. so aus:

Datensatz 1
72.1
75.0
75.1
72.0
72.1
72.2
72.0
72.2
77.9
72.1
72.2
75.2

Datensatz 2

77.2
77.1
76.9
77.0
83.5
77.0
77.1
77.3
77.1
77.0
79.4
79.1

Die Temperaturen können schwanken, was beachtet werden muss! Denke daran, dass eine Taste einmal, zweimal, dreimal oder auch viermal gedrückt werden könnte; die Raute wird einmal gedrückt worden sein. Das Sternchen sollte eigentlich nicht gedrückt worden sein.

Counting Ones

Das Problem Nr. 9 „Counting Ones“ wird bereis als Spaßproblem („This program is a fun math problem!“) beschrieben. Es sind in einem Zahlenbereich von 1 bis einschließlich einer Zahl n alle Einser gezählt werden. Im Bereich bis 10 finden sich so z. B. zwei Einser und zwar bei 1 und einmal bei 10. Die Lösung des Problems, wenn man die Dateneingabe außen vor lässt, ist knapp zu formulieren:
def counting_ones(n):
    """ Soll alle Einser zwischen
    1 bis einschließlich n ermitteln

    """
    zahlen = [str(n) for n in range(1,n + 1)]
    zahlenreihe = "".join(zahlen)
    return zahlenreihe.count("1")


for i in [13,1,999,23,1111,9997,511]:
    print(counting_ones(i))
Schöne, einfache Probleme, zumindest die, die ich mir jetzt angesehen habe.

Distinct Letters

Das Problem 8 „Distinct Letters“ von HP Code wars 2013 für 4 Punkte ist eher eines der sehr einfachen Probleme. Es muss geprüft werden, ob ein Wort einen jeden Buchstaben des Wortes nur einmal verwendet.
data = """UNCOPYRIGHTABLE 
FLIPPER 
EXECUTABLE 
UNPROFITABLE 
QUESTIONABLY 
WINDOW 
TAMBOURINE 
. """


def daten_aufbereiten(data):
    """ Wandelt die Daten in Zeilen
    in einer Liste um und gibt die
    Liste zurück...

    """
    zeilen = data.replace(" ","").split("\n")
    if zeilen[-1] == ".":
        zeilen.pop()
    return zeilen


def distinct_letters_pruefen(wort):
    """ Muss prüfen, ob ein Wort einen
    Buchstaben mehr als einmal nutzt,
    dann ist der Rückgabewert
        FALSE
    sonst
        TRUE
    """
    if len(wort) != len(set(wort)):
        return False
    else:
        return True


woerter = daten_aufbereiten(data)

for wort in woerter:
    if distinct_letters_pruefen(wort):
        print("{} USES DISTINCT LETTERS.".format(wort))
    else:
        print("{} DOES NOT USE DISTINCT LETTERS.".format(wort))
Ich finde meine Lösung intelligent, weil kurz und richtige Ergebnisse geliefert werden ohne dass ich eine Prüfung je Buchstabe durchführen muss.

Selling Shirts

Die Aufgaben von HP Code wars 2013 sind online und die erste echte Aufgabe ist eine Sache für wenige Minuten:
""" Die Formel zur Berechnung des Profits lautet

    P = 8 * N – 95

    $ 8 pro verkauftem Shirt
    N   = die Zahl der verkauften Shirts
    95  = die Standgebühr
"""

profit = lambda n : 8 * n - 95

print(profit(31),end=" $")
Die Formel zur Berechnung des Profits kann gut mittels lambda-Operator ausgedrückt werden.

Sonntag, 3. März 2013

E-Mail-Versand mit Python

Das Thema E-Mail-Versand mit Python finde ich ganz spannend.

Brauchbare Ressourcen

Für den Versand von E-Mails mit Python haben sich folgende Ressourcen als ganz brauchbar herausgestellt:

Module:
  • Das Modul smtplib
  • Das Modul email
  • Das Modul ...

Referenzen:

Einfache Text-E-Mails

Text

Versand von HTML-E-Mails

Text

Versand von E-Mails mit Anhängen

Text

Name That Cow

Aus dem OpenClipart-Project
Das Name That Cow“-Problem klingt recht spannend, allerdings ist ein Problem, dass mir die Datentabelle mit den 5.000 „acceptable cattle names“ nicht zur Verfügung steht.

Problembeschreibung

Auf einer texanischen Rinderfarm soll für die Seriennummer einer Kuh eine Liste weiblicher Vornamen vorgeschlagen werden, wobei die Übersetzung sich am Tastenfeld eines Telefons orientiert, d. h. für die Zahl 2 kann im Vornamen der Buchstabe A, B oder C stehen.

Ich verwende meine Telefontastatur, wie ich sie auf meinem Telefon vorfinde.

1 2
ABC
3
DEF
4
GHI
5
JKL
6
MNO
7
PQRS
8
TUV
9
WXYZ

Diese Änderung sollte unproblematisch sein. Die richtige Funktionsweise meines Programms kann später über die Tastatur überprüft werden. Wirft mir das Programm für den Code 23353 z. B. den Vornamen Adele aus, dann kann ich prüfen, ob die Buchstaben jeweils in den den Zahlen zugeordneten Buchstabenlisten enthalten sind.

Folglich stellt sich folgendes Problem: Schreibe ein Programm das für die Nummer eines Rinds alle validen Namen ausgibt, die für diese Nummer generiert werden können. Sonst lautet die Ausgabe „No matching names found“. Seriennummern dürfen maximal 9 Zahlen lang sein. Das Programm endet, wenn eine 0 eingegeben wird.

Vorüberlegungen

Die Aufgabenstellung führt zu folgenden Vorüberlegungen:
  • Die Seriennummer eines Rindes darf keine 0 oder 1 enthalten, weil ich diesen Ziffern keinen Buchstaben zuweisen kann.
  • Die Verwendung des RE-Moduls bietet sich m. E. an. Die dynamische Generierung eines RE-Ausdrucks ist m. E. erforderlich. (Ging einfacher)
  • Möglicherweise macht es Sinn die Vornamen in Listen entsprechend der Länge aufzuteilen. Das könnte helfen die Performanz zu verbessern.

Datendatei aufbauen

Ich habe mir - leider manuell - aus der Wikipedia eine Liste mit - laut Wikipedia - 1.761 weiblichen Vornamen (Stand März 2013) geholt und aufbereitet. Aus dieser Liste soll das Programm geeignete Namen auswählen.

Die Vornamensliste wird aus dem Quelltext der Kategorienseiten heraus aufgebaut:
with open("Männlicher Vorname.txt") as f, open("Männliche Vornamen.txt","w") as g:

    for line in f:
        
        line = line.replace("\n","")
        # title="Zsuzsanna"
        if "title" in line:

            line = line.split('title="')[1]
            vorname = line.split('"')[0]

            vorname = vorname.replace(" (Vorname)","")
            vorname = vorname.replace(" (Name)","")

            print(vorname)
            vorname += "\n"
            g.write(vorname)
Das war gerade etwas Handarbeit, aber noch im Rahmen und einfacher und schneller als sich beim Pywikipediabot einzulesen.

Quelle: Deutschsprachige Wikipedia (2. März 2013)


Die entsprechende Übersicht mit denn männlichen Vornamen bietet - laut Wikipedia - 3.390 männliche Vornamen (Stand März 2013).

Quelle: Deutschsprachige Wikipedia (2. März 2013)


Aus beiden Listen kann man die benötigte Vornamensliste aufbauen.

Ein- und Ausgabe

Die Eingabe stellt man sich bei HP in etwa in folgender Form vor:
Program Input
232
252473
727225
0

Program Output
Possible names for #232 are: Ada
Possible names for #252473 are: Blaise, Claire
Possible names for #727225 are: Pascal
Sieht leistbar aus.

Mein Programm

Das re-Modul kommt hier nicht zum Einsatz, weil es Treffer für Strings findet, nicht aber in Listen. Eigentlich hätte ich gerne alle Listenelemente bekommen und muss daher - gefühlt - einen kleinen Umweg nehmen.
# Code wars IV
# Problem 9: Name That Cow


def codeliste_aufbauen(data):
    ''' Bekommt die Daten und gibt
    einzelne Codes in einer Liste zurück

    '''
    data = data.replace(" ","")
    data = data.split("\n")
    if data[-1] == "0":
        data.pop()

    return data


def ergebnis_ausgeben(code,namensliste):
    ''' Erledigt die Ausgabe in der Konsole

    '''
    if namensliste:        # Wahr, wenn die Liste nicht leer ist!
        print("Possible names for #{} are: {}.\n".format(code,", ".join(namensliste)))
    else:
        print("No matching names found for #{}.\n".format(code))


def vornamenliste_aufbauen():
    ''' Holt sich die Daten aus den Vornamenslisten

    Offene Probleme:
    [  ]   Es werden alle Namen geholt, nicht nur die, die
           auch möglich sind, z. B. < 10 oder ohne Leerzeichen
           und ohne Sonderzeichen
    '''
    vornamen = []
    dateien = ["Männliche Vornamen.txt","Weibliche Vornamen.txt"]
    
    for datei in dateien:
        with open(datei) as f:
            for line in f:
                line = line.replace("\n","")
                vornamen.append(line)
    vornamen.sort()

    # Trainingsmaterial
    '''
    Wähle code = 382 -> EVA
    vornamen = ['Bob', 'Eda', 'Eda', 'Eka', 'Eka', 'Eva', 'Ewa', \
                'Ida', 'Iga', 'Ina', 'Ina', 'Ira', 'Ira', 'Isa', \
                'Isa', 'Iva', 'Lea', 'Lia', 'Mia', 'Nea', 'Nia', \
                'Noa', 'Néa', 'Oda', 'Ola', 'Ola', 'Ona', 'Oya', \
                'Pia', 'Ria', 'Rob', 'Uta']
    '''
    return vornamen


def treffer_suchen(code,vornamen):
    ''' Suche alle Treffer in der Vornamensliste für
    den dekodierten code und gibt die Liste zurück
    '''
    codeliste = {"2":["A","B","C"],
                 "3":["D","E","F"],
                 "4":["G","H","I"],
                 "5":["J","K","L"],
                 "6":["M","N","O"],
                 "7":["P","Q","R"],
                 "8":["T","U","V"],
                 "9":["W","X","Y","Z"]}

    results = [] # Nimmt die Ergebnisse auf
    
    if "1" in code or "0" in code:
        # Der 1 sind keine Buchstaben zugeordnet
        return []
    else:

        for vorname in vornamen:

            match = True
            
            if len(vorname) != len(code):
                # Kann nicht passen
                pass
            elif " " in vorname:
                # Kann nicht passen
                pass
            else:
                for letter, i in zip(list(vorname),list(code)):
                    if not letter.upper() in codeliste[i]:
                        match = False
                        # Muss nicht weiterprüfen
                        break
                        # Nächster Vorname!
                    
                
                if match == True:
                    results.append(vorname)
        
        return results


def main():
    """ Mainfunktion

    """
    data = """114
    2662
    6886
    42664
    42662
    58473
    58472
    5642662
    382
    232
    252473
    727225
    6424235
    0"""

    # Übungsmaterial
    # data = """382"""

    # Daten aufbereiten
    codes = codeliste_aufbauen(data)
    vornamen = vornamenliste_aufbauen()

    # Treffer suchen
    for code in codes:
        treffer = treffer_suchen(code,vornamen)
        ergebnis_ausgeben(code,treffer)


if __name__ == "__main__":
    main()
Zu verbessern wäre hier wohl die Funktion treffer_suchen(code,vornamen). Mich würde interessieren, ob es eine bessere Lösung - z. B. mittels Datenbank oder re-Modul geben könnte. Eine Musterlösung von HP gibt es für die frühen Code wars leider noch nicht.

Verbesserungsvorschläge und Feedback

Ich habe im Python-Forum und zwar hier um Kritik gebeten und bekommen.

Samstag, 2. März 2013

CSI Crime Lab

Bei Aufgabe „CSI Crime Lab“ von HP Codewars VII sollte eine DNA-Prüfung implementiert werden, was mich etwas Zeit und Energie gekostet hat, weniger aufgrund der Komplexität der Aufgabe, als vielmehr, weil ich mir die Datenstruktur mit 2 dictionaries und dort u. U. hinterlegten Listen erst einmal vorgestellen musste.
# CodeWars VII Problems
# CSI Crime Lab

def suspects_aufbereiten(suspects):
    ''' Soll die Daten aufbereiten und in
    ein Wörterbuch packen
    '''
    personen = {}

    suspects = suspects.split("\n")
    for suspect in suspects:
        name,DNA = suspect.split(": ")
        personen[name] = DNA
    return personen


def daten_aufbereiten(scene):
    ''' Soll die Daten vom Tatort
    aufbereiten
    '''
    data = {}
    
    scene = scene.split("\n")
    for datum in scene:
        datum = datum.replace("On ","")
        ort,dna_spur = datum.split(": ")
        data[ort] = dna_spur.split(", ") # Werte sind in einer Liste (!)
    return data


def spuren_prüfen(suspects,spuren):
    ''' Vorgaben von HP
    a.) Es gibt nur einen Verdächtigen, dessen Name
        zurückgegeben werden muss
    b.) Falls kein positiver Treffer, dann ist die Ausgabe
        des Programms "NO MATCH", berücksichtigen
    c.) Positiver Treffer nur, wenn ein Verdächtiger
        DNA-Spuren an allen Tatorten hinterlassen hat
    d.) Es kann je Tatort mehrere DNA-Spuren geben

    Achtung - meine Ergänzung
    e.) Das Programm liefert nur den ersten Treffer mit
        Spuren an allen Tatorten zurück. Es wird nicht
        geprüft, ob das auch für andere Verdächtige
        zutrifft. Das könnte eine Fehlerquelle sein!
    '''

    # Beispieldaten
    # Larry King: GACTAATAACTTCATATATACACAGGTTAC
    # revolver: GACTATTC, GACTAATA

    # Was muss getan werden?
    # Prüfe, ob eine der Spuren in der DNA-Sequenz enthalten ist

    results = {}
    
    for suspect in suspects:

        results[suspect] = 0
        
        dna = suspects[suspect]

        for spurensatz in spuren:   # Spuren im Datensatz

            match = False

            for spur in spuren[spurensatz]:

                if spur in dna:
                    match = True

            if match == True:
                results[suspect] += 1
    
    # Rückgabe: Name eines Verdächtigen oder "" (= False!)
    keys = results.keys()
    for key in keys:
        if results[key] == 3:
            return key
    else:
        return "NO MATCH"


suspects = """Larry King: GACTAATAACTTCATATATACACAGGTTAC
Paula Abdul: GACTATTCATCATAGATAGACAGTACCTAA
Charlie McCarthy: GATTCATTGACATACATACATTAGAGTTCA"""

scene = """On revolver: GACTATTC, GACTAATA
On door: GACTAAT, CATAGAT
On phone: CATACATT, ATTAGAG, ATAGATAG"""

# Daten aufbereiten
suspects = suspects_aufbereiten(suspects)

spuren = daten_aufbereiten(scene)

# Schick die Daten durch die Datenbank
suspect = spuren_prüfen(suspects,spuren)

# Ermittle das Ergebnis
if not suspect == "NO MATCH":
    print("The suspect is: {}".format(suspect))
else:
    print("NO MATCH")
Das hätte wohl etwas den Zeitrahmen gesprengt und ich bin mir auch noch nicht sicher, ob das wirklich die beste Implementierung ist. Produktiv würde ich das jedenfalls nicht zum Einsatz empfehlen, weil nur ein erster Verdächtiger benannt wird, nicht alle möglichen Täter ermittelt werden.

Spellbinder

Aufgabe Spellbinder war Problem 2 bei HP Code wars II. Das Problem ist recht einfach, wie mir scheint:
import string


def buchstaben_ermitteln(eingabe,ausgabe):
    ''' Ermittelt den Buchstaben und stellt fest,
    ob es Groß- (capital) oder Kleinbuchstabe (lower-case)
    ist...
    '''
    for a, b in zip(eingabe,ausgabe):

        if a != b:
            letter = b
            break

    if letter in string.ascii_uppercase:
        type = "capital"
    else:
        type = "lower_case"

    return type,letter
    

data = """fountain mountain
pet pen
check chuck
Mike bike"""

data = data.split("\n")

for line in data:
    ''' Ausgabe
    '''
    ausgabe,eingabe = line.split(" ")

    type,letter = buchstaben_ermitteln(eingabe,ausgabe)
    
    print('Ripping the {} "{}" from his shirt, Letterman'.format(type,letter)) 
    
    print('changes "{}" back to "{}".'.format(eingabe,ausgabe))
Keine Herausforderung für 2 Punkte.

Palindromtest

Problem Nr. 3 bei HP Code Wars II war einen Palindromtest zu implementieren. Ich hatte mich mit dem Thema Palindrom bereits einmal befasst. Im Kern keine Herausforderung, aber eine nette Übung.
def palindrom_testen(word):
    ''' Teste auf Palindrom

    '''
    for zeichen in [" ",",",".",";","'","\n"]:
        word = word.replace(zeichen,"")
        
    if word.lower() == word.lower()[::-1]:
        return True
    else:
        return False


data = """1881 
Madam, I'm Adam. 
Lisa Bonet ate no basil. 
Taste penne pasta."""

data = data.split("\n")

for line in data:
    # Prüfung und Ausgabe
    print(line)

    if palindrom_testen(line):
        print("\tis a palindrome.")
    else:
        print("\tis *not* a palindrome.")
Den heutigen Teilnehmern an den HP Code wars viel Erfolg. Ich verfolge es gerade über Facebook.