Re: Aufgabenverwaltung
Verfasst: Samstag 28. Juni 2014, 13:31
Btw.: für pickle solltest Du die Dateien für binäres Lesen und Schreiben öffnen.
Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
Code: Alles auswählen
Zum einen sind pickle-Dateien nicht menschenlesbar
Das heißt, dass Du zwischen Speichern und Laden von Klassenexemplaren nichts an einer Klasse ändern darfst. Wenn Du also aus irgendeinem Grund der Klasse noch zusätzliche Attribute hinzufügst oder bestehende wegnimmst, kannst Du mit den bereits gepickelten Daten erstmal nichts mehr anfangen, da diese in die geänderte Klassenstruktur nicht mehr hineinpassen, da sie ja von den geänderten Attributen nichts wissen. In einem solchen Fall muss man also die alten Daten erstmal in die alte Klassenstruktur laden, diese Exemplare dann in die neue Klassenstruktur konvertieren und dann erst wieder abspeichern. Sehr mühsam und eigentlich unnötig, wenn man auf pickle im Produktiveinsatz verzichtet, da es ja eben ausreichend Ersatz gibt, z. B. eben json oder gleich 'ne Datenbanklösung, wenn das denn nötig ist.Xfd7887a hat geschrieben:Den anderen Punkt verstehe ich nicht, ich fange erst mit Klassen an.
Ich finde ja. Momentan befinden sich Deine Daten `aufgaben` auf Modulebene, wo Sie eigentlich nicht hingehören. Wenn Du dafür eine Klasse `Tasks` (ich bevorzuge ja englische Namen) erstellst fände ich das übersichtlicher. Zudem wäre dann zusammen, was zusammengehört: Die Attribute einer Aufgabe wie Fach, Datum etc. und die Methoden (Funktionen), die Du darauf anwendest. Zum Beispiel:Xfd7887a hat geschrieben:Apropos Klassen: Würde es Sinn machen, mein Programm mit Klassen auszudrücken?
Code: Alles auswählen
class Task(object):
def __init__(self, subject, date, theme, grade):
self.subject = subject
self.date = date
self.theme = theme
self.grade = grade
def __str__(self):
return 'Task: {s} {d} {t} {g}'.format(
s=self.subject, d=self.date,
t=self.theme, g=self.grade)
class Tasks(object):
def __init__(self):
self.tasks = set()
def add_task(self, task):
self.tasks.add(task)
def __iter__(self):
for task in self.tasks:
yield task
Code: Alles auswählen
>>> import todo
>>> tasks = todo.Tasks()
>>> tasks.add_task(todo.Task('Mathe', '28.06.2014', 'Bruchrechnen', 'befriedigend'))
>>> tasks.add_task(todo.Task('Deutsch', '27.06.2014', 'Rechdschraibuhnk', 'ungenuegend'))
>>> for task in tasks:
... print task
...
Task: Mathe 28.06.2014 Bruchrechnen befriedigend
Task: Deutsch 27.06.2014 Rechdschraibuhnk ungenuegend
OOP selbst ist relativ leicht zu verstehen. Insbesondere dann, wenn man Vererbung erstmal außen vorlässt. Es wird eigentlich erst dann wirklich komplex, wenn man die besagte Vererbung nutzt und wenn man die Funktionalität auf Basis bestimmter Protokolle aufbaut. Im hier gezeigten Beispiel wurde das Protokoll für Iteratoren mittels ``__iter__`` implementiert. Häufig findet man auch Implementationen von ``__str__`` oder ``__repr__``. Das sieht anfangs wie Voodoo aus (ist es ja eigentlich auch ^^), aber mit der Zeit gewöhnt man sich daran und beginnt, die entsprechenden Vorteile zu erkennen und sinnvoll zu nutzen. Ob man die Klasse ``Tasks`` in seiner vorgeschlagenen Form wirklich so benötigt oder ob man nicht direkt ein Set (also ohne die "Hülle") benutzen möchte, sei übrigens mal dahingestellt...Xfd7887a hat geschrieben:Ich glaube, ich werde mich erstmal gründlicher in die OOP einarbeiten. Das ist doch komplizierter als ich dachte und ich weil mein Programm nicht "verschlimmbessern".
Code: Alles auswählen
import json
from datetime import datetime as DateTime
DATE_FORMAT = '%Y-%m-%d'
class Task(object):
def __init__(self, subject, date, topic, grade):
self.subject = subject
self.date = date
self.topic = topic
self.grade = grade
def __cmp__(self, other):
return cmp(self.subject, other.subject)
def __hash__(self):
return hash(self.subject)
def __str__(self):
return 'Task: {0.subject} {0.date} {0.topic} {0.grade}'.format(self)
def to_list(self):
return [
self.subject,
self.date.strftime(DATE_FORMAT),
self.topic,
self.grade,
]
@classmethod
def from_list(cls, values):
subject, date, topic, grade = values
return cls(subject, DateTime.strptime(date, DATE_FORMAT), topic, grade)
class Tasks(object):
def __init__(self, tasks=()):
self.tasks = set()
self.add_tasks(tasks)
def add_task(self, task):
self.tasks.add(task)
def add_tasks(self, tasks):
for task in tasks:
self.add_task(task)
def __iter__(self):
return iter(self.tasks)
def to_dict(self):
return {'tasks': [task.to_list() for task in self]}
def save(self, filename):
with open(filename, 'w') as json_file:
json.dump(json_file, self.to_dict())
@classmethod
def from_dict(cls, values):
return cls(Task.from_list(t) for t in values['tasks'])
@classmethod
def load(cls, filename):
with open(filename, 'r') as json_file:
return cls.from_dict(json.load(json_file))
Code: Alles auswählen
def debug_example(first=None, second=None):
import pdb; pdb.set_trace()
third = first + second
import pdb; pdb.set_trace()
return third
Code: Alles auswählen
>>> debug_example('eins', 'zwei')
> <stdin>(3)debug_example()
(Pdb) first
'eins'
(Pdb) second
'zwei'
(Pdb) third
*** NameError: name 'third' is not defined
(Pdb) c
> <stdin>(5)debug_example()
(Pdb) third
'einszwei'
(Pdb) q
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in debug_example
File "<stdin>", line 5, in debug_example
File "/usr/lib/python2.7/bdb.py", line 49, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib/python2.7/bdb.py", line 68, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit
Code: Alles auswählen
def __cmp__(self, other):
return cmp(self.subject, other.subject)
Code: Alles auswählen
def __hash__(self):
return hash(self.subject)
Aber wie kann ich mir das jetzt vorstellen?Return the hash value of the object (if it has one). Hash values are integers. They are used to quickly compare dictionary keys during a dictionary lookup.