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.
Antworten
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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()
Ich programmiere erfolglos, also bin ich nicht.
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

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: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

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.
When we say computer, we mean the electronic computer.
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

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
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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)
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

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
When we say computer, we mean the electronic computer.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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)
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

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.
When we say computer, we mean the electronic computer.
Benutzeravatar
__blackjack__
User
Beiträge: 13067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@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
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

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).
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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)
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: wie man diese ganze Distanzberechnung in 3 Zeilen macht, hab ich Dir ja schon gezeigt. Sobald Du in Pandas etwas mit for-Schleifen über einen Index machst, machst Du etwas falsch. Ich werd jetzt nicht nochmal jede der Funktionen umschreiben, das solltest Du selbst als Übung machen. Ziel ist es, keine einzige for-Schleife mehr zu haben.

Es ist an der Grenze, ob Track überhaupt eine richtige Klasse ist. Du hast nur ein Attribut, eine Serie von Punkten, die Du auch so als Parameter einer Funktion `total_distance` übergeben könntest.
Die Methoden calculate_distance_between_2_points, create_list_of_velocities, calculate_elapsed_time_between_2_points, create_list_of_distance_values_Added_Together und plot_velocities_over_distances gehören alle nicht in die Klasse, weil `self` nicht brauchen, also nichts mit den Daten der Instanz machen.
Benutzeravatar
__blackjack__
User
Beiträge: 13067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich würde empfehlen alle vorkommen des Wortes `list` aus den Namen zu entfernen. Grunddatentypen haben in Namen nichts verloren, weil man Probleme bekommt wenn man den Datentyp dann mal ändern will/muss und überall sinnloserweise Namen anpassen muss, und ausserdem wird nicht jeder Code tatsächlich eine Liste benötigen. Einige, wenn nicht gar die meisten Codestellen werden mit jedem Sequenztyp klar kommen, und einige werden wahrscheinlich nur irgendetwas iterierbares verarbeiten.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten