@Blank44: Weitere Anmerkungen zum Code: Wenn möglich sollte man die ``with``-Anweisung verwenden um das Schliessen von Dateien sicherer zu machen.
Das `i` in der ersten Schleife würde man nicht manuell verwalten sondern mit der `enumerate()`-Funktion erstellen. Allerdings ist das alles sehr umständlich geschrieben. Einfacher wäre es erst alles in `g` einzulesen und dann `v` und `t` per „slicing“ daraus zu erstellen. Und `g` ist letztlich ja nur das Ergebnis von ``file.read().split()``.
`g`, `v`, und `t` sind keine guten Namen. `all_values`, `velocities`, und `times` wären bessere.
Code und Funktionsdefinitionen zu mischen ist unübersichtlich. Auf Modulebene sollte auch nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Also `mid_speed()` statt `midSpeed()`.
Wenn Namen Tätigkeiten beschreiben, ist es leichter sie von anderen Werten zu unterscheiden, man braucht nicht nach einem anderen Namen für den Wert suchen den sie berechnen, oder einen total generischen Wert wie `wert` verwenden, weil der eigentlich passende Name schon durch den Funktionsnamen belegt ist.
Wobei die Funktion keinen Sinn macht. Weder `i` noch `j` werden verwendet, es werden in jedem Schleifendurchlauf die gleichen, festen, ziemlich willkürlich aussehenden Indexwerte verwendet um auf Elemente von `v` und `t` zuzugreifen. Und da `summe` in jedem äusseren Schleifendurchlauf wieder auf 0 gesetzt wird, hat die äussere Schleife gar keinen Einfluss auf das Ergebnis (ausser in dem Sonderfall das `t` leer ist!). Vom Effekt her kann man die Funktion auch so schreiben:
Code: Alles auswählen
def calculate_mid_speed(velocities, times):
if times:
return len(velocities) * (
(velocities[167] - velocities[0]) / (times[167] - times[0])
)
else:
raise NameError('summe is undefined')
``for i in range(len(sequence)):`` nur um `i` dann als Index in die Sequenz zu verwenden ist in Python ein „anti pattern“. Man kann direkt über die Elemente von Seuquenzen iterieren, ohne den Umweg über einen Index. Wenn man *zusätzlich* eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion. Wenn man über mehrere iterierbare Objekte ”paralell” iterieren möchte, gibt es die `zip()`-Funktion.
Die Argumente beim `legend()`-Aufruf sind falsch. Da wird versucht ein Tupel zu erstellen aus den Aufrufen von `v`, `a`, und `s` mit `t` als Argument, nur das `v`, `a`, und `s` gar nicht aufrufbar sind. Das sollten wohl Zeichenkettenliterale sein.
Beim `plot()`-Aufruf ist dann das Problem das nur `v` eine Sequenz von Daten, die anderen beiden Argumente dagegen Einzelwerte sind. Das geht natürlich nicht.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import matplotlib.pyplot as plt
def calculate_mid_speed(velocities, times):
#
# FIXME This doesn't make sense.
#
if times:
return len(velocities) * (
(velocities[167] - velocities[0]) / (times[167] - times[0])
)
else:
raise NameError('summe undefined')
def main():
with open('v_t.dat.txt', 'r', encoding='utf-8') as file:
all_items = file.read().split()
velocities = list(map(float, all_items[0::3]))
times = list(map(float, all_items[1::3]))
print(velocities)
print(times)
print(all_items)
mid_speed = calculate_mid_speed(velocities, times)
print(f'{mid_speed:.3f} m/s')
distance = 0
for velocity, time in zip(velocities, times):
distance += velocity * time
print(f'{distance:.3f} m')
acceleration = 0
for velocity, time in zip(velocities, times):
acceleration += velocity / time
print(f'{acceleration:.3f} m/s^2')
plt.legend(['v(t)', 'a(t)', 's(t)'], loc='upper left')
plt.xlabel('Zeit')
plt.ylabel('Geschwindigkeit, Beschleunigung, Weg')
#
# FIXME `distance` and `acceleration` are scalars.
#
plt.plot(velocities, distance, acceleration)
plt.show()
if __name__ == '__main__':
main()