Hallo, ein Neuling steckt in Schwierigkeiten :)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Nein, stellt sie nicht. Das ist im moment die 2. Teilaufgabe und ich befinde mich in der Funktion neuesKind(kinderliste).

Zu enumerate() .. warscheinlich tu ich mich so schwer damit, weil man mir vor längerer Zeit schonmal das mit dem Laufindex eingeprügelt hat und dieser einen Widererkennungswert hat. Mein Hirn versucht an Sachen anzuknüpfen, die es schon kennt und nicht erst verstehen muss .. auch wenn es zugegebenermaßen bei enumerate() nicht viel zu verstehen gibt. :P Das Hirn muss trotzdem einmal drüber schlafen um es ordentlich abzuspeichern. :D

Das str.lower() hatte ich weiter unten in meinem Code, sollte ich das schon während der Eingabe einbauen?

Code: Alles auswählen

geschlecht = input('Geschlecht: ')
    while geschlecht not in ('m','w'):
        geschlecht = input('Nochmal das Geschlecht eingeben: ')
Das ist jetzt der Code, funktioniert erstmal dank des Tipps mit "not in" statt "!=" ... allerdings fängt er jetzt auch die Großbuchstaben W und M ab .. also muss ich lower() wohl doch schon bei der Eingabe einbauen.

@BlackJack:

Code: Alles auswählen

def werteAus(liste):
    i = 0
    m = w = n = 0
    
    for zeichen in liste:
        
        if zeichen == 'm':
            m +=1
        elif zeichen == 'w':
            w += 1
        else:
            liste[i] = None
            n += 1
        i += 1
Das ist der aktuelle Stand.

EDIT: Wie anstrengend es ist zwischen Programmierung und Forenbeiträgen lesen hin und her zu springen glaubt echt kein Mensch! :D

EDIT2:
So sieht der Code "neuesKind(kinderliste)" jetzt aus.

Code: Alles auswählen

def neuesKind(kinderliste):
    name = vorname = geschlecht = ''
    while name == '':
        name = input('Nachname: ')
    while vorname == '':
        vorname = input('Vorname: ')
    geschlecht = input('Geschlecht: ')
    while geschlecht.lower() not in ('m','w'):
        geschlecht = input('Nochmal das Geschlecht eingeben: ')
            

        
    kinderliste.append([name, vorname, geschlecht.lower()])
    
    return kinderliste

liste = []
print(neuesKind(liste))
Die Aufgabe wäre damit ja erledigt wenn ich das richtig sehe.
Noch irgendwelche Anmerkungen zu Sachen die unnütz oder doppelt gemoppelt sind wie z.B. die lower() Funktion? Ich würde (wenn ich könnte) die ja gleich in die Eingabe mit einbinden. Ich probier mal rum.

EDIT3:
Ok der Tipp von Hyperion mit dem "str.lower()" hat gefruchet.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: EDIT3:
Ok der Tipp von Hyperion mit dem "str.lower()" hat gefruchet.
Hm... nur bedingt! Du musst das nun zweimal anwenden... wieso manipulierst Du nicht das Ergebnis der Eingabe *direkt*? (Da Du vor der Schleife ein imho unnötigs `input` durchführst, sparst Du so noch nichts - aber wenn Du das eliminierst, dann wird es effizienter!)

So sähe meine Lösung aus:

Code: Alles auswählen

    while True:
        geschlecht = input("Geschlecht: ").lower()
        if geschlecht in ("m", "w"):
            break
    kinderliste.append([name, vorname, geschlecht])
Und das `return` ist immer noch unnütz - auch wenn in der Aufgabenstellung dies bezüglich etwas uneindeutiges steht...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@hoola: Deine Funktion zu Aufgabe 2.a ist so noch nicht "fertig"...

Ich habe mal einen Gist erzeugt, in dem ich die Klausur gelöst habe: Link

Aufgabe 2.a löse ich aber auch nicht exakt, wie gewollt. Da "schlampe" ich ein wenig ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Also zu dem str.lower(), ich habe das in meinen Code "eingepflegt", nur noch nicht hier reingestellt.
Aber du hast recht, ich muss es 2 mal benutzen .. bei der ersten Eingabe und bei der Fehlereingabe.
Deine Lösung ist da natürlich wesentlich eleganter.
Statt "while True" hättest auch irgendetwas anderes schreiben können a la "while 3<4" oder so .. da soll einfach irgendwas stehen um die Schleife ewig durchlaufen zu lassen. Beendet wird sie lediglich durch break, versteh ich das richtig?

Hauptsache du hast die Klausur gelöst .. nur gut, dass mir die meisten Lösungen nicht all zu viel bringen .. dann kann ich mich nicht so gut selbst bescheißen :P

Hab nochmal eine Frage zu Aufgabe 3.
Das habe ich bisher programmiert:

Code: Alles auswählen

#Aufgabe 3
def kuerze(string, n):
    string.split(' ')
    for wort in string:
        wort = wort[:n]
        
    return string.join(' ')

text = 'Kuchen Torte Mezzoforte'
kuerze(text, 3)
print(text)
Ich schätze mal diese Zeile wird falsch sein "wort = wort[:n]". Jemand einen klugen Ratschlag? Sitz jetzt schon wieder seit über einer Stunde an diesem Problem ... -_-
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: Statt "while True" hättest auch irgendetwas anderes schreiben können a la "while 3<4" oder so .. da soll einfach irgendwas stehen um die Schleife ewig durchlaufen zu lassen. Beendet wird sie lediglich durch break, versteh ich das richtig?
Genau. Aber `3<4` ergibt auch `True`. `while` wertet den folgenden Ausdruck bezüglich seines Wahrheitswertes aus. Daher kann man anstatt irgend wie umständlich eine immer wahre Bedingung zu formulieren auch einfach den direkten Weg nehmen und `while True` schreiben.
hoola hat geschrieben: Hauptsache du hast die Klausur gelöst .. nur gut, dass mir die meisten Lösungen nicht all zu viel bringen .. dann kann ich mich nicht so gut selbst bescheißen :P
Du musst ja nicht spicken :-P
hoola hat geschrieben: Hab nochmal eine Frage zu Aufgabe 3.
Ich schreibe mal Kommentare in Deinen Code:

Code: Alles auswählen

#Aufgabe 3
def kuerze(string, n):
    # Du bindest das Ergebnis von `str.split` an keinen Namen!
    # Damit "wirfst" Du das Ergebnis de facto weg.
    string.split(' ')
    # hier musst Du Dich auf eben diesen Rückgabewert (also die Liste mit Wörtern!) beziehen
    for wort in string:
        # Du merkst Dir hier nur pro Durchlauf der Schleife *ein* gekürztes Wort
        # Du musst Dir aber *alle* gekürzten Wörter merken.
        # Also brauchst Du noch z.B. ein Listenobjekt, in dem Du das erledigen kanns
        wort = wort[:n]
    # das hier geht komplett in die Hose. `join` ist eine *Methode* auf einem
    # String-Objekt. Wenn Du also eine Liste von Strings zusammensetzen willst, dann lege einen String fest, der als Verbindungselement dient.
    # Du willst dafür ein einzelnes Space: `" ".join(Listenobjekt)`
    return string.join(' ')
Ich hoffe das hilft Dir als Denkanstoß weiter. Meine Lösung macht im übrigen genau das beschriebene - ich nutze nur eine kompaktere Schreibweise dafür (aka Generatorausdruck).

Du musst Dir besser klar machen, wann man "neue" Objekte durch eine Funktion erhält und wann bestehende Objekte verändert werden. Das ist wirklich elementar und wichtig.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ergänzend dazu ist der Bezeichnername string extrem unglücklich gewählt, da er das eingebaute Modul string verdeckt.
BlackJack

Naja, „eingebaut” würde ich das nicht nennen. Es ist halt in der Standardbibliothek. Wenn man es nicht importiert würde ich den Namen als „frei” ansehen.
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Code: Alles auswählen

#Aufgabe 3
def kuerze(string, n):
    neue_liste = string.split(' ')
    end_liste=[]
    for wort in neue_liste:
        wort = wort[:n]
        end_liste.append(wort)

    print(' '.join(end_liste))


text = 'Kuchen Torte Mezzoforte'
kuerze(text, 4)
So sieht der Code jetzt nach bearbeitung und Anwendung deiner Tipps aus. Ich hoffe das ist soweit ok. Jedenfalls tut er das, was er soll. Nur ganz sicher bin ich mir nicht was die Satzzeichen angeht. Immerhin sollen diese bestehen bleiben, soweit ich das aus der Aufgabenstellung entnehmen kann.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:Naja, „eingebaut” würde ich das nicht nennen. Es ist halt in der Standardbibliothek. Wenn man es nicht importiert würde ich den Namen als „frei” ansehen.
Und dann greift man potenziell ins Klo wenn das Modul später doch mal importiert wird.
BlackJack

@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.

Hier mal mein Ansatz (ist für Python 2.x geschrieben):

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())
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Oops, ich hatte da wohl die letzte Aufgabe nicht korrekt gelesen. Hier die korrigierte Version. BlackJacks Ansatz mit der Datenstruktur ist aber wesentlich besser und auch beim Parsen müsste ich mir mehr "Mühe" geben.

@BlackJack: Dafür ist Deine Rückgabe bei Aufgabe 1 nicht korrekt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Mal zu aufgabe 4 a).
Ich bin gerade dabei mir die Grundsätze des Dictionarys anzueignen .. scheint ja nicht all zu schwer zu sein.
Allerdings verstehe ich bei BlackJacks Lösung folgendes nicht ganz: "Date(2009, 1, 1)".
Ist "Date()" jetzt ein Tupel oder eine extra Funktion von Python oder was?
Verstehe grad den Grund nicht wirklich, warum der Stand in dieser Form dargestellt werden muss.
Kann man den Stand so besser ändern, wenn es mal eine "neue Version" einer Karte geben sollte?
Ich dachte Tupel sind immutabel, oder ist das gar kein Tupel?
Könnt ihr mir auf die Sprünge helfen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: Ist "Date()" jetzt ein Tupel oder eine extra Funktion von Python oder was?
Da hilft ein Blick ganz nach oben in BJs Lösung:

Code: Alles auswählen

from datetime import date as Date
Das ist ein spezieller Datentyp für ein Datum in Python. Kannst das in der Doku im `datetime`-Modul mal nachlesen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Was bewirkt die dreifache Zuweisung in ``sex = sexes = sex if sex in allowed_sexes else None``?
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Hyperion hat geschrieben:
hoola hat geschrieben: Ist "Date()" jetzt ein Tupel oder eine extra Funktion von Python oder was?
Da hilft ein Blick ganz nach oben in BJs Lösung:

Code: Alles auswählen

from datetime import date as Date
Das ist ein spezieller Datentyp für ein Datum in Python. Kannst das in der Doku im `datetime`-Modul mal nachlesen.
Super vielen Dank.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

webspider hat geschrieben:Was bewirkt die dreifache Zuweisung in ``sex = sexes = sex if sex in allowed_sexes else None``?

BlackJack "überschreibt" damit `sex`, damit er die Vorkommen im `defaultdict` korrekt hochzählen kann. Man will da ja wissen, wieviele "Fehler" aufgetreten sind, daher muss man sich da auf den Wert `None` beziehen und nicht auf `s` oder was da sonst noch stehen könnte.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Ups, hier 1 b) mit korrektem Rückgabetyp. :oops:

Code: Alles auswählen

# 
# 1 b)
# 
def get_unique_characters(string):
    """
    >>> get_unique_characters('')
    []
    >>> get_unique_characters('baabcad')
    ['a', 'b', 'c', 'd']
    >>> get_unique_characters('mississippi')
    ['i', 'm', 'p', 's']
    >>> get_unique_characters('python')
    ['h', 'n', 'o', 'p', 't', 'y']
    """
    return sorted(set(string))
@webspider: Das ist nur eine zweifache Zuweisung. Da wird entweder der Wert von `sex` oder `None` an `sex` und `sexes` gebunden, je nach dem ob es ein erlaubter Wert ist oder nicht. Das da `sexes` mit drin steht hat den Grund in der IMHO komischen Aufgabenstellung dass die Funktion eine Änderung der Liste als Seiteneffekt haben soll.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ja, da sind einige Sachen eher "unpythonisch" und allgemein sonderbar. Ich denke wir sind uns auch einig, dass da vieles eben nicht mit Bordmitteln gelöst werden soll - Aufgabe 1 ist mit unserer Lösung ja eher, nunja, "trivial". Ich vermute doch mal stark, dass hier eher C-like Schleifen a la "problembär" benutzt werden sollten. Aber vielleicht irre ich mich auch :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Aufgabe 1 b) scheint mir gar keine ernsthafte Programmieraufgabe zu sein, sondern einfach nur geschenkte Punkte für Leute, die den gegebenen Quelltext von 1 a) verstanden haben und sich noch erinnern wie man Funktionen definiert. ;-)
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Code: Alles auswählen

ISBN = {
    '9783768825825':['Delius Klasing','MV - Bornholm', Date(2009, 1, 1), 54.90, 2],
    '9783768832021':['Delius Klasing','MV - Bornholm', Date(2011, 1, 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 inventur(dictionary):
    summe = 0
    for key in dictionary.keys():
        summe += dictionary[key][3]*dictionary[key][4]
    return summe

print(inventur(ISBN))
Aufgabe 4 b) geschafft .. Dictionarys scheinen relativ einfach sein.
Geht die Lösung so?
Antworten