Hallo zusammen,
ich möchte eine Funktion erstellen, die float Zahlen von 0.00 bis 0.50 in Schritten von 0.05 in eine Liste gibt und die ich danach ausgeben kann. Danach möchte ich die Quadrate dieser Zahlen ebenfalls ausgeben lassen. Das Problem das ich zurzeit habe ist, das ich keinen richtigen Anfang hinbekomme, da ich mit der for - Schleife und dem range()-Befehl ja nur int-Werte hochzählen lassen kann hilft mir diese ja nicht weiter. Danach hatte ich die Idee mit einer while Schleife also: while zahl <= 0.50: , da weiß ich aber nicht wie ich dann die zahlen hochzählen lassen kann und später dann eine Berechnung damit ausführen kann. Könnt Ihr mir da etwas auf die Sprünge helfen?
Rechenoperationen mit float Zahlen (Wertebereich)
@duodiscus
Vielleicht so?
mutetella
Vielleicht so?
Code: Alles auswählen
>>> def frange(start, stop, step, precise):
... while start < stop:
... yield round(start, precise)
... start += step
...
>>> list(frange(0.0, 0.5, 0.05, 2))
[0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5]
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@duodiscus: Also bei einer ``while``-Schleife müsstest Du doch nur in jedem Schleifendurchlauf 0.05 zu `zahl` dazu addieren. Aber Achtung: Die Genauigkeit von Gleitkommazahlen ist begrenzt und 0.05 kann der Rechner in diesem Format nicht exakt speichern:
Das heisst man kann nicht genau 0.05 addieren und damit addiert man bei jedem Schritt einen kleinen Fehler dazu und wenn man das 10 mal macht, kommt da *nicht* 0.5 heraus. Und es wird noch schräger, denn obwohl der tatsächliche Wert von 0.05 etwas *grösser* ist, wie man oben sehen kann, ist das Ergebnis von 10 mal 0.05 aufaddieren *kleiner* als 0.5:
Willkommen in der lustigen Welt der Gleitkommazahlen in Rechnern.
Wenn man also eine ``while zahl < 0.5:``-Schleife schreibt die mit `zahl` gleich 0 anfängt und in jedem Durchlauf 0.05 dazu addiert, dann wird diese Schleife 11 mal durchlaufen. Was überraschend sein kann.
Darum addiert man nicht wiederholt in Schleifen Gleitkommawerte auf, wenn sich das vermeiden lässt. Und das lässt sich vermeiden, denn man kann ja über die ganzen Zahlen 0 bis 9 mit einer ``for``-Schleife iterieren und die entsprechende Zahl daraus berechnen. Das kann auch etwas ungenau sein, prinzipbedingt wegen den Gleitkommazahlen, aber es addieren sich so nicht die ungenauigkeiten aller vorherigen Schleifendurchläufe auf. Zum Vergleich:
Mehr zum Thema Gleitkommazahlen: http://floating-point-gui.de/
Code: Alles auswählen
In [5]: '%.50f' % 0.05
Out[5]: '0.05000000000000000277555756156289135105907917022705'
Code: Alles auswählen
In [6]: sum(0.05 for _ in xrange(10))
Out[6]: 0.49999999999999994
Wenn man also eine ``while zahl < 0.5:``-Schleife schreibt die mit `zahl` gleich 0 anfängt und in jedem Durchlauf 0.05 dazu addiert, dann wird diese Schleife 11 mal durchlaufen. Was überraschend sein kann.
Darum addiert man nicht wiederholt in Schleifen Gleitkommawerte auf, wenn sich das vermeiden lässt. Und das lässt sich vermeiden, denn man kann ja über die ganzen Zahlen 0 bis 9 mit einer ``for``-Schleife iterieren und die entsprechende Zahl daraus berechnen. Das kann auch etwas ungenau sein, prinzipbedingt wegen den Gleitkommazahlen, aber es addieren sich so nicht die ungenauigkeiten aller vorherigen Schleifendurchläufe auf. Zum Vergleich:
Code: Alles auswählen
In [7]: zahl = 0
In [8]: zahlen = list()
In [9]: for _ in xrange(10):
...: zahl += 0.05
...: zahlen.append(zahl)
...:
In [10]: zahlen
Out[10]:
[0.05,
0.1,
0.15000000000000002,
0.2,
0.25,
0.3,
0.35,
0.39999999999999997,
0.44999999999999996,
0.49999999999999994]
In [11]: [0.05 * i for i in xrange(1, 11)]
Out[11]:
[0.05,
0.1,
0.15000000000000002,
0.2,
0.25,
0.30000000000000004,
0.35000000000000003,
0.4,
0.45,
0.5]
Um mal das aufzugreifen, was BlackJack geschrieben hat:
mutetella
Code: Alles auswählen
>>> def frange(start, stop, step, digits):
... for i in xrange(int(stop/step)+1):
... yield round(i*step, digits)
...
>>> list(frange(0.0, 0.5, 0.05, 2))
[0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5]
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
Danke für deine sehr ausführliche Antwort. Ich habe jetzt ein wenig damit rumprobiert und habe das Ergebnis nach deiner zweiten Variante in eine Liste übertragen. Der Tip mit der Fehlerquote war top. Das werde ich mir für spätere Sachen merken!
Wenn ich das Ergebnis aber statt in eine Liste vor zu einem Tupel formen möchte. Wie muss ich das syntaktisch da schreiben? Also Ergebnis in ein Tupel und das Tupel dann der Liste zuführen!
Der .append() Befehl gibt es ja nur bei Listen und funktioniert dort leider nicht.
Könnte man mir da nochmal weiterhelfen?
Ich habe nämlich danach dann vor, den jeweiligen durchlauf dann zu quadrieren, das Ergebnis wiederum dann auch einem Tupel zuführen und nachher der Liste hinzufügen.
Und ganz am Ende dann die Liste ausgeben.
Code: Alles auswählen
def f():
sammelstelle = [ ]
for e in range(1,11):
ergebnis = e*0.05
sammelstelle.append(ergebnis)
print(sammelstelle)
Der .append() Befehl gibt es ja nur bei Listen und funktioniert dort leider nicht.
Könnte man mir da nochmal weiterhelfen?
Ich habe nämlich danach dann vor, den jeweiligen durchlauf dann zu quadrieren, das Ergebnis wiederum dann auch einem Tupel zuführen und nachher der Liste hinzufügen.
Und ganz am Ende dann die Liste ausgeben.
@duodiscus: Ich verstehe glaube ich die Frage nicht wirklich: Du willst Tupel die genau ein Element enthalten haben? Warum? Das wäre doch nur unnötig umständlich. Wenn Du die Zahl dann quadrierst und sowohl die jeweilige Zahl als auch deren Quadrat als Tupel in einer Liste speichern möchtest, kannst Du *dann* Tupel mit den beiden Werten erstellen. Denn bei zwei Werten machen Tupel Sinn zum zusammenfassen.
@Sirius: Ich würde es nicht so machen. Aber in der Aufgabe die ich bearbeiten soll, ist es nunmal so vorgegeben.
@BlackJack: Nein du hast es missverstanden. Ich möchte es folgendermaßen bzw. soll es folgendermaßen aufbauen:
1. Zahlen von 0.0 bis 0.50 in 0.05er Schritten hochzählen lassen und diese Zahlen in einem Tupel ablegen.
2. Das Ergebnis dieser Zahlen zum Quadrat wiederum in ein weiteres/anderes Tupel geben.
3. Die Zahlen die hochgezählt wurden zur Basis 2 potenzieren, die Ergebnisse wiederum in ein weiteres Tupel geben.
4. Abschließend alle 3 Tupel in eine Liste geben.
5. Diese Liste dann zurückgeben.
Ich weiß jetzt nicht wie ich diese verschiedenen Tupel erstellen kann. Elemente einer Liste hinzufügen ist klar, aber wie die Ergebnisse in ein Tupel verwandeln?
@BlackJack: Nein du hast es missverstanden. Ich möchte es folgendermaßen bzw. soll es folgendermaßen aufbauen:
1. Zahlen von 0.0 bis 0.50 in 0.05er Schritten hochzählen lassen und diese Zahlen in einem Tupel ablegen.
2. Das Ergebnis dieser Zahlen zum Quadrat wiederum in ein weiteres/anderes Tupel geben.
3. Die Zahlen die hochgezählt wurden zur Basis 2 potenzieren, die Ergebnisse wiederum in ein weiteres Tupel geben.
4. Abschließend alle 3 Tupel in eine Liste geben.
5. Diese Liste dann zurückgeben.
Ich weiß jetzt nicht wie ich diese verschiedenen Tupel erstellen kann. Elemente einer Liste hinzufügen ist klar, aber wie die Ergebnisse in ein Tupel verwandeln?
@duodiscus:
als kleiner Hinweis
Code: Alles auswählen
l = range(10)
type(l)
#<type 'list'>
t = tuple(l)
type(t)
#<type 'tuple'>
Wobei das IMHO sinnfrei ist beziehungsweise sogar eine falsche Verwendung von Tupeln. Tupel verwendet man eher für Daten mit unterschiedlicher Bedeutung um die zu einem Objekt zusammen zu fassen. Also zum Beispiel Koordinaten oder einen Eintrag in einer Highscoreliste mit Punktanzahl und Name als Elemente. Das was Du da hast sind ja Daten wo jedes Element die gleiche Bedeutung hat — eine Zahl in der Sequenz.
@mcdwerner:
Danke
Er gibt mir aber bei mir eine Fehlermeldung:
Danke
Er gibt mir aber bei mir eine Fehlermeldung:
Code: Alles auswählen
for e in range(1,11):
a = e*0.05
ergebnis1 = tuple(a)
print(type(ergebnis1))
Code: Alles auswählen
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
f5()
File "/Users/A11.py", line 6, in f5
ergebnis1 = tuple(a)
TypeError: 'float' object is not iterable
@duodiscus: Ja, man kann ja auch eine Zahl nicht in ein Tupel umwandeln. Genau was die Fehlermeldung sagt. Du musst an `tuple()` ein Objekt übergeben über das man iterieren kann. Also zum Beispiel eine Liste mit den Zahlen. Also erst eine Liste mit den Zahlen erstellen und *die* danach in ein Tupel überführen.
Das ist einer der Gründe warum Tupel für so etwas blöd sind: Man muss schon ein anderes Objekt haben, das alle Elemente liefert um daraus ein Tupel zu erstellen, denn Tupel können nach dem Erstellen nicht mehr verändert werden.
Edit: Wenn man nicht gerade Anfänger ist, würde man einen Generatorausdruck als Argument verwenden, das hält den Quelltext halbwegs erträglich und man erzeugt keine extra Liste. Zumindest nicht explizit, und intern kann die `tuple()`-Funktion das besser optimieren als man das mit einer Liste auf Python-Ebene selber tun könnte:
Das ist einer der Gründe warum Tupel für so etwas blöd sind: Man muss schon ein anderes Objekt haben, das alle Elemente liefert um daraus ein Tupel zu erstellen, denn Tupel können nach dem Erstellen nicht mehr verändert werden.
Edit: Wenn man nicht gerade Anfänger ist, würde man einen Generatorausdruck als Argument verwenden, das hält den Quelltext halbwegs erträglich und man erzeugt keine extra Liste. Zumindest nicht explizit, und intern kann die `tuple()`-Funktion das besser optimieren als man das mit einer Liste auf Python-Ebene selber tun könnte:
Code: Alles auswählen
In [4]: tuple(i * 0.5 for i in xrange(1, 11))
Out[4]: (0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0)
Ich nehme mal an du darfst kein numpy verwenden, oder? (Andernfalls fehlt bei der Aufgabe der pädagogische Effekt, nehme ich an.)
Code: Alles auswählen
import numpy
a=numpy.arange(0,51,5)/100.
b=tuple(a)
c=tuple(a**2)
print type(b), b
print type(c), c