Trail length

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
Kingoffly
User
Beiträge: 8
Registriert: Freitag 11. November 2022, 19:10

Ich will den for i in range() aus den Eckigeklammer nehmen und einmal benutzen, irgendwie klappt es nicht.

from math import sqrt

def path_length(trail):
n = len(trail)
x = [trail[0] for i in range(n)]
y = [trail[1] for i in range(n)]
lv = [sqrt((x-x[i-1])**2 + (y-y[i-1])**2) for i in range (1,n)]
L = sum (lv)
return L

def main():
trail = [ (142.492, 208.536), (142.658, 207.060), (143.522, 205.978), (145.009, 205.546) ]
print(path_length(trail))

if __name__ == "__main__":
main()
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Kingoffly hat geschrieben: Freitag 18. November 2022, 09:41 Ich will den for i in range() aus den Eckigeklammer nehmen und einmal benutzen, irgendwie klappt es nicht.
Du hast da drei list comprehensions in denen `for i in range(n)` steht? Welche davon meinst du und was meinst du mit "einmal benutzen"?
Kingoffly
User
Beiträge: 8
Registriert: Freitag 11. November 2022, 19:10

from math import sqrt

def path_length(trail):
for i in range(len(trail) - 1):
for j in range(i + 1, len(trail)):
x = trail[0]
y = trail[1]
lv = sqrt((x[j]-x[j-1])**2 + (y[j]-y[j-1])**2)
L = sum(lv)
return L

def main():
trail = [ (142.492, 208.536), (142.658, 207.060), (143.522, 205.978), (145.009, 205.546) ]
print(path_length(trail))

if __name__ == "__main__":
main()

Ich will gerne so machen, aber dann kommt error.
Sirius3
User
Beiträge: 18276
Registriert: Sonntag 21. Oktober 2012, 17:20

Und welcher Error ist das?

Die äußere for-Schleife ist unnötig, weil sie ja exakt einmal durchlaufen wird.
Über einen Index iteriert man nicht. Variablennamen werden komplett klein geschrieben und sollten sprechend sein, lv und L sind das nicht.

Ohne Index könnte das ganze so aussehen:

Code: Alles auswählen

def path_length(trail):
    trail = iter(trail)
    previous_point = next(trail)
    segment_lengths = []
    for point in trail:
        segment_lengths.append(sum((a - b)**2 for a, b in zip(previous_point, point))**0.5)
        previous_point = point
    return sum(segment_lengths)
Kingoffly
User
Beiträge: 8
Registriert: Freitag 11. November 2022, 19:10

Das sind die Fehler meldung:

Traceback (most recent call last):
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test1.py", line 17, in <module>
main()
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test1.py", line 14, in main
print(path_length(trail))
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test1.py", line 6, in path_length
x = trail([0])
TypeError: 'list' object is not callable

Process finished with exit code 1
Sirius3
User
Beiträge: 18276
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist jetzt aber ein anderer Code, als der, den Du gepostet hast und damit auch eine andere Fehlermeldung.
Klammern bedeuten hier, dass der Name als Funktion aufgerufen werden soll, (vrgl. print(...), oder path_length(...)). `trail` ist aber eine Liste und kann nicht aufgerufen werden. Was also sollen die Klammern bedeuten?
Kingoffly
User
Beiträge: 8
Registriert: Freitag 11. November 2022, 19:10

Ich habe vorher falsche Fehler Meldung kopiert:
Traceback (most recent call last):
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test.py", line 17, in <module>
main()
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test.py", line 14, in main
print(path_length(trail))
File "C:\Users\bbavi\Desktop\Informatik_1\P05_1\Test.py", line 8, in path_length
lv = sqrt((x[j]-x[j-1])**2 + (y[j]-y[j-1])**2)
TypeError: 'float' object is not subscriptable
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na hast du die Fehlermeldung mal gegoogelt? Da findet sich doch eine Menge. Du denkst du hast eine Liste, oder ein Tupel, aber greifst auf eine einzelne Zahl zu.

Und bitte gewoehn dir an, Code und Fehlermeldungen in den dafuer vorgesehenen Code-Tags zu posten - das ist der </>-Knopf im vollstaendigen Editor.
Sirius3
User
Beiträge: 18276
Registriert: Sonntag 21. Oktober 2012, 17:20

Bie solchen Fehlern hilft es immer, sich die Werte der einzelnen Variablen ausgeben zu lassen, daran sieht man dann, was Du tatsächlich hast, und dann siehst Du hoffentlich, dass der Index 1 bei einer Zahl wie 142.492 nicht sinnvoll ist.
Benutzeravatar
__blackjack__
User
Beiträge: 14069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mit dem `pairwise`-Rezept aus der Dokumentation von `itertools` lässt sich das auch noch ein bisschen kompakter schreiben:

Code: Alles auswählen

def path_length(trail):
    return sum(
        sum((a - b) ** 2 for a, b in zip(point_a, point_b)) ** 0.5
        for point_a, point_b in pairwise(trail)
    )
Noch einen Tick leichter verständlich wird es wenn man die Berechnung des Abstands zwischen zwei Punkten in eine Funktion herauszieht:

Code: Alles auswählen

def calculate_distance(point_a, point_b):
    return sum((a - b) ** 2 for a, b in zip(point_a, point_b)) ** 0.5


def path_length(trail):
    return sum(
        calculate_distance(point_a, point_b)
        for point_a, point_b in pairwise(trail)
    )
Und weil Python eine objektorientierte Sprache ist, könnte man den Punkten auch einen eigenen Datentyp spendieren, statt die in anonymen Tupeln zu speichern:

Code: Alles auswählen

#!/usr/bin/env python3
from math import sqrt

from attrs import field, frozen
from more_itertools import pairwise


@frozen
class Point:
    x = field()
    y = field()

    def distance(self, other):
        return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)


def path_length(points):
    return sum(
        point_a.distance(point_b) for point_a, point_b in pairwise(points)
    )


def main():
    trail = [
        Point(142.492, 208.536),
        Point(142.658, 207.060),
        Point(143.522, 205.978),
        Point(145.009, 205.546),
    ]
    print(path_length(trail))


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten