Dateien herunterladen und in einem Verzeichnis ablegen

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.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Trick ist das getLogger mit dem gleichen Namen immer den gleichen Logger zurueckgibt. Der ist an anderer Stelle (also initialize_logger) konfiguriert worden, aber benutzen kannst du ihn ueberall mit

Code: Alles auswählen

logging.getLogger("Data download").info("text")
Ueblicherweise verwendet man stattdessen das hier https://docs.python.org/2/howto/logging ... g-tutorial beschriebene

Code: Alles auswählen

# modul-global!
logger = logging.getLogger(__name__)
Und statt in initialise_logger einen Namen anzugeben, machst du nur "logger = logging.getLogger()", womit du den root-logger bekommst. Alle anderen Logger mit Namen wie "mein.package.submodul" delegieren immer weiter nach oben, bis zur Wurzel.
aaron
User
Beiträge: 92
Registriert: Donnerstag 1. Dezember 2016, 23:10

Als Ergebnis möchte ich eine Ausgabe wie folgt haben:
File for AUDJPY/2017/1 already fetched.
File for AUDJPY/2017/2 already fetched.
File for AUDJPY/2017/3 already fetched.
File for AUDJPY/2017/4 already fetched.
File for AUDJPY/2017/5 already fetched.

Das Logging muß ja in der Schleife aufgerufen werden.
1. wenn die Datei nicht vorhanden, oder beschädigt ist.
2. wenn die Datei schon heruntergeladen wurde.
Der Inhalt des Logfiles sieht so aus:
2017-04-26 17:45:21,064 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,140 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,215 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,300 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,381 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,470 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,559 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,636 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,736 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,823 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,921 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,006 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,086 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,179 - Data download - ERROR - HTTP Error 404: Not Found

ERROR - HTTP Error 404: Not Found ist ja richtig. Nur möchte ich wissen welche Datei nicht vorhanden, oder beschädigt ist.

Hier noch einmal die Funktion. So schwer kann das doch nicht sein. Das HOWTO bringt mich nicht weiter, weil ich nicht erkennen kann, wie ich was in der Schleife aufrufe.

Code: Alles auswählen

def fetch_whole_year(symbol, year):                                              
      for symbol in symbol:                                                        
          last_week = datetime.date(year, 12, 31).isocalendar()[1]                 
          for week in range(1, last_week + 1):                                     
              try:                                                                 
                  if not exists_file(symbol, year, week):                          
                      data = pull_file(symbol, year, week)                         
                      print_data_length(data)                                      
                      save_file(symbol, year, week, data)                          
              except Exception as e:                                               
                  logging.getLogger("Data download").error(e)                      
              else:                                                                
                  print("File for {}/{}/{} already fetched.".format(               
                      symbol, year, week)                                          
                  )    
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann musst du doch nur die dazu notwendigen Daten loggen, also symbol, year, week, bzw. den Filenamen der dazugehoert.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@aaron: so

Code: Alles auswählen

import logging
logger = logging.getLogger('Data download')

def fetch_whole_year(symbol, year):
    for symbol in symbol:
        last_week = datetime.date(year, 12, 31).isocalendar()[1]
        for week in range(1, last_week + 1):
            try:
                if not exists_file(symbol, year, week):
                    data = pull_file(symbol, year, week)
                    print_data_length(data)
                    save_file(symbol, year, week, data)
            except Exception:
                logger.exception("while downloading {}/{}/{}".format(symbol, year, week))
            else:
                logger.info("File for {}/{}/{} already fetched.".format(symbol, year, week))

def initialize_logger():
    logfile_name = generate_logfile()
    ensure_logdir_exists(logfile_name)
    logging.basicConfig(filename=logfile_name, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@aaron: wenn Du am aktuellen Datum aufhören willst, dann prüf einfach auf das aktuelle Datum:

Code: Alles auswählen

last_day = min(datetime.date(year, 12, 31), datetime.date.today())
new_year, last_week, _ = day.isocalendar()
if new_year > year:
    last_week = 52
elif new_year < year:
    return
aaron
User
Beiträge: 92
Registriert: Donnerstag 1. Dezember 2016, 23:10

Ich möchte den Codeschnipsel als Funktion einbauen.

Code: Alles auswählen

def check_date():                                                               
    last_day = min(datetime.date(year, 12, 31), datetime.date.today())     
    new_year, last_week, _ = day.isocalendar()                                  
    if new_year > year:       
        last_week = 52                                                          
    elif new_year < year:                        
        return         
Ich bekomme folgende Fehlermeldung:

Code: Alles auswählen

TickDataCsv.py|91 col 1 error| E0602 undefined name 'year' [pyflakes]                                                                                                                                              
TickDataCsv.py|91 col 1 error| W0612 local variable 'last_day' is assigned to but never used [pyflakes]
TickDataCsv.py|92 col 1 error| E0602 undefined name 'day' [pyflakes]
TickDataCsv.py|93 col 1 error| E0602 undefined name 'year' [pyflakes]
TickDataCsv.py|94 col 1 error| W0612 local variable 'last_week' is assigned to but never used [pyflakes]
TickDataCsv.py|95 col 1 error| E0602 undefined name 'year' [pyflakes]
Ich wollte die Funktion dann in der Funktion fetch_whole-year aufrufen.

Code: Alles auswählen

def fetch_whole_year(symbol, year):
      for symbol in symbol:
          check_date()
          last_week = datetime.date(year, 12, 31).isocalendar()[1]
          for week in range(1, last_week + 1):
              try:
                  if not exists_file(symbol, year, week):
                      data = pull_file(symbol, year, week)
                      print_data_length(data)
                      save_file(symbol, year, week, data)
              except Exception:
                  logger.exception("while downloading {}/{}/{}".format(
                      symbol, year, week)
                  )
              else:
                  logger.info("File for {}/{}/{} already fetched.".format(
                      symbol, year, week)
                  )
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@aaron: lerne was Funktionen sind.
aaron
User
Beiträge: 92
Registriert: Donnerstag 1. Dezember 2016, 23:10

Ich versuche schon lange die Funktionen zu begreifen. Hier meine erste Frage. Als Parameter übergebe ich year und day, weil ich aktuelle Datum prüfen möchte. Ist 2017 > 2016, dann ist die letzte Woche die 52. Kalenderwoche. Was ist bei einem Jahr mit 53 Kalenderwochen? Ist das neue Jahr < Jahr dann return. Kann mir bitte jemand erklären wie diese Funktion richtig funktioniert, woher die Parameter kommen und wie diese richtig an die nächste Funktion übergeben werden.

Code: Alles auswählen

def check_date(year, day):
      last_day = min(datetime.date(year, 12, 31), datetime.date.today())
      new_year, last_week, _ = day.isocalendar()
      if new_year > year:
          last_week = 52
      elif new_year < year:
          return
Als Fehlermeldung bekomme ich

Code: Alles auswählen

TickDataCsv.py|91 col 1 error| W0612 local variable 'last_day' is assigned to but never used [pyflakes]                                                                                                            
TickDataCsv.py|94 col 1 error| W0612 local variable 'last_week' is assigned to but never used 
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@aaron: was verstehst Du denn nicht (da hat es noch einen ziemlich offensichtlichen Fehler)? Zu welchem Zweck rufst Du die Funktion auf?
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Ich habe die Diskussion nicht verfolgt. Möglicherweise macht es Sinn die Diskussionen (z. B. Logging-Problem) jeweils in neue Threads zu packen, so dass kleinere Einheiten (Diskussionnen) entstehen und man das später mittels Foren-Suche noch mal nutzen kann.

Code: Alles auswählen

def check_date(year, day):
      last_day = min(datetime.date(year, 12, 31), datetime.date.today())
      new_year, last_week, _ = day.isocalendar()
      if new_year > year:
          last_week = 52
      elif new_year < year:
          return
Zu den einzelnen Zeilen:
1. Du definierst eine Funktion check_date, die die beiden Parameter year und day erwartet.
2. Du ermittelst den last_day als Minimum zweier Daten, arbeitest in der Funktion aber nicht mehr (!) mit dieser Variable, was die Fehlermeldung 1 moniert.
3. Du bestimmst die Variablen new_year und last_week, nutzt aber die Variable last_week nicht mehr in der Funktion. Fehlermeldung 2. Ein echter Fehler, der zu einem Programmabbruch führen sollte, ist das beides nicht.
4. Du prüfst, ob das new_year größer als der Wert der Variable year ist und (5.) weist der Variablen last_week in diesem Fall den Wert 52 zu. Du verwendest diesen Wert in der Funktion sonst nicht mehr.
6. Ist new_year kleiner als year, dann machst du einen Rückgabewert ohne etwas zurückzugeben. Der Rückgabewert ist deshalb None.

Bei den Funktionen musst du verstehen, dass alles, was in der Funktion definiert und berechnet wird, dort bleibt (!), wenn es nicht zurückgegeben wird. Die Zuweisung in Zeile 5 z. B. ist wirkungslos, weil du damit weder weiterrechnest, noch etwas irgendwo veränderst (z. B. Prozedur), noch etwas zurückgibst.

Ich sehe nicht, dass die Funktion etwas leistet.
BlackJack

Wie pixewakb ja schon schrieb sind die beiden gemeldeten Fehler gar keine Fehler im Sinne das dort das Programm abbricht. Die kommen auch nicht von Python sondern von der IDE die dafür anscheinend `pyflakes` verwendet. Die Nummer der Meldungen beginnt mit einem W für Warning. Falls die IDE nicht zwischen Fehlern und Warnungen deutlich unterscheidet, sollte man das in den Einstellungen anpassen. Falls das nicht geht, würde ich die IDE wechseln.
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Hilft Dir das:

Code: Alles auswählen

def quadrieren(a, b):
    # quadriert die beiden Zahlen a und b
    if type(a) not in [int, float]:
        raise TypeError("a ist keine Zahl!")
    if type(b) not in [int, float]:
        raise TypeError("b ist keine Zahl!")
    return a * b


def main():
    # Hauptprogramm, Prozedur ohne Rückgabewert
    a = 2
    b = 3

    produkt = quadrieren(a, b)

    print(produkt)

    a = b
    b = produkt

    produkt = quadrieren(a, b)

    print(produkt)


if __name__ == "__main__":
    main()
Formulier mal in Sprache, was Dein Algorithmus erledigen soll. Für mich ist es momentan schwierig Deinen Quelltext und Deine Aufgabe zu verstehen. Wenn ich es richtig denke, dann musst Du prüfen, ob der Ordner noch OK ist, falls ja, speicherst Du daran, falls nein, erzeugst Du einen neuen Ordner und speicherst dann da rein? Ich kann nicht sagen, dass ich ganz durchblicke. Momentan bin ich mit Arbeit eingedeckt und werde mich nicht (komplett) durch deinen Quelltext arbeiten können.
BlackJack

@pixewakb: Die Typprüfungen verhindern das man beispielsweise `long`; `decimal.Decimal`; `fractions.Fraction`; `mpz`-, `mpf`-, oder `mpq`-Objekte aus dem `gmpy`-Modul; Zahltypen und Arraytypen von Numpy, und wahrscheinlich noch eine ganze Menge anderer ”Zahlen” mit der Funktion verwenden kann. Warum?

Zudem würde man wenn schon mit `isinstance()` prüfen um wenigestens direkt abgeleitete Typen nicht auszuschliessen.
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Autsch, wegduck. :oops: :oops: :oops:

In freier Wildbahn prüfe ich selten und wenn dann gezielt auf ganz wenige Dinge. Wie würdest Du die Typprüfung umsetzen, wenn man fragen darf.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@pixewakb: meist gar nicht. Passen die Typen nicht, fliegt einem das ja spätestens bei a*b um die Ohren.
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

aaron hat geschrieben:Ich versuche schon lange die Funktionen zu begreifen. Hier meine erste Frage. Als Parameter übergebe ich year und day, weil ich aktuelle Datum prüfen möchte. Ist 2017 > 2016, dann ist die letzte Woche die 52. Kalenderwoche. Was ist bei einem Jahr mit 53 Kalenderwochen? Ist das neue Jahr < Jahr dann return. Kann mir bitte jemand erklären wie diese Funktion richtig funktioniert, woher die Parameter kommen und wie diese richtig an die nächste Funktion übergeben werden.

Code: Alles auswählen

def check_date(year, day):
      last_day = min(datetime.date(year, 12, 31), datetime.date.today())
      new_year, last_week, _ = day.isocalendar()
      if new_year > year:
          last_week = 52
      elif new_year < year:
          return
Als Fehlermeldung bekomme ich

Code: Alles auswählen

TickDataCsv.py|91 col 1 error| W0612 local variable 'last_day' is assigned to but never used [pyflakes]                                                                                                            
TickDataCsv.py|94 col 1 error| W0612 local variable 'last_week' is assigned to but never used 
Mal eine Verständnisfrage: Beim Speichervorgang würde ich doch nur das Speicherziel ermitteln, da wäre es doch eigentlich egal, in welcher Woche du dich befindest, das würde ich Python überlassen wollen. Wenn Du wieder laden willst (getrennter Vorgang, sonst würde ich mit dem Python-generierten Wert weiterarbeiten), bestimmst Du den letzten Ordner auf der Platte. Die Detailfragen dahinter - ohne mich jetzt durch den Quelltext zu arbeiten, Sorry, mein Schreibtisch liegt voll - müssten dich doch eigentlich gar nicht interessieren?
Antworten