Montag, 30. September 2013

 

Python Kommandozeilenparameter

Kommandozeile (unter Linux/Unix)

Gleich zur Kommandozeilenbearbeitung mit Python
Folgender Artikel gibt einen kurzen Einblick in die Geschichte der Kommandozeile: Commandline resurrected.

Viele Aufgaben lassen sich auch wesentlich schneller auf der Kommandozeile erledigen als mit der grafischen Oberfläche (Click-Click-Drag usw). Ein paar Beispiele (Shell bedeutet hier Kommandozeile):

Suche alle .c Dateien, die neuer sind als Makefile.


Shell... find . -name ' *.c' -newer Makefile -print
GUI... Öffne den Explorer, navigiere zum entsprechenden Verzeichnis, Klicke auf die Datei Makefile und merke das Änderungsdatum bzw. Zeit. Dann Starte Tools/Find und gib *.c als Suchkriterium ein. Wähle den Datumsreiter und gib das gemerkte Datum ein. Klicke OK.

Erzeuge an zip/tar-Archiv meines Sourcecodes (C-Code).


Shell... zip archive.zip *.h *.c oder tar cvf archive.tar *.h *.c
GUI... Öffne ein ZIP-Werkzeug (z.B. WinZip), wähle "Neues Archiv", gib den Namen ein, wähle das (Quell-)Verzeichnis im Hinzufügen Dialog, setze den Filter auf *.c und klicke "Hinzufügen", dann setze einen weiteren Filter auf *.h und klicke "Hinzufügen" und schließe das Archiv wieder.

Ein letztes Beispiel:

Welche Java-Dateien wurden letzte Woche geändert?


Shell... find . -name '*.java' -mtime +7 -print
GUI... Klicke und navigiere zu "Suche Dateien", klicke auf "Name" und gib "*.java" ein, wähle "Datum letzte Änderung" und klicke auf "Beginndatum", gib das Startdatum des Projekts ein (wann war das, verd**** noch mal?). Weiters klicke auf "Endedatum" und gib das Datum von vor einer Woche ein (schau mal schnell auf einen Kalender...). Klicke "Suche".
Anmerkung: Möglicherweise sind die genauen Bezeichnungen bzw. Beschriftungen beim GUI nicht ganz korrekt, denn die hängen von der Version sowie von Typ der Grafischen Oberfläche (GUI = Graphical User Interface) ab. Die (Shell-) Befehle sind jedoch korrekt.

Befehls-Syntax

Unix (Linux) Befehle haben folgende einheitliche Struktur. Bis auf den Befehlsnamen (Programmname) sind grundsätzlich alle anderen Angaben optional.
Befehlsname [Option...] [Argument...] [Ein-/Ausgabeumlenkung]
Die eckigen Klammern deuten an, dass dieser Parameter optional ist. Die drei Punkte geben zusätzlich an, dass mehrere solcher Parameter möglich sind.
Optionen sind syntaktisch von anderen Argumenten unterscheidbar: sie beginnen mit einem Minus, haben einen Buchstaben und danach optional ein Argument für diese Option
-x [Argument]
oder sie beginnen mit zwei Minus und einem Optionsnamen sowie dem optionalen Argument.
--Optionsname [Argument]

Befehlsargumente sind Dateinamen oder andere für den Befehl wichtige Informationen.
Normalerweise lesen Unix-Programme Eingaben vom Terminal und geben Ausgaben auf das Terminal aus. Diese Datenkanäle können durch Ein-Ausgabeumlenkung geändert werden. Diese Umleitungen unterscheiden sich ebenfalls von den Optionen und anderen Argumenten (< Eingabedatei, > Ausgabedatei und | für die Pipe).
<
Das Kommando liest von der angegebenen Datei (statt von der Tastatur).
>
Das Kommando schreibt in die angegebene Datei (statt auf das Terminal).
|
Die Ausgabe des Kommandos links vom | wird als Eingabe für das Kommando rechts vom | verwendet. Die Kommandos sind über eine Pipe (Leitung, Rohrleitung) verbunden.
Ein paar Beispiele:
hh@knuth:~$ cd workspace
hh@knuth:~/workspace$ ls
c2bf  demo  eclimd.log  guidemo  libbf  programmierblog  python  python3  python-sum
pythontest  pythonX  scm-demo  _SCRIPTS_  unit-tests
hh@knuth:~/workspace$ cd c2bf
hh@knuth:~/workspace/c2bf$ ls
1tox  cc  GPL  ld  Makefile  math  README  strip  test.sh  wrapper
hh@knuth:~/workspace/c2bf$ cd cc
hh@knuth:~/workspace/c2bf/cc$ ls
ast.h  c2bf-cc  c2bf-dispast  dispast.c  dispast.o  genbf  genbf.h  genbfmain.c
genbfmain.o  gram.o  gram.y  main.c  main.o  Makefile  README.txt  scan.l  
scan.o  tests  y.output  y.tab.h
hh@knuth:~/workspace/c2bf/cc$ ls *.c *.h
ast.h  dispast.c  genbf.h  genbfmain.c  main.c  y.tab.h
hh@knuth:~/workspace/c2bf/cc$ ls -l *.c *.h
-rw-rw-r-- 1 hh hh 21061 Aug 31 21:40 ast.h
-rw-rw-r-- 1 hh hh 30503 Aug 31 21:40 dispast.c
-rw-rw-r-- 1 hh hh  6627 Aug 31 21:40 genbf.h
-rw-rw-r-- 1 hh hh   953 Aug 31 21:40 genbfmain.c
-rw-rw-r-- 1 hh hh   917 Aug 31 21:40 main.c
-rw-rw-r-- 1 hh hh  7631 Aug 31 21:45 y.tab.h
hh@knuth:~/workspace/c2bf/cc$ cd
hh@knuth:~$
Mehr Informationen zur Shell (Kommandozeile) gibt es hier: Bash (Shell)

Kommandozeilenparameter mit Python bearbeiten

Das (Standard-) Modul sys ermöglicht es von Python auf die Umgebung, in der Python läuft, zuzugreifen. In unserem Fall wenden wir uns der Kommandozeile zu.
#!/usr/bin/python3
import sys

print("commandline:")
for arg in sys.argv:
    print(arg)
hh@knuth:/tmp$ vim cmd.py 
hh@knuth:/tmp$ cat cmd.py 
#!/usr/bin/python3
import sys

print("commandline:")
for arg in sys.argv:
    print(arg)
hh@knuth:/tmp$ python3 cmd.py -o --option par1 par2
commandline:
cmd.py
-o
--option
par1
par2
hh@knuth:/tmp$ chmod +x cmd.py 
hh@knuth:/tmp$ ./cmd.py -o --option par1 par2
commandline:
./cmd.py
-o
--option
par1
par2
hh@knuth:/tmp$ 
Die Zeile
#!/usr/bin/python3
dient dazu, dem Betriebssystem zu sagen, mit welchem Programm diese (Text-) Datei zu starten ist, wenn man sie mit chmod +x file ausführbar gemacht hat.

Sie sehen, dass alle Parameter nach python3 ausgegeben werden. Ist die Pythondatei ausführbar, bekommt man die (fast) dieselbe Ausgabe (./ vor einem Kommando bedeutet, dass dieses Kommando im aktuellen Verzeichnis und nicht im Pfad zu finden ist).
hh@knuth:/tmp$ python3
Python 3.2.3 (default, Sep 10 2012, 18:14:40) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> type(sys.argv)
<class 'list'>
>>> 
sys.argv ist eine Liste, die alle Kommandozeilenparameter inklusive des Scriptnamens enthält. Das Pythonprogramm muss die Argumente entsprechend behandeln: Optionen erkennen, Argumente verwenden. Nur die Ein-/Ausgabeumlenkung braucht man nicht im Programm behandeln (solange man nur die Standardkanäle verwendet).
hh@knuth:/tmp$ ./cmd.py -o --option par1 par2 > outputfile
hh@knuth:/tmp$ cat outputfile
commandline:
./cmd.py
-o
--option
par1
par2
hh@knuth:/tmp$ 
Bei der Ausgabeumleitung auf die Datei outfile "verschwindet" die Ausgabe in dieser Datei.

Ein einfaches Beispiel, das den "Typ" der Argumente ausgibt:
import sys

def info(progname):
    """print some information"""
    print(str.format("""
usage:
    {0} [-h] [parameter...]
prints type of parameters

Options:
-h ... this help

(c) 2012 Harald R. Haberstroh
    """, progname))
    
    
if __name__ == '__main__':
    if "-h" in sys.argv:
        info(sys.argv[0])
    else:
        for arg in sys.argv:
            if arg.isdigit():
                print("number", arg)
            elif arg.isalpha():
                print("word", arg)
            else:
                print("string", arg)
hh@knuth:/tmp$ python3 cmdline.py 123 Harald '+$' -h

usage:
    cmdline.py [-h] [parameter...]
prints type of parameters

Options:
-h ... this help
    
(c) 2012 Harald R. Haberstroh
hh@knuth:/tmp$ python3 cmdline.py 123 Harald '+$' 
string cmdline.py
number 123
word Harald
string +$
hh@knuth:/tmp$
Ihre Python-Programme sollten immer eine Hilfe mit der Option -h oder --help anbieten. Dort muss auch Ihr Name und die Klasse ausgegeben werden.

Nach der Ausgabe der Hilfe (Info) soll das Programm beendet werden. Damit kann man wie im obigen Beispiel einfach -h an die Kommandozeile anhängen.

In der Hilfe/Info muss auch immer der Programmname wie im Beispiel ausgegeben werden (sys.argv[0])!

Labels: , ,


 

Python Objekte, Aufrufstack (POS1: 2BHIF)

Objekte

In Python sind alle Elemente Objekte. Folgendes Beispiel enthält ein paar solche Objekte:
def fun(x):       # auch ein Objekt!
    y = x * x
    return y

f2 = fun          # f1 ist eine Refernz auf fun

lst = [1, 2, fun] # Liste mit 3 Objekten
l2 = lst          # l2 ist eine Refernz auf obige Liste

erg = fun(2)
print(erg)
erg = f2(3)
print(erg)
print(f2 == fun)
print(l2 == lst)
print(lst)

Folgendes Bild zeigt den Speicher, wenn das Progarmm in der Zeile 3 angelangt ist, nach dem f2(3) (ist ja fun(3)) in der Zeile 12 Aufgerufen wurde.



Sie können den Ablauf unter folgendem Link testen: objects.py

Sie sehen auf der rechten Seite die Objekte, welche Python angelegt hat. Der linke Bereich ("Frames") zeigt den Speicher, den Python für die (globalen) Variablen anlegt sowie den Speicher für die aufgerufene Funktion. Für jede Funktion wird so ein Bereich (Frame) angelegt und beim beenden wieder zerstört.

Pfeile stellen Referenzen dar. Zum Beispiel stellt der Pfeil von lst zum Listenobjekt [1, 2, fun] dar. Auch l2 ist eine Referenz zu dieser Liste.
In dieser Liste gibt es eine weitere Referenz zur Funktion fun. Funktionsnamen sind also Referenzen zu "Funktions-Objekten" (die den Code der Funktion "enthalten").

Aufrufstack

Beim folgenden Beispiel können Sie sehen, wie Frames sich bei den Aufrufen der Funktion fact() stapeln und dann in Folge wieder zerstört werden:

def fact(n):
    if n > 1:
        return n * fact(n - 1)
    else:
        return 1

f = fact(5)
print(f)


Folgendes Bild zeigt die Frames, wenn das Programm die Zeile 5 erreicht (aber nicht ausgeführt) hat. Sie sehen einen Stapel von Frames. Ein Frame pro Aufruf. Diese Frames werden anschließend bei jedem return wieder zerstört. Man nennt diesen Stapel Aufrufstack:



Sie können den Ablauf unter folgendem Link testen: fact.py

Labels: , ,


 

vim Übung

Legen Sie eine Datei mit ihren Initialen und Extension .txt an
Bsp:
  hh.txt
Einfügen von 5 Zeilen mit beliebigem Text
Einfügen von Asterix als eigene Zeile nach der 4. Zeile
Positionieren auf 3. Zeile
Am Ende der Zeile das wort xyyz einfügen
Kopieren der 3. Zeile
Einfügen dieser Zeile 85 mal nach der 5. Zeile
Suchen nach String rix
Schalten Sie die Zeilennummerierung ein
Gehe zu Zeile 70
Lösche 10 Zeilen
Kopiere Zeilen 13-45 in eine neue Datei mit Namen 'parthh.txt'
Alle Zeichen 'y' durch '§' ersetzen
Einfügen der Zeilen 5-10 aus der Datei 'parthhtxt' nach der letzten Zeile

Labels: , ,


 

vim Einführung (POS1: 2BHIF)

Vim ist ein hervorragender Editor mit Syntaxhervorhebung und Vergleichsfunktionen, mehreren Darstellungsfenstern und vielen anderen nützlichen Funktionen. Leider ist der Einstieg damit nicht immer ganz leicht, da vim eine Weiterentwicklung des Editors vi ist, den es bereits in den 80er Jahren gab, wo Benutzerfreundlichkeit noch eine andere Bedeutung hatte als heute. Weiterhin erscheint vim im unkonfigurierten Zustand zunächst erstmal sehr langweilig und es ist mühselig eine passende Konfiguration zu erstellen.
Der vi ist praktisch auf jedem Linux-System verfügbar und kann von der Shell (Terminal) aus verwendet werden. Daher ist es praktisch, wenn man den vi(m) beherrscht, wenn man einen Server (z.B. Web-Server) über das Internet warten muss. Die wichtigsten Funkionen kann man probieren und üben mit vimtutor
Weitere Dokumentation finden Sie hier:
vim Kurzreferenz auf LinWiKi
vim Homepage www.vim.org
vim Quick Reference Card (2 Seiten)
Wir verwenden eine spezielle Konfigurationsdatei für den vim. Im Laufe dieses Schuljahres werden wir Ihnen diese Datei (eigentlich eine überarbeitete Version, denn die bisherige Version ist hauptsächlich für C-Programmierung eingerichtet) zur Verfügung stellen. Also, bleiben Sie dran oder suchen Sie auf www.vim.org/scripts nach passenden Scripts für den vim.

vim ist eine Erweiterung des Standard-Unix-Editors vi. vim steht für vi improved.
vim gibt es nicht nur für Unix-Plattformen, sondern auch für andere Betriebssysteme (Windows, OSX). Siehe dazu auch http://www.vim.org/. vim ist frei verfügbar.
Es ist besser, einen Editor wirklich gut zu beherrschen als viele verschiedene Editoren oder Entwicklungsumgebungen nur mittelmäßig bedienen zu können. Der vim eignet sich besonders als universeller (Programmier-)Editor, da er für jede Plattform verfügbar ist und hochgradig konfigurierbar bzw. programmierbar ist.
vi gibt es auf jedem Unix-ähnlichem System. Wenn nichts mehr geht, dann muss man u.U. dem vi nehmen und in den Konfigurationsdateien Änderungen vornehmen.

vim hat (wie vi) mehrere Betriebsmodi:
Dies hat den Vorteil, dass man einen mächtigen Editor (vim ist programmierbar, arbeitet mit regulären Ausdrücken usw.) auch über einfache Terminals bedienen kann. Alle Funktionen sind über eine Standardtastatur mit Escape-Taste verfügbar. Man braucht keine Funktionstasten und keine Cursortasten. Funktions- und Cursortasten sowie Maus können bei geeigneten Terminals (X-Window System, Console) verwendet werden.
Nachteilig ist der relativ hohe Lernaufwand.

Befehlsmodus

Grundsätzlich kann jeder Befehl mehrfach ausgeführt werden, indem zuerst eine Anzahl angegeben wird. Z.B. 10dd löscht 10 Zeilen (siehe unten), 2dw löscht 2 Worte.
[Anzahl] Befehl [Taste]
[Anzahl] Befehl [Bereich]
Cursorbewegung
k hinauf
h l links rechts
j hinunter
^F orward page
^B ackward page
^D own half page
^U p half page
w ord right
b ack word
[line]G oto line (default letzte Zeile)
( Sätze zurück
) Sätze vorwärts
{ Absätze zurück
} Absätze vorwärts
fc gehe zum Zeichen c in der aktuellen Zeile
'm gehe zu Marke m
ma mark a (setze Marke a), Marken werden auch für Lösch-, Änder- und Kopieroperationen verwendet (sieh weiter unten)
Löschen (d elete)
dd Zeile löschen
dw Wort löschen
x Zeichen unter Cursor löschen
X Zeichen links von Cursor löschen
D bis Zeilenende löschen
Bereichd löschen des Bereichs
d'marke löschen bis zur Marke marke (ein Buchstabe, vorher gesetzt mit mmarke)
Ändern
> schiebt Text nach rechts (shiftwidth)
< schiebt Text nach links (shiftwidth)
i Einfügen vor Cursor (insert)
a Einfügen nach Cursor (append)
I Einfügen Zeilenanfang (Insert)
A Einfügen Zeilenende (Append)
o Öffnet neue Zeile darunter (open line)
O Öffnet neue Zeile darüber
J (join) hänge die nächste Zeile an die aktuelle Zeile an (mit Leerzeichen getrennt)
rx ersetzen des aktuellen Zeichens durch das Zeichen x (kein ESC nötig)
cw ändert Wort (change word)
Bereichc ändert Bereich (vgl. Bereich angeben)
c'marke ändert Bereich bis zur Marke
Bereich angeben (markieren)
Cursor an ein Ende des Bereichs setzen, v eingeben, den Cursor zum anderen Ende bewegen und den gewünschten Befehl eingeben. Zeilenweise markieren mit V.
Wurde :set mouse=a gesetzt, dann kann auch mit der Maus markiert werden.
Fast alle Befehle arbeiten mit einem so markierten Bereich.
Kopieren/Einfügen
Bereichy "yank", Bereich wird in den Puffer kopiert
y'marke kopiert Bereich bis zur Marke in den Puffer
yw Wort in den Puffer
Y Zeile in den Puffer
p Einfügen nach Cursor (paste - "einkleben")
Suchen
^A sucht nächstes Vorkommen des Wortes unter Cursor
% platziert Curser auf zugehörige ( ) { } [ ]
Anzahl% platziert Cursor auf Anzahl Prozent der Datei
/text sucht vorwärts text oder regulären Ausdruck
?text sucht rückwärts text oder regulären Ausdruck
* sucht das Wort unter dem Cursor
Wiederholung
. (Punkt) wiederholt letztes Kommando
n letzte Suche wiederholen
N letzte Suche in umgekehrter Richtung
Rückgängig
u undo, der vi kann nur die letzte Änderung rückgängig machen (d.h. uu stellt die letzte Änderung wieder her), der vim kann im Prinzip beliebig viele Änderungen rückgängig machen
^r (crtl+r) redo (nur vim) macht das letzte undo bzw. die letzten undos wieder rückgängig
Sonstige Kommandos
^G zeigt Dateistatus und Zeilennummer
^L erneuert Bildschirm
Bereich! führt angegebenen Bereich einem Filter zu, der anschließend eingegeben werden muss

Änderungsmodus

Eingegebener Text wird eingefügt (bei i, a,...) bzw. ersetzt markierten Bereich (c,...), löschen mit Backspace in der aktuellen Zeile möglich (nur eben eingegebener Text).
Der Änderungsmodus wird mit der ESC-Taste verlassen.
^v (ctrl+v) stellt sicher, dass das nächste Zeichen normal eingegeben wird (z.B. wird bei TAB normalerweise nicht das Tabulator-Zeichen eingefügt sondern so viele Leerzeichen als nötig, will man jedoch das TAB-Zeichen einfügen, muss man ^vTAB drücken).

Ex-Befehle (Colon mode)

:[Zeile][,Zeile]Befehl Argumente
Der Bereich Zeile,Zeile bezeichnet Anfangszeile und Endzeile. Ein . (Punkt) bedeutet aktuelle Zeile, $ die letzte Zeile. Wurde vorher ein Bereich mit v ausgewählt, dann wird automatisch ein Bereich eingefügt: '<,'> (die Marke '< bezeichnet den Anfang und '> das Ende eines markierten Bereichs). % ist die Kurzform von 1,$.
:x Speichern und Ende
:w write, speichern
:w datei Speichern in Datei (write), wurde vorher ein Bereich markiert, so wird dieser Bereich in die datei geschrieben.
:r datei Einfügen von Datei (read)
:q Quit (schließen eines Fensters)
:split [datei] weiteres Fenster (mit datei öffnen)
Suchen und ersetzen
:s/suchtext/ersatztext/[g]
Ersetzen von suchtext durch ersatztext. Wird g (die eckigen Klammern bezeichnen "optional") angegeben, dann wird auch mehrfaches Vorkommen pro Zeile ersetzt. suchtext kann ein regulärer Ausdruck sein.
Wenn kein Bereich angegeben wird, dann wird die Ersetzung nur in der aktuellen zeile durchgeführt. Wird ein Bereich markiert, so wird nur in diesem Bereich ersetzt. Es können auch Zeilennummern angegeben werden:
:.,$s/i++/j++/g ersetze alle i++ durch j++ von der aktuellen Zeile bis zum
Ende der Datei.
Setzen von Modi
:se tabstop=3 Tabulatorweite
:se shiftwidth=3 Weite für > und <
:se ai oder :set autoindent automatisches Einrücken
:se et oder :set expandtab Tabulator wird durch Leerzeichen ersetzt (dies sollte eingestellt werden!)
:syntax on Highlighting von Sourcen
Abkürzungen
:ab lhs rhs Definieren einer Abkürzung lhs (left hand side) für rhs (right hand side), Abkürzungen werden expandiert, sobald ESC, Enter oder die Leertaste gedrückt wird.
:ab listet alle Abkürzungen auf.
:unab lhs löscht die Abkürzung lhs.
:help abbreviate Hilfe zu den Abkürzungen.
Konfigurationsdatei .vimrc
In dieser Datei können beliebige Ex-Befehle stehen. Diese Datei wird beim Starten von vim ausgeführt. Weitere Konfigurationsmöglichkeiten sind in der Dokumentation (:help) beschrieben. So können Abkürzungen definiert werden, Funktionstasten belegt werden und in Abhängigkeit eines Dateityps Konfigurationsdateien ausgeführt werden.
reguläre Ausdrücke
Reguläre Ausdrücke werden immer wieder benötigt. Der vim erlaubt es reguläre Ausdrücke zu beim Suchen. Das Programm grep erlaubt reguläre Ausdrücke. Reguläre Ausdrücke ermöglichen es Suchmuster anzugeben. Dabei gibt es viel mehr Möglichkeiten als bei den Shell-Suchmustern. Es folgen beispielhaft die wichtigsten Ausdrücke:
\. (Punkt) steht für ein beliebiges Zeichen
[aeiou] ein Selbstlaut klein geschrieben
[A-Z] alle Großbuchstaben
[^0-9] alles außer Ziffern
cdrom\|floppy alle Vorkommnisse der Worte cdrom oder floppy
a\+ mindestens ein a (a, aa, aaa, aaaa, ...)
.* keines, ein oder mehrere beliebige Zeichen (der * braucht
keinen
\)
\(ausdruck\)+ das Muster ausdruck muss mindestens einmal
vorkommen
ausdruck{von,bis} ausdruck muss mindestens von mal und höchstens
bis mal vorkommen.
ausdruck{n} ausdruck muss genau n mal vorkommen.
^ausdruck ausdruck muss am Zeilenanfang stehen.
Ausdruck$ ausdruck muss am Zeilenende stehen.
Die Operatoren \+ und * sind "gefräßig", d.h. sie nehmen soviel als möglich, u.U. bis zum Ende eine Zeile. Der Ausdruck a.*h passt auf ah, ahh, abh, abhcdh.
Beispiele:
[0-9A-Fa-f]+ erkennt Hexadezimalzahlen, z.B. 123, abc, F000 usw.
\(un\)*stable erkennt stable, unstable, ununstable,
unununstable etc.
\(un\)\{-,1}stable erkennt stable und unstable
int [a-z]\+(.*); passt auf alle Prototypen von int-Funktionen, die nur
Kleinbuchstaben im Namen haben.

Tipps

Wenn man nicht weiß, in welchem Modus sich der vi bzw. vim gerade befindet, drückt man am besten die ESC-Taste, dann ist man sicher im Befehlsmodus.
Generell ist zu empfehlen, :help tutor zu machen.
Mit :version erhält man Informationen zur Variable $VIM .
Der vi bzw. vim speichert regelmäßig gemachte Änderungen in eine Datei, die mit . (Punkt) beginnt und mit .swp (oder .swb, .swc usw.) endet. Dazwischen befindet sich der Name der editierten Datei (Aufruf vim hello.c, Sicherungsdatei .hello.swp). Beim Speichern und Beenden wird diese Datei gelöscht. Wird der vi bzw. vim gewaltsam terminiert (Stromausfall, killall -KILL vim, schließen des Terminals, in dem der vim läuft o.ä.), dann wird diese Sicherungsdatei nicht gelöscht. Darin sind im Allgemeinen fast alle Änderungen gespeichert.
Wird nach dem "Absturz" der vim wieder mit der vorigen Datei gestartet, so gibt er die Information aus, dass es eben diese Sicherungsdatei gibt und wie man die letzten Änderungen wiederherstellt. Das funktioniert normalerweise mit vim -r datei (-r wie recover). Wenn man dann alles geprüft hat, dann speichert man die Datei. Danach muss man die Sicherungsdatei löschen, da sonst wieder beim Starten von vim die Information angezeigt wird.
vim ist ein konfigurierbarer Editor, er hat eine eigene Programmiersprache eingebaut. Es gibt für viele Aufgaben fertige Scripts im Internet (http://www.vim.org ist ein guter Einstiegspunkt). Solche Scripts werden automatisch geladen, wenn sie sich im Verzeichnis ~/.vim/plugin befinden.

Labels: ,


Montag, 23. September 2013

 

Denksport mit Python, erste Anwendung von Mercurial (POS1: 2BHIF)

Abgabename: 2013_2bhif_aufgabe2_Name_Vorname.tgz

Lesen Sie Mercurial Einführung und legen Sie
  1. die Datei ~/.hgrc nach dem Muster des obigen Artikels an:
    [ui]
    username = Vorname Name <i99999@student.htlwrn.ac.at>
    
  2. ein Projekt mit dem Namen brain_teasers an.
  3. ein Mercurial Repository an.
Arbeiten Sie die Aufgaben der Reihe nach ab und nehmen Sie das jeweilige Pythonscript in das Repository auf. Machen Sie (spätestens) dann ein commit, wenn das Programm funktioniert (oder wenn es zumindest ohne Syntaxfehler läuft).

Schreiben Sie folgende Pythonprogramme:
pythagorean_triple.py
Es soll ein Pythagoreisches Tripel (a2 + b2 = c2 für a < b < c) für a + b + c == 1000.
sumdigits2pow1000.py
Es soll die Ziffernsumme (Quersumme, engl. cross sum) der Zahl 21000 ermittelt werden. Die Zahl soll als Programmargument angegeben werden.
sumdigitsfact.py
Es soll die Ziffernsumme der Fakultät von 100 (100!) ermittelt werden. Die Zahl soll als Programmargument angegeben werden.
palindrome4.py
Generiere 4-stellige Palindrome als Produkt 2-steliger Zahlen. Die Faktoren und das Palindrom soll ausgegeben werden. Da die Multiplikation kommutativ ist, müssen Duplikate entfernt werden: 74x66 == 66x74 (4884), also nur einmal ausgeben.
palindrome6.py
Generiere 6-stellige Palindrome als Produkt 3-steliger Zahlen. Gib das Maximum der Palindrome aus.

Labels: , , ,


Donnerstag, 19. September 2013

 

Linux, Bash (POS1: 2BHIF)

Das Betriebssystem, in unserem Falle Linux, stellt eine Schnittstelle zwischen Anwendungsprogrammen und der Hardware (Tastatur, Bildschirm, Maus, Festplatten, Netzwerk,...) dar. Das Betriebssystem ist also eine virtuelle Maschine mit einfachen Aufrufen zur Bedienung der Hardware.
Eine Shell ist nun ein Anwendungsprogramm, welches Eingaben vom Benutzer in geeignete Betriebssystemaufrufe umsetzt und ggf. andere Programme aufruft (d.h. das Betriebssystem mit einem bestimmten Aufruf das Programm starten lässt).
Darstellung Shell - schalenförmig über Betriebssystem über Hardware
Auch andere Betriebssysteme haben zur Bedienung Shells: Unter Windows gibt es CMD.EXE.
Die bash ist ein Interpreter mit einer vollständigen Programmiersprache. Es können damit on-the-fly kleine Programme mit Schleifen, Abfragen etc. erstellt werden, ohne dass man einen Editor dazu bemühen muss.
Da die Eingabe über die Tastatur speziell bei langen Pfadnamen (255 Zeichen für einen Dateinamen!) sehr mühsam und fehleranfällig ist, bietet die bash einige nützliche Features:

Ergänzung der Kommandozeile

Kommandos oder Pfade brauchen nicht vollständig eingetippt werden. Meist genügen wenige Buchstaben, die dann durch Drücken der Taste TAB (Tabulator) auf den richtigen Pfad (das richtige Kommando) ergänzt werden. Falls der Pfad nicht eindeutig ergänzt werden kann, werden alle Möglichkeiten durch neuerliches Drücken von TAB angezeigt. Pfade werden immer zum nächsten Directory ergänzt oder zumindest soweit sie eindeutig sind.

History

Die letzten Befehle können mit den Cursor-Tasten ausgewählt und editiert werden.
Mit !! wird der letzte Befehl ausgeführt, mit !-2 wird der vorletzte mit !-3 der vorvorletzte usw. ausgeführt. Mit !15 wird der 15. Befehl ausgeführt.
Mit !string wird der letzte Befehl, der mit string begonnen hat, ausgeführt.
Mit !?string? wird der letzte Befehl, der string enthält ausgeführt.
Mit string1^string2 wird das letzte Kommando ausgeführt, wobei string1 durch string2ersetzt wird.
Der Befehl history zeigt eine Liste der letzten Kommandos (mit deren Nummer) an.
Durch Drücken von ^r (Strg+R) kommt man in den Kommando-Suchmmodus, d.h. es wird das letzte Kommando angezeigt, welches die im folgenden getippten Buchstaben enthält. Mit weiteren ^r kommt man zum nächsten Befehl, der die Buchstaben enthält. Mit Enter wird der Befehl ausgeführt, mit den Links- und Rechts-Pfeiltasten kann der gewählte Befehl editiert werden.
Weiteres siehe unter man bash.
Beispiele ($ stellt den Prompt dar, alles hinter # gilt als Kommentar):
$ vim Telegramme.c                    # editieren
$ gcc -o telegramme Telegramme.c      # compilieren
$ telegramme                          # ausführen
$ !v                                  # Wiederholung von vim
$ !gc                                 # neuerliches compilieren
$ !t                                  # Aufruf von telegramme

Job-Control

Ein laufendes Programm kann mit ^z (Strg-Z) unterbrochen werden. Danach kann mit der bash weitergearbeitet werden. mit dem Befehl fg kann das letzte unterbrochene Programm wieder fortgesetzt werden.
Es können auch mehrere Programme unterbrochen werden (z.B. vim wird unterbrochen, man fprintf aufgerufen, dieses Kommando wird unterbrochen usw.). Die unterbrochenen Programme können mit jobs aufgelistet werden. Ein bestimmtes gestopptes (unterbrochenes) Programm mit der Job-Nummer 2 kann mit fg %2 wieder in den Vordergrund gebracht werden.
Mit diesen Möglichkeiten kann leicht zwischen mehreren Programmen hin- und hergeschaltet werden.
Programme, die vermutlich länger ohne Eingaben vom Benutzer laufen werden, können durch Anhängen von & als Hintergrundprozesse gestartet werden. Ein Hintergrundprozess kann ebenfalls mit fg wieder in den Vordergrund gebracht werden.
Beispiel: es sollen alle C-Files gesucht werden und die Namen (Pfade) in einer Liste gespeichert werden ($ ist der Prompt, wird also nicht eingegeben):
$ find / -name '*.c' -print > c-files.txt &
[1] 3751                                                   # Job-Nummer und Prozess-ID wird angezeigt
$ vim Telegramme.c
[1]+ Done find . -name '*.c' -print >c-files.txt           # Benachrichtigung, dass Kommando fertig
$ less c-files.txt                                         # Anzeigen des Files
Obiges Kommando könnte mittels kill %1 oder kill 3751 (kill und Prozess-ID) vorzeitig abgebrochen werden.
Programme im Vordergrund können mit ^c (Strg+C) abgebrochen werden.

Befehlssyntax

Generell sind Unix-Kommandos wie folgt aufgebaut:
$ cmd [optionen] [argument]...
Die eckigen Klammern [ ] zeigen an, dass dieser Teil optional ist. Die drei Punkte ...bedeuten, dass der Teil davor mehrfach vorhanden sein kann.
Prinzipiell können immer mehrere Parameter angegeben werden. Optionen beginnen immer mit einem Minus (-) und werden von einem Buchstaben gefolgt. Mehrere Optionen können zusammengefasst werden. z.B. ls -a -l kann auch als ls -al eingegeben werden.
Viele (neuere, GNU-) Programme erlauben auch lange Optionen, d.h. ganze Wörter zur Bezeichnung einer Option. Solche Optionen beginnen mit zwei Minus (). Das Kommando findist hier eine Ausnahme (s.o.).
Beispiel: ls -l und ls –format=long geben beide den Inhalt des Verzeichnisses im langen Format aus.
Generell sind Wildcards und reguläre Ausdrücke als Argumente möglich (die Shell erweitert reguläre Ausdrücke auf Listen von Parametern, d.h. das Kommando wird dann mit einer Liste aller passenden Files aufgerufen).

Wildcards

Wildcards sind Ersetzungsmuster, die von der Shell ersetzt werden. Wenn Sie z.B. alle Dateien auflisten wollen, die mit einem 'a' beginnen, dann geben Sie echo a* ein. Es werden dann Dateien der Art aa1abcalloc.c aufgelistet, falls sie existieren. Der '*' steht fürkeinein oder mehrere beliebige Zeichen. Wenn Sie Dateien suchen, die ein 'z' enthalten, dann geben Sie echo *z* ein. Tatsächlich ändert aber die Shell die Parameterliste für den Befehl echo, d.h. die Shell erzeugt eine Liste von Dateinamen, auf die das Muster zutrifft und ruft dann erst echo auf.
Nehmen Sie an, das aktuelle Verzeichnis enthielte folgende Dateien:
a.c zahlen.c anz.c anz.h anz hello.c a.out
Wenn Sie nun
echo *z*
eingeben, erzeugt die Shell folgenden Aufruf
echo zahlen.c anz.c anz.h
und führt den Befehl aus. echo braucht sich nicht darum zu kümmern!
Die Shell versteht noch andere Musterangaben. Beispielsweise:
[aeiou]*alle Dateien, die mit einem Selbstlaut beginnen
[0-9a-h]*alle Dateien, die mit 0 bis 9 oder a bis h beginnen
??alle Dateien, die aus genau 2 Zeichen bestehen (? steht für ein Zeichen)
*.[^ch]alle Dateien, die nicht mit .c oder .h enden
\*alle Dateien, die einen Stern enthalten
Mehr dazu unter man bash.

Abkürzungen

Tilde ~
~/ ist eine Abkürzung für das Home-Verzeichnis des angemeldeten Benutzers (meist/home/user, wenn user der Loginname).
~user/ ist die Abkürzung für das Homeverzeichnis des Users user.
alias
Mit dem Befehl alias können selbst Abkürzungen zu längeren Befehlen gemacht werden:
alias md="mkdir"md ist nun eine Kurzversion von mkdir (MaKe DIRectory)
Sie können mehrere immer wieder verwendete Abkürzungen in der Datei .bashrc speichern..bashrc ist eine Datei, die automatisch beim Starten einer bash interpretiert (ausgeführt) wird.
Der Befehl alias ohne Argumente gibt die Liste der derzeit aktiven Abkürzungen aus.

Shell-Variable

Da die bash eine vollständige Programmiersprache ist, gibt es natürlich auch Variable. Diese Variable werden nicht nur für die Programmierung eingesetzt sondern auch für die Konfiguration.
Shell-Variable werden üblicherweise in Großbuchstaben geschrieben (Groß-/Kleinschreibung ist entscheidend).
Für die interaktive Verwendung wird normalerweise das Kommando export verwendet:
export PATH=~/bin:$PATH
Mit obigem Befehl wird der Suchpfad, das sind diejenigen Verzeichnisse, in denen ein Programm oder ein Kommando gespeichert ist, geändert. Es wird der Pfad ~/bin vorne angefügt. $PATH liefert den Inhalt der Variable PATH (es erfolgt reine Textersetzung).
Einige Variable sind schon vordefiniert:
$HOMEHomeverzeichnis
$SHELLdie verwendete Shell

Ein-/Ausgabeumlenkung

Die Ausgabe von Kommandos kann mit dem Größerzeichen (>) in eine Datei umgelenkt werden. Z.B.:
ls -l /usr/bin > ls.txt
Die Datei ls.txt wird erzeugt und die Ausgabe von ls darin gespeichert.
Verwendet man zwei Größerzeichen (>>), so wird die Ausgabe an die angegebene Datei angehängt.
Umgekehrt kann auch die Eingabe für ein Programm aus einer Datei erfolgen, indem man das Kleinerzeichen verwendet:
grep ^d <eingabedatei
Diese Varianten können kombiniert werden.
kommando parameter… <eingabedatei>ausgabedatei
Oft werden Kommandos direkt kombiniert, indem die Ausgabe eines Programms direkt in die Eingabe des nächsten Programms gepumpt wird. Die Programme werden mit einer pipe(pipeline) verbunden. Das dafür nötige Zeichen ist der senkrechte Strich (|):
ls -l | grep ^d
Obiger Befehl gibt alle Verzeichnisse aus, da grep mit dem Parameter ^d alle Zeilen, die mit einem 'd' beginnen, ausgibt.
Es können beliebig viele Programme mit pipes verbunden werden, es entsteht dadurch eine richtige Verarbeitungskette. Ist die Ausgabe sehr lange, so könnte im obigen Beispiel nochless verwendet werden, um in der Ausgabe blättern zu können.
ls -l | grep ^d | less
Auf diese Weise lassen sich komplexe Aufgaben einfach und effizient erledigen.
Dabei ist zu beachten, dass die Shell hier einige Arbeit übernimmt: bei der Eingabeumlenkung öffnet die Shell die Datei zum Lesen und tippt die Zeilen ein. Bei der Ausgabeumlenkung öffnet die Shell die Datei zum Schreiben und verschiebt die Ausgabe in diese Datei. Die pipe kann man sich als temporäre Datei vorstellen, in die das eine Programm schreibt und aus der das nächste Programm liest, wenngleich der Mechanismus natürlich effizienter gelöst ist.

Wichtige Kommandos

Fast alle Befehle oder Programme erlauben die Option -h-help (ein Minus) oder –help (zwei Minus) und geben dann eine Kurzhilfe aus.
ls [optionen] [path]...
Anzeigen des Inhalts von Verzeichnissen. Die wichtigsten Optionen sind: -l um alle Informationen (langes Format) anzuzeigen, -a um alle Dateien anzuzeigen (auch die versteckten)
cp src... dest
Kopieren von Dateien. Hat cp mehr als zwei Parameter, so muss der letzte Parameter ein Verzeichnis sein.
Mit der Option -r können rekursiv ganze Verzeichnisbäume kopiert werden.
mv src... dest
Umbenennen/Verschieben von Dateien (move). Hat mv mehr als zwei Parameter, so muss der letzte Parameter ein Verzeichnis sein.
rm list...
Löschen von Dateien (remove).
Mit der Option -r können rekursiv ganze Verzeichnisbäume gelöscht werden (VORSICHTrm -rf * löscht alles innerhalb und unterhalb des aktuellen Verzeichnises).
mkdir list...
Erstellen von Verzeichnissen.
cd [path]
Wechsel in das angegebene Verzeichnis. Wird kein Parameter angegeben, so wird ins Home-Verzeichnis gewechselt.
rmdir list...
Löschen von Verzeichnissen (nur leere Verzeichnisse).
cat [list...]
Ausgeben der angegebenen Dateien (die angegebenen Dateien werden auf diese Weise verkettet, da sie unmittelbar hintereinander ausgegeben werden)
less [list...]
Seitenweise Ausgabe der angegebenen Dateien
tar czf archiv.tgz list...
Ein komprimiertes Archiv mit dem Namen archiv.tgz aus den Dateien/Verzeichnissen list… erzeugen
tar xzf archiv.tgz
Das Archiv wieder auspacken
tar tzf archiv.tgz
Den Inhalt des Archivs ausgeben. tar bietet noch viel mehr Optionen und Möglichkeiten und war ursprünglich ein Programm zur Datensicherung auf Bänder (tape archiver).
file list...
gibt die Dateitypen aus. Unter UNIX haben die Datei-Endungen nicht die Bedeutung wie unter Windows, oft kann die Endung beliebig gewählt werden. Das Programm file öffnet nun die angegebenen Dateien und versucht aufgrund des Inhalts den Typ zu ermitteln.
touch list...
ändert die Zugriffszeit der angegebenen Dateien oder erzeugt diese, wenn sie nicht existieren (Dateien mit der Länge 0).
grep suchbegriff [list...]
Sucht den Suchbegriff in den gegebenen Dateien oder Standardeingabe (Eintippen oder Eingabeumlenkung). Wenn nur der Dateiname gesucht ist, der den Suchbegriff enthält, dann ist die Option -l anzugeben. Der Suchbegriff kann aus regulären Ausdrücken bestehen, wodurch man komplexe Suchmuster angeben kann. Zu beachten ist allerdings, dass viele Sonderzeichen für reguläre Ausdrücke, eine spezielle Bedeutung in der Shell haben. Sie müssen daher maskiert werden, z.B. mit vorangestelltem \ oder unter einfache Hochkomma ('). Mehr dazu unter man grep bzw. man bash.
ps
Prozessstatus, listet alle Prozesse auf, die in dieser Shell gestartet wurden.
ps axu
listet alle Prozesse, aller User plus Zusatzinformationen auf. Die erste Spalte enthält den Usernamen, die zweite Spalte die Prozess-ID (PID) und die letzte Spalte den genauen Befehl.
kill [signal] pid...
Schickt den angegebenen Prozessen das TERM-Signal (Terminieren). Die wichtigen Signale sind:
-TERM-KILL (tötet den Prozess auf alle Fälle)
killall [signal] name...
Schickt den angegebenen Prozessen das TERM-Signal (Terminieren). Die Prozesse werden durch den Befehlsnamen name (aufgerufenes Kommando) ausgewählt.
Will man z.B. alle mozilla-Prozesse killen, gibt man killall mozilla ein.
sort [list...]
gibt die Zeilen der angegebenen Dateien sortiert aus (bzw. die Zeilen der Standardeingabe).
uniq [eingabedatei] [ausgabedatei]
löscht doppelte Zeilen aus einer sortierten Eingabe.

Fortgeschrittenes

Es gibt mehrere Möglichkeiten, aus der Ausgabe eines Programms Argumente für die Kommandozeile zu machen.
  1. Backticks:
    $ ls `echo $HOME`
    Hier wird zunächst der Befehl echo $HOME ausgeführt und dessen Ausgabe wird zum Argument des Befehls ls (das Home-Verzeichnis wird aufgelistet).
  2. xargs
    Das ist ein Programm, das von der Standardeingabe zeilenweise liest und jede Zeile als ein Kommandozeilenargument an das xargs übergebene Programm übergibt. Obiges Beispiel kann man also auch so schreiben:
    echo $HOME|xargs ls

Hilfe

UNIX-Systeme werden normalerweise mit ausführlicher Online-Dokumentation ausgeliefert. Die Standarddokumentation entspricht den gedruckten Handbüchern und ist in mehrere Abschnitte eingeteilt:
1 Ausführbare Programme oder Shellbefehle
2 Systemaufrufe (Kernelfunktionen)
3 Bibliotheksaufrufe (Funktionen in System-Bibliotheken)
4 Spezielle Dateien (gewöhnlich in /dev)
5 Dateiformate und Konventionen, z. B. /etc/passwd
6 Spiele
7 Makropakete und Konventionen, z. B. man(7), groff(7)
8 Systemadministrationsbefehle (in der Regel nur für root)
9 Kernelroutinen [Nicht Standard]
n neu [veraltet]
l lokal [veraltet]
p öffentlich [veraltet]
o alt [veraltet]
Zu jedem Befehl (Thema) gibt es eine Seite (können auch mehrere Seiten sein) mit dem Namen des Befehls (Themas). Will man eine bestimmte Seite des Manuals lesen, so verwendet man den Befehl man (manual):
man [abschnitt] seite
Wird abschnitt weggelassen, so zeigt man die passende Seite mit der niedrigsten Abschnittsnummer an. Oft gibt es zu einem Thema in mehreren Abschnitten eine Seite. Dann muss der gewünschte Abschnitt angegeben werden.
Beispiele:
man manHilfe zu man
man bashHilfe zur bash
man tarHilfe zu tar
man printfHilfe zu printf der Shell
man 3 printfMeist will man aber Hilfe zur C-Funktion printf
Oft weiß man nicht genau, welche Manualseite man braucht. Mit man -k schlüsselwort kann man nach Schlüsselworten suchen lassen. Die Ausgabe ist eine Liste der Befehle, auf die das Schlüsselwort zutrifft.
apropos schlüsselwort sucht nach Schlüsselworten in der Indexdatenbank der Manualseiten.
Für GNU-Programme hat sich die Dokumentation im info-Format eingebürgert:
info seite

Weitere Informationen

Fragen

1. Was ist eine Shell?
2. Geben Sie Beispiele verschiedener Shells!
3. Wie wird die Eingabe von langen Pfaden bei der bash erleichtert?
4. Welche Möglichkeiten gibt es frühere Befehle wieder zu verwenden? Nennen Sie 3 Arten!
5. Wie können in einer Shell mehrere Programme so gestartet werden, dass sie gleichzeitig laufen?
6. Wie funktioniert Job-Control? Was ist der Zweck?
7. Was sind Shell-Variable? Nennen Sie zwei Beispiele für die Verwendung!
8. Wie sieht die allgemeine Befehlssyntax aus?
9. Welche Bedeutung hat das Symbol ~ ?
10. Was können Sie tun, damit Sie statt ls das Kommandos dir verwenden können?
11. Was müssen Sie tun, damit dir auch beim nächsten Mal wieder funktioniert?
12. Was können Sie tun, wenn ein Programm keine Dateien lesen/schreiben kann, Sie aber mit diesem Programm dennoch Dateien bearbeiten wollen?
13. Sie haben 3 Dateien adr1adr2 und adr3, welche Zeilen mit Namen und e-Mail-Adressen enthalten. Eine Zeile hat die Form name vorname email. Die Einträge sind nicht sortiert. Manche Namen kommen nur in einer Datei vor, andere in mehreren Dateien. Geben Sie die Kommandozeile an, die alle 3 Dateien verknüpft, sortiert, die doppelten Namen löscht und in die Datei adr ausgibt. Welcher Mechanismus muss hier verwendet werden?
14. Sie haben ein Programm myprog gestartet, welches hängen geblieben ist. Welche Möglichkeiten haben Sie, das Programm zu beenden?
15. Sie wollen wissen, welche C- oder Java-Datei im aktuellen Verzeichnis die Funktionlongjmp enthält. Geben Sie das Kommando an! Was passiert hier genau?
16. Sie wissen nicht genau, wie Befehl zum Archivieren/Zippen von Dateien heißt. Wie finden Sie die Information?

Labels: ,


Montag, 16. September 2013

 

Python - suchen und ersetzen einzelner Zeichen

Sie wollen in einem String zum Beispiel alle Dollar-Zeichen ($) durch Euro (€), alle Fragezeichen (?) durch Rufzeichen (!), einfache Hochkomma (') durch doppelte Hochkomma (") ersetzen und eckige Klammern ([ und ]) löschen.

Definieren Sie eine Übersetzungstabelle (Dictionary) und verwenden Sie die Methode str.translate(table)).

translation_table = {
    "$": "€",
    "?": "!",
    "'": '"',
    "[": None,
    "]": None
}

teststring = """Das ist ein Test? Der kostet ['1000$']"""
print(teststring.translate(str.maketrans(translation_table)))

Folgendes wird dann ausgegeben:

hp@if211l $ python3
Python 3.2.3 (default, Apr 10 2013, 06:11:55) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> translation_table = {
...     "$": "€",
...     "?": "!",
...     "'": '"',
...     "[": None,
...     "]": None
... }
>>>
>>> teststring = """Das ist ein Test? Der kostet ['1000$']"""
>>> print(teststring.translate(str.maketrans(translation_table)))
Das ist ein Test! Der kostet "1000€"
>>>

str.maketrans(table) erzeugt ein Dictionary mit den Unicode-Werten der Zeichen.

Tatsächlich können Sie einzelne Zeichen sogar durch ganze Strings ersetzen. Wenn Sie zB. Umlaute durch die entsprechenden HTML-Sequenzen ersetzen wollen, dann können Sie eine Tabelle wie folgt verwenden:

translation_table = {
    "Ä": "&Auml;",
    "ä": "&auml;",
    "Ö": '&Ouml;',
    "ö": "&ouml;",
    "Ü": "&Uuml;",
    "ü": "&uuml;"
}

>>> translation_table = {
...     "Ä": "&Auml;",
...     "ä": "&auml;",
...     "Ö": '&Ouml;',
...     "ö": "&ouml;",
...     "Ü": "&Uuml;",
...     "ü": "&uuml;"
... }
>>> "Übermäßig".translate(str.maketrans(translation_table))
'&Uuml;berm&auml;ßig'
>>> 

Labels:


Mittwoch, 11. September 2013

 

Android Sudoku (POS1: 4BHIF)

Abgabename: 2013_4bhif_aufgabe1_name_vorname.zip (oder .tgz)

Programmieren Sie ein einfaches Sudoku, welches etwa wie folgt aussieht:
Im einfachsten Fall soll eine fixe Anzahl von Sudokus angeboten werden. Im schwierigsten Fall sollen Sudokus generiert werden oder von einer Webseite geladen werden können.

Labels: , , ,


Sonntag, 8. September 2013

 

Wiederholung Python (POS1: 2BHIF)

Abgabename: 2013_2bhif_aufgabe1_Name_Vorname.tgz

Die folgenden Aufgaben ermöglichen Ihnen einen Wiedereinstieg in das Programmieren mit Python. Das Rüstzeug zur Lösung sollten Sie in der ersten Klasse bekommen haben.
Googlen Sie nach 'python "reference card"' und suchen Sie eine passende Kurzreferenz.
  1. Schreiben Sie eine Funktion input_sentences in einem Modul text_analyzer, die den Benutzer nach beliebigen Sätzen fragt, diese in einer Liste abspeichert und danach zurückliefert. Das könnte also so aussehen:
    Bitte geben Sie die zu analysierenden Sätze ein (CTRL-D bricht ab):
    Satz: Maxi und Mini verliefen sich im Wald, aber bald.
    Satz: 10 alte Fledermäuse flogen im Wald
    Satz: Hat die alte Meisterhexe...
    Satz: Seid's gewesen. Denn als Geister...
    Satz: Erst hervor der alte Meister.
    Satz: <ctrl-d>
    
    CTRL-D bewirkt ein Ende der Eingabe (EOF ... End Of File).
  2. Fügen Sie dazu in diesem Modul einen Aufruf dieser Funktion ein, sodass das Modul sowohl als Modul als auch als Programm verwendet werden kann. Dies macht man üblicherweise folgendermaßen:
    # prüft, ob das Modul als Programm aufgerufen wurde
    if __name__ == '__main__': # main
        lst = input_sentences()
    

  3. Schreiben Sie eine Funktion split_sentences(lst), die eine Liste solcher Sätze bekommt und eine Liste von Wortlisten zurückliefert, wobei die übergebene Liste lst direkt verändert werden soll.

    Die Wortlisten entstehen indem man die Sätze an den Whitespace Zeichen und den Satzzeichen ("',;.:-) trennt. Die Satzzeichen werden nicht benötigt.

    Gehen Sie dazu folgendermaßen vor:
    1. Ersetze zuerst alle Satzzeichen hintereinander durch Leerzeichen. Verwende dazu die replace Methode des Typs str.
    2. Trenne (splitte) danach den String in die einzelnen Wörter mittels der Methode split des Typs str.
    Für die obigen Daten sieht das Ergebnis dieses Funktionsaufrufes folgendermaßen aus:
    >>> lst = ['Maxi und Mini verliefen sich im Wald, aber bald.',
    ... '10 alte Fledermäuse flogen im Wald',
    ... 'Hat die alte Meisterhexe...',
    ... "Seid's gewesen. Denn als Geister...",
    ... 'Erst hervor der alte Meister.']
    >>> split_sentences(lst)
    [['Maxi', 'und', 'Mini', 'verliefen', 'sich', 'im', 'Wald',\
    'aber', 'bald'], ['10', 'alte', 'Fledermäuse', 'flogen', 'im', 'Wald'],\
    ['Hat', 'die', 'alte', 'Meisterhexe'], ['Seid', 's', 'gewesen', 'Denn',\
    'als', 'Geister'], ['Erst', 'hervor', 'der', 'alte', 'Meister']]
    >>> lst
    [['Maxi', 'und', 'Mini', 'verliefen', 'sich', 'im', 'Wald',\
    'aber', 'bald'], ['10', 'alte', 'Fledermäuse', 'flogen', 'im', 'Wald'],\
    ['Hat', 'die', 'alte', 'Meisterhexe'], ['Seid', 's', 'gewesen', 'Denn',\
    'als', 'Geister'], ['Erst', 'hervor', 'der', 'alte', 'Meister']]
    
    Bei der obigen Ausgabe wurden zur besseren Lesbarkeit die Zeilen manuell umgebrochen und der Zeilenumbruch jeweils mit einem \ gekennzeichnet.

    Baue diese Funktion in das Hauptprogramm ein.

  4. Schreiben Sie eine Funktion purge_bad_words(lst), die eine Liste von Listen von Wörtern erhält und alle diejenigen herauslöscht, die
    • weniger als 2 Zeichen lang sind oder
    • nicht alphabetische Zeichen enthalten
    Die übergebene Liste lst soll direkt manipuliert und auch zurückgeliefert werden:
    >>> purge_bad_words(lst)
    [['Maxi', 'und', 'Mini', 'verliefen', 'sich', 'im', 'Wald', 'aber',\
    'bald'], ['alte', 'Fledermäuse', 'flogen', 'im', 'Wald'], ['Hat',\
    'die', 'alte', 'Meisterhexe'], ['Seid', 'gewesen', 'Denn', 'als',\
    'Geister'], ['Erst', 'hervor', 'der', 'alte', 'Meister']]
    
    Wie leicht zu sehen sind sind die zu kurzen Wörter und die Wörter, die nicht-alphabetische Zeichen enthalten entfernt worden.

  5. Schreiben Sie eine Funktion analyze_words(lst), die eine Liste wie aus dem vorhergehenden Punkt als Argument bekommt und ein Dictionary mit allen Worten als Keys und deren Häufigkeiten als Values zurückliefert, wobei aber alle Wörter nur klein geschrieben gezählt werden:
    >>> analyze_words(lst)
    {'wald': 2, 'mini': 1, 'aber': 1, 'gewesen': 1, 'flogen': 1, 'im': 2,\
    'hervor': 1, 'als': 1, 'verliefen': 1, 'maxi': 1, 'sich': 1,\
    'meister': 1, 'hat': 1, 'bald': 1, 'meisterhexe': 1, 'erst': 1,\
    'fledermäuse': 1, 'geister': 1, 'die': 1, 'alte': 3, 'und': 1,\
    'denn': 1, 'seid': 1, 'der': 1}
    

  6. Schreiben Sie eine Funktion analyze_letters(lst), die wiederum eine Liste der Liste der Wörter bekommt und ein Dictionary mit Buchstaben als Keys und deren Häufigkeiten als Values zurückliefert. Wiederum werden alle Buchstaben als Kleinbuchstaben betrachtet:
    >>> analyze_letters(lst)
    {'a': 10, 'c': 1, 'b': 2, 'e': 28, 'd': 9, 'g': 3, 'f': 3, 'i': 12,\
    'h': 4, 'm': 7, 'l': 10, 'o': 2, 'n': 7, 's': 9, 'r': 10, 'u': 2,\
    't': 8, 'w': 3, 'v': 2, 'x': 2, 'ä': 1}
    

  7. Schreiben Sie nun eine Funktion purge_analyzed_letters(dic), die alle Umlaute (ä, ü, ö) aus dem Dictionary (des vorhergehenden Punktes) entfernt:
    >>> purge_analyzed_letters(dic)
    {'a': 10, 'c': 1, 'b': 2, 'e': 28, 'd': 9, 'g': 3, 'f': 3, 'i': 12,\
    'h': 4, 'm': 7, 'l': 10, 'o': 2, 'n': 7, 's': 9, 'r': 10, 'u': 2,\
    't': 8, 'w': 3, 'v': 2, 'x': 2}
    

  8. Entwicklen Sie eine Funktion sort_letters(dic), die ein Dictionary wie aus dem vorhergehenden Punkt bekommt und eine absteigend sortierte Liste von Tupel mit Buchstabe und Häufigkeit zurückliefert:
    >>> sort_letters(dic)
    [('e', 28), ('i', 12), ('a', 10), ('l', 10), ('r', 10), ('d', 9),\
    ('s', 9), ('t', 8), ('m', 7), ('n', 7), ('h', 4), ('g', 3), ('f', 3),\
    ('w', 3), ('b', 2), ('o', 2), ('u', 2), ('v', 2), ('x', 2), ('c', 1)]
    

  9. Probieren Sie aus:
    1. "abcdef".index("c")
    2. "abcdef".index("g")
    3. "abcdef".index("de")
    4. "c" in "abcdef"
    5. "g" in "abcdef"
    6. "de" in "abcdef"
    7. "abcdef"[2:4]
    8. "abcdef"[2:]
    9. "abcdef"[-1]
    10. "abcdef"[2:-1]
    11. [1, 2, 3, 4, 5].index(3)
    12. [1, 2, 3, 4, 5].index(9)
    13. [1, 2, 3, 4, 5][5]
    14. [1, 2, 3, 4, 5][2:4]
    15. [1, 2, 3, 4, 5][-2]
    16. [1, 2, 3, 4, 5][5:9]
    17. [1, 2, 3, 4, 5][4:]
    18. len("abc") + len(range(3)) + len({1, 2, 3}) + len({1: 2, 2: 3})

    Speichern Sie die Aufrufe und das Ergebnis in einer Datei log.txt, welche Sie dann mit abgeben.

  10. Bauen Sie in ihr Main Testaufrufe aller Funktionen mit einer fixen Liste auf (Kommentieren Sie den Aufruf von input_sentences() aus). Es soll jedes Stadium der Verarbeitung der Liste ausgegeben werden. Bauen Sie die Aufrufe aus obigem Punkt (Probieren Sie aus) ein und geben Sie das Ergebnis aus. Man muss den Programmcode (print() verwenden) sehen und das Ergebnis.

  11. Geben Sie das Beispiel ab, indem Sie text_analyzer.py und log.txt in ein Archiv mit dem Namen Abgabename: 2013_2bhif_aufgabe1_Name_Vorname.tgz (Name ist Ihr Familienname und Vorname ist Ihr Vorname, wobei Sie Umlaute und scharfes s durch ASCII-Zeichen ersetzen müssen, also z.B. 2013_2bhif_aufgabe1_grossauer_guenter.tgz für Günter Großauer) packen und diese Datei auf dem edvossh.htlwrn.ac.at nach /home/teachers/hp/abgabe/2bhif/ kopieren.
    Beachten Sie, dass Sie das oben angegebene Verzeichnis nicht lesen können, Sie können in dieses Verzeichnis wohl aber schreiben.
    Denken Sie an den Header, der etwa so aussehen muss:
    """
    author: Großauer, Günter
    matnr:  i09666
    file:   bubblesort.py
    desc:   sort lists with bubblesort
    date:   2013-09-08
    class:  2bhif
    catnr:  33
    """
    


Das Original zu dieser Aufgabe stammt von Dr. Kolousek.

Labels: , ,


This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]