Seite 4 von 5
Re: Python 'Benzingespräche'
Verfasst: Donnerstag 9. Dezember 2021, 21:31
von ulipy
narpfel hat geschrieben: Donnerstag 9. Dezember 2021, 21:23
@ulipy: Ich bin mir sicher, dass du deine Funktion nie mit null Argumenten getestet hast, aber (fehlerhaften) Code geschrieben hast, der das behandeln soll. Dass dir das nicht aufgefallen ist, zeigt, dass der Code zu komplex ist. Insbesondere auch, weil die Prüfung komplett überflüssig wäre, wenn du den Code auf zwei Funktionen aufgeteilt hättest.
Absolut einverstanden - danke!
Es fand bisher kein nennenswertes Testen statt und ich war und bin absolut
nicht der Ansicht, dass der Code - so wie er gerade ist - bereits zuverlässig verwendbar wäre.
Im Gegenteil - es war klar, dass das rein logische Nachvollziehen hier
nicht ausreichernd ist, genau wegen dieser Struktur..
Re: Python 'Benzingespräche'
Verfasst: Donnerstag 9. Dezember 2021, 21:34
von ulipy
Nachtrag: ich gehe aber davon aus, dass der Programmierer rasch etwas bemerken würde, falls er sich so etwas einfallen ließe...
Re: Python 'Benzingespräche'
Verfasst: Donnerstag 9. Dezember 2021, 22:01
von ulipy
@ulipy: Ich bin mir sicher, dass du deine Funktion nie mit null Argumenten getestet hast, aber (fehlerhaften) Code geschrieben hast, der das behandeln soll. Dass dir das nicht aufgefallen ist, zeigt, dass der Code zu komplex ist. Insbesondere auch, weil die Prüfung komplett überflüssig wäre, wenn du den Code auf zwei Funktionen aufgeteilt hättest.
Jetzt muss ich doch sofort nachfragen - das ist erst mal sehr überraschend:
Weshalb genau ergibt dies einen
Laufzeitfehler - ein solcher is ja deutlich unwillkommener als eine Parser-Meldung...
Mit
if 1 < len(args) > 3 or len(args) == 0:
passiert das nicht mehr

Re: Python 'Benzingespräche'
Verfasst: Donnerstag 9. Dezember 2021, 22:06
von __deets__
Mit positions Argumenten hätte man lesbare Namen, und sowas passiert erst recht nicht, weil der Interpreter einen warnt. Ohne das man das vergessen kann & den Code mit solchen statements versalzt.
Re: Python 'Benzingespräche'
Verfasst: Donnerstag 9. Dezember 2021, 22:19
von narpfel
@ulipy: Für welche Zahlen `x` gilt denn `1 < x > 3`?
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 17:56
von ulipy
@all
in dem für mich als crash-Seitenensteiger extrem "dichten Wald" "Python" war ich in Sachen if-Struktur auch noch betriebsblind geworden
[ironie an]
Hätte mir doch jemand erklärt, dass "man" eine read-only Abfrage auch in einen bereits vorhandenen read-only block mit reinnimmt, aber nein...
[ironie aus]
Wurde dann heute beim Lesen von
viewtopic.php?f=1&t=53600 wenigstens
etwas getröstet - ich bin nicht alleine

(wobei dies thematisch mit dem vorliegenden nichts bis wenig zu tun hat, mir jedoch
sehr bekannt vorkommt...)
Vielleicht ist das hier unten ein besserer Weg, um erst daran anschliessend ggfs. auftauchende Umsetzungs-Schwierigkeiten klären zu können?
Die Erstellung eines doc-strings
vor dem Umsetzen hätte ganz klar viele Vorteile - zumindest für mich persönlich (bin da ja aus Erfahrung nun durchaus deutlich vorsichtiger geworden..)
Beim ursprünglichen Wunsch, eine kleine Hilfe für den reinen Eigenbedarf zu erstellen, kam diese Ebene - wie fast immer, denke ich - definitiv zu kurz
Meint ihr, so was macht Sinn?
Code: Alles auswählen
# Meta-Bemerkungen (in deutscher Sprache) entfallen ab dem pre-release.
# Sie dienen bis dahin ausschließlich Kommentaren, welche zum leichteren Verständnis des aktuellen Code-Status dienen
# !access settings via this function only please!
def settings(mode, keywrd, value):
"""
Requires:
# hier stehen momentan nur zwei Platzhalter
environement(...)
custom_error_handling(...)
At program start, data_dict is loaded either
from default_dict or from a settings-file
Arguments use:
mode keywrd value
---- ------ -----
'read_default_data' None None
return: data_dict
'save_settings_dict' None None
return: data_dict
'get_keyval' dict-key None
return: value
'update_keyval' dict-key value
return: value
Access samples:
settings('read_default_data', None, None)
settings('save_settings_dict', None, None)
settings('get_keyval', key, None)
settings('update_value', key, value)
"""
Falls ja, könnte zuerst die Logik im doc-string abgeklopft werden?
Zumindest kann ich mir das vorstellen.
Die Umsetzung könnte dann bei Bedarf am Ende dessen stehen.
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 18:37
von Sirius3
Dass jetzt kein *args mehr benutzt wird, ist definitiv besser. Trotzdem, statt eine Funktion zu schreiben, die über ihr erstes Argument vier verschieden Dinge macht, ist es immer noch besser vier Funktionen zu schreiben.
Das `Requires` ist unnötig, oder hast Du das schon jemals in einem Doc-String gelesen? Der Entwickler der Funktion muß ja sicherstellen, dass alle Abhängigkeiten vorhanden sind, das interessiert den Nutzer nicht die Bohne.
Und was zum Henker hast Du Dir dabei gedacht, bei keywrd das o wegzulassen? Wir sind nicht bei Glücksrad, wo man Vokale extra kaufen muß.
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 18:50
von ulipy
@narpfel
so wie du fragst, ist mit Sicherheit der Wurm drin - der Test 1 < len(args) > 3 war auf genehmigte 1 bis 3 Argumente angelegt (falsch natürlich wegen der 1, hätte 0 sein sollen...)
@Sirius3
Klare Ansage!
- Sparen ist nicht immer richtig - war absolut unnötig
- das mit der einen Funktion ist "eigen"
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 18:58
von narpfel
@ulipy: Wie ist es denn mit 0 statt 1 richtiger?
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 19:56
von ulipy
@narpfel
war nicht das wesentliche Problem zu dieser Zeit - weshalb sagst du mir nicht einfach, wie die korrekte Syntax wäre?
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:01
von ulipy
@Sirius3
Hmmm.. - den Docstring hatte ich bisher ausschließlich als für den Entwickler gedacht gesehen - nciht für den Anwendere des Programms. Verhält sich dies üblicherweise anders?
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:08
von pillmuncher
@ulipy: Die Syntax ist richtig, aber die Bedingung ist falsch. Das hier:
bedeutet dasselbe wie
und damit dasselbe wie
Die Bedingung ist also bereits erfüllt, wenn
len(args) größer ist als 3. Der Test darauf, ob
len(args) größer ist als 1, ist folglich redundant, weil alles, was größer ist als 3 automatisch auch größer ist als 1.
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:09
von Sirius3
@ulipy: die Dokumentation enthält normalerweise keine Implementierungsdetails. Die muß der Anwender der Funktion nicht kennen.
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:24
von ulipy
pillmuncher hat geschrieben: Samstag 11. Dezember 2021, 20:08
@ulipy: Die Syntax ist richtig, aber die Bedingung ist falsch.
...
Danke dir, schau mir das genauer an!
@Sirius3
oh mei - wann würde denn der Docstring für einen Anwender relevant? Die Idee war ja genau die, ihn nur sehr begrenzt mit eher technischen Details zu konfrontieren -- auch noch auf englisch .
Dachte bis jetzt, der Anwender kommt nicht in den Kontakt mit Docstrings?
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:31
von pillmuncher
@ulipy: Der Anwender einer Bibliotheksfunktion ist der Programmierer, der diese Bibliotheksfunktion verwendet. Der Docstring ist für diesen Programmierer gedacht.
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:42
von ulipy
ok, dann habe ich das jetzt so verstanden:
der Anwender (Programmierer) muss in der Regel keine Implementierungsdetails aus dem docstring entnehmen können - stimmt das denn dann so?
Die Abgrenzung wäre damit natürlich Ermessensfrage
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 20:45
von ulipy
schaue jetzt erst mal im PEP 257 nach - komme dann evtl. zurück...
Re: Python 'Benzingespräche'
Verfasst: Samstag 11. Dezember 2021, 21:49
von ulipy
@pillmuncher, @narpfel
Nach einem "Klassenbesten" in Mathe es ist eine (fast) erschreckende Selbsterkenntnis, eine schlichte logische Bedingung dermaßen "falsch" zu formulieren.
Es sind die knapp dreißig Jahre, in denen dieser "trait" nicht bewusst und diszipliniert genutzt wurde, die solche Aberrationen erlauben...
Für meinen Teil ist das hier erst mal durch - ich stell nach den Anpassungen die ganze Funktion nochmals rein.
Danke!
Re: Python 'Benzingespräche'
Verfasst: Sonntag 12. Dezember 2021, 22:15
von ulipy
@all
Hab jetzt versucht, so
eigentlich alles bisher Gesagte zu berücksichtigen - außer der gewollt beibehaltenen "Eigenheit" der Bedeutung des nun "task" genannten ersten args.
Bin inzwischen wirklich müde mit den "settings" - aber leider hilft das nicht weiter... es sollen ja die wichtlgsten Aspekte pythonischen (einfachen) Codes berücksichtigt sein, damit diese dann auch in kommenden Modulen angewandt werden können.
Wenn's "zerrissen" werden muss, dann muss das eben so sein...
Code: Alles auswählen
### B I T T E V O R S I C H T ###
# Es könnte zu Testzwecken eine Testdatei in das
# Arbeitsverzeichnis geschrieben werden!
# Der Dateiname ist jedoch so gewählt, dass ein
# Konflikt zu unser aller Lebzeiten - auch in Summe -
# eher nicht vorkommen kann. :-)
# Meta-Bemerkungen (in deutscher Sprache):
# Diese entfallen ab dem pre-release
# Sie dienen bis dahin ausschließlich Kommentaren,
# welche dem leichteren Verständnis des aktuellen
# Code-Status während der Entwicklung dienen
# Laufzeitumgebung (Planungsgrundlage):
# Win10, Python3
# Umgebungsvariablen wie z. B. Installationsverzeichnis,
# Zugriffsrechte etc. werden an anderem Ort überprüft
# BS-Unabhängigkeit:
# Betriebssystem-Unabhängigkeit hat ! Erste Priorität !
# (Sofern für das aktuelle target-System begründet
# keine alternativen, proprietären Optionen vorzuziehen sind
import os
import json
# define customError class to intercept possible
# errors during coding of the APP
class customError(Exception):
pass
# !access settings dictionary via this function only please!
def settings(task, keyword, value):
u"""
Read write settings data.
At program start, settings_data is loaded either
from DEFAULT_SETTINGS or from data_path (settings-file).
The arguments use is self-explanatory:
task keyword value
---- ------ -----
'read_default_data' None None
return: settings_data
'save_settings_data' None None
return: settings_data
'get_keyval' dict-key None
return: value
'update_keyval' dict-key value
return: value
Access samples:
settings('read_default_data', None, None)
settings('save_settings_data', None, None)
settings('get_keyval', key, None)
settings('update_keyval', key, value)
# raise a customError:
settings('read_default_data', None, 'any item except "None"')
"""
ERR_MSG_ARG = 'An arg != None was encountered unexpectedly'
ERR_MSG_ARGS = 'The type of at least one of two arguments was detected to be != None'
ERR_MSG_TYPE = 'Arg one unexpectedly was not of type string'
ERR_MSG_TASK = 'Arg one was not interpretable'
# Arbeitsverzeichnis und Dateiname ist temporär !!!
data_path = '.\\dummy_f_dfg_ff__Y_TmP_mydata.json'
# defaults for settings data
DEFAULT_SETTINGS = {
'_del_orphaned': False, # if true: del orphaned versions
'_demo_only': False, # if true: demo only
'_hide_versions': False, # if true: hide
'_symlinks_dirs': False, # if false: ignore
'_symlinks_files': False, # if false: ignore
# 'scan_all_subdirs', # visibility of subdirs for power-user
}
# load settings_data
if not os.path.exists(data_path):
settings_data = DEFAULT_SETTINGS
else:
with open(data_path, 'r') as f:
settings_data = json.load(f)
# get DEFAULT_SETTINGS
if task == 'read_default_data':
if keyword != None or value != None:
raise customError(ERR_MSG_ARGS)
quit()
return DEFAULT_SETTINGS
# save settings to disc
elif task == 'save_settings_data':
if keyword != None or value != None:
raise customError(ERR_MSG_ARGS)
quit()
with open(data_path, 'w') as f:
json.dump(settings_data, f)
return settings_data
# get a settings value
elif task == 'get_keyval':
# if not type(value) == str:
# raise customError(ERR_MSG_TYPE)
# quit()
return settings_data[keyword]
# update a dict value and save it
elif task == 'update_keyval':
# if not type(value) == str:
# raise customError(ERR_MSG_TYPE)
# quit()
settings_data['keyword'] = value
with open(data_path, 'w') as f:
json.dump(settings_data, f)
return settings_data[keyword]
else:
raise customError(ERR_MSG_TASK)
quit()
print("settings('read_default_data', None, None)")
print(settings('read_default_data', None, None))
print()
print("settings('save_settings_data', None, None)")
settings('save_settings_data', None, None)
settings('get_keyval', '_hide_versions', None)
print("settings('get_keyval', '_hide_versions', None)")
settings('update_keyval', '_hide_versions', True)
print("settings('update_keyval', '_hide_versions', True)")
# raise a customError:
# print("settings('read_default_data', None, 'any item except None'")
# print(settings('read_default_data', None, 'any item except None'))
Das oben Stehende läuft wenigstens ohne Fehlermelduung durch - so weit ist das dann getestet...
Re: Python 'Benzingespräche'
Verfasst: Montag 13. Dezember 2021, 01:37
von snafu
Total intuitiv, diese festgelegten Strings und das doppelte None. Richtig pythonisch und bestimmt auch sehr leicht zu debuggen, wenn irgendwo ein Buchstabe verdreht oder vergessen wurde.
