Sehr geehrter Herr Buechel, i ch habe alles überprüft. Es sind versehentlich einige chinesische Zeichen doppelt erfasst. Das wird derzeit berichtig. Ich komme darauf zurück mfg Erich Schnoor
> Anfang der weitergeleiteten Nachricht: > > Von: Wolli Buechel über python-de <python-de@python.org> > Betreff: [Python-de] Re: Fwd: Keyboard coding > Datum: 23. Juli 2024 um 17:44:11 MESZ > An: python-de@python.org > Antwort an: Wolli Buechel <wjb...@web.de> > > Sehr geehrter Herr Schnoor, > > Sie haben Ihr persönliches "Spezialprogramm" zur Prüfung des Strings > <ziffern> auf Mehrfachzeichen bisher nicht vorgelegt. Andererseits hat > bislang keiner der Mitforisten an meinem Nachweis genau dieses Defekts von > <ziffern> Kritik geübt. Wie es scheint, sind Sie als einziger davon > überzeugt, dass Ihr <ziffern>String ein taugliches Gebilde zur fehlerfreien > Kodierung und Dekodierung von Zahlen zur Basis 4096 ist. > > Anyway. > > Machen wir ein neues Faß auf. Untersuchen wir die Frage: Was ist > problematisch, wenn ein solcher Ziffernstring ein Zeichen mehrfach enthält? > > (1) Als Beispiel betrachte ich Hexzahlen mit dem Standard-Ziffernstring > ziffern = '0123456789ABCDEF'. > Als Studienobjekt wähle ich – angregt durch wikipedia – die Dezimalzahl z1 = > 45054 (eine Palindromzahl), umgewandelt in HexForm ergibt sich z2 = > hex(z1)[2:].upper() = 'AFFE'. > > Konvertiert man z2 zurück in eine Dezimalzahl, erhält man mit z3 = int(z2, > 16) = 45054 die Ausgangszahl z1. > > Wenn <ziffern> OK ist, hat man eine "Reise" von z1 zu z2, von z2 zu z3 > absolviert. Und prüft abschließend, ob z1 und z3 gleich sind, ob man also ein > Rundreise absolviert hat. Das Umgekehrte gilt auch: Wenn die Reise eine > Rundreise war, ist <ziffern> OK. > > Man kann dies kompakt so formulieren: > int(hex(z1)[2:].upper(), 16) == z1, > mit dem Output True. > > (2) Jetzt sei <ziffern> defekt, enthalte aber weiterhin 16 Zeichen, jedoch > eines doppelt, etwa statt D ein F, also > ziffern2 = '0123456789ABCFEF', kurz Hexgestört. > > Jetzt benötigt man zum Kodieren und Dekodieren zwei selbstgestrickte > Funktionen. > > Man kann sich freilich jetzt schon klar machen: Die Kodierung von Dezimal z1 > via Hexgestört zu z2 geht ohne Probleme. Denn zum Kodieren einer Dezimalzahl > nach einer anderen Basis wird der Euklidische Divisionsalgorithmus verwendet. > Der berechnet aus z1 iteriert die Reste bei Division von z1 durch 16 (rest = > z1 % 16), wobei z1 schrittweise ebenfalls verkleinert wird durch > Ganzzahldivision z1 = z1 // 16. > > Daraus folgt für den Kodierschritt: Auch mit einem defekten Ziffernstring > geht das problemlos. > > Mit der folgenden Funktion > > def dezToBase(basis, zahl, ziffern=None): > # > https://stackoverflow.com/questions/2267362/how-to-convert-an-integer-to-a-string-in-any-base > # etwas erweitert. > if zahl == 0: > if ziffern: return '0' > else: return [0] > > # Methode: Euklidischer Divisionsalgorithmus > reste = [] > while zahl: > reste.append(zahl % basis) > zahl //= basis > reste = reste[::-1] # Reihenfolge der Reste umkehren > if ziffern: > return ''.join([ ziffern[x] for x in reste ]) > else: > return reste > > und basis = len(ziffern2) > > ergibt sich z2 = zahl2Base(basis, z1, ziffern2) = 'AFFE'. > > (3) Beim Dekodierschritt stößt man auf ein mögliches Problem: Hier wird z2 zu > einer (Pseudo-)Dezimalzahl > > z3 = A*16**3 + F*16**2 + F*16**1 + E*16**0 > > umgewandelt. Man sieht, wo das Problem (für den Algorithmus) liegt: Welchen > Wert für F nehme ich aus <ziffern2>? Das linke F (der Ersatzspieler für D) > hat den Index-Wert 13, das rechte (=richtige) F hat weiterhin den Index-Wert > 15. > Wegen der Wahl des Buchstabens aus <ziffern2> mittels ziffern2.index(.) fällt > die Wahl des Algorithmus auf das linke F (weil der Indexwert 13 < 15 ist). > > Mit der Funktion > > def bas2dez(basis, zahl, ziffern): > z10 = 0 > for i in range(len(zahl)): > z10 = z10*basis + ziffern.index(zahl[i]) > return z10 > > ergibt sich z3 = 44510 != z1, also eine Fehl-Dekodierung > > (4) Wie prüft man das gesamte Zahlensystem (aus <ziffern> und davon > abgeleiteter basis) auf Korrektheit? > Dazu genügt es, jede Zahl im Intervall [0, basis] zu Kodieren und zu > Dekodieren, und die Ergebnisse auf Gleichheit zu prüfen. Etwa so: > > for z1 in range(basis): > z2 = dezToBase(basis, z1, ziffern) > z3 = bas2dez(basis, z2, ziffern) > if z1 != z3: > print("%s == %s" % (z1, z3)) > > Für das defekte <ziffern2> oben ergibt sich damit: > > 45054 == 44510 # eine richtige Fehl-Dekodierung > > (5) Man könnte jetzt noch weitere Defekte durchspielen (E ersetzen durch F, C > ersetzen durch D, ...). Es mag sein, dass in EINZELFÄLLEN z1 gleich z3 > resultiert. Schön, aber irrelevant. Es geht einzig um die > > Frage: Arbeitet das System in ALLEN Fällen korrekt? > > (6) Zusammenfassung: > Ein Zahlensystem zu einer "höheren" Basis mit einem > Nicht-Standard-Ziffernstring funktioniert nur genau dann (in ALLEN Fällen) > korrekt, wenn dieser Ziffernstring kein Zeichen mehrfach enthält. > > (7) Prüft man das System ziffern4096 von Ihnen, Herr Schnoor, -- hier > publiziert, von Ihnen bis heute als tauglich und insbesondere frei von > Mehrfachzeichen behauptet -- so ergibt sich (nach Tilgung der untauglichen, > da unsichtbaren whitespace-Zeichen, unter Beibehaltung der 60+ > Mehrfachzeichen, und unter Voranstellung der (bislang fehlenden) Ziffer '0', > folgender Output mit 77 Fehl-Dekodierungen: > > Basis : 4059 # bewirkt durch die eben beschriebenen "Reinigungsmaßnahmen" > ziffern : "0123456789 ... ꇰꇱꇲꇳꇴꇵꇶꇷꇸꇹ" > > [ 1] 877 == 844 [ 2] 878 == 876 [ 3] 879 == 845 [ 4] > 880 == 876 > [ 5] 881 == 846 [ 6] 882 == 876 [ 7] 883 == 851 [ 8] > 884 == 876 > [ 9] 885 == 856 [10] 886 == 876 [11] 888 == 876 [12] > 890 == 876 > [13] 892 == 876 [14] 964 == 943 [15] 966 == 944 [16] > 967 == 965 > [17] 968 == 956 [18] 969 == 965 [19] 1047 == 1025 [20] > 1049 == 1026 > [21] 1050 == 1048 [22] 1506 == 1505 [23] 1516 == 1515 [24] > 1517 == 1507 > [25] 1522 == 1521 [26] 1523 == 1507 [27] 1528 == 1527 [28] > 1529 == 1507 > [29] 1534 == 1533 [30] 1535 == 1507 [31] 1548 == 1503 [32] > 3885 == 857 > [33] 3886 == 858 [34] 3887 == 859 [35] 3888 == 860 [36] > 3889 == 861 > [37] 3890 == 862 [38] 3891 == 863 [39] 3892 == 864 [40] > 3893 == 865 > [41] 3894 == 866 [42] 3895 == 867 [43] 3947 == 3077 [44] > 3948 == 3078 > [45] 3949 == 3079 [46] 3950 == 3080 [47] 3951 == 3081 [48] > 3952 == 3082 > [49] 3953 == 3083 [50] 3954 == 3084 [51] 3955 == 3085 [52] > 3956 == 3086 > [53] 3957 == 3090 [54] 3959 == 3461 [55] 3960 == 3462 [56] > 3961 == 3463 > [57] 3962 == 3464 [58] 3963 == 3465 [59] 3964 == 3466 [60] > 3965 == 3467 > [61] 3966 == 3468 [62] 3967 == 3469 [63] 3968 == 3470 [64] > 3969 == 3471 > [65] 3970 == 3472 [66] 3971 == 3473 [67] 3972 == 3474 [68] > 3973 == 3475 > [69] 3974 == 3476 [70] 3975 == 3477 [71] 3976 == 3478 [72] > 3977 == 3479 > [73] 3978 == 3480 [74] 3979 == 3445 [75] 3980 == 3446 [76] > 3981 == 3447 > [77] 3982 == 3448 > > Erst nach Tilgung der Mehrfachzeichen durch > > ziffern = ''.join(sorted(list(set(ziffern)))) > > gibt es keine Fehler mehr. > > Dafür hat man aber auch die Basis 4096 "verloren" und gegen die Basis 3982 > getauscht. Will man die Wunschbasis 4096 wiederhaben, muß man halt – wie > schon früher gesagt – nachbessern. > > W. Büchel > _______________________________________________ > python-de Mailingliste -- python-de@python.org > Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an > python-de-le...@python.org > https://mail.python.org/mailman3/lists/python-de.python.org/ > Mitgliedsadresse: eschn...@multi-matrix.de _______________________________________________ python-de Mailingliste -- python-de@python.org Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an python-de-le...@python.org https://mail.python.org/mailman3/lists/python-de.python.org/ Mitgliedsadresse: arch...@mail-archive.com