Hallo,
bin schon den ganzen Tag daran, finde aber nichts.
Habe eine Webseite, die Speichert die Angabe der ausgewählten Wochentage, als Zahl "Code"...
Mo = 1
Di = 2
Mi = 4
Do = 8
Fr = 16
Sa = 32
So =64
Wähle ich als Tag Di+Do und Sonntag aus. So wird dies als "10" (Quersumme/Summierung der Auswahl) gespeichert etc..
Also von 1 bis 127 ist alles möglich.
Diesen Weg finde ich recht praktisch.
Ich hab es mal nachgerechnet, diese Verdoppelung/Duplation Werte sollten immer eindeutig sein.
Ich habe auf der Seite versucht den JS-Code durch den Debugger laufen zu lassen, um die Stelle, welches eine Codierte Eingabe auf die Tage umrechnet, zu kommen.
Entweder gibt es diese Stelle nicht, es wird die fest hinterlegte Liste genommen oder ich übersehe etwas.
Mein Code baue ich in Python auf, aber auf eine sinnvolle Umsetzung außer...
if code = 1 == Mo
elif Code == 2 == Mo, Di
...etc,
komme ich bis jetzt nicht.
Zwar habe ich alle Codes/Kombinationen schon als ein Dict abgelegt. In diesem könnte ich den Wochentag manuell einmalig fest eintragen.
Aber ich bin mir sicher, das es da Mathematisch möglich seien muss.
Wenn es dafür schon Beispiele gibt, dann reicht auch nur ein Link.
Ich konnte dazu bisher NULL finden. Da aber bin ich mir sicher, habe ich immer falsch gesucht. Aber einen richtigen Begriff habe ich dafür bis jetzt nicht.
Nochmals zusammengefasst.
Ich habe von bei Zahlen von 1 bis 127 auf die tage zu schließen.
Bsp: 118 würde z.b. Di+Mi+Fr-So bedeuten.
Mo = 1
Di = 2
Mi = 4
Do = 8
Fr = 16
Sa = 32
So =64
Mo == 1 kann man ganz leicht raus bekommen. Prüfung auf gerade/ungerade.
Dann aber bleiben noch Di-So übrig und hier brauche ich einen Denkanstoß.
Viele Grüße
Chris
Wochentage Mo-So Codiert (Encodieren/umrechnen/berechnen)
Über die Binärdarstellung läßt sich das einfach Umwandeln. Hier wird auf die einzelnen Bits getestet:
Code: Alles auswählen
WEEKDAYS = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
encoded_days = 56
weekdays = [
weekday
for idx, weekday in enumerate(WEEKDAYS)
if encoded_days & (1 << idx)
]
-
- User
- Beiträge: 32
- Registriert: Freitag 23. September 2022, 09:36
Guten Abend Sirius,
was soll ich sagen. Top, kurz getestet funktioniert.
Ich muss es noch auseinander nehmen, da ich das WARUM/WIE, noch nicht verstehe
Aber es tut genau was es soll.
Viele Grüße
Chris
was soll ich sagen. Top, kurz getestet funktioniert.
Ich muss es noch auseinander nehmen, da ich das WARUM/WIE, noch nicht verstehe

Aber es tut genau was es soll.
Viele Grüße
Chris
Dann schau dir mal den Teil an, der die zu prüfenden Werte erzeugt. Wenn du ihn etwas veränderst, lässt sich das anschaulich mit print() darstellen:chris_adnap hat geschrieben: ↑Dienstag 30. Mai 2023, 22:16 Ich muss es noch auseinander nehmen, da ich das WARUM/WIE, noch nicht verstehe![]()
Code: Alles auswählen
for index, weekday in enumerate(WEEKDAYS):
print(weekday, "->", 1 << index)
In der Dezimaldarstellung sind das nur Zahlen, die verdoppelt werden. Um nun zu sehen, wo ein Bit jeweils gesetzt wird, nehmen wir die Binärdarstellung mit rein:
Code: Alles auswählen
for index, weekday in enumerate(WEEKDAYS):
value = 1 << index
print(f"{weekday}\t{value}\t{value:>07b}")
Und um jetzt zu testen, ob ein Bit gesetzt ist, nimmt man den ``&``-Operator. Falls du mit den Details hierzu nicht vertraut bist, dann gib bitte "binary and" in eine Suchmaschine deiner Wahl ein. Ich spare mir an dieser Stelle die näheren Ausführungen dazu.
Zur Verknüpfung mehrerer Bits nutzt man den ``|``-Operator ("binary or"). Dein Beispiel sprach von Di+Mi+Fr-So. Dies entspricht:
Code: Alles auswählen
1 << 1 | 1 << 2 | 1 << 4 | 1 << 5 | 1 << 6

Übrigens, mit den richtigen Importen lässt sich das Erzeugen, Kodieren und Dekodieren auch jeweils als Einzeiler umsetzen:
Die long_encode()-Funktion demonstriert hierbei bloß die Abläufe in encode() etwas ausführlicher. Die kann man natürlich auch weglassen. 
Bei der Bitdarstellung sollte einem bewusst sein, dass quasi von rechts nach links gelesen werden muss zum Nachvollziehen der kodierten Wochentage.
Code: Alles auswählen
#!/usr/bin/env python3
from enum import IntFlag
from functools import reduce
from operator import or_
Weekday = IntFlag("Weekday", "Mo Di Mi Do Fr Sa So".split())
def long_encode(days):
result = 0
for day in days:
result |= Weekday[day]
return result
def encode(days):
return reduce(or_, map(Weekday.__getitem__, days))
def decode(value):
return [day for day in Weekday if value & day]
def main():
value = encode(["Di", "Mi", "Fr", "Sa", "So"])
print(f"{value} -> {value:>07b}")
print(decode(value))
if __name__ == "__main__":
main()

Bei der Bitdarstellung sollte einem bewusst sein, dass quasi von rechts nach links gelesen werden muss zum Nachvollziehen der kodierten Wochentage.
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@snafu: Den `split()`-Aufruf kannst Du weg lassen. Die `Enum`-Klassen verhalten sich da wie `collections.namedtuple()` und machen das schon selbst wenn sie eine Zeichenkette übergeben bekommen. 
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Wie immer gibt es verschiedene Wege zum Ziel. Diese Variante hat weniger Magie in reduce() und nutzt einen anderen Ansatz zum Auspacken der Bits:
Code: Alles auswählen
#!/usr/bin/env python3
from enum import IntFlag, show_flag_values
from functools import reduce
Weekday = IntFlag("Weekday", "Mo Di Mi Do Fr Sa So")
def pack(day_names):
return reduce(
lambda first, second: first | second,
(Weekday[name] for name in day_names)
)
def unpack(flag):
return [Weekday(bit) for bit in show_flag_values(flag)]
def main():
packed = pack(["Di", "Mi", "Fr", "Sa", "So"])
print(repr(packed))
print(unpack(packed))
if __name__ == "__main__":
main()
Und wer Spaß dran hat, kann sich den Zusammenhang zwischen Bits und angezeigten Wochentagen nochmal damit deutlich machen:
Nun aber genug von mir. Wenn noch Fragen offen sind, kann man die hier gerne äußern...
Code: Alles auswählen
#!/usr/bin/env python3
from enum import IntFlag, show_flag_values
from functools import reduce
Weekday = IntFlag("Weekday", "Mo Di Mi Do Fr Sa So")
def names_to_flag(day_names):
return reduce(
lambda first, second: first | second,
(Weekday[name] for name in day_names)
)
def flag_to_names(flag):
return [Weekday(bit).name for bit in show_flag_values(flag)]
def main():
for i in range(30):
print(flag_to_names(i), "->", bin(i))
if __name__ == "__main__":
main()
Das Kling für mich nach einem Fall für enum.Flag:
Folgender Code sollte das decodieren hinbekommen.
Folgender Code sollte das decodieren hinbekommen.
Code: Alles auswählen
import enum
class Weekdays(enum.IntFlag):
MO = 0x01
DI = 0x02
MI = 0x04
DO = 0x08
FR = 0x10
SA = 0x20
So = 0x40
flags = Weekdays(56)
for day in Weekdays:
if day in flags:
print(day.name)
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@imonbln: Öhm, schau doch mal was die ganzen vorhergehenden Beiträge benutzten: `IntFlag`.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware