Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

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

Posted on 17. April 202116. April 2021 by Stefan Draeger

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

Schreibe einen Kommentar Antworten abbrechen

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

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}