Bitte um Vorschläge, wie man mit Python eine Datei anpassen kann.
@RIN67630_ Wie ich bereits schrieb: Es geht nich tum einen _Python_-Schönheitswettbewerb. Dieses C&P ist in jeder Programmiersprache, die Funktionen kennt, falsch. Auch in C++. Und wenn du hier Code veröffentlichst, dann musst du damit leben, dass der auch kritisiert wird. Das kannst du als persönlichen Angriff sehen - oder als Chance Programm und deine Erfahrung zu verbessern.
Es geht aber –das habe ich gleich am Anfang erklärt– darum eine C++ Lösung für Noobs ohne Kompilieren bereitzustellen.Sirius3 hat geschrieben: Samstag 6. Juli 2024, 07:59 Du behauptest, ja angeblich C++ Programmierer zu sein. Und darauf bauen meine Kommentare auf. Funktionen, Schleifen, alles nichts Neues wenn man C++ beherrscht.
...
In diesem Kontext, hat eine einfache lineare Gestaltung Vorteile gegenüber ausgefeilten Programmiertechniken, weil es leichter zu verstehen ist.
Weshalb es besser sein soll alles eine eine main() Funktion zu packen, um sie dann am Ende abrufen mit
if __name__ == "__main__":
main()
erschließt sich mir bei einem einfachen Skript, das nur einmal durchlaufen soll und niemals in einer Bibliothek wiederverwendet wird, wirklich nicht.
Warum ich es lieber 5-mal im Code belasse, habe ich auch erklärt.
Keep it simple and stupid. Python muss nicht Selbstzweck sein.
Was ich in C++ schreibe, kannst ja bei https://github.com/rin67630/ selbst lesen.
Ein schones Wochenede noch...
Laszlo
Diese Argumentation ist nachvollziehbar. Wenn du eine Art Wegwerfskript schreibst, das von oben nach unten abgearbeitet wird – quasi wie ein simples bash-Skript – dann brauchst du das nicht.RIN67630 hat geschrieben: Samstag 6. Juli 2024, 08:37 Weshalb es besser sein soll alles eine eine main() Funktion zu packen, um sie dann am Ende abrufen mit
if __name__ == "__main__":
main()
erschließt sich mir bei einem einfachen Skript, das nur einmal durchlaufen soll und niemals in einer Bibliothek wiederverwendet wird, wirklich nicht.
Wenn das "Skript" hingegen etwas länglicher wird, dann ist es gut eine Strukturierung mit Funktionen vorzunehmen. Dann aber auch konsequent, so dass sämtlicher Code in Funktionen steckt und eine dieser Funktionen als Einsprungpunkt dient. Also genau wie in C. Analog zu C wird diese Funktion gerne als "main" bezeichnet (obwohl dies in Python wahlfrei ist). Von dort ist es nur noch eine zusätzliche Zeile Code "if __name__ == '__main__':" einzufügen.
Erlaubt noch eine letzte Frage.
Das Skript speichert die Datei {outfile}
Jetzt soll Python dieses Befehl vom Betriebsystem aus ausführen:
wobei "ESP_SwissArmyKnife_Rev06_2024_patched.bin" in der Variable outfile steht.
Wie schreibt man das korrekt?
mit
kann es aber nicht funktionieren, da muss alles in einem einzigen String sein.
Wahrscheinlich nutzt man subprocess.run?
Versuche ich es so:
oder so
oder so:
kommt immer. ^
SyntaxError: invalid syntax
Wie schreibt man es denn korrekt?
Oder kann man gar nicht so python aus python ausrufen?
Danke für die Hilfe.
Das Skript speichert die Datei {outfile}
Jetzt soll Python dieses Befehl vom Betriebsystem aus ausführen:
Code: Alles auswählen
python3 esptool.py write_flash -z 0x0000 ESP_SwissArmyKnife_Rev06_2024_patched.bin
Wie schreibt man das korrekt?
mit
Code: Alles auswählen
os.system (" python3 esptool.py write_flash -z 0x0000 {outfile}")
Wahrscheinlich nutzt man subprocess.run?
Versuche ich es so:
Code: Alles auswählen
subprocess.run(["python3", "esptool.py", "write_flash", "-z 0x0000", "{outfile}"])
Code: Alles auswählen
subprocess.run(["python3", "esptool.py", "write_flash", "-z 0x0000", {outfile}])
Code: Alles auswählen
subprocess.run(["python3", "esptool.py", "write_flash", "-z 0x0000", outfile ]).
SyntaxError: invalid syntax
Wie schreibt man es denn korrekt?
Oder kann man gar nicht so python aus python ausrufen?
Danke für die Hilfe.
- __blackjack__
- User
- Beiträge: 14002
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@RIN67630: Nur die letzte Variante bringt einen Syntaxfehler. Wegen dem Punkt am Ende. Die anderen beiden bringen den nicht, machen aber auch keinen Sinn.
Und was da noch falsch ist, ist das "-z 0x0000". Das ist so *ein* Argument, als wenn man das in der Shell in Anführungszeichen gesetzt hätte. Das müssen aber zwei Argumente sein.
Wenn das nicht mit irgendeinem python3 ausgeführt werden soll, das der Benutzer vielleicht gar nicht hat, würde ich das erste Argument durch `sys.executable` ersetzen.
Und was da noch falsch ist, ist das "-z 0x0000". Das ist so *ein* Argument, als wenn man das in der Shell in Anführungszeichen gesetzt hätte. Das müssen aber zwei Argumente sein.
Wenn das nicht mit irgendeinem python3 ausgeführt werden soll, das der Benutzer vielleicht gar nicht hat, würde ich das erste Argument durch `sys.executable` ersetzen.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Danke, das war's. Klappt jetzt !__blackjack__ hat geschrieben: Montag 8. Juli 2024, 22:23 Und was da noch falsch ist, ist das "-z 0x0000". Das ist so *ein* Argument, als wenn man das in der Shell in Anführungszeichen gesetzt hätte. Das müssen aber zwei Argumente sein.
[/quote]
Wenn das nicht mit irgendeinem python3 ausgeführt werden soll, das der Benutzer vielleicht gar nicht hat, würde ich das erste Argument durch `sys.executable` ersetzen.
[/quote]
Habe ich auch gemacht, obwohl meine Anwenderbescreibung das Installieren von Python3 (wenn nicht vorhanden) beschreibt.
- __blackjack__
- User
- Beiträge: 14002
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@RIN67630: Naja, aber dann hat der Anwender vielleicht schon Python ohne das zu wissen. Siehe MacOS oder zumindest in der Vergangenheit war das auch manchmal auf vorinstallierten Windows-PCs von HP zu finden.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Super, jetzt kappt soweit alles im Normallfall.
Jetzt muss noch der Feinschliff hin.
1) Was passiert, wenn der Anwender eine Frage nur mit "return" beantwortet?
2) Wie optimiert man einen 2. Durchlauf wenn es schon eine gepatchte Datei gibt?
bei 1) bei der erste Frage, welche Datei zu patchen ist, dann loopen bis eine gültige Datei eingegeben wurde.
Besser aber alle vorhandene Dateien im Verzeichnis, die mit .bin enden, anzeigen und der Anwender gibt nur die nummer des Treffers ein.
Das habe ich versucht:
Schön ist das nicht 
Komischerweise fand ich nirgendswo ein Beispiel, um einen Tuple zusammen mit der Indexnummern seiner Elemente auszudrucken.
Das dürfte doch eine ziemlich übliche Aufgabe sein, wenn man danach ein Element aus der Liste auswählen will, nicht wahr?
Wie macht man das besser?
Bei 1) bei der nächsten Fragen der Credentials, jetzt wird bei leere Antwort das gepatchtes Parameter mit Null überschrieben, das ist nicht schön.
Erste Abhilfe, bei leerer Antwort, nichts patchen, oder die Antwort mit dem ungepatchtem Inhalt vorzubelegen.
bei 2) für folgende Durchläufe wäre es gut, bei leeren Antworte, die bereits gepatchten Ergebnisse beizubehalten.
Dafür müsste man die bereits gepatchte Datei mit lesen und den Inhalt kopieren, der sich jetzt am Platz des Platzhalters der Originalstelle findet.
Suchen und Ersetzen wie zuvor geht ja nicht, weil man gar nicht weiss, was man suchen soll...
Da lasse ich mir noch etwas einfallen...
Jetzt muss noch der Feinschliff hin.
1) Was passiert, wenn der Anwender eine Frage nur mit "return" beantwortet?
2) Wie optimiert man einen 2. Durchlauf wenn es schon eine gepatchte Datei gibt?
bei 1) bei der erste Frage, welche Datei zu patchen ist, dann loopen bis eine gültige Datei eingegeben wurde.
Besser aber alle vorhandene Dateien im Verzeichnis, die mit .bin enden, anzeigen und der Anwender gibt nur die nummer des Treffers ein.
Das habe ich versucht:
Code: Alles auswählen
from pathlib import Path
import os
# directory/folder path
dir_path = Path.home().joinpath("Desktop")
# list to store found_files
found_files = []
found_files_index = []
# Iterate directory
for file_path in os.listdir(dir_path):
# check if current file_path is a file
if os.path.isfile(os.path.join(dir_path, file_path)):
# add filename to list
found_files.append(file_path)
found_files_index.append(file_path)
# add index to list
index = found_files.index(file_path)
found_files_index.append(index)
print(found_files_index)

Komischerweise fand ich nirgendswo ein Beispiel, um einen Tuple zusammen mit der Indexnummern seiner Elemente auszudrucken.
Das dürfte doch eine ziemlich übliche Aufgabe sein, wenn man danach ein Element aus der Liste auswählen will, nicht wahr?
Wie macht man das besser?
Bei 1) bei der nächsten Fragen der Credentials, jetzt wird bei leere Antwort das gepatchtes Parameter mit Null überschrieben, das ist nicht schön.
Erste Abhilfe, bei leerer Antwort, nichts patchen, oder die Antwort mit dem ungepatchtem Inhalt vorzubelegen.
bei 2) für folgende Durchläufe wäre es gut, bei leeren Antworte, die bereits gepatchten Ergebnisse beizubehalten.
Dafür müsste man die bereits gepatchte Datei mit lesen und den Inhalt kopieren, der sich jetzt am Platz des Platzhalters der Originalstelle findet.
Suchen und Ersetzen wie zuvor geht ja nicht, weil man gar nicht weiss, was man suchen soll...
Da lasse ich mir noch etwas einfallen...
in meine User-Beschreibung soll er das mit__blackjack__ hat geschrieben: Dienstag 9. Juli 2024, 08:34 @RIN67630: Naja, aber dann hat der Anwender vielleicht schon Python ohne das zu wissen. Siehe MacOS oder zumindest in der Vergangenheit war das auch manchmal auf vorinstallierten Windows-PCs von HP zu finden.
Code: Alles auswählen
python3 --version
Wenn da ein Fehler kommt (bei Windows etwa) soll er Python3 vom Windows-Store holen.
Er braucht es eh' um den ESP zu flashen.
Doch etwas gefunden, ganz einfach sogar:
Edit: das Beispiel im Internet war buggy.
richtig ist:
Code: Alles auswählen
import os
import sys
items = os.listdir("D:/Logs")
fileList = [name for name in items if name.endswith(".log")]
for cnt, fileName in enumerate(fileList, 1):
sys.stdout.write("[%d] %s\n\r" % (cnt, fileName))
choice = int(input("Select log file[1-%s]: " % cnt))
print(fileList[choice])
richtig ist:
Code: Alles auswählen
choice = int(input("Select log file[1-%s]: " % cnt)) -1
Zuletzt geändert von RIN67630 am Dienstag 9. Juli 2024, 09:48, insgesamt 1-mal geändert.
Warum benutzt Du os.listdir, wenn Du doch schon pathlib benutzt?
Man speichert nicht zusammengehörende Daten in zwei unabhängigen Listen. Was möchtest Du mit dem Index überhaupt machen? Warum stehen in der Liste found_files_index sowohl Strings als auch Zahlen?
Warum suchst Du jetzt plötzlich log-Files unter D:/Logs? Um etwas auszugeben benutzt man `print` und nicht `sys.stdout.write`? Wie bist Du auf diese Idee gekommen?
Auch das würde man einfacher mit pathlib schreiben:
Bei falschen Eingaben würde ich den Nutzer einfach erneut fragen:
Da Du ein Fan von linearer Programmierung bist, darfst Du diese Schleife gerne sechs mal in Deinem Code kopieren und die einzelnen Stellen an die Namen anpassen.
Man speichert nicht zusammengehörende Daten in zwei unabhängigen Listen. Was möchtest Du mit dem Index überhaupt machen? Warum stehen in der Liste found_files_index sowohl Strings als auch Zahlen?
Warum suchst Du jetzt plötzlich log-Files unter D:/Logs? Um etwas auszugeben benutzt man `print` und nicht `sys.stdout.write`? Wie bist Du auf diese Idee gekommen?
Auch das würde man einfacher mit pathlib schreiben:
Code: Alles auswählen
for index, path in Path("D:/Logs").glob("*.log"):
print(f"[{index}] {path.name}")
Code: Alles auswählen
def input_value(name, placeholder):
while True:
value = input(f"Enter {name}:")
if not value:
print("Empty value not allowed.")
elif not value.isascii():
print("Unicode not supported.")
else:
encoded_value = value.encode().ljust(len(placeholder), b"\0")
if len(encoded_value) > len(placeholder):
print("Input too long.")
else:
return encoded_value
Alles schon gerade gebogen, sogar das Beispiel im Internet berichtigt.Sirius3 hat geschrieben: Dienstag 9. Juli 2024, 09:41 Warum benutzt Du os.listdir, wenn Du doch schon pathlib benutzt?
Man speichert nicht zusammengehörende Daten in zwei unabhängigen Listen. Was möchtest Du mit dem Index überhaupt machen? Warum stehen in der Liste found_files_index sowohl Strings als auch Zahlen?
Jetzt ist die Dateieingabe soweit rund:
...
Code: Alles auswählen
#Listing potential files to patch in current directory
items = os.listdir()
fileList = [name for name in items if name.endswith(".bin")]
for cnt, fileName in enumerate(fileList, 1):
print(f"[%d] %s\n\r" % (cnt, fileName))
#Chosing the one you want to patch
choice = int(input("Select .bin file[1-%s]: " % cnt))
infile = (fileList[choice - 1])
print (f"working on {infile}, let's begin to patch !")
#Preparing the output filename
outfile = infile.replace(".bin", "_patched.bin")
infile_path = Path.home().joinpath("Desktop", infile)
outfile_path = Path.home().joinpath("Desktop", outfile)
Dein Programm hat jetzt noch den Fehler, dass Du zwar das aktuelle Arbeitsverzeichnis durchsuchst, dann aber davon ausgehst, dass es eine Datei mit selbem Namen auch unter .../Desktop gibt.
Warum hast Du einen f-String der keine Platzhalter hat, benutzt dann aber %?
Warum nicht einfach:
Warum hast Du einen f-String der keine Platzhalter hat, benutzt dann aber %?
Warum nicht einfach:
Code: Alles auswählen
bin_paths = sorted(Path(".").glob("*.bin"))
for index, path in enumerate(bin_paths, 1):
print(f"[{index}] {path.name}")
choice = int(input(f"Select .bin file[1-{index}]: "))
input_path = bin_paths[choice - 1])
print (f"working on {input_path}, let's begin to patch !")
output_path = input_path.with_stem(input_path.stem + "_patched")
- DeaD_EyE
- User
- Beiträge: 1224
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Dann hofft mal, dass die Nutzer keine Verzeichnisse erstellen, die auf .bin enden.
Im Beispielcode wird nicht geprüft, ob es sich um eine Datei handelt.
Gerade, wenn man Dateien kopiert und modifiziert, sollte man solche Fehler vermeiden.
Es gab Fälle, bei denen aufgrund fehlerhafter Scripte das komplette Home-Verzeichnis gelöscht worden ist. Den Bug in srcds_run (für Gameserver) hat ein Kollege mal eingeführt und Valve hat die Änderung übernommen.
Im Beispielcode wird nicht geprüft, ob es sich um eine Datei handelt.
Gerade, wenn man Dateien kopiert und modifiziert, sollte man solche Fehler vermeiden.
Code: Alles auswählen
bin_paths = sorted([element for element in Path(".").glob("*.bin") if element.is_file()])
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
- DeaD_EyE
- User
- Beiträge: 1224
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
https://github.com/rin67630/ESP_Binary_ ... Credits.md
Damit hat sich das Thema für mich erledigt. Schönen Tag noch.This software is open-source under creative common license CC BY-SA
It is given in the hope to be useful, but I am NOT RESPONSIBLE IN ANY WAY OF DAMAGES WHATSOEVER
occuring from the use of my software.
Credits: Thanks to the user inq720 from the forum https://forums.raspberrypi.com/ for the idea to simply patch the binary.
No thank to the users of many Python Forums, where I asked for help, since I have practically no experience with Python.
They spent pages trying to discourage me of doing what I have done, and kept telling me to "read the tutorials" when I just needed some examples to start with the unknown syntax.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Verzeihung, es war überreagiert, hab ich wieder herausgenommen.DeaD_EyE hat geschrieben: Dienstag 9. Juli 2024, 12:21 https://github.com/rin67630/ESP_Binary_ ... Credits.md
Damit hat sich das Thema für mich erledigt. Schönen Tag noch.
An dem Abend hatte ich so einen Hals, dass wir so lange um den heißen Brei herumreden mussten.
- pillmuncher
- User
- Beiträge: 1529
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@RIN67630: Wenn dir gesagt wird, du sollst die Dokumentation lesen, dann aus dem Grund, dass es irgendwie sinnlos ist, wenn wir dir die Dokumentation hier schriftlich vorlesen. Wir können auch nicht viel anderes schreiben, als was in der offiziellen Dokumentation steht. Die übrigens hervorragend ist, verglichen mit anderen Sprachen, die man nennen könnte. Der Zweck des Forums ist es IMO, das zu behandeln, was nicht bereits in der Dokumentation steht und Hilfe zur Selbsthilfe zu geben. Und da kommt nunmal oft der Hinweis auf die Dokumentation, weil dort die Wahrheit steht, die ganze Wahrheit, und nichts als die Wahrheit.
In specifications, Murphy's Law supersedes Ohm's.
...soweit zur Theorie. In der Praxis gibt es dort hunderten Stellen die heute obsolet sind, die man heute anders löst, wo konkrete Beispiele fehlen und noch mehr unbeschriebene Notwendigkeiten, die nur Erfahrene intus haben.pillmuncher hat geschrieben: Dienstag 9. Juli 2024, 14:50 ...da kommt nunmal oft der Hinweis auf die Dokumentation, weil dort die Wahrheit steht, die ganze Wahrheit, und nichts als die Wahrheit.
Auch das ist irgendwo von irgendwer niedergeschrieben worden, aber dann müsste man 3 Jahren Lesen, bevor man Ergebnisse erzielen könnte.
Man lernt auch nicht Autofahren in dem man die StVo durchliest.
- __blackjack__
- User
- Beiträge: 14002
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@RIN67630: Das Tutorial sollte auch nicht einfach nur durchgelesen werden, sondern durchgearbeitet. Das heisst die Sachen dort ausprobieren, verändern, um ein Verständnis dafür zu bekommen. Auch das kann Dir niemand abnehmen.
Woher weisst Du wie die Python-Dokumentation in der Praxis aussieht wenn Du die gar nicht gelesen hast? Oder sind das jetzt Deine Ausreden das gar nicht erst anfangen zu müssen, weil das ja bestimmt alles ganz schlecht ist‽
Woher weisst Du wie die Python-Dokumentation in der Praxis aussieht wenn Du die gar nicht gelesen hast? Oder sind das jetzt Deine Ausreden das gar nicht erst anfangen zu müssen, weil das ja bestimmt alles ganz schlecht ist‽
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
- pillmuncher
- User
- Beiträge: 1529
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Das mag in anderen Sprachen so sein, aber nicht in Python. Die Dokumentation ist immer aktuell, zeigt immer idiomatischen Code, und ist immer vollständig. Da gibt es keine unbeschriebenen Notwendigkeiten.RIN67630 hat geschrieben: Dienstag 9. Juli 2024, 15:37 In der Praxis gibt es dort hunderten Stellen die heute obsolet sind, die man heute anders löst, wo konkrete Beispiele fehlen und noch mehr unbeschriebene Notwendigkeiten, die nur Erfahrene intus haben.
In specifications, Murphy's Law supersedes Ohm's.