Python Flask – Währungsrechner Teil3 – anzeigen der historischen Daten in einem Graph

In diesem Beitrag möchte ich dir zeigen wie du den kleinen Währungsrechner um einen Graph erweiterst welcher die historischen Daten anzeigt.

Im letzten Beitrag Python Flask – Währungsrechner Teil2 – Umrechnungskurse online beziehen habe ich dir gezeigt wie du Umrechnungskurse vom deutschen Zoll im XML Format beziehen und parsen kannst. Nun soll es darum gehen diese Daten lokal zu speichern und in einem Graph anzeigen zu lassen.

Python Flask - Währungsrechner mit historischen Daten
Python Flask – Währungsrechner mit historischen Daten

speichern der Daten in einer CSV Datei auf dem Server

Damit wir später die Daten in einem Liniendiagramm darstellen können müssen wir zunächst die bereits geladenen Daten lokal speichern. Man könnte sicherlich dazu eine Datenbank nutzen aber das wäre wie sprichwörtlich „mit Kanonen auf Spatzen schießen“, es reicht daher für unseren Fall aus, die Daten in einer kommaseparierten Datei (*.csv) speichern.

Die CSV Datei soll lediglich die 4 Spalten:  Monat, Jahr, ISO3* und Wert enthalten. (Von der Schnittstelle des deutschen Zolls erhalten wir die Umrechnungskurse auf dem Monat genau.)

*Den ISO3 Wert speichern wir uns zusätzlich ab, damit wir später einfacher den Währungsrechner um eine zusätzliche Währung ergänzen können.

laden der historischen Daten beim starten des Servers

Die gespeicherten Daten müssen wir nun laden und für die spätere Darstellung ein wenig aufbereiten.

Die Aufbereitung beinhaltet in diesem Beispiel lediglich die Zuordnung der Werte (Monat,Jahr, ISO3, Wert) zu Feldern in einer geeigneten Klasse.

class Currency:
    def __init__(self, month, year, iso3, value):
        self.month = int(month)
        self.year = int(year)
        self.iso3 = str(iso3)
        self.value = float(value)

Die Daten laden wir in der Funktion „loadData“ welche beim starten des Servers ausgeführt wird. Dieses hat den großen Vorteil das der Besucher gewöhnlich keine zusätzliche Wartezeit hat.

historyCurrencys = []; 

def loadData():
    global currencys
    with open("static/data.csv", "r") as file:
        for line in file:
            values = line.strip().split(";")
            print(values)
            if(len(values)==4):
               historyCurrencys .append(Currency(values[0],values[1],values[2],values[3]))      

app.before_first_request(loadData);

In der Funktion „loadData“ prüfen wir zusätzlich ob der aktuelle Monat in der Liste vorhanden ist und wenn dieses nicht so ist, werden die Daten geladen und gespeichert.

def historyListContainsElement(month, year, iso3):
    return findHistoryElement(month, year, iso3) != None

def findHistoryElement(month, year, iso3):
    for c in historyCurrencys:
        if c.month == month and c.year == year and c.iso3 == iso3:
            return c
    return None

def loadData():
   ...
   year = datetime.date.today().year 
   month = datetime.date.today().month
   iso3 = currencys["USD"]["iso3code"]
   if historyListContainsElement(month, year, iso3):
       iso2 = currencys["USD"]["iso2code"]
       value = loadDataFromCustoms(iso2, month, year)
       appendHistoryData(month, year, iso3, value)

Die neuen Daten für den aktuellen Monat müssen nun in die Liste sowie in die CSV Datei gespeichert werden.

def appendHistoryData(month, year, iso3, value):    
    if findHistoryElement(month, year, iso3) != None:
        historyCurrencys.append(Currency(month, year, iso3, value))
        with open("static/data.csv", "a") as file:
            file.write(str(month) +';' + str(year) + ';' + str(iso3) + ';' + str(value))

laden der Daten für das berechnen der Umrechnungskurse

Beim Serverstart laden wir bereits die historischen Daten nun müssen wir noch prüfen ob der aktuelle Monat enthalten ist. Für diesen recht einfachen Anwendungsfall müssen wir nur die Liste durchlaufen und prüfen ob ein Eintrag enthalten ist bei welchem der Monat und das Jahr mit dem aktuellen identisch ist.

Wenn dieses nicht so ist dann wird die Liste um genau diesen Eintrag erweitert und die CSV Datei aktualisiert.

@app.route('/')
def start():
    ...    
    currentYear = datetime.date.today().year 
    currentMonth = datetime.date.today().month
    currentDateStr = getFormatedDate(currentMonth, currentYear)
	
    isPresent = False
    for c in historyCurrencys:
       if c.month == currentMonth and c.year == currentYear:
          isPresent = True
	  usDollar = c.value
       if isPresent == False:
          usDollar = loadDataFromCustoms(currencys["USD"]["iso2code"], currentMonth, currentYear)
	  appendHistoryData(currentMonth, currentYear, currencys["USD"]["iso3code"], usDollar)

darstellen eines Graphen in HTML

Unser Währungsrechner ist auf einer kleinen HTML Seite welche mit Python Flask & Jinja2 entwickelt wurde. Auf dieser Seite möchte ich nun zusätzlich einen Graph, also ein Diagramm anzeigen lassen.

Für das darstellen eines Diagramms auf einer Webseite gibt es diverse Frameworks. Ich als Lösung für dieses „Problem“ gerne die JavaScript Google Chart Bibliothek welche ich schon in diverse Projekte mit dem ESP8266 eingesetzt habe.

Zum Beispiel habe ich die Daten eines Temperatur & rel. Luftfeuchtigskeits Sensors mit hilfe der Google Gauges auf einer kleinen Webseite angezeigt, siehe WEMOS D1 – WLAN Thermometer mit DHT11 Sensor.

DHT11 Sensordaten auf Google Gauges
DHT11 Sensordaten auf Google Gauges

Jedoch möchten wir in unseren Währungsrechner ein Liniendiagramm anzeigen lassen. Welches aber genauso einfach zu implementieren ist. Es wird lediglich eine JavaScript Bibliothek benötigt.

Die Ressourcen zur Google Chart Bibliothek liegen leider nicht als Offline Version vor, d.h. es ist nur möglich diese als externe Ressource einzubinden.

übergeben der historischen Daten in das Template

Die historischen Daten laden wir bereits beim starten des Flask Servers, diese Daten wollen wir nun in das Template übergeben.

historyCurrencys = [];  

@app.route('/')
def start():  
    return render_template("template.html", historyCurrencys =historyCurrencys )

zeichnen der historischen Daten in ein Liniendiagramm

Nachdem wir nun die Daten in einer CSV Datei gespeichert und die Werte in das Template übergeben haben möchten wir diese historischen Daten in ein Google Line Chart zeichnen.

Dazu müssen wir zunächst die bereits benannte JavaScript Bibliothek laden. Dazu fügen wir nachfolgende Zeile in den HEAD Tag im HTML Dokument wie folgt ein.

<html>
   <head>
      <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>  
   </head>
...

Hier nun der JavaScript Code zum zeichnen eines Liniendiagramms wie im Teaserbild gezeigt.

<script type = "text/javascript" >
    google.charts.load('current', {'packages': ['corechart']});
    google.charts.setOnLoadCallback(drawChart);

function drawChart() {
    var data = google.visualization.arrayToDataTable([
        ['Monat-Jahr', 'Wert'],

        {% for value in historyCurrencys %}
            ['{{ value.month }}-{{ value.year }}', {{ value.value }}],
        {% endfor %}
    ]);

    var options = {
        title: 'Wechselkurs EURO > US-Dollar ({{historyCurrencys[0].month}}-{{historyCurrencys[0].year}} bis heute)',
        titlePosition: 'out',
        curveType: 'none',
        backgroundColor: '#edf6ff',
        legend: 'none',
        colors: ['#E59400'],
        hAxis: {
            slantedText: true,
            slantedTextAngle: 45,
            gridlines: { count: 7 }
        },
        vAxis: { format: '#.000$' }
    };

    var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
    chart.draw(data, options);
} </script>

Besonderes Hauptaugenmerk möchte ich auf die Generierung der Daten für das Diagramm hinweisen.

Für jeden Eintrag in der Liste mit historischen Währungsdaten wird ein JavaScript Array Eintrag generiert.

{% for value in historyCurrencys %}
   ['{{ value.month }}-{{ value.year }}', {{ value.value }}],
{% endfor %}

Release 0.4 auf GitHub

In der Rubrik Releases auf meinem GitHub Repository findest du die nun neue Version 0.4 mit dem Liniendiagramm inkl. historischer Daten.

Währungsrechner Version 0.4 mit historischen Daten in einem Liniendiagramm
Währungsrechner Version 0.4 mit historischen Daten in einem Liniendiagramm

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.