Lineare Funktionen - endlich!

Code-Stücke können hier veröffentlicht werden.
Antworten
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

Hii ^.^

Habe mich jetzt endlich hingesetzt und ein Skript geschrieben, das aus zwei gegebenen Punkten eine lineare Funktion errechnet. Ich habe meine Erwartungen allerdings insoweit zurückgeschraubt, als dass ich nicht mehr versuche, beliebig hohe Grade zu implementieren, so nach dem Motto "mein Skript kann Funktionen a'la f(x) = ax^9 + bx^8 + cx^7... ausrechnen". Gerade Striche reichen mir momentan ;p

Übrigens, mein Algorithmus entstammt einer Rechnung auf Papier, völlig ohne numerische Werte, nur mit Variablen. War echt anstrengend, umso mehr freut es mich, dass das seltsame Ergebnis tatsächlich funktioniert.

Code: Alles auswählen

# Deklaration Funktionen

def user_input():
    while True:
        try:
            x1 = float(input('Punkt 1, x-Wert: \n'))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')
            continue
        else:
            break

    while True:
        try:
            y1 = float(input('Punkt 1, y-Wert: \n'))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')
            continue
        else:
            break

    while True:
        try:
            x2 = float(input('Punkt 2, x-Wert: \n'))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')
            continue
        else:
            break

    while True:
        try:
            y2 = float(input('Punkt 2, y-Wert: \n'))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')
            continue
        else:
            break

    return [x1, y1, x2, y2]


def linear_function(points):    # erwartet eine Liste/Tupel mit zumindest vier Zahlen. -> [x1, y1, x2, y2], siehe oben
    b = (((points[3] * points[0]) / points[2]) - points[1]) / ((-1) + (points[0] / points[2]))

    a = (points[1] / points[0]) - (b / points[0])

    return "f(x) = {}x + {}".format(a, b)

# ---------------------------

print(linear_function(user_input()))
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Joshuah992: wenn man etwas mehrfach kopiert, dann ist das immer ein Zeichen dafür, dass man eigentlich eine Funktion schreiben sollte, wie z.B. bei Deinen while-Schleifen. Ein `continue` wenn danach nichts mehr kommt, ist überflüssig. `continue` sollte man soweit sinnvoll wegen komplexer Ausführungsreihenfolge vermeiden.
Du hast eigentlich keine 4 Zahlen, sondern zwei Zahlenpaare. Am besten bildest Du das in Deinem Code mit ab.
Zwei der drei Kommentare sind überflüssig und der dritte sollte ein Doc-String sein.

Code: Alles auswählen

def input_float(prompt):
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')

def input_points():
    result = []
	for nr in range(1,3):
        result.append((
            input_float('Punkt {}, x-Wert: \n'.format(nr)),
            input_float('Punkt {}, y-Wert: \n'.format(nr))
        ))
    return result
 
def linear_function(points):
    "erwartet eine Liste/Tupel mit zwei Zahlenpaaren. -> [(x1, y1), (x2, y2)], siehe oben"
    m = points[0][0] / points[1][0]
    b = (points[1][0] * m - points[0][1]) / (m - 1)
    a = (points[0][1] - b) / points[0][0]
    return "f(x) = {}x + {}".format(a, b)
 
print(linear_function(input_points()))
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

@Sirius3 vielen Dank fürs drüberschauen! Diese Input-funktion von Dir, verrückt, dass ich da nicht selber drauf gekommen bin :lol: Aber super, jetzt kenn ich diesen Weg auch.

Ach ja, mal ne Frage zu "#-------------" - Kommentaren: Ich trenne damit Codeteile, weil ich das Ganze so besser überblicken kann. Kann sein, dass Code zu lesen einfach noch sehr ungewohnt für mich ist, und ich mich deshalb damit besser fühle, aber wie, wenn überhaupt, macht das ein Programmierer, also Code optisch strukturieren?
Astorek
User
Beiträge: 72
Registriert: Samstag 24. Januar 2009, 15:06
Kontaktdaten:

Das ist eine Frage, in der man ein paar "Best Practices" nennen kann, bei der man aber NICHT (direkt) den Finger draufhalten kann nach dem Motto: "SO muss das"... Aber generell kommt sowas mit der Zeit und genügend Übung. Irgendwann macht man zwangsläufig Fehler (was gerade in der Anfangszeit völlig normal beim Programmieren ist) und dann merkt man auch selbst, was für Nachteile man hat, weil man dieses oder jenes nicht so stark berücksichtigt hat beim Korrigieren. *Wenn* man den Fehler gemacht hat, kann man natürlich auch draufzeigen^^.

- Einrückungen verwenden (erwähne ich der Vollständigkeit halber, weil das in *allen* höheren Programmiersprachen gilt; in Python ist es ja fast nicht möglich, Einrückungen zu ignorieren)
- Wie Sirius3 schon sagt: Don't repeat yourself. Wenn du mehrmals fast exakt denselben Quelltext schreibst und nur minimal was änderst, ist das fast immer ein Indikator dafür, dass sowas womöglich besser in einer Funktion oder einer Schleife aufgehoben ist. Reduziert die Zahl der Quelltextzeilen und sorgt dafür, dass du ggf. bei einer Änderung im Quelltext diese nicht an mehreren Stellen vornehmen musst (was fehleranfällig ist, erst recht wenn man einen Quelltext erst nach längerer Zeit wieder öffnet, weil man zwischendurch das Geschriebene großteils wieder vergessen hat)
- Kommentare und, was speziell Python angeht, Docstrings sinnvoll benutzen. Bei Kommentaren gilt: Nicht schreiben, "was" der Quelltext macht (das sieht man ja am Quelltext schon selbst) sondern *wie* oder *warum* man etwas im Quelltext macht.
- Es hilft auch sehr schön, sich "fremden" Quelltext von anderen Leuten anzusehen. Einerseits um sich Methoden abzuschauen ("ach, SO hat er das Problem gelöst"), andererseits wird einem dabei sehr schnell sehr deutlich vor Augen geführt, wie "lesbar" der Quelltext für einen selber ist - und sich, je nach Qualität des Quelltextes, selber daran zu halten oder als mahnendes Beispiel, wie der eigene Quelltext auf andere wirkt, davon abzusehen.
- Eindeutige Variablennamen verwenden. "x" und "y" können als Namen bei Positionsbeschreibungen gerade noch so in Ordnung gehen, und wenn eine Variable nur übergangsweise für die nächsten 3-4 Zeilen (hypothetische Zahlen) verwendet und danach nichtmehr gebraucht wird, ist der Name auch nicht so wichtig. Aber für alles, womit man längerfristig arbeitet, sollte man sinnvolle Namen wählen. Wenn ein mehrere hundert Zeilen großer Quelltext völlig abhängig von einer Variable namens "tmp" ist, dann ist was gehörig schiefgelaufen^^.
- Ist zwar eine Geschmacksfrage, aber dennoch: Selbst bei kleineren Projekten würde ich schon auf eine einigermaßen brauchbare IDE zurückgreifen, die z.B. Syntaxhervorhebung bietet und auch alle geschriebenen Funktionen, Klassen und Methoden in einer Liste darstellt. Zur Not Geany (auch wenn das Ding merkwürdige Voreinstellungen bei der Einrückung hat - unbedingt in den Optionen dafür sorgen, dass Geany Tabs in Leerzeichen umwandelt, falls man Geany wirklich benutzen will!), aber welchen Editor man schlussendlich nutzen mag, bestimmt jeder für sich selbst.
- Ein Fehler, den auch hin und wieder Anfänger machen: Bloß nicht damit anfangen, den Quelltext irgendwie "optisch zu dekorieren". Was nützt es, wenn jede einzelne Quelltextzeile an exakt derselben Spalte aufhört, wenn dadurch die Lesbarkeit stark drunter leidet? Quelltext wird öfters gelesen als er geschrieben wird, dementsprechend sollte auch der Fokus gesetzt werden.
- Bei größeren Quelltexten ist es auch oft eine gute Idee, diese in mehrere Dateien aufzuteilen. Funktionen und Klassen sollte man idealerweise eh nie zu lang werden lassen (weil dann die Gefahr besteht, dass es sich um Gottklassen handeln), aber auch für die Wiederverwendbarkeit kann es sinnvoll sein, thematisch "verwandte" Funktionen in eine andere Quelltext-Datei auszulagern. Aber auch das ist was, was man irgendwann selbst herausfindet - wenn der eigene Quelltext 5000 Zeilen umfasst und man mehr mit Scrollen als mit Quelltextschreiben beschäftigt ist, weiß man, dass man da was tun muss, ums mal nett zu formulieren^^.
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

Na dann will ich das mal so versuchen, danke dafür! Ich geh mal davon aus, dass ich das noch nicht zu 100% schaffe, aber Perfektion ist sowieso ein frustrierendes Ziel. Ich benutze übrigens PyCharm, mit diesem krassen dunklen Skin :lol:
Drover
User
Beiträge: 1
Registriert: Dienstag 2. März 2021, 09:20

Hi,

das Thema hat zwar schon ein paar Tage aufm Buckel, da mich googel bei meiner Fragestellung aber direkt hierher geleitet hat:

ich habe sowohl den Code von Joshuah als auch den von Sirius ausprobiert. Da ich zuerst mit abstrackten Werten getestet habe deren Ergebnis ich nicht geprüft habe alles schön und gut. In den Code von Sirius allerdings einfach mal x1=1 y1=10 x2=2 y2=20 eingegeben bringt mir : f(x) = -8.0x + 18.0, also ein falsches Ergebnis, Joshuahs Code gibt mir fleißig f(x) = 10.0x + 0 aus.

Zum nachvollziehen fehlt mir gerade die Zeit und wenn das nur an mir liegt bitte ignorieren, dachte aber das sollte der Vollständigkeit-halber hier stehen, hätte das nämlich fast blind in mein Programm implementiert.

Gruß

Alex
luzi
User
Beiträge: 1
Registriert: Dienstag 20. April 2021, 20:38

Hallo zusammen,

ich habe mir den Code angeschaut und meines Erachtens wird bei dem Code von Sirius die Steigung m und der Y-Achsenabschnitt b nicht richtig berechnet.

Hier der Code mit Anpassungen:

Code: Alles auswählen

def input_float(prompt):
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print('Bitte eine Zahl eingeben! \n')

def input_points():
    result = []
    for nr in range(1,3):
        result.append((
        input_float('Punkt {}, x-Wert: \n'.format(nr)),input_float('Punkt {}, y-Wert: \n'.format(nr))))
    return result

def linear_function(points):
    "erwartet eine Liste/Tupel mit zwei Zahlenpaaren. -> [(x1, y1), (x2, y2)], siehe oben"
    "y = m * x + b"
    m = (points[1][1] - points[0][1]) / (points[1][0]-points[0][0])
    b = points[0][1]-m*points[0][0]
    return "f(x) = {}x + {}".format(m, b)

print(linear_function(input_points()))
sry ich weiß aktuell noch nicht wie man den Code als Code einfügt nicht als Text

Beste Grüße
Luzi
Antworten