Erste Gehversuche mit Klasse

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.
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Donnerstag 15. November 2018, 16:34

Hallo!

Ich bekomme als Fehlermeldung:
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')
Traceback (most recent call last):

File "<ipython-input-16-f241b1804623>", line 1, in <module>
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py", line 57, in <module>
calc1.read_GPX_file()

TypeError: read_GPX_file() missing 1 required positional argument: 'filename'
Welchen Fehler mache ich? Es soll eigentlich der dataFrame testweise ausgegeben werden. Er bekommt doch das Argument!

Hier der Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Created on Thu Nov 15 15:50:07 2018

@author: Strawk Work
"""
import gpxpy
import pandas as pd
from geopy import distance
import matplotlib.pyplot as plt

class VariousCalcFromGPXfile:
    def __init__(self, filename):
        self.filename = filename
        
    def read_GPX_file(self, filename):
        gpx_file = open(self.filename, 'r')
        gpx = gpxpy.parse(gpx_file)
        data = gpx.tracks[0].segments[0].points
        df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])

        for point in data:
            df = df.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
        
        dataFrame = df
        
        return dataFrame
        print(dataFrame)
    
    def create_list_of_seconds(self, dataFrame):
        lstTimestamps = []
        lstTwoTimestamps = []
        lstSeconds = []
    
        maxTrkPoints = dataFrame.shape[0]
        
        for i in range(0, maxTrkPoints): # extracts time out of the dataFrame
            oneTimestamp = (dataFrame['time'][i])
            lstTimestamps.append(oneTimestamp)
    
        for i in range(0, maxTrkPoints-1): # order timestamps pairwise 
            pairOfTimestampsToAppend = (lstTimestamps[i], lstTimestamps[i+1])
            lstTwoTimestamps.append(pairOfTimestampsToAppend)
    
        for i in range(1, maxTrkPoints-1): # call calculate_elapsed_time_between_2_points and enlarge list of seconds
            time1 = lstTwoTimestamps[i][0]
            time2 = lstTwoTimestamps[i][1]
            seconds = calculate_elapsed_time_between_2_points(time1, time2)
            lstSeconds.append(seconds)
    
        return lstSeconds

if __name__ == "__main__":
    # print(read_GPX_file = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx'))
    calc1 = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx')
    # print(calc1.dataFrame)
    calc1.read_GPX_file()
Bolitho
User
Beiträge: 56
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Donnerstag 15. November 2018, 16:40

Code: Alles auswählen

def read_GPX_file(self, filename):
nimm das filename raus - filename ist durch die Initialisierung des Objekts unter self.filename verfügbar.

(hatte nur Zeit für kurze Antwort und zum Überfliegen des Texts.)
Zuletzt geändert von Bolitho am Donnerstag 15. November 2018, 16:41, insgesamt 1-mal geändert.
Benutzeravatar
sls
User
Beiträge: 286
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Donnerstag 15. November 2018, 16:40

Du übergibst `filename` bei der Initialisierung der Klasse, ja, aber deine Methode erwartet genauso einen Übergabeparameter.

Ich würde self.filename entfernen, da es ja nur im lokalen Namespace der Methode read_GPX_file() verwendet wird. Für das Einlesen von Dateien sollte man das with-Statement verwenden, da der filedescriptor sonst manuell geschlossen werden muss, was du ohnehin nicht machst.
With great processing power comes great responsibility.
Benutzeravatar
noisefloor
User
Beiträge: 2525
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Donnerstag 15. November 2018, 16:47

Hallo,

deine Methode erwartet genau das, was du programmiert hast: das `filename` explizit als Argument _übergeben_ wird. Brauchst du aber nicht, weil du a) das Argument der Funktion später nicht mehr nutzt, b) weil du das Attribut der Klasse nutzt.

So funktioniert es:

Code: Alles auswählen

...
def read_GPX_file(self,):
        gpx_file = open(self.filename, 'r')
        ...
Schlecht ist übrigens, dass du die Datei öffnest, aber nicht mehr schließt. Das kann (muss aber nicht) zu Problemen führen. Also besser das `with` Statement beim Öffnen nutzen, dann wird die Datei automatisch geschlossen.

Gruß, noisefloor
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Donnerstag 15. November 2018, 16:59

Das hat soweit geklappt. Jetzt aber (ich verstehe die Hierarchie der Methoden nicht) ...

Fehler:
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')
Traceback (most recent call last):

File "<ipython-input-28-f241b1804623>", line 1, in <module>
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py", line 60, in <module>
calc1.create_list_of_seconds(dataFrame)

File "C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py", line 38, in create_list_of_seconds
maxTrkPoints = dataFrame.shape[0]

AttributeError: 'function' object has no attribute 'shape'


In [29]:
Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Created on Thu Nov 15 15:50:07 2018

@author: Strawk Work
"""
import gpxpy
import pandas as pd
from geopy import distance
import matplotlib.pyplot as plt

class VariousCalcFromGPXfile:
    def __init__(self, filename):
        self.filename = filename
        
    def read_GPX_file(self):
        gpx_file = open(self.filename, 'r')
        gpx = gpxpy.parse(gpx_file)
        data = gpx.tracks[0].segments[0].points
        df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])

        for point in data:
            df = df.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
        
        dataFrame = df
        # print(dataFrame)
        return dataFrame
        
    def calculate_elapsed_time_between_2_points(self, timestamp1, timestamp2):
        elapsedTime = timestamp2 - timestamp1
        return elapsedTime # is just 1 elapsed time between 2 points
    
    def create_list_of_seconds(self, dataFrame):
        lstTimestamps = []
        lstTwoTimestamps = []
        lstSeconds = []
    
        maxTrkPoints = dataFrame.shape[0]
        
        for i in range(0, maxTrkPoints): # extracts time out of the dataFrame
            oneTimestamp = (dataFrame['time'][i])
            lstTimestamps.append(oneTimestamp)
    
        for i in range(0, maxTrkPoints-1): # order timestamps pairwise 
            pairOfTimestampsToAppend = (lstTimestamps[i], lstTimestamps[i+1])
            lstTwoTimestamps.append(pairOfTimestampsToAppend)
    
        for i in range(1, maxTrkPoints-1): # call calculate_elapsed_time_between_2_points and enlarge list of seconds
            time1 = lstTwoTimestamps[i][0]
            time2 = lstTwoTimestamps[i][1]
            seconds = self.calculate_elapsed_time_between_2_points(time1, time2)
            lstSeconds.append(seconds)
        print(lstSeconds)
        return lstSeconds

if __name__ == "__main__":
    calc1 = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx')
    dataFrame = calc1.read_GPX_file
    calc1.create_list_of_seconds(dataFrame)
Benutzeravatar
sls
User
Beiträge: 286
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Donnerstag 15. November 2018, 17:35

Du rufst die Methode nicht auf, es sollte wohl eher:

Code: Alles auswählen

dataFrame = calc1.read_GPX_file()
heißen.

Du hast hier auch überhaupt nichts gewonnen:

Code: Alles auswählen

dataFrame = df
With great processing power comes great responsibility.
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Donnerstag 15. November 2018, 17:44

Ja, genau. Und das habe ich auch geändert. Das dataFrame = df sorgt für einen sprechenderen Namen (selbstdokumentierender Code).

Aber jetzt bekomme ich:
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')
Traceback (most recent call last):

File "<ipython-input-4-f241b1804623>", line 1, in <module>
runfile('C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py', wdir='C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data')

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py", line 59, in <module>
calc1.create_list_of_seconds(dataFrame)

File "C:/Users/Strawk Work/Documents/Programmierung_ausser_PHP/Python/analysis_of_geo_data/various_calc_from_gpx_file_01.py", line 38, in create_list_of_seconds
maxTrkPoints = dataFrame.shape[0]

AttributeError: 'function' object has no attribute 'shape'
Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Created on Thu Nov 15 15:50:07 2018

@author: Strawk Work
"""
import gpxpy
import pandas as pd
from geopy import distance
import matplotlib.pyplot as plt

class VariousCalcFromGPXfile:
    def __init__(self, filename):
        self.filename = filename
        
    def read_GPX_file(self):
        gpx_file = open(self.filename, 'r')
        gpx = gpxpy.parse(gpx_file)
        data = gpx.tracks[0].segments[0].points
        df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])

        for point in data:
            df = df.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
        
        dataFrame = df
        # print(dataFrame)
        return dataFrame
        
    def calculate_elapsed_time_between_2_points(self, timestamp1, timestamp2):
        elapsedTime = timestamp2 - timestamp1
        return elapsedTime # is just 1 elapsed time between 2 points
    
    def create_list_of_seconds(self, dataFrame):
        lstTimestamps = []
        lstTwoTimestamps = []
        lstSeconds = []
    
        maxTrkPoints = dataFrame.shape[0]
        
        for i in range(0, maxTrkPoints): # extracts time out of the dataFrame
            oneTimestamp = (dataFrame['time'][i])
            lstTimestamps.append(oneTimestamp)
    
        for i in range(0, maxTrkPoints-1): # order timestamps pairwise 
            pairOfTimestampsToAppend = (lstTimestamps[i], lstTimestamps[i+1])
            lstTwoTimestamps.append(pairOfTimestampsToAppend)
    
        for i in range(1, maxTrkPoints-1): # call calculate_elapsed_time_between_2_points and enlarge list of seconds
            time1 = lstTwoTimestamps[i][0]
            time2 = lstTwoTimestamps[i][1]
            seconds = self.calculate_elapsed_time_between_2_points(time1, time2)
            lstSeconds.append(seconds)
        print(lstSeconds)
        return lstSeconds

if __name__ == "__main__":
    calc1 = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx')
    dataFrame = calc1.read_GPX_file
    calc1.create_list_of_seconds(dataFrame)
Benutzeravatar
sls
User
Beiträge: 286
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Donnerstag 15. November 2018, 17:51

Du musst mal etwas genauer hinsehen:

Statt:

Code: Alles auswählen

if __name__ == "__main__":
    calc1 = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx')
    dataFrame = calc1.read_GPX_file
    ...
So:

Code: Alles auswählen

if __name__ == "__main__":
    calc1 = VariousCalcFromGPXfile('Aljibe_Picacho_2017-03-08_10-32-52.gpx')
    dataFrame = calc1.read_GPX_file()
    ...
Du rufst die Methode immer noch nicht auf. Du hast keine Klammern hinter read_GPX_file gesetzt.
With great processing power comes great responsibility.
Benutzeravatar
__blackjack__
User
Beiträge: 1580
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 15. November 2018, 18:03

@Strawk: Neben den Details wär's wahrscheinlich noch wichtig zu erwähnen, dass das keine Klasse ist. Es macht absolut keinen Sinn diese drei Funktionen in eine Klasse zu stecken. Warum machst Du das?

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Donnerstag 15. November 2018, 20:58

Hallo Nutzer und Profis!

plan - list of all functions in class:
read_GPX_file
calculate_elapsed_time_between_2_points
create_list_of_seconds
calculate_distance_between_2_points
create_list_of_distances
create_list_of_velocities
create_list_of_distance_values_Added_Together
plot_velocities_over_distances
calculate_total_distance

Einiges wird wohl durch das Nutzen vom Modul numpy noch umgestrickt werden.

Grüße, Strawk
Benutzeravatar
__blackjack__
User
Beiträge: 1580
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 15. November 2018, 23:21

@Strawk: Was war denn die Motivation diese Liste zu posten? Alleine schon die unterstrichene Zeile macht deutlich dass das wohl eher keine Klasse sein sollte, denn sonst würde da nicht das Wort „functions“ stehen. Der Name der Klasse sagt auch schon dass das keine Klasse ist sondern eine Sammlung von Funktionen die syntaktisch in eine Klasse gesteckt wurden statt in ein Modul.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Sirius3
User
Beiträge: 8805
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 16. November 2018, 09:52

@Strawk: das erste Anzeichen dafür, dass man keine Klasse hat, ist, dass die Funktionen gar nicht mit dem Zustand der Klasse arbeiten, also self gar nicht benutzen, wie z.B. `calculate_elapsed_time_between_2_points`. Das ist einfach eine Funktion die man außerhalb der Klasse definieren sollte. `create_list_of_seconds` benutzt dann self auch nicht mehr, raus aus der Klasse damit. `read_GPX_file` benutzt nur self um auf filename zuzugreifen, was aber sonst nirgends verwendet wird, filename sollte als ein Parameter für read_GPX_file sein, und damit fliegt die Funktion auch aus der Klasse raus. Eine leere Klasse wird aber nicht gebraucht.

Die Begründung der Umbenennung von df nach dataFrame ist lustig, denn dataFrame ist so generisch, dass es auch nicht mehr aussagt als df. dataFrame sollte nach Konvention data_frame heißen, und warum nimmst Du nicht überall data_frame statt df?

Auch sonst hältst Du Dich nicht an die Namenskonvention, dass Variablen klein_mit_unterstrich geschrieben werden.
In `create_list_of_seconds` ist der lst-Präfix überflüssig, die Pluralform zeigt schon, dass es sich um irgendeine Art Sammlung von Timestamps handelt.
for-Schleifen über Indices ist in Python unüblich, da man direkt über die Elemente iterieren kann, bei Dir ist es sogar so, da Du pandas benutzt, kann man mit ganzen Spalten arbeiten und braucht gar keine Schleifen.

Wodurch das dann so aussehen könnte:

Code: Alles auswählen

def read_GPX_file(filename):
    with open(filename) as gpx_file
        gpx = gpxpy.parse(gpx_file)
    points = gpx.tracks[0].segments[0].points
    data_frame = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])
    for point in points:
        data_frame = data_frame.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
    # print(data_frame)
    return data_frame

def calculate_elapsed_time_between_2_points(timestamp1, timestamp2):
    return timestamp2 - timestamp1 # is just 1 elapsed time between 2 points

def create_difference_in_seconds(points_and_times): # formerly known as create_list_of_seconds
    timestamps = points_and_times['time'].values
    diff_timestamps = numpy.diff(timestamps)
    return diff_timestamps
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Samstag 17. November 2018, 09:47

Hallo!

Daraus schließe ich u.a., dass es Kriterien gibt, wann man Programmcode in eine Klasse überführt / Strukturen die Form einer Klasse gibt. Welches sind diese Kriterien?

Grüße
Strawk
Sirius3
User
Beiträge: 8805
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 17. November 2018, 10:04

Das einfachste Kriterium ist, bietet die Klasse einen Mehrwert gegenüber einzelnen Funktionen.
In Objekten gesprochen: ist das, was ich da beschreibe ein Objekt, also etwas was einen definierten Zustand hat und Methoden, die diesen Zustand abfragen oder verändern.
Man merkt, dass man eine Klasse braucht, wenn man mehrere Variablen hat, die immer in Gruppen an verschiedene Funktionen übergeben werden müssen und diese Gruppe von Variablen irgendwie zusammengehören (das tritt typischerweise auf, wenn man GUIs programmiert).
Strawk
User
Beiträge: 74
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: RegBez Köln
Kontaktdaten:

Donnerstag 29. November 2018, 12:43

Bitte beigefügten Code kritisieren! Danke.

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 23 09:04:31 2018

@author: Karl Kraft
"""

import gpxpy
import pandas as pd
from geopy import distance
import matplotlib.pyplot as plt

class Track():
    def __init__(self, gpxdata): # constructor creates dataframe
        data = gpxdata.tracks[0].segments[0].points
        df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])

        for point in data:
            df = df.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
        
        self.df = df
    
    def total_distance(self): # calculates the total distance of walked track
        # again Martin's version because:
        # object of type 'zip' has no len() in Python 3.6
        Npoints = self.df.shape[0]
        lstPairsOfPoints = []

        for i in range(0, Npoints):
            pair = (self.df['lat'][i], self.df['lon'][i])
            lstPairsOfPoints.append(pair) # pairs of points are appended

        lstPairs = []

        for i in range(0, Npoints-1): 
            onePair = (lstPairsOfPoints[i], lstPairsOfPoints[i+1])
            lstPairs.append(onePair) # pairs are appended
    
        dist = 0

        for i in range(0, Npoints-1):
            lat1 = lstPairs[i][0][0]
            lon1 = lstPairs[i][0][1]
            lat2 = lstPairs[i][1][0]
            lon2 = lstPairs[i][1][1]
        
            dist += distance.distance((lat1,lon1), (lat2,lon2)).km # distance value gets enlarged by next 1 distance

        return dist
    
    def calculate_distance_between_2_points(self, *geodata):
        point1 = (geodata[0], geodata[1])
        point2 = (geodata[2], geodata[3])
        singleDistance = distance.distance(point1, point2).km
        return singleDistance # is just 1 distance between 2 points
    
    def create_list_of_distances(self): # all single distances are calculated, necessary for velocity-calculation
        df = self.df
        lstLatLon = []
        lstTwoPairs = []
        lstDistances = []
        maxTrkPoints = df.shape[0]
        
        for i in range(0, maxTrkPoints): # extracts latitude and longitude out of the dataFrame
            onePair = (df['lat'][i], df['lon'][i])
            lstLatLon.append(onePair)
        
        for i in range(0, maxTrkPoints-1): # order trackpoints pairwise (pair of pairs)
            pairOfTrackpointsToAppend = (lstLatLon[i], lstLatLon[i+1])
            lstTwoPairs.append(pairOfTrackpointsToAppend)
    
        for i in range(1, maxTrkPoints-1): # call calculate_distance_between_2_points and enlarge list of distances
            lat1 = lstTwoPairs[i][0][0]
            lon1 = lstTwoPairs[i][0][1]
            lat2 = lstTwoPairs[i][1][0]
            lon2 = lstTwoPairs[i][1][1]
        
            lstDistances.append(self.calculate_distance_between_2_points(lat1, lon1, lat2, lon2))

        return lstDistances
    
    def create_list_of_velocities(self, lstSeconds, lstDistances):
        Npoints = self.df.shape[0]
        lstVelocities = []
    
        for i in range(0, Npoints-2):
            lstVelocities.append((lstDistances[i]*1000) / lstSeconds[i].total_seconds()*3.6)
        
        return lstVelocities
    
    def total_elapsed_time(self):
        Npoints = self.df.shape[0]
        startTime = self.df['time'][0]
        endTime = self.df['time'][Npoints-1]
        total_elapsed_time = endTime - startTime
        return total_elapsed_time
   
    def calculate_elapsed_time_between_2_points(self, timestamp1, timestamp2):
        elapsedTime = timestamp2 - timestamp1
        return elapsedTime # is just 1 elapsed time between 2 points
    
    def create_list_of_seconds(self): # all single seconds are calculated, necessary for velocity-calculation
        lstTimestamps = []
        lstTwoTimestamps = []
        lstSeconds = []
    
        maxTrkPoints = self.df.shape[0]
        
        for i in range(0, maxTrkPoints): # extracts time out of the dataFrame
            oneTimestamp = (self.df['time'][i])
            lstTimestamps.append(oneTimestamp)
    
        for i in range(0, maxTrkPoints-1): # order timestamps pairwise 
            pairOfTimestampsToAppend = (lstTimestamps[i], lstTimestamps[i+1])
            lstTwoTimestamps.append(pairOfTimestampsToAppend)
    
        for i in range(1, maxTrkPoints-1): # call calculate_elapsed_time_between_2_points and enlarge list of seconds
            time1 = lstTwoTimestamps[i][0]
            time2 = lstTwoTimestamps[i][1]
            seconds = self.calculate_elapsed_time_between_2_points(time1, time2)
            lstSeconds.append(seconds)
        
        return lstSeconds
    
    def create_list_of_distance_values_Added_Together(self, lstDistances): # cumulative sum
        valueToAppend = 0
        lstDistancesAddedTogether = []
        for i in range(0, len(lstDistances)):
            valueToAppend += lstDistances[i]
            lstDistancesAddedTogether.append(valueToAppend)
        
        return lstDistancesAddedTogether

    def plot_velocities_over_distances(self, lstVelocities, lstDistancesAddedTogether):
        plt.plot(lstDistancesAddedTogether, lstVelocities)
        plt.xlabel('Distance [km]')
        plt.ylabel('Velocity [km/h]')
        
if __name__ == "__main__":
    gpx_file = open("Aljibe_Picacho_2017-03-08_10-32-52.gpx", "r")
    gpxdata = gpxpy.parse(gpx_file)
    mytrack = Track(gpxdata)
    total_distance = mytrack.total_distance()
    print(total_distance)
    total_elapsed_time = mytrack.total_elapsed_time()
    print(total_elapsed_time)
    list_of_seconds = mytrack.create_list_of_seconds()
    list_of_distances = mytrack.create_list_of_distances()
    list_of_velocities = mytrack.create_list_of_velocities(list_of_seconds, list_of_distances)
    list_of_distance_values_Added_Together = mytrack.create_list_of_distance_values_Added_Together(list_of_distances)
    plot = mytrack.plot_velocities_over_distances(list_of_velocities, list_of_distance_values_Added_Together)
Antworten