Seite 1 von 1
Wurzelberechnung
Verfasst: Sonntag 7. Februar 2010, 15:37
von Dav1d
1 Funktion zur Berechnung der n-ten Wurzel aus x
und eine zur Berechnung der 2. Wurzel aus x
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
from decimal import Decimal, getcontext
def calculate(wexp, radi, acc=50):
'''Berechnung mithilfe der numerischen Berechnung
wexp = Wurzelexponent, radi = Radikand'''
getcontext().prec = acc
y = 2
wexp = Decimal(str(wexp))
radi = Decimal(str(radi))
while True:
old_y = y
y = ((wexp - 1) * y**wexp + radi) / (wexp * y**(wexp-1))
if old_y == y:
break
return y
def calculate_newton(radi, acc=50):
''' Berechnung mithilfe des Newton-Verfahrens, nur f�r
die 2. Wurzel!'''
getcontext().prec = acc
y = 2
einhalb = Decimal('0.5')
radi = Decimal(str(radi))
while True:
old_y = y
y = einhalb * (y + (radi/y))
if old_y == y:
break
return y
if __name__ == '__main__':
print calculate(2, 2, 10)
print calculate_newton(2)
Re: Wurzelberechnung
Verfasst: Sonntag 7. Februar 2010, 16:05
von numerix
Dav1d hat geschrieben:1 Funktion zur Berechnung der n-ten Wurzel aus x
Code: Alles auswählen
>>> from decimal import Decimal
>>> nroot = lambda x,n:(Decimal(x).ln()/n).exp()
>>> print nroot(12345,6)
4.807454497944548271506999339
Dav1d hat geschrieben:und eine zur Berechnung der 2. Wurzel aus x
Code: Alles auswählen
>>> print Decimal(12345).sqrt()
111.1080555135405112450044387
Im übrigen ist "calculate" ein ausgesprochen schlechter Name für eine Funktion, weil es nichts darüber aussagt, WAS berechnet wird.
Verfasst: Sonntag 7. Februar 2010, 16:15
von EyDu
Den gezeigen Code könnte man auch nochweiter verallgemeinern:
Code: Alles auswählen
def calculate(wexp, radi, acc=50):
wexp = Decimal(str(wexp))
radi = Decimal(str(radi))
return iterative(2,
lambda y: ((wexp-1)*y**wexp + radi)/(wexp * y**(wexp-1)),
acc)
def calculate_newton(radi, acc=50):
half = Decimal('0.5')
radi = Decimal(str(radi))
return iterative(2, lambda y: half * (y + (radi/y)), acc)
def iterative(value, func, acc=50):
getcontext().prec = acc
while True:
old_value = value
value = func(value)
if value == old_value:
return value
Verfasst: Sonntag 7. Februar 2010, 16:22
von Dav1d
numerix, ja das stimmt wohl, da es aber nur kleine Beispiele sind finde ich das Ok
EyDu, das gefällt mir

Verfasst: Sonntag 7. Februar 2010, 17:42
von numerix
Dav1d hat geschrieben:numerix, ja das stimmt wohl, da es aber nur kleine Beispiele sind finde ich das Ok
Den Satz verstehe ich nicht.
Verfasst: Sonntag 7. Februar 2010, 20:38
von Dav1d
numerix hat geschrieben:Im übrigen ist "calculate" ein ausgesprochen schlechter Name für eine Funktion, weil es nichts darüber aussagt, WAS berechnet wird.
Ich finde das nicht (nichtssagender Name) so schlimm, weil es nur ein kleines Beispiel ist
Verfasst: Montag 8. Februar 2010, 09:20
von lunar
Dav1d hat geschrieben:numerix hat geschrieben:Im übrigen ist "calculate" ein ausgesprochen schlechter Name für eine Funktion, weil es nichts darüber aussagt, WAS berechnet wird.
Ich finde das nicht (nichtssagender Name) so schlimm, weil es nur ein kleines Beispiel ist
Wo ist dann die Grenze zwischen „kleinem Beispiel“ (nicht so schlimm) und „produktivem Code“ (sehr schlimm!)?

Verfasst: Montag 8. Februar 2010, 09:30
von numerix
Dav1d hat geschrieben:numerix hat geschrieben:Im übrigen ist "calculate" ein ausgesprochen schlechter Name für eine Funktion, weil es nichts darüber aussagt, WAS berechnet wird.
Ich finde das nicht (nichtssagender Name) so schlimm, weil es nur ein kleines Beispiel ist
Was heißt schon "schlimm". Es gibt eigentlich keinen Grund dafür, einer Funktion einen nichtssagenden Namen zu geben, egal wie kurz oder lang ein Beispiel ist. Man sollte es sich zur guten Angewohnheit machen, bei der Wahl von Bezeichnernamen gute Entscheidungen zu treffen, weil es die Lesbarkeit von Code erhöht - auch für einen selbst, wenn man nach einigen Wochen wieder mal in den Code hineinschaut.
Verfasst: Montag 8. Februar 2010, 14:01
von Dav1d
lunar hat geschrieben:Wo ist dann die Grenze zwischen „kleinem Beispiel“ (nicht so schlimm) und „produktivem Code“ (sehr schlimm!)?

Ich habe den Code gepostet, damit andere Teile aus ihm weitervwenden können, wenn der Code aber "groß" wird, in Richtung Projekt dann ist es für aussenstehende leichter zu erknennen was "passiert"
@numerix, Der Name unter dem ich die Datei gespeichert habe sagt mir um was es geht

Ich verstehe was du meinst und ich merks mir, mir ist in dem Moment nichts besseres eingefallen
Wie wärs mit calculate_root?
Verfasst: Montag 8. Februar 2010, 14:53
von numerix
Dav1d hat geschrieben:Wie wärs mit calculate_root?
Das ist doch schon ein deutlicher Fortschritt.
Grundsätzlich hilfreich ist der Wechsel der Perspektive: Lässt sich aus Sicht dessen, der den Code nicht selbst geschrieben hat, allein anhand des Funktionsnamens erkennen, was die Funktion macht? Kannst du diese Frage mit "ja" beantworten, dann spricht das für die Wahl des Bezeichners (ist aber nicht das einzige Kriterium!). Da "root" nicht eindeutig ist -
welche Wurzel soll berechnet werden? - würde ich die Bezeichnung noch weiter spezifieren. Und statt calculate reicht in der Regel auch "calc". Man könnte das "calc" natürlich auch ganz weglassen, aber dann lässt sich aus dem Namen nicht mehr erschließen, dass hier etwas
getan wird.
Verfasst: Montag 8. Februar 2010, 15:06
von Dav1d
die 1. Funktion berechnet jede Wurzel also trifft der Name doch zu
Verfasst: Montag 8. Februar 2010, 15:17
von BlackJack
@Dav1d: Die Frage ist, ob man das weiss wenn man den Namen liest. `calculate_nth_root()` oder so wäre deutlicher. Denn wenn die Leute nur "Wurzel" lesen, nehmen sie in aller Regel "Quadratwurzel" an, denn die ist, zumindest umgangssprachlich, normalerweise gemeint, wenn man's nicht näher spezifiziert.
Verfasst: Montag 8. Februar 2010, 17:27
von Gabelmensch
In wieviele Teile wollt ihr das Haar noch spalten?
Verfasst: Montag 8. Februar 2010, 17:31
von numerix
Gabelmensch hat geschrieben:In wieviele Teile wollt ihr das Haar noch spalten?
Das ist ganz und gar keine Haarspalterei. Letztenendes geht es hier um die Lesbarkeit von Quelltexten und das kann man gar nicht hoch genug schätzen.
Verfasst: Montag 8. Februar 2010, 18:10
von hendrikS
Dav1d hat geschrieben:Wie wärs mit calculate_root?
Also ich habe noch in keiner Sprache eine Funktion gesehen, die mit "calculate_" beginnt.
calculate_sin, calculate_abs, etc. Das würde mich nerven. Daß da was kalkuliert wird, ist doch klar. Nenn sie doch einfach nthroot. Jeder würde damit klarkommen. Warum immer so kompliziert.
Verfasst: Montag 8. Februar 2010, 19:50
von Dav1d
Die 1. heist jetzt nth_root, die 2. sqrt_newton

Verfasst: Montag 8. Februar 2010, 20:29
von numerix
Dav1d hat geschrieben:Die 1. heist jetzt nth_root, die 2. sqrt_newton

Dann kannst du ja jetzt anfangen, dich um die Performance zu kümmern.
Du könntest beispielsweise √2 auf möglichst viele Nachkommastellen berechnen. Was dein Algorithmus in punkto Geschwindigkeit zu bieten hat, kannst du dann z.B. bei
SPOJ messen ...
Verfasst: Montag 15. März 2010, 15:13
von mathi
mal noch ne Frage,
warum nicht einfach :
Code: Alles auswählen
>>> from __future__ import division
>>> 12345**(1/6)
4.8074544979445477
nehmen??
Der einzige Grund, der mir einfiele ist die Genauigkeit ab der 10. Stelle nach dem Komma....
Verfasst: Montag 15. März 2010, 15:16
von numerix
mathi hat geschrieben:Der einzige Grund, der mir einfiele ist die Genauigkeit ab der 10. Stelle nach dem Komma....
Ob es jetzt genau die 10. Stelle ist, sei mal dahingestellt, aber: Genau das ist der Grund.
Verfasst: Montag 15. März 2010, 18:47
von Dav1d
Ja, das ist's
Mit dem Decimal-Modul, kann ich die Genauigkeit genau einstellen