Archiv rubriky: python

Zjisteni aktualni verejne IP z terminalu a skriptu

Casto je potreba znat verejnou IP adresu, za kterou se PC schovava. Hodne znamy je web http://www.mojeip.cz/ ktery vsak jde pouzit jenom pres webovy prohlizec. Pokud potrebujeme zjistit IP v terminalu, nebo ve skriptu, museli bychom si napsat parser webove stranky. Z lenosti jsem si napsal vlastni skript na zjistovani adresy. Celý příspěvek

Python: kompilace do nativniho kodu platformy

Python je momentalne muj nejoblibenejsi jazyk. Je rychly na prototypovani, umoznuje psat kratke skripty, velke GUI aplikace, webove stranky,…
Jednou z jeho nejvetsich (ne)vyhod je, ze jde o interpretovany jazyk. Tudiz je pomalejsi, nez jazyky kompilovane a kazdy muze videt zdrojovy kod.

Problem se nastesti da relativne snadno vyresit kompilaci.

Nebudu to rozebirat nijak do hloubky. Kdo chce podrobnosti, odkazu ho na pouzite zdroje v zaveru a na Google. Jde pouze o ukazani moznosti.

Prvni ukazka. Jednoduchy program na vypis aktualniho casu. Po spusteni jako samostatny program vypise cas a ukonci se. Pri importu jako modul v pythonu nevypise nic, ceka na zavolani funkce cas().

from datetime import datetime
 
def mojeFunkce(cas):
        print "Je %s hodin." % cas
       
def cas():
    hodiny = datetime.now().strftime('%H:%M:%S')
    mojeFunkce(hodiny)

if __name__ == '__main__':
    print "_RUN_"
    cas()
else:
    print "import"
martin@martin:~$ cython --embed prvni.py
martin@martin:~$ gcc prvni.c -I/usr/include/python2.7 -lpython2.7 -o prvni
martin@martin:~$ s -lh
celkem 172K
-rwxr-xr-x 1 martin martin  48K pro  8 13:03 prvni
-rw-r--r-- 1 martin martin 112K pro  8 13:03 prvni.c
-rw-r--r-- 1 martin martin  268 pro  8 13:02 prvni.py
-rw-r--r-- 1 martin martin  541 pro  8 13:02 prvni.pyc
martin@martin:~$ strip prvni
martin@martin:~$ ls -lh
celkem 164K
-rwxr-xr-x 1 martin martin  37K pro  8 13:03 prvni
-rw-r--r-- 1 martin martin 112K pro  8 13:03 prvni.c
-rw-r--r-- 1 martin martin  268 pro  8 13:02 prvni.py
-rw-r--r-- 1 martin martin  541 pro  8 13:02 prvni.pyc
martin@martin:~$ ./prvni 
_RUN_
Je 13:03:19 hodin
martin@martin:~$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import prvni
>>> prvni.cas()
Je 13:03:33 hodin.
>>>
martin@martin:~$ ldd ./prvni
	linux-vdso.so.1 =>  (0x00007fff957fe000)
	libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f5f68c47000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5f68882000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5f68663000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5f6844a000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5f68246000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f5f68042000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5f67d3c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f5f691db000)
martin@martin:~$ 

 

Prvni prikaz (cython) vegeneruje z pythoniho zdrojoveho kodu C zdrojovy kod. Je tezko clovekem citelny, protoze je generovany. Parametr embed zajisti pridani main() funkce. Cython dokaze generovat C a C++ zdrojaky a pouzivat Python2, nebo Python3.

Pote je mozne vygenerovany C soubor pomoci gcc zkompilovat. Stripnuta binarka ma jenom 37kB.

Pri spusteni jako samotny program (./prvni) vypise _RUN_. Zavislosti (viz vystup ldd) jsou bezne linuxove knihovny plus navic libpython.

 

Druha ukazka je o trochu slozitejsi. Pomoci skvele knihovny requests stahne JSON z meteostanice a vypise aktualni teplotu.

import requests
import json
import time
import sys

try:
    debug = sys.argv[1]
except IndexError:
    debug = 0

def stahniData(debug):
    url = 'http://teplomer.jicin.cz/vystup-json.php'
    headers = {'user-agent': 'Python_test_app/0.0.1'}

    r = requests.get(url, headers=headers)

    odpovedText = r.text
    if debug:
        print odpovedText

    data = json.loads(odpovedText)
    teplota = str(data['teplota'])
    cas = str(data['cas'])

    return teplota, cas

while True:
    print 'Aktualne je {0}C, v {1}.'.format(*stahniData(debug))
    time.sleep(5)

 

martin@martin:~$ cython --embed druhy.py 
martin@martin:~$ gcc druhy.c -I/usr/include/python2.7 -lpython2.7 -O3 -o druhy
martin@martin:~$ ls -lh
celkem 340K
-rwxr-xr-x 1 martin martin  45K pro  8 13:12 druhy
-rw-r--r-- 1 martin martin 125K pro  8 13:12 druhy.c
-rw-r--r-- 1 martin martin  573 pro  8 13:11 druhy.py
martin@martin:~$ strip druhy
martin@martin:~$ ls -lh
celkem 328K
-rwxr-xr-x 1 martin martin  34K pro  8 13:13 druhy
-rw-r--r-- 1 martin martin 125K pro  8 13:12 druhy.c
-rw-r--r-- 1 martin martin  573 pro  8 13:11 druhy.py
martin@martin:~$ file druhy
druhy: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=4afeb4fa92c52bf9bb549e838525ca3416281bb9, stripped
martin@martin:~$ ldd ./druhy
	linux-vdso.so.1 =>  (0x00007fff0e72b000)
	libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f9a35878000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a354b3000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a35294000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f9a3507b000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a34e77000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f9a34c73000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a3496d000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f9a35e0c000)
martin@martin:~$ ./druhy 
Aktualne je 7.1C, v 2015-12-08 13:12:35.
Aktualne je 7.1C, v 2015-12-08 13:12:35.
...
martin@martin:~$ ./druhy 1
{
   "teplota": 7.1,
   "vlhkost": null,
   "cas": "2015-12-08 13:12:35",
   "umisteni": "<a href="http://www.mapy.cz/s/hgUU">Zizkovo nam. 18</a>"
}

Aktualne je 7.1C, v 2015-12-08 13:12:35.
{
   "teplota": 7.1,
   "vlhkost": null,
   "cas": "2015-12-08 13:12:35",
   "umisteni": "<a href="http://www.mapy.cz/s/hgUU">Zizkovo nam. 18</a>"
}

Aktualne je 7.1C, v 2015-12-08 13:12:35.
...
martin@martin:~$

 

Mezi hodne zajimave vyhody kompilace Pythonu patri i mozne zrychleni. Python je dynamicky silne typovany jazyk. Neustale zjistovani a kontrola typu zpusobuje znatelne zpomaleni behu programu. Zvlast u nekterych vypoctu je rozdil obrovsky (proto se na vypocty ma pouzivat NumPy). Proto umoznuje Cython nadefinovat promennym datove typy.

Hodne zajimave je toto PDF. Urcite doporucuji precist. Z neho je take nasledujici ukazka:

def exp(x, terms = 50):
	sum = 0.
	power = 1.
	fact = 1.
	for i in range(terms):
	sum += power/fact
	power *= x
	fact *= i+1
	return sum
# doba behu pro 50 000 - 1,05s
	
def exp(double x, int terms = 50):
	cdef double sum
	cdef double power
	cdef double fact
	cdef int i
	sum = 0.
	power = 1.
	fact = 1.
	for i in range(terms):
	sum += power/fact
	power *= x
	fact *= i+1
	return sum
# doba behu pro 50 000 - 0,042s
# rozdil - 25x

 

Aneb jak se pise na oficialnim webu Cythonu: „Cython is Python with C data types“ (Cython je Python s C datovymi typy).

 

Pouzite zdroje: