Datum:
Hallo liebe Experten, ich brauche etwas, das die Werte der E-Reihen in einem bestimmten Wertebereich listet und habe das nachstehende zusammengefrickelt:
def e_series(ser, minimum, maximum):
'''
values of the E<ser>-series from minimum to maximum.
ser may be =6, 12, 24, 48, 96
'''
# vollstaendiger code im anhang
series = {6: [1.0, 1.5, 2.2, 3.3, 4.7, 6.8],
12: [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2]}
base_decade = 10.0 ** int(math.log10(minimum) - 1)
top_decade = 10.0 ** (int(math.log10(maximum)) + 1)
decade = base_decade
while decade <= top_decade:
for factor in series[ser]:
value = decade * factor
if minimum <= value <= maximum:
yield value
decade *= 10
if __name__ == '__main__':
for i in e_series(12, 0.1001, 6):
print i,
print
|
Die Ausgabe ist '0.12 0.15 0.18 0.22 0.27 0.33 0.39 0.47 0.56 0.68 0.82 1.0 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6'. Ich würde das ganze gerne so erweitern, dass der Wert davor und der danach (also 0.1 und 6.2) optional auch geliefert werden können und stehe irgendwie auf dem Schlauch. Hat jemand eine Idee? Alle Verbesserungsvorschläge und elegantere Lösungen sind auch höchst willkommen, der Code oben hat einige sehr hässliche Stellen, z.B. 'if minimum <= value <= maximum:' und die Berechnung der Dekaden. Grüße, Tom EDIT: Effizienz ist in diesem Fall ziemlich egal, Wenn auf einem Core2Duo ein Wert pro Sekunde rauskommt, wäre das auch noch ausreichend ;)
Datum:
Angehängte Dateien:Anhang ging nicht.
Datum:
Angehängte Dateien:Hab mal was ziemlich Generatorisches zusammengefrickelt (e_series.py). Die optionalen Davor- und Danach-Werte erfordern allerdings leichte Verrenkungen. Deswegen habe ich noch eine vereinfachte Version ohne diesen Zusatz hochgeladen (e_series_simple.py). Sie entspricht im Wesentlichen deiner ursprünglichen Version, unterstützt aber alle E<k>-Reihen mit k=3·2^n, also E3, E6, E12, E24, E48, E96, E192 usw. Edit: Da ist noch ein Fehler drin. Korrektur siehe Beitrag "Re: Python: Generator für E-Reihen"
Datum:
>Hab mal was ziemlich Generatorisches zusammengefrickelt
Hm. Und Du hast die berechneten Werte alle mit den Normwerten
verglichen?
Ich hatte leider nie eine genaue Vorschrift für die Rundung gefunden --
bei Wikipedia heißt es "Die Glieder der Folge werden so gerundet, dass
sich bei den Reihen E3 bis E24 zwei und bei den Reihen E48 bis E192 drei
signifikante Stellen und außerdem zwischen benachbarten Folgengliedern
minimale Differenzen ergeben." Was gemeint ist, ist mir zwar vom Prinzip
klar, aber nicht so recht, wie man das konkret realisieren soll. Es gibt
jedenfalls Aussagen, dass die E-Reihen recht willkürlich sind und nicht
wirklich berechnet werden können. Zumindest heißt es bei Wikipedia ja
auch "entsprechen in der E24-Reihe die Werte von 2,7 bis 4,7 nicht den
Rundungsregeln".
Na gut, Dir traue ich durchaus eine richtige Lösung zu.
Was ich mal machen wollte: Ein Skript, wo man einen gewünschte Wert und
die zulässige Toleranz eingibt und dann passende E-Reihen-Werte bekommt.
Datum:
Angehängte Dateien:>Hm. Und Du hast die berechneten Werte alle mit den Normwerten >verglichen? Nun ja, es sieht ja schon recht gut aus. Allerdings gibt dein Script mit der geänderten Zeile >for r in e_series(192, 100, 1000, True): bei mir dem Wert 919.0 aus. Nach Wikipedia sollte das eher 920 sein. http://de.wikipedia.org/wiki/E-Reihe Ich habe mal die Werte von http://en.wikipedia.org/wiki/Preferred_number#E_se... zusammen kopiert, siehe Anhang. Mit cut --fields=4 E-Reihen.txt |grep "\S" bekommt man die einzelnen Reihen unter Unix, fields= kann 1 bis 6 sein je nach Reihe. Mit diff kann man dann die Werte mit dem Python-Script vergleichen. Na ja wer mag, ich kenne mich besser mit Ruby als mit Python aus...
Datum:
Mist, du hast recht :-/ Die E24-Reihe habe ich kontrolliert. Dafür eine Formel zu finden, war auch nicht ganz leicht, weil die Werte teilweise ziemlich willkürlich augewählt worden sind. Auf jeden Fall stimmen damit auch E12, E6 und E3. Für E48 und darüber habe ich einmal gelesen, dass diese einfach durch Runden der Werte der entsprechenden Exponentialfunktion ergeben und habe sie deswegen nur stichprobenweise kontrolliert. Anscheinend war aber diese Information falsch bzw. das zu verwendende Rundungverfahren ist ein komplizierteres. Es ist wohl so, dass bei der Rundung nicht nur der jeweils aktuelle Wert, sondern auch die beiden Nachbarn mit einbezogen werden, um einen möglichst gleichmäßigen Verlauf zu erhalten. Da müsste ich also noch einmal darübergehen :) Im Moment habe ich nur keinen PC hier.
Datum:
Du kannst die E-Reihe nicht mit einer Formel ausrechnen. Das sieht man bei Wikipedia ( siehe Link oben ), wenn man auf Diskussionen geht ist dort ein einfacher Java Code, der nach der angegebenen Formel die Werte der E-Reihe bestimmt und ausgibt. Es sind dann die Werte markiert, die von der ( realen ) E-Reihe abweichen.
Datum:
Ich habe die Werte nun für alle E-Reihen komplett überprüft. Der von Stefan gefundene Fehler Stefan Salewski schrieb: > bei mir dem Wert 919.0 aus. > Nach Wikipedia sollte das eher 920 sein. war der einzige. Der rechnerische Wert 9,19 in der E192-Reihe hat die unschöne Eigen- schaft, dass sich seine Abstände zum Vorgänger (9,09) und Nachfolger (9,31) um 2 unterscheiden. Für alle anderen Werte in der Reihe beträgt dieser Unterschied maximal 1. Das ist wohl der Grund, warum der Wert in der offiziellen E192-Reihe durch 9,20 ersetzt wurde. Ersetzt man in den obigen Programmen die Zeile 22
series = [round(10**(i/float(ser)), 2) for i in range(ser)] |
durch
series = [round(10**(i/192.)+i**3*4e-11, 2) for i in range(0, 192, 192/ser)] |
sind alle Werte in E3, E6, E12, E24, E48, E96 und E192 korrekt. Ich gebe zu: Ein wenig hingemurkst ist es ja schon :)
Datum:
Vielen Dank! Die Zauberei mit itertools muss ich mir mal genauer ansehen.