Relative Häufigkeiten Fehler

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.
Antworten
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

Ich hab ein Programm geschrieben das fuer mich wuerfelt und das Ergebniss der Wuerfelei auswertet.
Allerdings berechnet er mir nicht die relativen Häufigkeiten ordnungsgemäß, da er bei jedem 0% anzeigt.
Wo ist der Fehler?

Code: Alles auswählen

import time, random
Z = [0, 0, 0, 0, 0, 0]
print "[1] Muenze werfen \n[2] Wuerfeln"
A = int(raw_input("Zahl fuer Aktion eingeben"))
print

if A == 1:
    W = int(raw_input("Wie of moechtest du werfen?"))
    print "\nDie Muenze wird " + str(W) + " mal geworfen.\n"
    for i in range (W):
        We = random.randint (1, 2)
        if We == 1: Z[0] += 1
        elif We == 2: Z[1] += 1
    time.sleep(2)
    print "Anzahl Kopf " + str(Z[0]) + "   relative Haeufigkeit: " + str((Z[0] / W) * 100.0) + "%"
    print "Anzahl Zahl " + str(Z[1]) + "   relative Haeufigkeit: " + str((Z[1] / W) * 100.0) + "%\n"

if A == 2:
    W = int(raw_input("Wie oft moechtest du werfen"))
    print "\nEs wird " + str(W) + " mal geworfen.\n"
    for i in range(W):
        We = random.randint (1, 6)
        if We == 1: Z[0] += 1
        if We == 2: Z[1] += 1
        if We == 3: Z[2] += 1
        if We == 4: Z[3] += 1
        if We == 5: Z[4] += 1
        if We == 6: Z[5] += 1
        
    time.sleep(2)
    print "1 gewuerfelt: " + str(Z[0]) + "   relative Haeufigkeit: " + str((Z[0] / W) * 100.0) + "%"
    print "2 gewuerfelt: " + str(Z[1]) + "   relative Haeufigkeit: " + str((Z[1] / W) * 100.0) + "%"
    print "3 gewuerfelt: " + str(Z[2]) + "   relative Haeufigkeit: " + str((Z[2] / W) * 100.0) + "%"
    print "4 gewuerfelt: " + str(Z[3]) + "   relative Haeufigkeit: " + str((Z[3] / W) * 100.0) + "%"
    print "5 gewuerfelt: " + str(Z[4]) + "   relative Haeufigkeit: " + str((Z[4] / W) * 100.0) + "%"
    print "6 gewuerfelt: " + str(Z[5]) + "   relative Haeufigkeit: " + str((Z[5] / W) * 100.0) + "%\n"

print W
print Z[0]
raw_input("")
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Der Fehler: Integer-Division vs. "normale" Division

Code: Alles auswählen

In [1]: 1 / 2
Out[1]: 0

In [2]: 1.0 / 2
Out[2]: 0.5

In [3]: float(1) / 2
Out[3]: 0.5

In [4]: from __future__ import division

In [5]: 1 / 2
Out[5]: 0.5
Edit: Noch ein paar Anmerkungen:

Code: Alles auswählen

        We = random.randint (1, 6)
        if We == 1: Z[0] += 1
        if We == 2: Z[1] += 1
        if We == 3: Z[2] += 1
        if We == 4: Z[3] += 1
        if We == 5: Z[4] += 1
        if We == 6: Z[5] += 1
zu

Code: Alles auswählen

        We = random.randint (1, 6)
        Z[We - 1] += 1
oder du verwendest ein Dictionary und umgehst das Umrechnen auf einen Index.

Code: Alles auswählen

print "1 gewuerfelt: " + str(Z[0]) + "   relative Haeufigkeit: " + str((Z[0] / W) * 100.0) + "%"
Du suchst String-Formatierung:

Code: Alles auswählen

print "1 gewuerfelt: %d relative Haeufigkeit: %.2f%%" % (Z[0], Z[0] * 100.0 / W))
Und gleich alle mit einer Schleife ausgeben:

Code: Alles auswählen

 for eyes, frequency in enumerate(Z, 1):
    print "%d gewuerfelt: %d relative Haeufigkeit: %.2f%%" % (eyes, frequency, frequency * 100.0 / W)
Die Namen sind uebrigens unter aller Sau :roll:
BlackJack

@Dexter1997: Die Divisionen passieren mit ganzen Zahlen, das heisst beim Ergebnis ist der Nachkommateil nicht vorhanden. Mindestens einer der beiden Operanden muss eine Gleitkommazahl sein, oder Du musst als ersten ``import`` einen ``from __future__ import division`` in das Modul schreiben.

Schön ist das ganze Programm nicht gerade. Das sollte man auf mindestens drei Funktionen aufteilen, je eine für die beiden Programmpunkte und eine für das Hauptprogramm. Dann sind die ganzen einbuchstabigen Namen ziemlich nichtssagend. Blöcke sollten eingerückt in der Zeile nach dem ``:`` stehen, auch wenn sie nur aus einer Zeile bestehen. Da ist viel Quelltext der nach kopieren und einfügen und ganz geringfügig ändern aussieht, der in Schleifen gehört, oder anderweitig verkürzt werden kann. Zeichenketten und Werte mit ``+`` und `str()` zusammensetzen ist kein idiomatisches Python. Dazu ist das ``print`` sogar unnötig die Zeichenkette überhaupt zusammenzusetzen. Man könnte Texte und Werte auch einfach mit Kommas trennen. Statt `range()` sollte man `xrange()` verwenden wenn man die Liste mit den Zahlen nicht braucht.
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

Danke für die schnelle und hilfreiche Antwort! :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hier mal ein Vorschlag in Python3: Gist

Die Kernfunktionalität kann man schön verallgemeinern; ich habe sie mittels zweier Funktionen ``generate_distribution`` und ``calculate_rates`` umgesetzt. Im Endeffekt unterscheiden sich Münze und Würfel ja nicht - lediglich die Anzahl an Möglichkeiten ändert sich (zwei bzw. sechs). Insofern bietet es sich an, die Durchführung des Werfens / Würfelns und die Auswertung zu vereinheitlichen.

Ob der Ausgabe kann man sich streiten; da der OP auch dort relativ ähnliche Ausgaben wollte, habe ich das mittels Template-Strings ebenfalls gekaspelt.

Evtl. wäre eine Klasse für die Datenhaltung sogar sinnvoller gewesen... naja, kleine Übung für andere Teilnehmer ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Vorschlag für Python 2:

Code: Alles auswählen

#!/usr/bin/env python
from __future__ import division
import random
from collections import namedtuple, OrderedDict

Experiment = namedtuple('Experiment', 'subject article choices')

EXPERIMENTS = [
    Experiment('Muenze', 'die', ['Kopf', 'Zahl']),
    Experiment('Wuerfel', 'der', xrange(1, 7)),
]


def create_histogram(choices, count):
    result = OrderedDict.fromkeys(choices, 0)
    for _ in xrange(count):
        result[random.choice(choices)] += 1
    return result


def main():
    print '\n'.join(
        '[{0}] {1}'.format(i, e.subject) for i, e in enumerate(EXPERIMENTS, 1)
    )
    experiment = EXPERIMENTS[int(raw_input('Was soll geworfen werden: ')) - 1]
    total_count = int(raw_input('Wie oft moechtest Du werfen: '))
    print '{0} {1} wird {2} mal geworfen'.format(
        experiment.article.title(), experiment.subject, total_count
    )
    histogram = create_histogram(experiment.choices, total_count)
    for value, count in histogram.iteritems():
        print 'Anzahl {0}: {1}  relative Haeufigkeit {2:.2f}%.'.format(
            value, count, count / total_count * 100.0
        )


if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

»format« kann auch in Prozent ausgeben:

Code: Alles auswählen

print 'Anzahl {0}: {1}  relative Haeufigkeit {2:.2%}.'.format(value, count, count / total_count)
Antworten