Archiv nach Kategorien: Python

Thema der GnomeShell ändern

Mit der “user theme” Erweiterung für die GnomeShell lassen sich Themen sehr einfach wechseln. Prinzipiell muss dafür nur mit “dconf” der Schlüssel “/org/gnome/shell/extensions/user-theme/name” geändert werden. Damit die Erweiterung die Themen auch findet, müssen diese zuvor im Ordner “~/.themes” abgelegt worden sein.

Um nun das Thema zu ändern, genügt es, folgenden Befehl in der Konsole abzusetzen:

dconf write /org/gnome/shell/extensions/user-theme/name "'DarkGlass'"

Ebenso könnte mit dem Werkzeug “dconf-editor” der entsprechende Schlüssel angepasst werden.

Weil dieses Vorgehen doch eher umständlich ist, gibt es die Erweiterung “themeselector“, die die Möglichkeit, das Thema zu ändern, direkt in die GnomeShell integriert.

Leider scheint diese Erweiterung noch nicht mit der aktuellen Version der GnomeShell lauffähig zu sein und da es nicht mit einer einfachen Anpassung der Versionsnummer in der Datei “metadata.json” getan war, habe ich ein kleines Python-Skript geschrieben, das ebenfalls in der Lage ist, die GnomeShell-Themen auf die Schnelle zu ändern.

Das Skript findet sich hier auf GitHub und sollte mit Python2 und Python3 lauffähig sein. Voraussetzung ist natürlich die Installation der oben erwähnten und verlinkten Erweiterung “user theme”. Außerdem müssen die Bibliotheken für die Anbindung von Python an die GObject-Introspektion installiert sein, unter Ubuntu oder Arch sind diese beispielsweise im Paket “python-gobject” bzw. “python-gobject2″ zu finden.

Wer schnell mal ein paar Shell-Themen ausprobieren möchte, kann ja einen Blick darauf werden.

//edit: Wie Christoph in den Kommentaren erwähnt, steht diese Funktion auch über das “gnome-tweak-tool” zur Verfügung; da das die meisten Shell-Nutzer wohl installiert haben dürften, besteht natürlich kaum Bedarf für ein zusätzliches Skript :).

freiesMagazin – Python Sonderausgabe

Das freieMagazin hat eine Python-Sonderausgabe veröffentlicht, in der die bisher erschienenen 6 Teile meiner Python-Einführung, die ich nun seit etwa einem halben Jahr für das freieMagazin schreibe, zusammengefasst wurden.

Wer die Reihe noch nicht kennt, kann mit der Sonderausgabe ja mal einen Einstieg wagen. Und auch so ist diese Zusammenstellung vielleicht nochmal eine ganz nette Übersicht für Anfänger.

Ganz lieben Dank an dieser Stelle übrigens an Christian Hausknecht, der mir seit dem zweiten Teil der Reihe als geduldiger und kompetenter Korrektor zur Seite steht!

I wanna watch this!

Wer sich auf Youtube, Google Video oder sonstwo im Netz gerne von Flash-Videos berieseln lässt, kennt das Problem: Nach x Minuten bequemt sich der Monitor in den Energiesparmodus und erst panisches Rütteln an der Maus überzeugt das System davon, dass der Nutzer noch am PC ausharrt – der Monitor wird wieder geweckt.

Ich habe deshalb schon einige Abende damit verbracht, im 5-Minuten-Intervall mein Mausrad zu rollen, weil die Maus von der Couch aus noch erreichbar war und ich keine Lust hatte im Energiespar-Menü das Abschalten des Bildschirms im Leerlauf zu deaktivieren :). Faulheit ist nicht immer ökonomisch!

Das dauerhafte Deaktivieren dieser Option ist für mich aber auch keine Alternative – ich habe keine Lust mir jedes Mal, wenn ich den PC verlasse, zu überlegen, ob es sich lohnt den Bildschirm auszuschalten oder nicht.

Das Ärgerliche bei der ganzen Sache: Totem und andere Videoplayer geben dem System einfach Bescheid: Hey, es sieht zwar aus, als sei der Nutzer untätig, aber eigentlich schaut er ein Video. Lass das mal mit dem Bildschirmschoner/Energiesparmodus. Flash bietet diesen Luxus nicht. Verschiedene Ansätze wurden daher bereits diskutiert und ich dachte, ich füge einfach mal einen weiteren hinzu:

I wanne watch this (iwwt)

IWWT ist ein kleines Python-Skript, das in festen Intervallen die Fenstertitel der Fenster auf dem Desktop auf das Vorhandensein bestimmter Zeichenketten überprüft. Findet sich also “youtube”, “google video” oder ähnliches in einem Fenstertitel, deaktiviert das Tool den Bildschirmschoner und sorgt dafür, dass der Mauszeiger nach 1 Sekunde unsichtbar wird.

Natürlich räumt das Skript hinterher auch auf: Findet sich kein entsprechender Fenstertitel mehr, wird für Bildschirmschoner und Maus wieder das Standardverhalten aktiviert.

Als kleine Erweiterung kennt das Skript noch den Schalter “-a”, mit dem nur aktive Fenster der Prüfung unterzogen werden.

Abhängigkeiten

Benötigt werden folgende Pakete:

  • python-wnck
  • unclutter

Ersteres stellt für Python eine Schnittstelle zum Fenstermanager bereit, das zweite Paket versteckt den Mauszeiger bei Untätigkeit.

Einstellungen

Das Skript kann verhältnismäßig leicht angepasst werden: In Zeile 23 ff. können die verschiedenen Fenstertitel (bzw. Bestandteile davon) eingetragen werden, bei denen der Bildschirmschoner deaktiviert werden soll. In Zeile 35 wird festgelegt, wie viele Sekunden das Skript zwischen zwei Überprüfungen warten soll, in Zeile 38 und 39 lassen sich die vom Skript aufgerufenen Programme konfigurieren.

Ecken und Kanten

Auch diese Lösung ist nicht perfekt. Sie funktioniert ausschließlich mit GNOME. Außerdem muss der Benutzer alle von ihm genutzten Video-Seiten vorher definieren.

Das 30-sekündige Pollen aller Fenstertitel ist weiterhin nicht unbedingt eine schöne Lösung. Der Timeout kann grundsätzlich aber auf x-1 Sekunden eingestellt werden (wobei x die Leerlaufzeit des Monitors bzw. Bildschirmschoners ist).

Damit man das Skript nicht jedes Mal, wenn man ein Video schauen möchte, von Hand aufrufen muss (das wäre wohl kaum eine Arbeitserleichterung), empfiehlt es sich mMn, das Skript bei der Anmeldung direkt ausführen zu lassen (System->Einstellungen->Startprogramme).

Download

iwwt.py.tar

configparser gone pythonic

Zum Lieferumfang von Python gehört ja auch der ConfigParser. Mit dieser Bibliothek lassen sich Konfigurationsdateien erstellen, lesen und bearbeiten, was gerade im Linux-Umfeld ja eine durchaus nützliche Sache ist (wenngleich natürlich nicht alle Konfigurationsdateien dem selben Standard gehorchen). Wer seinen Nutzern aber schnell und unkompliziert die Möglichkeit bieten möchte, bestimmte Verhaltensweisen seines Programms zu beeinflussen, bekommt mit dem ConfigParser ein nützliches Werkzeug dazu an die Hand.

Es geht aber noch besser, wie ich gerade festgestellt habe. Mit ConfigObj lassen sich noch einfacher und pythonischer Konfigurationsdateien bearbeiten. Dazu wird die jeweilige Konfig-Datei auf ein verschachteltes Dictionary abgebildet. Ein Aufruf könnte entsprechend so aussehen:

config[“Section1″] = {}
config[“Section1″][“OptionA”] = “Mein Wert”

Was mir daran besonders gefällt: Statt mit irgendwelchen config.has_section(“Section1″) oder section.has_option(“OptionA”) Aufrufen fragt man ganz bequem und python-intuitiv “Section1″ in config oder “OptionA” in section und erhält die gewünschte Antwort.
ConfigObj bietet darüber hinaus natürlich noch einige Möglichkeiten, wie etwa verschachtelte Sektionen. Was mich aber besonders zum Umstieg bewogen hat, ist der Umstand, dass ConfigObj die Kommentare in den Konfigurationsdateien belässt. ConfigParser hat dahingegen die lästige Angewohnheit, Kommentare beim Schreiben und Aktualisieren von Konfigurationsdateien zu entfernen. Eine Möglichkeit, dieses Verhalten zu ändern, habe ich bisher nicht aufgetan.

Wie auch immer: Dank der intuitiven Syntax lassen sich bestehende Programme leicht auf ConfigObj migrieren. Ich konnte zumindest mit wenigen Zeilen Code meine bestehende ConfigParser-Schnittstelle auf ConfigObj umbiegen.

Pong A.I.

So funktioniert die Pong A.I. Das Hintergrundbild stammt übrigens von Gnome-look.org und steht unter GPL.

Pong dürfte wahrscheinlich zu den meist umgesetzten Spielen überhaupt gehören. Sehr vielsagend, was die Umsetzung angeht, ist dabei folgendes Wikipedia-Zitat:

»Das programmtechnisch aufwändigste an Pong war die Anzeige des aktuellen Punktestandes.«

Es gibt übrigens sogar eine elektromechanische Variante von Pong! Kurzum: Die dem Spiel zu Grunde liegende Logik ist doch recht einfach zu implementieren.

Fast jede Pong-Implementierung bietet  die Möglichkeit, gegen den Computer zu spielen. Auch das liegt wohl daran, dass die Logik, die nötig ist, um den Computer Pong spielen zu lassen, nicht besonders anspruchsvoll ist: Da sich die Schläger nur auf der Y-Achse bewegen, reicht eine Überlegung wie “Wenn der Ball sich oberhalb des Schlägers befindet, bewege den Schläger hoch, wenn er sich unterhalb des Schlägers befindet, bewege den Schläger runter – und sonst tu einfach nichts”.
Auch lässt sich diese Art von Computergegner wunderbar skalieren: Je öfter der Computer diese “drüber/drunter” Überlegung pro Sekunde anstellt und seinen Schläger entsprechend bewegen darf, desto schwerer wird es für den menschlichen Spieler, den künstlichen Gegenspieler auszutricksen.

Nun hat diese Variante aber auch einen Nachteil: Der Schläger des Computerspielers fährt fortwährend den Bildschirm ab und folgt dem Ball somit auf der Y-Achse. Das sieht in der Regel relativ unnatürlich aus und macht das Spiel für den menschlichen Spieler nicht gerade attraktiver. Auch ist diese Art der A.I. relativ anfällig für Bälle, die über Bande gespielt werden: Stellen wir uns vor, ein Ball bewegt sich recht zügig und in einem spitzen Winkel auf die Bande unten links zu. Links sei in diesem Beispiel auch die Seite des Computergegners. Die “drunter/drüber”-Logik würden den A.I.-Schläger auf der Y-Achse ganz nach unten bewegen, da ja auch der Ball sich auf der Y-Achse nach unten bewegt. Prallt der schnelle Ball nun aber im  von der Bande ab, wird er sich relativ zügig in die obere linke Ecke des Spielfeldes bewegen. gemäß der “drunter/drüber”-Logik wird der Computer-Schläger dem Ball zwar folgen – allerdings oft erfolglos.
Nun könnte man als Gegenmaßnahme zwar den Interval, in dem der PC die Ball- und Schlägerposition abgleicht, erhöhen – dadurch würde der PC-Schläger auch immer schneller und wäre bei normalen horizontalen Bällen immer schwerer zu schlagen. Natürlich lässt sich all dies beheben – aber grundsätzlich sind dies die Nachteile dieser einfachen Logik.

Ich habe nun also versucht, ein etwas realistischeres A.I.-Verhalten zu implementieren. Stufe 1 dieser Logik berechnet – wenn der Ball sich auf den Computer-Schläger zubewegt – an Hand der Bewegungsrichtung des Balls, wann und wo dieser vermutlich auf Schläger-Höhe sein wird. Nun muss der Schläger nur noch Zug für Zug  an diese Position bewegt werden. So gesehen also eine recht realistische Verhaltensweise, die auch sehr leicht mit mehreren Banden-Abprallern fertig wird.
Stufe 2 dieser Logik geht noch einen Schritt weiter: Hier wird die Flugbahn des Balls nicht nur berechnet, wenn er sich auf den PC-Schläger zubewegt, sondern auch, wenn der Ball in Richtung des gegnerischen Paddles unterwegs ist. Mit der selben Logik lässt sich so leicht berechnen, wo und wann der Ball auf Gegner-Höhe sein wird und vor allem, wie die vermutete Flugbahn des Balls sein wird, wenn der Gegner ihn trifft und wieder in Richtung des PC-Paddles schlägt. So berechnet diese A.I. bereits in dem Moment, in dem der Ball vom Schläger abprallt, wo der Ball bei der nächsten Runde vermutlich landen wird. Schneidet der Gegner den Ball an, ist dies auch nicht sonderlich schlimm, da ja in dem Moment, in dem der Ball den gegnerischen Schläger verlässt, wieder eine neue Flugbahn berechnet wird. Auch mehr oder minder große Rechenfehler – die sich mit der Zahl der Bandenberührungen potenzieren – sind so kein großes Problem, da ja die Flugbahn des Balls ständig kontrolliert wird.

Dieses Verhalten hat mehrere Vorteile gegenüber der “drunter/drüber”-Logik:

  1. Die Schläger-Bewegung sind weniger hektisch und intuitiv nachvollziehbar.
  2. Die A.I. ist auch und besonders bei Banden-Bällen sehr stark.
  3. Die Schwierigkeit lässt sich nicht nur durch die Anzahl der Aufrufe der A.I. einstellen: Durch leicht zu implementierende Zufallsabweichungen kann die A.I. “menschlicher” gemacht werden.
  4. Diese A.I.-Variante kann bereits mit verhältnismäßig wenigen Aufrufen pro Sekunde sehr gute Spielergebnisse erzielen – ist also deutlich stärker als die “drunter/drüber”-Logik.

Eine grobe Version meiner A.I. gibts nach dem Klick.
Weiterlesen »