Seite 2 von 3

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 16:49
von Hyperion
Naja, es fehlt zunächst die Eingabe des Geschlechts ;-)

Und dann suchst Du die Methode `list.append()`; damit kannst Du ein Element zu einer Liste hinzufügen. Dieses Element ist laut Aufgabenstellung auch wieder eine Liste, wobei diese eben genau drei Element hat: Die Namen und das Kürzel für das Geschlecht.

Das `return` ist hier überflüssig, da Du ein bereits bestehendes Objekt änderst. Ich demonstriere das hier mal:

Code: Alles auswählen

data = []

def modify(data):
    data.append(["Python", 42])

modify(data)

print data
#-> [['Python', 42]]

modify(data)

print data
#-> [['Python', 42], ['Python', 42]]
Wie Du siehst wird das Objekt hinter dem Namen `data` innerhalb der Funktion `modify` geändert, da es der Funktion als Parameter übergeben wird. Ich muss es nicht zurückgeben, wie man es bei einer Kopie oder einem neuen Objekt tun würde.

Edit: Ok, nach mehrmaligen Lesens der Aufgabe sehe ich es auch so, dass man wohl falsche Eingaben beim Geschlecht abfangen soll. Prinzipiell regelt man so etwas gerne über `while`-Schleifen. Entweder durch eine Endlosschleife (`while True: ...`), aus der nur heraus gesprungen wird (z.B. via `break`), wenn eine korrekte Eingabe erfolgt ist, oder durch das Testen auf eine korrekte Eingabe im Kopf der Schleife.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 16:59
von hoola
BlackJack hat geschrieben:@hoola: Wenn man Element *und* Index benötigt ist `enumerate()` der vorgesehene Weg. Es geht auch anders, aber eigentlich nicht einfacher. Es gibt in der Tat tausende Funktionen, aber `enumerate()` gehört zu denen, die ohne explizit importiert werden zu müssen zur Verfügung stehen. Das gehört also zum Kernbereich der Sprache. Sind in den 3 SWS schon die Stunden inbegriffen, die ihr euch ausserhalb der Vorlesung/Übung damit beschäftigt? Bei uns (Uni) wurde immer betont dass die Veranstaltungen nicht die Programmiersprachen lehren sollen, sondern dass man sich das selbst aneignen muss.
Ist natürlich richtig .. außerhalb des Infokurses soll man auf jede SWS ungefähr 2 Stunden nacharbeiten. Aber das gleiche erwartet auch jeder andere Prof. von dir und das dann in Fächern, die für mein Eigentliches Ziel (nämlich Betriebsingenieur zu werden) von wesentlich größerer Bedeutung sind.
Irgendwo muss man leider immer Abstriche machen .. und so ist das bei Informatik der Fall gewesen. Andere Module hatten für mich Priorität.
Aber enumerate() werde ich mir wohl noch merken können, zumal es eine sehr schöne Funktion zu sein scheint. Aber mich würde rein aus Interesse doch noch interessieren, wie man die Geschichte ohne enumerate() löst. Irgendwie muss ich ja an den Index des gerade bearbeiteten Elementes rankommen. Da würde mir index() einfallen .. allerdings bekommt man da ja nur den Index des ersten Zeichens in der Liste .. ist ja doof, wenn das Zeichen mehrmals existiert.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:12
von Hyperion
hoola hat geschrieben: Aber mich würde rein aus Interesse doch noch interessieren, wie man die Geschichte ohne enumerate() löst. Irgendwie muss ich ja an den Index des gerade bearbeiteten Elementes rankommen.
Es gibt keine Methode, mit der Du an den aktuellen Index herankommst - was ist auch schon der "aktuelle" Index? ;-)

Da `enumerate` das Mittel der Wahl ist, hier nur einige Workarounds:

- Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)

- Du kannst `enumerate` mittels `itertools.count` emulieren:

Code: Alles auswählen

from itertools import count, izip

l = ["a", "b", "c"]

for index, item in izip(l, count()):
    print index, item

# ->
# a 0
# b 1
# c 2
- Du kannst Dein eigenes `enumerate` schreiben:

Code: Alles auswählen

def my_enumerate(iterable, start=0):
    for index, item in izip(l, count(start)):
        yield index, item

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:28
von hoola

Code: Alles auswählen

while geschlecht != ('m','w'):
        geschlecht = input('Geschlecht: ')
Wo ist denn hier der Fehler?
Ich check es einfach nicht. :(
Er will nach einer Eingabe, egal ob rictig oder falsch, einfach nicht aus der Schleife springen.
Kann ja nur an "geschlecht != ('m','w')" liegen ..

Oder kann ich "geschlecht != ('m','w')" nur in einer if-Anweisung benutzen? :K

EDIT:
Also mal zur Fehleingabe .. ich muss zuerst prüfen, ob in Geschlecht etwas drin steht bzw. ob 'm' oder 'w' drin steht. Wenn das nicht der Fall ist, soll nochmal eine Eingabe erfolgen. Das kann doch nun wirklich nich so schwer sein oder was?

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:34
von hoola
Hyperion hat geschrieben: - Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)
Nach sowas hab ich gesucht .. danke.
Auch wenn die anderen Lösungen super sind .. sowas allgemeines wie Zählvariable im Schleifenrumpf mitlaufen lassen kann ich mir bis zur Prüfung auf jeden Fall merken und vielfach anwenden.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:36
von EyDu
Du meinst: Solange geschlecht nicht "m" oder "w" ist. Geschrieben hast du aber: solange geschlecht nicht ("m", "w"). Wie soll denn die Eingabe zu einem Tupel werden? Was du meinst ist:

Code: Alles auswählen

while geschlecht not in ("m", "w")

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:37
von Hyperion
Des weiteren fehlt da ein `str.lower()` ;-)

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:38
von EyDu
hoola hat geschrieben:
Hyperion hat geschrieben: - Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)
Nach sowas hab ich gesucht .. danke.
Auch wenn die anderen Lösungen super sind .. sowas allgemeines wie Zählvariable im Schleifenrumpf mitlaufen lassen kann ich mir bis zur Prüfung auf jeden Fall merken und vielfach anwenden.
Ich kann ehrlich nicht verstehen, wass an einem

Code: Alles auswählen

index = 0
for x in xs:
    ...
    index +=1
leichter zu merken sein soll, als das sprechende

Code: Alles auswählen

for index, x in enumerate(xs):
    ...
Es ist ja nicht so, dass es da etwas zu verstehen gibt.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:42
von Hyperion
@EyDu: Tja, diese Frage haben wir doch einem ehemaligen Forenmitglied so gefühlte einhundert Mal gestellt... :mrgreen:

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:43
von BlackJack
@hoola: Falls die zuletzt gezeigte `werteAus()`-Funktion der aktuelle Stand ist, dann erfüllt sie nicht die Aufgabenstellung. Ganz so schlecht ist die nämlich nicht gestellt.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 17:57
von hoola
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.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 19:25
von Hyperion
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...

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 19:29
von Hyperion
@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 ;-)

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 20:04
von hoola
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 ... -_-

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Samstag 7. Juli 2012, 21:06
von Hyperion
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.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Sonntag 8. Juli 2012, 01:37
von /me
Ergänzend dazu ist der Bezeichnername string extrem unglücklich gewählt, da er das eingebaute Modul string verdeckt.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Sonntag 8. Juli 2012, 07:56
von 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.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Sonntag 8. Juli 2012, 09:34
von hoola

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.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Sonntag 8. Juli 2012, 09:36
von /me
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.

Re: Hallo, ein Neuling steckt in Schwierigkeiten :)

Verfasst: Sonntag 8. Juli 2012, 09:43
von 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())