Posts by __blackjack__

    Flexibel Hier mal die angepassten Preise auf Basis des RAM-Ausbaus von 1986. Erst ein kleines C-Programm das ich unter DOS geschrieben habe (lässt sich auch auf dem Raspi problemlos übersetzen) um die 400 DM an den heutigen Wert anzupassen:

    Schauen wir mal was die 400 DM heute in € sind:

    Code
    C:\> infadj 1986 400
    400.00 Mark in 1986 = 445.33 EUR in 2026.

    Und dann die Hoch- beziehungsweise Umrechnung auf verschiedene Speichergrössen auf einem ZX Spectrum:

    Code
       10 LET price per kb=445.33/384: LET u$="KMG"
       20 READ size,magnitude: IF size=0 THEN STOP 
       30 LET price=size*1024↑magnitude*price per kb
       40 PRINT size;TAB 4;u$(magnitude+1);"iB = ";INT (price*100+.5)/100;" EUR"
       50 GO TO 20
       60 DATA 1,0,48-16,0,384,0,1,1,1,2,2,2,4,2,8,2,16,2,32,2,0,0

    Ergebnis:

    Code
    1   KiB = 1.16 EUR
    32  KiB = 37.11 EUR
    384 KiB = 445.33 EUR
    1   MiB = 1187.55 EUR
    1   GiB = 1216047.8 EUR
    2   GiB = 2432095.6 EUR
    4   GiB = 4864191.2 EUR
    8   GiB = 9728382.3 EUR
    16  GiB = 19456765 EUR
    32  GiB = 38913529 EUR

    Es hätte also nur 37,11 € gekostet einen ZX Spectrum mit 16 KiB auf die vollen 48 KiB aufzurüsten. Aber Du musstest ja unbedingt einen PC verwenden. ;)

    hyle Das Überverzeichnis kann man nicht weg lassen. In das venv-Verzeichnis gehört nur das venv. Alles andere, Quelltext, Dokumentation, requirements.txt, Konfigurationsdatei(en) und so weiter gehört nicht in das venv-Verzeichnis. Das muss problemlos löschbar sein, und das kommt zum Beispiel auch nicht mit in die Versionsverwaltung.

    uv erstellt das Verzeichnis ja auch versteckt als .venv/ und nicht als venv/. Das hat so einen ähnlichen Status wie ein .hg/ oder .git/ Verzeichnis.

    Hajulied Die Meldung bedeutet, dass pip keine Schreibrechte hat das systemweit zu installieren und es deswegen nur für den Benutzer installiert hat unter dem Du das gemacht hast.

    Thonny verwendet entweder eine andere Python-Installation als die, die Du in der Power Shell verwendet hast um icecream zu installieren, oder Thonny hat für das Projekt ein venv eingerichtet oder zumindest aktiviert und dort ist icecream nicht installiert.

    ver-pi-lt Mir ging es nicht darum das in möglichst schwer zugänglichem Fachchinesisch hören zu wollen, sondern etwas konkreteres als „K.I. soll das verbessern“ — was halt so gar nichts aussagt. Zusammen mit der geäusserten Vorstellung der A.I.-Hat muss da nur drauf gesteckt werden und beliebige Programme die was mit “K.I.“ machen — was immer das bedeutet und wie das eine externe Hardware erkennen können soll — klang das halt nach einem hoffnungslos naiven Ansatz zu dem man IMHO nichts anderes sagen kann, als das man mehr und deutlich konkretere Informationen braucht.

    Bertthias Ich verstehe das auch, und mache das auch hin und wieder selbst. Nur eben auch wie Du, nur so viele print()s, dass ich nicht den Überblick verliere welche Ausgabe von wo kommt. Das passiert ja eher nur wenn man da immer mehr und mehr von ansammelt, und auch welche hat, die gar nichts mehr mit dem aktuellen Problem zu tun haben, das man gerade debuggen will.

    Ergänzend zu noisefloor: Es kann natürlich auch mehr als genau ein print() werden, aber das macht man ja um einen Fehler zu finden/einzugrenzen, oder einen bestimmten Teil im Programm etwas genauer zu verstehen. Zum Beispiel um zu sehen was irgendwo in eine Funktion oder einen Abschnitt an Daten rein geht, und was hinterher dabei heraus kommt. Oder wie sich bestimmte Werte im Laufe einer Schleife verändern. Da weiss man welcher Code ausgeführt wird, wo die Ausgaben erzeugt werden, und braucht keine Zeilennummern in der Ausgabe; für Code den man gerade im Editor parallel offen hat und sieht. Da schreibt man neben den Werten die man ausgibt als Text wo man sich gerade befindet, und nicht als nichtssagende Zeilennummer, die sich zudem jederzeit ändern kann, wenn man etwas am Code verändert. Also so etwas wie ”frobnicate()-Argumente: a=… b=…” am Anfang einer Funktion oder ”n ist Primzahl”/”n ist nicht prim” in if- und else-Zweig wenn die Bedingung is_prime(n) war, damit man sieht welcher Zweig genommen wurde, oder einfach nur ”A” und ”B”, weil man den Code dazu im Editor offen hat.

    icecream (und ähnliche Bibliotheken) hat gegenüber print() ein paar Vorteile. Der Aufruf ist grundsätzlich genau so einfach wie print(). Aber es heisst anders, das heisst es ist sehr leicht von echten print()-Aufrufen, die zur Kommunikation mit dem Benutzer dienen, zu unterscheiden und man kann den Editor danach suchen lassen, oder mit grep oder ack ausserhalb eines Editors oder einer Entwicklungsumgebung. Es gibt automagisch den Ausdruck aus, dessen Wert man damit ausgibt und es gibt diesen Wert auch als Ergebnis zurück, statt grundsätzlich None wie print(). Man kann das also auch in einem Audruck verwenden, um ein Teilergebnis auszugeben, ohne dafür Code zu kopieren oder den Code so umschreiben zu müssen, dass man eine extra Variable hat, nur um deren Wert mit print() ausgeben zu können.

    Bei Variante 1 und 2 muss man den Teilausdruck 2 bis 3 mal kopieren. Wenn der komplexer als das Beispiel ist, und man an genau diesem Ausdruck gerade entwickelt, muss man aufpassen, dass alle Kopien gleich bleiben. Bei Variante 2 ist der Rückbau ein bisschen fehleranfälliger.

    Strategisch platzierte print()s, oder eben so etwas wie ic()- oder snoop.pp()-Aufrufe, sind etwas kurzfristiges. Da baut man ein paar davon ein, um etwas bestimmtes zu verstehen oder heraus zu finden. Das macht man dann, und danach werden die Aufrufe wieder entfernt. Dabei entsteht das Problem, die Zeilennummer für eine Ausgabe finden zu müssen, gar nicht. Wenn man an dem Punkt ist, wo das ein Problem wird, dann hat man offensichtlich den Überblick über die Anzahl und Stellen verloren, wo man solche Ausgaben eingebaut hat. Und/oder das sind keine temporär eingebauten Ausgaben mehr. Dafür ist dann die Lösung Logging. Diese Aufrufe braucht man nicht entfernen, weil man die Ausgaben einfach über das Loglevel deaktivieren kann, beziehungsweise in verschiedenen Stufen wählen kann. Logging kann dann auch Modulnamen und Zeilennummern automagisch ausgeben.

    Wie Dennis89 gezeigt hat, kann man icecream so konfigurieren, dass bei jedem Aufruf auch Dateiname und Zeilennummer ausgegeben wird. Das ist mir persönlich schon zu nah an Logging als das ich an der Stelle dann nicht darauf umsteigen würde. Mir reicht sonst zur Orientierung, wo im Code der Ablauf gerade ist, das was ic() ausgibt wenn man es ohne Argumente aufruft. Und das ist mehr als die Zeilennummer und da ist die dann auch nur nett zu haben, denn Modul- und Funktionsname finde ich an der Stelle deutlich hilfreicher als eine magische und wenig aussagekräftige Zeilennummer, die sich ändern kann wenn man im Code etwas ändert zwischen den Läufen.

    Falls man sehr viele print() oder ic() für nur einen Fehler oder eine Verständnisgfrage hat, dann ist das snoop-Modul das richtige Werkzeug. Das ist so ähnlich wie set -x in der Bash oder TRACE ON in einigen BASIC-Dialekten, oder Python's trace-Modul, aber noch ein bisschen besser. Mit nur einem Dekorator an einer Funktion wird jede Zeile, die ausgeführt wird, protokolliert plus die Namen und Werte der betroffenen lokalen Variablen. Bevor man also anfängt zwischen fast jede reguläre Codezeile ein print() zu schreiben, sollte man sich snoop anschauen.

    Das ganze Zeugs ist selbst in Python geschrieben. Also wenn man nichts zusätzliches Installieren möchte, kann man sich das auch selber basteln, in abgespeckter Form. Wenn man wirklich icecream komplett nachbaut, kann man auch einfach gleich das Original verwenden. Es sei denn es geht nur um den Lerneffekt. Ausgangspunkt um die Zeilennummer des Aufrufs in einer Funktion zu bekommen wäre zum Beispiel inspect.currentframe() aus der Standardbibliothek. So etwas was die C-Präprozessor-Makros __LINE__ und __FILE__ statisch zur Übersetzungszeit machen, kann man sich in Python als Funktionen, die das dynamisch zur Laufzeit ermitteln, recht einfach selbst schreiben. Mit der Einschränkung, dass der Aufruf in der Regel aus Python-Code kommen muss. Wenn dazwischen nativer Maschinencode steht, der keinen Rahmen auf dem Python-Aufrufstapel hat, bekommt man den letzten Python-Code als Quelle für die Information.

    Wenn die regelbasierte Steuerung in der Lage ist, die ”K.I.” Vorschläge zu bewerten, warum kann die dann nicht selbst mindestens genau so gute Einstellungen vornehmen? Mir ist nicht so wirklich klar was das soll. Kannst Du das mal mit echten Fachbegriffen erklären die eine Bedeutung haben, statt so wolkig mit irgendwie ”K.I.”? K.I. gibt's nicht. Und man kann auch nicht irgendeine Hardware wo drauf stecken die ”übernimmt”, wenn sie ”merkt” dass eine ”K.I.” an der Arbeit ist. Was ist denn das für eine merkwürdige magische Vorstellung wie so ein Rechner funktioniert?

    Was das rumliegen von einem Raspi und die Dimensionierung angeht: Falls man das nicht abschätzen kann und man zukunftssicher sein will, dann zwei Raspis. Einen auf dem man entwickelt und der das beste/meiste bietet was man bekommen oder sich leisten kann/möchte. Und wenn man dann weiss, dass das Projekt auch mit weniger produktiv laufen würde, einen Raspi der für den Produktivbetrieb taugt/ausreicht. Den Entwicklungsrechner hat man dann herumliegen, aber das nächste Projekt oder Weiterentwicklung von etwas vorhandenem, oder OS-Updates kommen bestimmt. Und man hat einen Reserverechner falls ein Produktivsystem den Löffel abgibt.

    Erster Ansatz wäre das gar nicht zu machen. Wenn man so viele vorübergehende print()-Aufrufe im Programm hat dass man Zeilennummern in der Ausgabe hat um die wiederzufinden, dann hat man zu viele davon.

    Für vorübergehende Ausgaben wäre es auch besser so etwas wie icecream zu verwenden. Das kann man auch so konfigurieren, dass der Dateiname und die Zeilennummer mit ausgegeben wird. Und man findet die Aufrufe zum entfernen einfacher als bei print(), weil man da nicht unterscheiden muss zwischen Aufrufen, die nur zeitweise da sein sollen, und solchen, die zum normalen Programm gehören.

    Weitere Möglichkeit wäre Logging über DEBUG oder TRACE Loglevel. logging aus der Standardbibliothek oder beispielsweise das externe loguru.

    Falls man es mit solchen Ausgaben wirklich krass übertreiben will, ohne tatsächlich nach jeder Zeile eine weitere einzufügen, gäbe es noch das snoop-Package.

    Flexibel Das mit den Unterstrichen ist keine so gute Idee, weil die Schriftart nicht bei allen Nutzern gleich ist. Das Forum kann doch Tabellen in Beiträgen:

    Speichergrösse

    Einheit

    Preis in €

    384

    KB

    200

    1

    MB

    520

    1

    GB

    520.000

    16

    GB

    8.320.000

    32

    GB

    16.640.000

    Oder man setzt es in einem Code-Block:

    Code
    384 KB =        200 €
      1 MB =        520 €
      1 GB =    520.000 €
     16 GB =  8.320.000 €
     32 GB = 16.640.000 €

    Wobei die Zahlen nicht so ganz stimmen. Beziehungsweise stimmen die schon in gewisser Weise aber niemand rechnet bei Arbeitsspeicher in MB. Auch damals nicht als MB bei Arbeitsspeicher noch falsch verwendet wurde, hat man trotzdem 1024 KiB dafür angenommen. Also wäre der 1 MiB Preis schon mal 533,33 €. Und schon bei der ersten Umrechnung von DM in € kann man ja gerne den einfachen Umrechnungsfaktor 2 verwenden, ist ja nah genug dran, aber dann sollte man schon die Inflation von damals bis heute da drauf schlagen um einen sinnvollen Vergleich zu heutigen Preisen zu haben. :)

    McDotter Das ist halt Computer-Oldtimer-Hobby. Das Bild auf einem Röhrenmonitor/-fernseher ist was anderes als auf einem modernen LCD-Monitor. Bei den alten Rechnern geht das oft noch durch einen HF-Modulator. Das hat dann so Effekte, dass bei PAL beispielsweise 50% der Farbinformationen in die jeweils nächste Zeile gemischt wird, wodurch man Farben darstellen kann, die es in der Farbpalette des Rechners eigentlich nicht gibt. Auf einem modernen Monitor hat man da dann teilweise deutlich abgegrenzte Linien in alternierenden Farben die komisch bis hässlich aussehen, die auf dem Medium auf dem das Bild mal erstellt wurde, aber eine gemischte Farbe ergeben.

    Oder ”interlace”, also zwei Bilder so schnell wie möglich abwechselnd darstellen um eine höhere Punkt und/oder Farbauflösung zu simulieren. Das flackert auf einem Röhrenmonitor oft deutlich weniger, weil die beiden Einzelbilder ”nachleuchen” und damit ”weicher” übergehen.