Vorstellung, erster Beitrag und Frage

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.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

__blackjack__ hat geschrieben: Dienstag 18. Januar 2022, 01:27 @rogerb: Ich mache das bei `datetime` aber tatsächlich wegen der Namenskonvention, weil insbesondere bei `date` es total sch…e ist das der Typ `date` es einem unmöglich macht den Namen für ein konkretes Datum zu verwenden.
Das ist meiner Meinung nach eine übertriebene Auslegung der Namenskonvention. Und wenn ich mal weiterlese ist dein Grund ja auch eher praktischer Natur. Denn du machst das ja sicher nicht bei allen kleingeschriebenen Klassennamen, die aus Python kommen.

"from operator import itemgetter as Itemgetter" ?

Für mich ist der Alias-Import eigentlich nur eine Notlösung um Namenskonflikte aufzulösen. Wenn "import numpy as np" nicht quasi ein *muss* wäre, würde ich das wohl auch nicht verwenden.
Insbesondere Namen, die direkt aus Python kommen, würde ich eigentlich nie umbenennen. Die Gefahr, dass es Verwirrung stiftet ist mir zu groß.

Wenn ich versuche eine größere Menge Fremdcode zu verstehen und mich durch die Module klicken muss, nervt es doch schon mal, wenn eine Klasse im importierenden Modul plötzlich einen anderen Namen als im Ursprungsmodule hat. Wenn die jetzt noch an ein anderes Modul durchgereicht wird und da wieder einen anderen Namen bekommt, ... (alles schon gesehen)

Dass bestimmte kleingeschriebene Instanz-Namen wie "date" nicht mehr zur Verfügung stehen, hat mich auch schon gestört. Andererseits ist man dann aber auch gezwungen aus dem eher generischen "date" ein "startdate" zu machen.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rogerb: Nee, generell mache ich das tatsächlich nicht. Hauptsächlich bei `datetime`. Bei einigen Sachen weiss man ja auch gar nicht, oder erwartet zumindest nicht 100%ig, dass es eine Klasse ist. In `itertools` ist einiges, was zwar eine klein geschriebene Klasse ist, aber genau so gut eine Funktion sein könnte. Davon leitet ja auch niemand etwas ab, sondern kombiniert das in dem man es mit anderen `itertools` und `map()`, `zip()`, `filter()` & Co zusammenstöpselt.

Gerade im `operator`-Modul gibt aber auch Namen die so schlecht sind, dass ich die tatsächlich in/für lesbare(m|n) Code umbenenne. So etwas wie ``from operator import ge as (is_)greater_or_equal`` findet man da bei mir schon mal. In dem Fall um zu verhindern das ein Leser überhaupt erst suchen muss was `ge` denn bedeuten mag und wo das denn her kommt, denn ich gehe davon aus, dass `is_greater_or_equal()` *deutlich* weniger Fragezeichen aufwirft als `ge()` und damit eine Umbenennung gerechtfertigt ist.

Ich glaube das einzige was ich sonst noch recht regelmässig umbenenne, weil es den Code wo es verwendet wird deutlicher macht, ist in `pytest`-Unittests ``from contextlib import ExitStack as does_not_raise`` um es in parametrisierten Tests als ”Gegenstück” zu `pytest.raises()` zu verwenden.

Und natürlich die Klassiker wie `tk`, `np`. Ich denke ``ctypes as ct``, ``sqlalchemy as sa``, und ``pyparsing as pp`` sind nicht so geläufig, habe ich aber auch hier und da bei anderen gesehen. Der Grund bei all *diesen* Beispielen ist ja letztendlich dass man beim schreiben schon weiss, man wird sehr sehr viele Namen aus diesen Modulen verwenden, weiss aber noch nicht welche das genau sind.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

ok, ich habe weitergemacht.

Mal sehen, ob ich was gelernt habe und aus dem Code ersichtlich ist,
was ich wollte und was dabei rausgekommen ist.

Für Anregungen bin ich wie immer sehr dankbar.
Ich bin der Meinung, dass es zumindest funktioniert.

Besten Dank vorab - und nun, Feuer frei

Code: Alles auswählen

[
# Funktionen berechnen ausgehend von einer Benutzereingabe vom Typ
# Datum dd.mm.YY den jeweils Monatsletzten und Monatsersten
# Format datetime

from datetime import datetime
from dateutil.relativedelta import relativedelta
# ------------------------------------------------------------------
def berechne_monatsletzten (datum):
    return datum + relativedelta(day=31)

def berechne_monatsersten (datum):
    #return datum + relativedelta(months=-1, day=1) # Monatserster Vormat
    return datum + relativedelta(day=1)

# --------------------- T E S T -------------------------------
eingabe_datum = datetime.strptime(input("Datum: "), "%d.%m.%Y")
monatsletzter = berechne_monatsletzten(eingabe_datum)
print(monatsletzter)

monatserster = berechne_monatsersten(eingabe_datum)
print(monatserster)/code]
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ja, die besondere Herausforderung ist natürlich Schaltjahre richtig zu behandeln. passt aber!
Man könnte bei der Ausgabe noch die Zeitangabe weglassen. Es geht ja nur um Tage, oder?


Fun-Fakt: relativedelta ist auch 'ne Klasse, die auch noch von "object" erbt.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Dann könnte man falsche Eingaben abfangen, 'monatsletzter' und 'monatserster' braucht man eigentlich nicht definieren, das könnte man direkt in die 'print'-Funktion schreiben.
Was du dir angewöhnten kannst/solltest, auf Modulebene gehört kein ausführbarer Code. Hier werden nur Konstanten, Funktionen und Klassen definiert. Üblicherweise steht das, was bei dir gerade auf Modulebene steht, in einer Funktion mit dem Namen 'main'. Aufgerufen wird die Funktion mit:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Ok erwirscht, diese Ausnahme darf/muss auf Modulebene stehen. Die sorgt dafür dass du das Programm in andere importieren kannst, ohne dass das automagisch gestartet wird.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

meinst Du mit ausführbarem Code das hier, was da nicht rein gehört?

Code: Alles auswählen

eingabe_datum = datetime.strptime(input("Datum: "), "%d.%m.%Y")
monatsletzter = berechne_monatsletzten(eingabe_datum)
print(monatsletzter)

monatserster = berechne_monatsersten(eingabe_datum)
print(monatserster)/code]

Das wird da auch nicht "drin" bleiben bzw. wird in Kommentar gesetzt werden.
Mehr oder weniger für mich, um schnell mal zu probieren.
Aber falls das gemeint war, danke ich Dir für den Hinweis.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

rogerb hat geschrieben: Donnerstag 20. Januar 2022, 22:30 Ja, die besondere Herausforderung ist natürlich Schaltjahre richtig zu behandeln. passt aber!
Man könnte bei der Ausgabe noch die Zeitangabe weglassen. Es geht ja nur um Tage, oder?


Fun-Fakt: relativedelta ist auch 'ne Klasse, die auch noch von "object" erbt.
Vielen Dank auch für diesen Hinweis.
Muss gestehen, aktuell noch ein wenig Bahnhof.
Das ist aber gut.
Ich werde es mir ansehen und versuchen zu verstehen.

Für "mein" Projekt habe ich so weit erst einmal viel geschafft, da ich viel mit Datum werde rechnen müssen.

Ja, es geht "nur"um Tage.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich war mal neugierig und habe versucht zu schauen bei wie vielen Klassen aus der Standardbibliothek der Name komplett klein geschrieben ist. Von 2203 Klassen die kein Implementierungsdetail sind und die nicht in `builtins` sind (Python 3.7 unter Linux) sind 145 komplett klein geschrieben. Hier die Liste:

Code: Alles auswählen

Classes: 2203
Classes with lower case name: 145
p abc.abstractclassmethod
p abc.abstractproperty
p abc.abstractstaticmethod
c array.array
p asynchat.async_chat
p asynchat.simple_producer
p asyncore.dispatcher
p asyncore.dispatcher_with_send
p asyncore.file_dispatcher
p asyncore.file_wrapper
c audioop.error
p binhex.openrsrc
p calendar.different_locale
p collections.defaultdict
p collections.deque
p contextlib.closing
p contextlib.nullcontext
p contextlib.redirect_stderr
p contextlib.redirect_stdout
p contextlib.suppress
p csv.excel
p csv.excel_tab
p csv.unix_dialect
p ctypes.c_bool
p ctypes.c_byte
p ctypes.c_char
p ctypes.c_char_p
p ctypes.c_double
p ctypes.c_float
p ctypes.c_int
p ctypes.c_long
p ctypes.c_longdouble
p ctypes.c_short
p ctypes.c_ubyte
p ctypes.c_uint
p ctypes.c_ulong
p ctypes.c_ushort
p ctypes.c_void_p
p ctypes.c_wchar
p ctypes.c_wchar_p
p ctypes.py_object
p datetime.date
p datetime.datetime
p datetime.time
p datetime.timedelta
p datetime.timezone
p datetime.tzinfo
p distutils.command.bdist.bdist
p distutils.command.bdist_dumb.bdist_dumb
p distutils.command.bdist_rpm.bdist_rpm
p distutils.command.bdist_wininst.bdist_wininst
p distutils.command.build.build
p distutils.command.build_clib.build_clib
p distutils.command.build_ext.build_ext
p distutils.command.build_py.build_py
p distutils.command.build_py.build_py_2to3
p distutils.command.build_scripts.build_scripts
p distutils.command.build_scripts.build_scripts_2to3
p distutils.command.check.check
p distutils.command.clean.clean
p distutils.command.config.config
p distutils.command.install.install
p distutils.command.install_data.install_data
p distutils.command.install_egg_info.install_egg_info
p distutils.command.install_headers.install_headers
p distutils.command.install_lib.install_lib
p distutils.command.install_scripts.install_scripts
p distutils.command.register.register
p distutils.command.sdist.sdist
p distutils.command.upload.upload
p enum.auto
p filecmp.dircmp
p ftplib.error_perm
p ftplib.error_proto
p ftplib.error_reply
p ftplib.error_temp
p functools.partial
p functools.partialmethod
c grp.struct_group
c itertools.accumulate
c itertools.chain
c itertools.combinations
c itertools.combinations_with_replacement
c itertools.compress
c itertools.count
c itertools.cycle
c itertools.dropwhile
c itertools.filterfalse
c itertools.groupby
c itertools.islice
c itertools.permutations
c itertools.product
c itertools.repeat
c itertools.starmap
c itertools.takewhile
c itertools.zip_longest
p macpath.norm_error
p mailbox.mbox
c mmap.mmap
p netrc.netrc
c nis.error
p operator.attrgetter
p operator.itemgetter
p operator.methodcaller
p os.stat_result
p os.statvfs_result
p os.terminal_size
c parser.st
p platform.uname_result
p poplib.error_proto
c posix.sched_param
c posix.times_result
c posix.uname_result
c posix.waitid_result
c pwd.struct_passwd
c pyexpat.xmlparser
p re.error
c resource.struct_rusage
p sched.scheduler
c select.epoll
p shlex.shlex
p shutil.usage
p signal.struct_siginfo
p socket.gaierror
p socket.herror
p socket.socket
p socket.timeout
c spwd.struct_spwd
p struct.error
c termios.error
c time.struct_time
p typing.typing.io
p typing.typing.re
p urllib.request.ftpwrapper
p urllib.response.addbase
p urllib.response.addclosehook
p urllib.response.addinfo
p urllib.response.addinfourl
p warnings.catch_warnings
p weakref.finalize
c xxlimited.error
c xxsubtype.spamdict
c xxsubtype.spamlist
c zipimport.zipimporter
c zlib.error
Das "p"/"c" vor den Namen bedeutet ob die Klasse in Python oder in C geschrieben ist. Da wollte ich schauen, ob das vielleicht ein Muster ergibt, weil die eingebauten klein geschriebenen Namen, wo das klein schreiben ja ”normal” ist, alle in C implementiert sind.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ein Muster erkenne ich da jetzt aber nicht.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Das was in itertools, contextlib oder operator angeboten wird, fühlt sich für mich mehr nach Funktionen an. Wirklich störend sind datetime und socket.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Nun, ich habe nochmal eine Frage zur Klasse date aus dem Modul datetime

ich importiere:
from datetime import date
dann folgt:

Code: Alles auswählen

def datum_nach_deutsch (self, datedatum):
        """ Wandelt ein datetime Datum in die deutsche Schreibweise um
            Das wird für die spätere Ausgabe des Datums benötigt """
        benutzerdatum = datedatum.strftime("%d.%m.%Y")
        return benutzerdatum
Ich finde das "schick", weil ich die Uhrzeit nicht benötige.


Um das ganze "umzudrehen" benutze ich strptime aus der Klasse datetime vom Modul datetime.
Nun kommt aber ja immer auch die Uhrzeit dazu.
Was ich nicht benötige.

Wie bekomme ich nur über date ein Benutzerdatum (also Eingabe als str wie z.B. 06.02.2022)
in ein korrektes date Objekt? Also ohne datetime zu verwenden?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein datetime-Objekt hat auch das reine Datum, siehe https://docs.python.org/3/library/datet ... etime.date

Du verwendest also weiterhin strptime, und rufst dann auf dem resultierenden Objekt nochmal date() auf.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@derkai74: Warum steckt die Funktion in einer Klasse? Und was soll einem `datedatum` sagen? Das ist eine verwirrende denglisch-Namensgebung
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

der Vollständigkeit halber, dass ist mein bisheriger Weg von Benutzeringabe
nach datetime Objekt, womit ich noch nicht so glücklich bin:

Code: Alles auswählen

def deutsch_nach_datum (self, benutzerdatum):
        """ Wandelt das Datum einer deutschen Benutzereingabe in
            ein datetime Objekt um """
        datedatum = datetime.strptime(benutzerdatum, "%d.%m.%Y")
        #datedatum = date(benutzerdatum) # geht nicht
        return datedatum
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Ich bereit mir eine Klasse zur Umwandlung diverser Berechnungen vor.
Daher steckt die Klasse darin.

datedatum soll bedeuten, dass es das Datum als Objekt von date ist.
Ich verstehe was Du meinst, ich werde es umbenennen
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Code: Alles auswählen

def datum_nach_deutsch (self, datum):
        """ Wandelt ein datetime Datum in die deutsche Schreiweise um
            Das wird für die spätere Ausgabe des Datums benötigt """
        return datum.strftime("%d.%m.%Y")

Code: Alles auswählen

def deutsch_nach_datum (self, datum):
        """ Wandelt das Datum einer deutschen Benutzereingabe in
            ein datetime Objekt um """
        return datetime.strptime(datum, "%d.%m.%Y")
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und da fehlt ein .date() bei deutsch_nach_datum. Dann bekommst du nur das date-Objekt.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Solange `self` nicht benutzt wird, ist die Klasse unnötig. Eine Klasse zu definieren, ist kein Selbstzweck, sondern nur dann sinnvoll, wenn sie auch wirklich benutzt wird.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Danke für den Hinweis, ich bekomme es leider nicht hin...
Wie müsste die Zeile genau aussehen?
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Ok, das meintest Du, richtig?

return datetime.strptime(datum, "%d.%m.%Y").date()

Vielen Dank.
Zuletzt geändert von derkai74 am Sonntag 6. Februar 2022, 18:11, insgesamt 1-mal geändert.
Antworten