Ok, hatte ich übersehen.
Danke euch allen.
Das wird.
Nur ein Bit ändern
Hallo,
hier meine erster Versuch der Umstellung.
Die Ergebnisse sind alle ok und entsprechen den hinterlegten Daten im Geber.
Der Aufbau des data-Strings werdet ihr sicher bemängeln. Macht ihr sicher eleganter.
Das mit dem number_of_datafields=int.from_bytes(response[3:4],'big',signed=False) ist ok?
Hatte ich aus dem Netz übernommen.
Ich stelle mittlerweile alles in Frage
hier meine erster Versuch der Umstellung.
Die Ergebnisse sind alle ok und entsprechen den hinterlegten Daten im Geber.
Der Aufbau des data-Strings werdet ihr sicher bemängeln. Macht ihr sicher eleganter.
Das mit dem number_of_datafields=int.from_bytes(response[3:4],'big',signed=False) ist ok?
Hatte ich aus dem Netz übernommen.
Ich stelle mittlerweile alles in Frage
Code: Alles auswählen
def listing(self):
BIT_AKTIV = 1 << 7
BIT_WRITABLE = 1 << 6
BIT_PASSWORT = 1 << 4
BIT_PASSAktiv = 1 << 3
BIT_SPEICHER = 1 << 0
data = bytearray.fromhex("FF 4E")
data.append(ChecksumXor8.calc(data))
try:
serial_interface.reset_input_buffer()
serial_interface.reset_output_buffer()#flush output buffer, aborting current output
time.sleep(0.01) #give the serial port sometime to receive the data
serial_interface.write(data)
time.sleep(0.01)
response = serial_interface.read(7)
number_of_datafields=int.from_bytes(response[3:4],'big',signed=False)
except Exception as e1:
print ("error communicating...: " + str(e1))
self.datenfeld_info.config(state='normal')
self.datenfeld_info.delete('2.0','end')
i=0
for i in range(number_of_datafields):
data = bytearray([0xff, 0x4c, i])
data.append(ChecksumXor8.calc(data))
try:
serial_interface.reset_input_buffer()
serial_interface.reset_output_buffer()
time.sleep(0.010)
serial_interface.write(data)
time.sleep(0.01)
response = serial_interface.read(7)
if response[0] == 0x50 or ChecksumXor8.calc(response) != 0:
print(sick_error.srm_errors(hex(response[1])))
else:
datenfeld = response[3]
nummer = '\n' + str(i) + '\t'
enabled = "ja\t" if datenfeld & BIT_AKTIV else "nein\t"
writeable = "ja\t" if datenfeld & BIT_WRITABLE else "nein\t"
password = str(datenfeld & BIT_PASSWORT)+'\t'
password_active = "ja\t" if datenfeld & BIT_PASSAktiv else "nein\t"
speichergroese = str((1 + (datenfeld & BIT_SPEICHER)) * 16) + '\t'
data = nummer + enabled + writeable + password + password_active + speichergroese
self.datenfeld_info.insert('end',data)
except Exception as e1:
print ("error communicating...: " + str(e1))
- __blackjack__
- User
- Beiträge: 14338
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@kiaralle: Konstanten definiert man üblicherweise nicht _in_ Funktionen, sondern auf Modulebene.
`BIT_PASSAktiv` ist von der Gross-/Kleinschreibung her inkonsistent.
`BIT_SPEICHER` ist so nur korrekt, falls das wirklich nur ein Bit ist, also es nur die Speichergrössen 16 und 32 geben kann. Dann könnte man sich aber auch die Rechnung sparen und das so schreiben wie man beispielsweise bei den Flags "ja" und "nein" an Namen gebunden hat. Sollte die Speichergrösse durch die drei untersten Bits entschieden werden, dann ist die Maske dafür, wie schon mal gesagt, 0b00000111, 0x07, 0o007, 7, ``(1 << 3) - 1``, oder ``2**3 - 1``, oder wie auch immer man den Wert schreiben möchte. Wenn es um Lesbarkeit geht, würde ich persönlich die Binärschreibweise verwenden, weil man da direkt, ohne überlegen oder rechnen sieht, wie die Bitmaske aussieht. Aus Gewohnheit wäre hexadezimal oder dezimal meine zweite Wahl, weil man das in vielen Sprachen, welche keine Binärschreibweise erlaubt, so machen muss, und man bei einem Wert wie 7 auch nicht lange überlegen muss wie das Bitmuster dazu aussieht, wenn man so etwas eine Weile gemacht hat. Das gleiche gilt auch für oktal, nur dass ich da erst seit kurzem Erfahrungen mit sammle. Ist etwas einfacher als bei hexadezimal, weil man nur eine Untermenge an Bitmustern auswendig lernen muss oder als Tabelle zu Hand haben muss. 0 bis 7 statt 0 bis 15.
Die Ausnahmebehandlung ist falsch. Du hast da beim Abfragen der Anzahl der Datenfelder ein ``try``/``except`` aber danach wird einfach weitergemacht als wäre alles okay, auch wenn die Abfrage gar nicht funktioniert hat und in den ``except``-Zweig gelaufen ist. Was unweigerlich in einen vermeidbaren Folgefehler laufen wird, weil dann `number_of_fields` überhaupt gar nicht definiert ist. Da müsste man dann entweder die Methode vorzeitig beenden, oder den Teil der nur laufen soll falls die Abfrage geklappt hat, in ein ``else`` zu dem ``try``/``except`` packen.
`serial_interface` kommt magisch aus dem nichts, ist also eine globale Variable/globaler Zustand. Alles was eine Funktion oder Methode ausser Konstanten benötigt, wird als Argument(e) übergeben. Also müsste das entweder an das Objekt gebunden sein, wo die Methode drauf definiert ist, oder als zusätzliches Argument beim Aufruf übergeben werden.
Es gibt wiederholten Code für das Senden eines Kommandos und Empfangen der Antwort, der dort nahezu identisch zwei mal steht. Das sollte man in eine Funktion oder Methode heraus ziehen. Kann bei der Abfrage der Anzahl der Felder die Prüfsumme nicht auch falsch sein? Oder ein Fehlercode wie 0x50 kommen?
Es sieht nach einer starken Vermischung von GUI und Programmlogik aus. Das sollte man auch besser trennen. Und vielleicht auch die _Details_ der Kommunikation besser ”verstecken”. Also nicht eine Funktion oder Methode in der man wissen muss welche Bytewerte die Abfrage der Feldanzahl kodieren, sondern eine Funktion oder Methode `get_data_field_count()` die dass dann weiss. Das macht den Code verständlicher.
`BIT_PASSAktiv` ist von der Gross-/Kleinschreibung her inkonsistent.
`BIT_SPEICHER` ist so nur korrekt, falls das wirklich nur ein Bit ist, also es nur die Speichergrössen 16 und 32 geben kann. Dann könnte man sich aber auch die Rechnung sparen und das so schreiben wie man beispielsweise bei den Flags "ja" und "nein" an Namen gebunden hat. Sollte die Speichergrösse durch die drei untersten Bits entschieden werden, dann ist die Maske dafür, wie schon mal gesagt, 0b00000111, 0x07, 0o007, 7, ``(1 << 3) - 1``, oder ``2**3 - 1``, oder wie auch immer man den Wert schreiben möchte. Wenn es um Lesbarkeit geht, würde ich persönlich die Binärschreibweise verwenden, weil man da direkt, ohne überlegen oder rechnen sieht, wie die Bitmaske aussieht. Aus Gewohnheit wäre hexadezimal oder dezimal meine zweite Wahl, weil man das in vielen Sprachen, welche keine Binärschreibweise erlaubt, so machen muss, und man bei einem Wert wie 7 auch nicht lange überlegen muss wie das Bitmuster dazu aussieht, wenn man so etwas eine Weile gemacht hat. Das gleiche gilt auch für oktal, nur dass ich da erst seit kurzem Erfahrungen mit sammle. Ist etwas einfacher als bei hexadezimal, weil man nur eine Untermenge an Bitmustern auswendig lernen muss oder als Tabelle zu Hand haben muss. 0 bis 7 statt 0 bis 15.
Die Ausnahmebehandlung ist falsch. Du hast da beim Abfragen der Anzahl der Datenfelder ein ``try``/``except`` aber danach wird einfach weitergemacht als wäre alles okay, auch wenn die Abfrage gar nicht funktioniert hat und in den ``except``-Zweig gelaufen ist. Was unweigerlich in einen vermeidbaren Folgefehler laufen wird, weil dann `number_of_fields` überhaupt gar nicht definiert ist. Da müsste man dann entweder die Methode vorzeitig beenden, oder den Teil der nur laufen soll falls die Abfrage geklappt hat, in ein ``else`` zu dem ``try``/``except`` packen.
`serial_interface` kommt magisch aus dem nichts, ist also eine globale Variable/globaler Zustand. Alles was eine Funktion oder Methode ausser Konstanten benötigt, wird als Argument(e) übergeben. Also müsste das entweder an das Objekt gebunden sein, wo die Methode drauf definiert ist, oder als zusätzliches Argument beim Aufruf übergeben werden.
Es gibt wiederholten Code für das Senden eines Kommandos und Empfangen der Antwort, der dort nahezu identisch zwei mal steht. Das sollte man in eine Funktion oder Methode heraus ziehen. Kann bei der Abfrage der Anzahl der Felder die Prüfsumme nicht auch falsch sein? Oder ein Fehlercode wie 0x50 kommen?
Es sieht nach einer starken Vermischung von GUI und Programmlogik aus. Das sollte man auch besser trennen. Und vielleicht auch die _Details_ der Kommunikation besser ”verstecken”. Also nicht eine Funktion oder Methode in der man wissen muss welche Bytewerte die Abfrage der Feldanzahl kodieren, sondern eine Funktion oder Methode `get_data_field_count()` die dass dann weiss. Das macht den Code verständlicher.
“It is easier to optimize correct code than to correct optimized code.” — Bill Harlan
- __blackjack__
- User
- Beiträge: 14338
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Bei der Fehlermeldung im zweiten Fall denke ich das ist falsch bei falscher Prüfsumme das gleiche zu machen wie bei einem 0x50 als erstem Bytewert. Bei einer falschen Prüfsumme weiss man ja letztlich gar nicht was das Problem ist, also welches Byte oder welche Bytes falsch sind. Und das muss man auch zuerst prüfen, denn bei einer falschen Prüfsumme kann man sich auch gar nicht sicher sein, dass 0x50 als erstes Byte auch tatsächlich der Wert ist, der gesendet wurde.
Wenn es im `tkinter`-Modul eine Konstante für Argumente gibt, die keine beliebigen Zeichenketten sind, sollte die auch verwenden. Also beispielsweise `tkinter.NORMAL` statt einer Zeichenkette mit dem Wort.
Die Zuweisung ``i = 0`` wird nirgends verwendet, kann also weg fallen.
Zeilenendezeichen gehören ans Ende. Das heisst man sollte Zeilen damit abschliessen, und nicht neue damit Anfangen und dann nicht beenden.
Beliebige Ausnahmen durch eine nichtssagende feste Zeile zu ersetzen hilft bei der Fehlersuche nicht nur nicht, sondern macht die auch noch schwerer. Statt `print()` würde man da Logging verwenden, was dann in diesem Fall auch gleich den kompletten Traceback mitprotokolliert.
Das ginge dann so ungefähr in diese Richtung:
Wenn es im `tkinter`-Modul eine Konstante für Argumente gibt, die keine beliebigen Zeichenketten sind, sollte die auch verwenden. Also beispielsweise `tkinter.NORMAL` statt einer Zeichenkette mit dem Wort.
Die Zuweisung ``i = 0`` wird nirgends verwendet, kann also weg fallen.
Zeilenendezeichen gehören ans Ende. Das heisst man sollte Zeilen damit abschliessen, und nicht neue damit Anfangen und dann nicht beenden.
Beliebige Ausnahmen durch eine nichtssagende feste Zeile zu ersetzen hilft bei der Fehlersuche nicht nur nicht, sondern macht die auch noch schwerer. Statt `print()` würde man da Logging verwenden, was dann in diesem Fall auch gleich den kompletten Traceback mitprotokolliert.
Das ginge dann so ungefähr in diese Richtung:
Code: Alles auswählen
BIT_AKTIV = 1 << 7
BIT_WRITABLE = 1 << 6
BIT_PASSWORT = 1 << 4
BIT_PASSWORD_ACTIVE = 1 << 3
MEMORY_SIZE_MASK = 0b0000_0111
def communicate(serial_interface, request):
request_data = bytearray(request)
request_data.append(ChecksumXor8.calc(request_data))
serial_interface.reset_input_buffer()
serial_interface.reset_output_buffer()
time.sleep(0.01)
serial_interface.write(request_data)
time.sleep(0.01)
response = serial_interface.read(7)
if ChecksumXor8.calc(response) != 0:
raise ChecksumXor8.ChecksumError()
if response[0] == 0x50:
raise sick_error.SRMError(response[1])
return response
...
def listing(self, serial_interface):
datafield_count = int.from_bytes(
communicate(serial_interface, [0xFF, 0x4E])[3:4], "big"
)
self.datenfeld_info.config(state=tk.NORMAL)
self.datenfeld_info.delete("2.0", tk.END)
for index in range(datafield_count):
try:
value = communicate(serial_interface, [0xFF, 0x4C, index])[3]
except:
logging.exception("error communicating...")
else:
row = [
str(index),
"ja" if value & BIT_AKTIV else "nein",
"ja" if value & BIT_WRITABLE else "nein",
str(value & BIT_PASSWORT),
("ja" if value & BIT_PASSWORD_ACTIVE else "nein"),
str((1 + (value & MEMORY_SIZE_MASK)) * 16),
]
self.datenfeld_info.insert(tk.END, "\t".join(row) + "\n")“It is easier to optimize correct code than to correct optimized code.” — Bill Harlan
-
Pedroski55
- User
- Beiträge: 44
- Registriert: Freitag 25. Juli 2025, 00:20
Das hat sich ausgeartet! Ursprunglich war die Frage, "Nur ein bit ändern"!
Müsste an Pyotr Ilyich Tchaikovsky denken, also habe ich einen Bitknacker gebaut!
Müsste an Pyotr Ilyich Tchaikovsky denken, also habe ich einen Bitknacker gebaut!
Code: Alles auswählen
def bit_knacker(num):
res = int(num, 16)
byt = format(res, '08b') # '11001001'
data = {'nummer': num, 'enabled': '', 'writable': '', 'password': '', 'password_aktiv': '', 'memory': '' }
data['password'] = byt[2:4] +"\t" # watn dat fürn passwort?
data['memory'] = byt[5:] +"\t"
if int(byt[0:1]) == '0':
data['enabled'] = "nein\t"
else:
data['enabled'] = "ja\t"
if byt[1:2] == '0':
data['writable' ]= "nein\t"
else:
data['writable' ] = "ja\t"
if byt[4:5] == '0':
data['password_aktiv'] = "nein\t"
else:
data['password_aktiv'] = "ja\t"
return data
bites = ['11001001', '10101010', '01010101', '11011011', '00111101']
for b in bites:
num = int(b, 2)
num = hex(num)
print('************')
res = bit_knacker(num)
for key in res.keys():
print(key, res[key])Ich verstehe nicht wieso du da soviel Datentypen umwandelst. Ìf`und `else` ergibt sich doch wenn du einfach auf den Wahrheitswer abfragst.
Das ganze etwas lesbarer und meiner Meinung nach angenehmer in der Anwendung, wenn man den Wert einzelner Bits abfragen will:
Ob `__call__` Sinn macht weiß ich noch nicht ganz. Im nachhinein denke ich eher weniger.
Grüße
Dennis
Das ganze etwas lesbarer und meiner Meinung nach angenehmer in der Anwendung, wenn man den Wert einzelner Bits abfragen will:
Code: Alles auswählen
from attrs import define, field, make_class
from attrs.validators import min_len, and_, max_len
result = make_class(
name="Result",
attrs=["enabled", "writable", "password", "password_active", "memory"],
)
@define(frozen=True)
class Encrypter:
ENABLED = 0
WRITABLE = 1
PASSWORD = 2
PASSWORD_STATE = 4
MEMORY = 5
bytes = field(validator=and_(min_len(8), max_len(8)))
def __call__(self):
return result(
self.bytes[self.ENABLED] == "1",
self.bytes[self.WRITABLE] == "1",
self.bytes[self.PASSWORD : self.PASSWORD_STATE],
self.bytes[self.PASSWORD_STATE] == "1",
self.bytes[self.MEMORY :],
)
def main():
for data in [b"11001001", b"10101010", b"01010101", b"11011011", b"00111101"]:
encrypted = Encrypter(data)()
print(encrypted)
print(f"Just the password: {encrypted.password}\n")
if __name__ == "__main__":
main()
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 14338
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Pedroski55: Warum Zeichenketten mit Binärzahlendarstellung in eine Zahl wandeln, die dann in eine Zeichenkette mit Hexadezimaldarstellung umgewandelt wird, die dann wieder in eine Zahl gewandelt wird, die wiederum in eine Zeichenkette mit Binärzahlendarstellung umgewandelt wird. Das ist total bekloppt diese ganzen unnötigen Umwandlungen zwischen Zeichenketten und Zahlen.
Und dann Bitoperationen auf der Zeichenkettendarstellung einer Binärzahl, statt das direkt auf der entsprechenden Zahl mit Bitoperationen zu machen, hatten wir doch hier gerade schon. Warum dann doch wieder so falsch‽
Dann wieder so übliche Sachen wie keine `main()`/Code auf Modulebene. Einbuchstabige Namen und kryptische dreibuchstabige Abkürzungen, statt aussagekräftiger Namen. Namen die an Werte mit unterschiedlichen Datentypen gebunden werden. Man muss nicht jedes kleine Zwischenergebnis an einen Namen binden.
Es macht keinen Sinn in einem Wörterbuch fast alle Schlüssel mit einem Wert zu belegen der niemals irgendwo verwendet wird, weil die gleich danach durch den tatsächlichen Wert ersetzt werden.
Das Tabulatorzeichen hat in der Datenstruktur nicht wirklich etwas zu suchen. Das ist später für die Ausgabe wichtig, man sollte die Ausgabe aber von der Verarbeitung und Datenhaltung trennen.
Wenn man über Schlüssel _und_ Werte eines Wörterbuchs iterieren möchte, dann gibt es dafür die `items()`-Methode.
Bitte kein komisches Denglisch-Gemisch in Daten und Namen.
Zwischenstand:
Wobei das noch nicht das Ende ist. Wörterbücher mit einem festen Satz an Zeichenketten als Schlüssel sind eigentlich Objekte, und dann wären die Werte auch besser unabhängig von der späteren Repräsentation. Das heisst Zahlen als Zahlen und Wahrheitswerte als True und False, statt alles als Zeichenketten in einer Darstellung die für _eine_ mögliche Präsentation des ganzen geeignet sind, und für alles andere wieder diese unsinnige Umwandelei zwischen Zeichenketten und Werten mit denen gearbeitet werden kann.
@Dennis89: `Encryptor` wäre eher ein `Decoder`. Der verschlüsselt ja nichts.
Und dann Bitoperationen auf der Zeichenkettendarstellung einer Binärzahl, statt das direkt auf der entsprechenden Zahl mit Bitoperationen zu machen, hatten wir doch hier gerade schon. Warum dann doch wieder so falsch‽
Dann wieder so übliche Sachen wie keine `main()`/Code auf Modulebene. Einbuchstabige Namen und kryptische dreibuchstabige Abkürzungen, statt aussagekräftiger Namen. Namen die an Werte mit unterschiedlichen Datentypen gebunden werden. Man muss nicht jedes kleine Zwischenergebnis an einen Namen binden.
Es macht keinen Sinn in einem Wörterbuch fast alle Schlüssel mit einem Wert zu belegen der niemals irgendwo verwendet wird, weil die gleich danach durch den tatsächlichen Wert ersetzt werden.
Das Tabulatorzeichen hat in der Datenstruktur nicht wirklich etwas zu suchen. Das ist später für die Ausgabe wichtig, man sollte die Ausgabe aber von der Verarbeitung und Datenhaltung trennen.
Wenn man über Schlüssel _und_ Werte eines Wörterbuchs iterieren möchte, dann gibt es dafür die `items()`-Methode.
Bitte kein komisches Denglisch-Gemisch in Daten und Namen.
Zwischenstand:
Code: Alles auswählen
#!/usr/bin/env python3
def parse(value):
return {
"value": hex(value),
"enabled": "yes" if value & 0b1000_0000 else "no",
"writable": "yes" if value & 0b0100_0000 else "no",
"password": f"{(value & 0b0011_0000) >> 4:02b}",
"password_active": "yes" if value & 0b0000_1000 else "no",
"memory_size": f"{value & 0b0000_0111:03b}",
}
def main():
byte_values = [0b11001001, 0b10101010, 0b01010101, 0b11011011, 0b00111101]
for byte_value in byte_values:
print("*" * 16)
for key, value in parse(byte_value).items():
print(key, value)
if __name__ == "__main__":
main()@Dennis89: `Encryptor` wäre eher ein `Decoder`. Der verschlüsselt ja nichts.
“It is easier to optimize correct code than to correct optimized code.” — Bill Harlan
@Pedroski55: verkürzte Namen haben das Problem, dass man sich sowohl an den richtigen Namen erinnern muß, als auch daran, wie man ihn falsch schreibt, bte oder byt oder doch bt? Ach nein, das war ja die Abkürzung für bit.
Beim ersten if hast du einen Fehler, wegen der vielen Umwandlungen von String nach Int und wieder zurück.
Man initialisiert kein Wörterbuch mit Dummywerten um sie gleich danach mit den richtigen zu überschreiben.
Für bit-Manipulation benutzt man am besten & statt Strings
Beim ersten if hast du einen Fehler, wegen der vielen Umwandlungen von String nach Int und wieder zurück.
Man initialisiert kein Wörterbuch mit Dummywerten um sie gleich danach mit den richtigen zu überschreiben.
Für bit-Manipulation benutzt man am besten & statt Strings
Code: Alles auswählen
def bit_knacker(num):
return {
'nummer': num,
'enabled': 'ja' if num & 128 else 'nein',
'writable': 'ja' if num & 64 else 'nein',
'password': (num >> 3) & 3,
'password_aktiv': 'ja' if num & 32 else 'nein',,
'memory': num & 7,
}
bits = ['11001001', '10101010', '01010101', '11011011', '00111101']
for bit in bits:
num = int(b, 2)
print('************')
res = bit_knacker(num)
for key, value in res.items():
print(key, value)Dann wie folgt. Mein `bytes`sollte auch nicht in der Mehrzahl in der Klasse stehen:
Dieses "Ja" und "Nein" mag ich nicht.
Code: Alles auswählen
from attrs import define, field, make_class
from attrs.validators import le as less_than
result = make_class(
name="Result",
attrs=["enabled", "writable", "password", "password_active", "memory"],
)
@define(frozen=True)
class Decoder:
ENABLED = 128
WRITABLE = 64
PASSWORD = 3
PASSWORD_STATE = 32
MEMORY = 7
byte = field(validator=less_than(256), converter=lambda x: int(x, 2))
def decode(self):
return result(
self.byte & self.ENABLED > 0,
self.byte & self.WRITABLE > 0,
(self.byte >> self.PASSWORD) & self.PASSWORD,
self.byte & self.PASSWORD_STATE > 0,
self.byte & self.MEMORY,
)
def main():
for data in [b"11001001", b"10101010", b"01010101", b"11011011", b"00111101"]:
encrypted = Decoder(data).decode()
print(encrypted)
print(f"Just the password: {encrypted.password}\n")
if __name__ == "__main__":
main()
"When I got the music, I got a place to go" [Rancid, 1993]
-
Pedroski55
- User
- Beiträge: 44
- Registriert: Freitag 25. Juli 2025, 00:20
Man kieken: Der OP hat Hexzahlen, bytes, Integer, Binärzahlen und string erwähnt. Er will irgendwie dazwischen umwandeln. Ich konnte auch nicht daraus schlau werden, was genau er hat oder will. Drum machte ich das ein bißchen vor, wie man leicht hin und her wechselt. Das hast ja nicht mitbekommen ne? Er kann sich etwas aussuchen, dann sich auf ein Format festlegen.@Pedroski55: Warum Zeichenketten mit Binärzahlendarstellung in eine Zahl wandeln, die dann in eine Zeichenkette mit Hexadezimaldarstellung umgewandelt wird, die dann wieder in eine Zahl gewandelt wird, die wiederum in eine Zeichenkette mit Binärzahlendarstellung umgewandelt wird. Das ist total bekloppt diese ganzen unnötigen Umwandlungen zwischen Zeichenketten und Zahlen.
In einer Post vom OP, schau doch nach, bevor du mal wieder jaulst, hat er gerade ja und nein als mögliche Zustände dargestellt, drum machte ich auch das nach. Fleißig nachschauen ja?
Ich denke auch, der OP will irgendwas mit den angesammelten Daten anfangen. Drum ist eine Dictionary grad gut:
Code: Alles auswählen
import json
savepath = '/home/peterr/temp/json/bit_knacker.json'
bites = ['11001001', '10101010', '01010101', '11011011', '00111101']
data2json = []
for b in bites:
num = int(b, 2)
num = hex(num)
print('************')
res = bit_knacker(num)
data2json.append(res)
with open(savepath, "w") as file:
json.dump(data2json, file, indent=4)Wenn man sich auf bytes festlegt, empfehle ich das Module struct.
- __blackjack__
- User
- Beiträge: 14338
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Pedroski55: Dem OP wurde bereits gesagt, dass er diese Sachen nicht haben sollte, die er da hat. Er bekommt `bytes`. Das sieht man an den Beiträgen und dem Code der dort gezeigt wurde. Das in Zeichenketten mit Hexadezimaldarstellung umzuwandeln ist unsinnig. Ich habe nicht nur die Beiträge verfolgt, sondern auch mitgedacht wie das einfacher und direkter geht. Alle möglichen Umwandlungen zu zeigen die nur zu Umwegen und komplexerem Code führen, macht keinen Sinn.
Das der OP "ja" und "nein" verwendet, statt True und False, ist halt das ebenfalls angesprochene Problem der fehlenden Trennung zwischen Programmlogik und grafischer Oberfläche. Bevor Du unterstellst ich hätte die Inhalte der Beiträge nicht mitbekommen und müsste da noch mal nachlesen, solltest Du vielleicht selbst noch mal nachlesen was hier schon besprochen wurde.
Weil man etwas mit Daten anfangen will, macht das ein Wörterbuch nicht zum guten Mittel. Man will ja immer etwas mit Daten anfangen, daraus würde dann nach dieser Logik folgen, Wörterbücher sind immer ein gutes Mittel um strukturierte Daten zu modellieren. Wie bereits gesagt sind Wörterbücher mit einem festen Satz von Texten als Schlüssel eigentlich Objekte. Das heisst ein Wörterbuch wird dann missbraucht, falls es nicht einen guten Grund für diese Form gibt, und man sich da keinen Datentyp für geschrieben hat. Ein Grund wäre eine Serialisierung als JSON für eine Speicherung oder falls eine andere API das in der Form braucht. Das liegt hier aber nicht vor. Die Daten werden in einer GUI als (Text-)Tabelle angezeigt. Da gibt es keinen Grund Wörterbücher als Zwischenform zu verwenden.
Das der OP "ja" und "nein" verwendet, statt True und False, ist halt das ebenfalls angesprochene Problem der fehlenden Trennung zwischen Programmlogik und grafischer Oberfläche. Bevor Du unterstellst ich hätte die Inhalte der Beiträge nicht mitbekommen und müsste da noch mal nachlesen, solltest Du vielleicht selbst noch mal nachlesen was hier schon besprochen wurde.
Weil man etwas mit Daten anfangen will, macht das ein Wörterbuch nicht zum guten Mittel. Man will ja immer etwas mit Daten anfangen, daraus würde dann nach dieser Logik folgen, Wörterbücher sind immer ein gutes Mittel um strukturierte Daten zu modellieren. Wie bereits gesagt sind Wörterbücher mit einem festen Satz von Texten als Schlüssel eigentlich Objekte. Das heisst ein Wörterbuch wird dann missbraucht, falls es nicht einen guten Grund für diese Form gibt, und man sich da keinen Datentyp für geschrieben hat. Ein Grund wäre eine Serialisierung als JSON für eine Speicherung oder falls eine andere API das in der Form braucht. Das liegt hier aber nicht vor. Die Daten werden in einer GUI als (Text-)Tabelle angezeigt. Da gibt es keinen Grund Wörterbücher als Zwischenform zu verwenden.
“It is easier to optimize correct code than to correct optimized code.” — Bill Harlan
