9
Běžné úlohy

### Datové struktury a práce s nimi

novy = {}
for klic in stary.keys():
    novy[klic] = stary[klic]

novy = stary.copy()

for klic in novejsi.keys():
    starsi[klic] = novejsi[klic]

def doplnitBezPrepisu(starsi, novejsi):
    S = starsi.copy()
    for klic in novejsi.keys():
        if klic in starsi.keys():
            raise ValueError, "slovníky sdílí klíče."
        S[klic] = novejsi[klic]
    return S

def doplnitNaNtice(starsi, novejsi):
    S = starsi.copy()
    for klic in novejsi.keys():
        if klic in starsi.keys():
            S[klic] = starsi[klic], novejsi[klic]
        else:
            S[klic] = novejsi[klic]
    return S

>>> import copy
>>> prvni = [{"cosi": 1, "neco": 2}, 3]
>>> obycejna = prvni[:]  # nebo obycejna=copy.copy(puvodni)
>>> rekurzivni = copy.deepcopy(prvni)
>>> prvni.append("kyhoslaka")
>>> prvni[0]["cosi"] = "nic moc"
>>> print prvni, obycejna, rekurzivni
[{'neco': 2, 'cosi': 'nic moc'}, 3, 'kyhoslaka']
[{'neco': 2, 'cosi': 'nic moc'}, 3]
[{'neco': 2, 'cosi': 1}, 3]

seznam = list(ntice)
seznam.sort()  
for x in seznam: print x     # nebo cokoli dalšího

klice = slovnik.keys()               # nesetříděné keys
klice.sort()                         #  zkopírujeme a setřídíme
for x in klice: print x, slovnik[x]

>>> def bezVelikosti(a, b):
...     from string import lower
...     return cmp(lower(a), lower(b))
...
>>> seznam = list('FDecaB')
>>> seznam.sort()
>>> print seznam
['B', 'D', 'F', 'a', 'c', 'e']
>>> seznam.sort(bezVelikosti)
>>> print seznam
['a', 'B', 'c', 'D', 'e', 'F']

import random
while seznam:  # dokud není prázdný
    prvek = random.choice(seznam)
    seznam.remove(prvek)
    print prvek,

class Zasobnik:
    def __init__(self, data):
        self._data = list(data)
    def uloz(self, x):
        self._data.append(x)
    def vyjmi(self):
        x = self._data[-1]
        del self._data[-1]
        return x

>>> ukole = Zasobnik(['napsat mamce', 'pozvat Honzu na jedno',
... 'dát prát košile'])
>>> ukole.uloz('umýt nádobí')
>>> ukole.vyjmi()
umýt nádobí
>>> ukole.vyjmi()
dát prát košile

from UserList import UserList  # třídu z modulu

class Zasobnik(UserList):      # dědíme z UserList
    uloz = UserList.append
    def vyjmi(self):
        x = self[-1]           # používá __getitem__
        del self[-1]           #  a __delitem__
        return x

>>> ukole = Zasobnik(['napsat mamce', 'pozvat Honzu na jedno',
... 'dát prát košile'])
>>> print ukole
['napsat mamce', 'pozvat Honzu na jedno', 'dát prát košile']
>>> ukole.vyjmi()
'dát prát košile'
>>> ukole.uloz('vyměnit olej')
>>> for ukol in ukole:          # for .. in .. = __getitem__
...     print ukol
...
napsat mamce
pozvat Honzu na jedno
vyměnit olej


### Práce se soubory

% cat pocetr.py

import sys
data = sys.stdin.readlines()
print "Počet řádků:", len(data)

% cat pocetr.py | python pocetr.py

Počet řádků: 3

C:\Python> type pocetr.py | python pocetr.py

Počet řádků: 3

import sys
for radka in sys.stdin.readlines():
    if radka[0] == '#': print radka,

import sys, string
for radka in sys.stdin.readlines():
    slova = string.split(radka)
    if len(slova) >= 4: print slova[3]

    try: print words[3]
    except IndexError: pass

import sys, string
for radka in sys.stdin.readlines():
    slova = string.split(radka, ':')
    if len(slova) >= 4: print string.lower(slova[3])

import sys, string
radky = sys.stdin.readlines()
sys.stdout.writelines(radky[:10])         # prvních deset
sys.stdout.writelines(lines[-10:])        # posledních deset
for kolikata in range(0, len(radky), 2):  # tedy 0, 2, 4, ...
    sys.stdout.write(radky[kolikata])

import string
text = open(jmenoSouboru).read()
print string.count(text, 'Python')

Jméno:   Honza  Petr  Radka  Pavel  Mary   Ahmed
Úroveň:    5     4      3      1     6       4   
Počet:    1324  4551  5515   5124  1881   5132

Jméno:  Úroveň:  Počet:
Honza   5        1234
...

import sys, string
radky = sys.stdin.readlines()
seznamySlov = []

for radky in radky:
    slova = string.split(radka)
    seznamySlov.append(slova)

for radek in range(len(seznamySlov[0])):
    for sloupec in range(len(seznamySlov)):
        print seznamySlov[sloupec][radek] + '\t',
    print

while 1:
    dalsi = sys.stdin.read(1)  # znak po znaku
    if not dalsi: break        # prázdný řetězec => konec
    Něco dál s dalsi

while 1:
    dalsi = sys.stdin.readline()  # řádku po řádce
    if not dalsi: break
    Něco dál s dalsi

% python skript.py vstup1.txt vstup2.txt vstup3.txt vystup.txt

import sys

vstupniJmena, vystupJmeno = sys.argv[1:-1], sys.argv[-1]
for vstupJmeno in vstupniJmena:
    vstupSoubor = open(vstupJmeno, "r")
    necoSeSouborem(vstupSoubor)
vystupSoubor = open(vystupJmeno, "w")
zapisVysledky(vystupSoubor)

['skript.py', 'vstup1.txt', 'vstup2.txt', 'vstup3.txt', 'vystup.txt']

def necoSeSouborem(vstupSoubor):
    for radka in vstupSoubor.readlines():
        necoSRadkou(radka)

import fileinput
for radka in fileinput.input():
    necoSRadkou(radka)

% cat mujgrep.py

import sys, string, fileinput
hledaneSlovo, sys.argv[1:] = sys.argv[1], sys.argv[2:]
for radka in fileinput.input():
    pocetVyskytu = string.count(line, hledaneSlovo)
    if pocetVyskytu: 
        print "'%s' nalezeno %dx v %s na řádce %d." \
             % (hledaneSlovo, pocetVyskytu, 
                fileinput.filename(), fileinput.filelineno())

% python mujgrep.py in recur1.py recur2.py mujgrep.py

'in' nalezeno 1x v recur1.py na řádce 4.
'in' nalezeno 1x v recur2.py na řádce 3.
'in' nalezeno 2x v mujgrep.py na řádce 1.
'in' nalezeno 3x v mujgrep.py na řádce 3.
'in' nalezeno 1x v mujgrep.py na řádce 4.
'in' nalezeno 1x v mujgrep.py na řádce 6.
'in' nalezeno 3x v mujgrep.py na řádce 8.

% cat prejmen.py

import os, string

if len(sys.argv) == 1: jmena = os.listdir(os.curdir)
else: jmena = sys.argv[1:]  # pokud tam jsou, tak z přík. řádky

for jmeno in jmena:
    if ' ' in jmeno:
        noveJmeno = string.replace(jmeno, ' ', '_')
        print "Přejmenovávám", jmeno, "na", noveJmeno, "..."
        os.rename(jmeno, noveJmeno)

% python prejmen.py *.txt

% cat glob1.py

import sys, glob, operator
print sys.argv[1:]
sys.argv = reduce(operator.add, map(glob.glob, sys.argv))
print sys.argv[1:]

/usr/python/book$ python glob1.py *.py

['mujgrep.py', 'prejmen.py', 'glob1.py']
['mujgrep.py', 'prejmen.py', 'glob1.py']

C:\python\book> python glob1.py *.py

['*.py']
['mujgrep.py', 'prejmen.py', 'glob1.py']

def mojeSkladani(a, b): return a + b

>>> cisla = range(30)
>>> print cisla
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

>>> def suda(x): return x % 2 == 0
...
>>> print filter(suda, cisla)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

import string

slova = string.split(open('soub.txt').read())  # všechna slova
def viceNez10(posl): return len(posl) >= 10 
dlouhaSlova = filter(viceNez10, slova)

radky = open('soub.txt').readlines()
radky = filter(None, radky)             # prázdný -> nepravda

import tempfile
docasny = tempfile.TemporaryFile() # jméno nás nezajímá

vstupni = open('vstup.txt', 'r')
prvniOperace(vstup = vstupni, vystup = docasny)

vystupni = open('output.txt', 'w')
druhaOperace(vstup = docasny, vystup = vystupni)

import os, tempfile

formular = "Dear %s,\nI'm writing to you to suggest that ..."

mujAdresar = [('Bill Clinton', 'bill@whitehouse.gov'),
              ('Bill Gates', 'bill@microsoft.com'),
              ('Bob', 'bob@subgenius.org')]

for jmeno, email in mujAdresar:
    konkretniDopis = formular % jmeno
    docasnyJmeno = tempfile.mktemp()
    docasnySoubor = open(docasnyJmeno, 'w')
    docasnySoubor.write(konkretniDopis)
    docasnySoubor.close()
    os.system(
     '/usr/bin/mail %(email)s -s "Cosi" < %(docasnyJmeno)s' 
     % vars()) #  
    os.remove(docasnyJmeno)

hodnota1 klic1
hodnota2 klic2
hodnota3 klic1
...

% cat sberac1.py

#!/usr/bin/env python
import sys, string

polozky = {}

for radka in open(sys.argv[1], 'r').readlines():
    leva, prava = string.split(radka)
    try: polozky[prava].append(leva)
    except KeyError: polozky[prava] = [leva]  # poprvé 

for (prava, leve) in polozky.items():
    print "%04d x '%s'\t - %s" % (len(leve), prava, leve)

    if entries.has_key(right): entries[right].append(left)
    else: entries[right] = [left]  # poprvé

% cat data.txt

1 jedna
2 jedna
3 dva
7 tri
8 dva
10 jedna
14 tri
19 tri
20 tri
30 tri

% python sberac1.py data.txt

0005 x 'tri'	 - ['7', '14', '19', '20', '30']
0002 x 'dva'	 - ['3', '8']
0003 x 'jedna'	 - ['1', '2', '10']

% cat sberac2.py

#!/usr/bin/env python
import sys, string

def sbirej(soubor):
    polozky = {}
    for radka in soubor.readlines():
        leva, prava = string.split(radka)
        try: polozky[prava].append(leva)
        except KeyError: polozky[prava] = [leva]
    return polozky

if __name__ == "__main__":
    if len(sys.argv) != 2: vysl = sbirej(sys.stdin)
    else: vysl = sbirej(open(sys.argv[1], 'r'))
    for (prava, leve) in vysl.items():
        print "%04d položky '%s'\t => %s" % \
        (len(leve), prava, leve)

% sberac2.py < data.txt

from sberac2 import sbirej
vysl = sbirej(open("soub.txt", "r"))

>>> from sberac2 import sbirej
>>> from StringIO import StringIO
>>> s = StringIO("1 jedna\n2 jedna\n3 dva")
>>> vysl = sbirej(s)
>>> print vysl
{'dva': ['3'], 'jedna': ['1', '2']}

### Práce s programy

for datovy in ['data.001', 'data.002', 'data.003']:
   for parametr1 in range(1, 10):
      os.system("analyzuj -in %(datovy)s \
                 -param1 %(parametr1)d" % vars())

% cat tabulatory.py

#!/usr/bin/env python
# prochází soubory, nahrazuje tabulátory za mezery

import string, os

# find je na Unixu běžně dostupný 
prikaz = 'find . -name "*.py" -print'

for soubor in os.popen(prikaz).readlines():
    x = 1
    jmeno = soubor[:-1]                        # ořízneme \n
    for radka in open(jmeno).readlines():
        kde = string.find(radka, "\t")
        if kde >= 0:
            print jmeno, x, kde 
            print '....', radka[:-1]           # [:-1] ořízne \n
            print '....', ' '*kde + '*', '\n'
        x += 1

C:\python> python tabulatory.py

./nezbedneprstiky.py 2 0
....   for i in range(10):
.... *
./happyfingers.py 3 0
....           print "oops..."
.... *
./happyfingers.py 5 5
.... print     "co to je za styl, proboha?"
....      *

if sys.platform == "win32":  # jsme na Windows
    try:
        import win32pipe
        popen = win32pipe.popen
    except ImportError: 
        raise ImportError, "modul win32pipe nenalezen."
else:                        # POSIX
    import os
    popen = os.popen
... něco dál ...

### Něco s Netem

% cat teploty.py

import urllib, urlparse, string, time

def jakaJeTeplota(zeme, stat, mesto):
    url = \
     urlparse.urljoin('http://www.weather.com/weather/cities/',
     string.lower(zeme)+'_' + string.lower(stat) + '_' + \
     string.replace(string.lower(mesto), ' ', '_') + '.html')
    data = urllib.urlopen(url).read()
    zacatek = string.index(data, 'current temp: ') \
             + len('current temp: ')
    konec = string.index(data, '&deg;F', start-1)
    teplota = int(data[start:stop]) 
    cas = time.asctime(time.localtime(time.time()))
    print ("%(cas)s: Teplota v '%(mesto)s, %(stat)s %(zeme)s'" \
         + " je %(teplota)s F.") % vars()

jakaJeTeplota('FR', '', 'Paris')
jakaJeTeplota('US', 'RI', 'Providence')
jakaJeTeplota('US', 'CA', 'San Francisco')

% python teploty.py

Teplota v 'Paris, FR' je 39 F.
Teplota v 'Providence, RI US' je 39 F.
Teplota v 'San Francisco, CA US' je 58 F.

>>> from poplib import *
>>> server = POP3('mailserver.spam.org')
>>> print server.getwelcome()
+OK QUALCOMM Pop server derived from UCB (version 2.1.4-R3) at spam starting.
>>> server.user('da')
'+OK Password required for da.'
>>> server.pass_('neuhodnutelne')
'+OK da has 153 message(s) (458167 octets).'
>>> header, msg, octets = server.retr(152)  # poslední zpráva
>>> import string
>>> print string.join(msg[:2], '\n')        # první 2 řádky
Return-Path: <jim@bigbad.com>
Received: from m.bigbad.com by mailserver.spam.org (4.1/SMI-4.1)

### Větší příklady

% cat uroky.py

vypis = 1  # výpis pro každý rok?

def uroc(vklad, urok, roky):
    for r in range(roky):
        vklad *= (1.00 + (urok / 100.0))
        if vypis: print '%s: %.2f' % (r+1, vklad),
    return vklad

% python

>>> from uroky import uroc
>>> uroc(10000, 5, 10)
1: 105000.00 2: 110250.00 3: 115762.50 4: 121550.63 5: 127628.16 6: 134009.56 7: 140710.04 8: 147745.54 9: 
155132.82 10: 162889.46

>>> import uroky
>>> uroky.vypis = 0
>>> uroc(100000, 5, 10)
162889.462678

def uroc(vklad, urok, roky):
    urok = urok / 100.0
    for r in range(roky):
        uroky = vklad * urok
        vklad += uroky
        if vypis: print r+1, '(+%d)' % uroky, '=> %.2f' % vklad
    return vklad

>>> uroky.vypis = 1
>>> uroc(100000, 5, 10)
1 (+5000) => 105000.00
2 (+5250) => 110250.00
3 (+5512) => 115762.50
4 (+5788) => 121550.63
5 (+6077) => 127628.16
6 (+6381) => 134009.56
7 (+6700) => 140710.04
8 (+7035) => 147745.54
9 (+7387) => 155132.82
10 (+7756) => 162889.46
162889.462678

% cat ven

#!/usr/bin/env python
# hledá volný modem(y), vytáčí pomocí kermitu

import glob, os, string
ZAMKY = "/var/spool/locks/"  # kde najdeme “zámky” 

zamcene = [0] * 10  # “zamčené”, obsazené modemy
for jmeno in glob.glob(ZAMKY + "LCK*modem*"):  # obsazené
    print '”Zámek”:', jmeno
    zamcene[string.atoi(jmeno[-1])] = 1  # číslice na konci

print 'Volné jsou: ',
for i in range(10):
    if not zamcene[i]: print i,
print

for i in range(10):
   if not zamcene[i] and raw_input("Zkusit č. %d? " % i) == 'a':
      os.system("kermit -m hayes -l /dev/modem%d -b 19200 -S"%i)
      if raw_input("Hledat další?") != 'a': break

Vítejte v našem malém adresáři!
Kamarádi: help

Dokumentované příkazy (help <příkaz>): 
=======================================
EOF             hledej          nacti           pridej          uloz            vypis           

Nedokumentované příkazy: 
=========================
help            

Kamarádi: help hledej
Hledá záznam (hledej <jméno>)

Kamarádi: pridej
Jméno: Petr
telefon? 05/59263141

Kamarádi: pridej Honza
telefon? 02/31415926

Kamarádi: vypis
=========================================
               Honza : 02/31415926         
                Petr : 05/59263141         
=========================================

Kamarádi: hledej Jakub
Záznam pro 'Jakub' nenalezen.

Kamarádi: uloz telefony
Kamarádi: ^D

Kamarádi: vypis

Kamarádi: nacti telefony

Kamarádi: vypis
=========================================
               Honza : 02/31415926         
                Petr : 05/59263141         
=========================================

% cat adresar.py

#!/usr/bin/env python
# interaktivní adresář

# na Unixu není od věci readline
import string, sys, pickle, cmd

class Adresar(cmd.Cmd):

    def __init__(self):
        cmd.Cmd.__init__(self)  # konstruktor mateřské tř.
        self.prompt = "Kamarádi: "
        self.intro = "Vítejte v našem malém adresáři!"
        self.doc_header = "Dokumentované příkazy " \
                         + "(help <příkaz>): "
        self.undoc_header = "Nedokumentované příkazy: "
        self.kamaradi = {}

    def help_pridej(self):
        print "Přidá nový záznam (pridej <jméno>)"
    def do_pridej(self, jmeno):
        if jmeno == "": jmeno = raw_input("Jméno: ")
        tel = raw_input("telefon? ")
        self.kamaradi[jmeno] = tel

    def help_hledej(self):
        print "Hledá záznam (hledej <jméno>)"
    def do_hledej(self, jmeno):
        if jmeno == "": jmeno = raw_input("Jméno: ")
        if self.kamaradi.has_key(jmeno):
            print "Telefon je %s." % (self.kamaradi[jmeno],)
        else:
            print "Záznam pro '%s' nenalezen." % (jmeno,)

    def help_vypis(self):
        print "Vypíše obsah našeho adresáře"
    def do_vypis(self, line):
        jmena = self.kamaradi.keys()        # klíče slovníku
        if jmena == []: return              # je sovník prázdný?
        jmena.sort()                        # setřídíme
        print '='*41
        for jmeno in jmena:
            print string.rjust(jmeno, 20), ":", \
                  string.ljust(self.kamaradi[jmeno], 20)
        print '='*41

    def help_EOF(self):
        print "Ukončí program"
    def do_EOF(self, line):
        sys.exit()

    def help_uloz(self):
        print "Uloží náš adresář (uloz <soubor>)"
    def do_uloz(self, jmeno):
        if jmeno == "": jmeno = raw_input("Do souboru: ")
        soub = open(jmeno, 'w')
        pickle.dump(self.kamaradi, soub)

    def help_nacti(self):
        print "Načte adresář ze souboru (nacti <soubor>)"
    def do_nacti(self, jmeno):
        if jmeno == "": jmeno = raw_input("Ze souboru: ")
        soub = open(jmeno, 'r')
        self.kamaradi = pickle.nacti(soub)  # přepíše kamaradi!     

if __name__ == '__main__':  # takhle může fungovat i jako modul
    adresar = Adresar()
    adresar.cmdloop()

### Cvičení