Dlouho jsem hledal, jak uzivatelum snadno umoznit psat pluginy do me aplikace. Hodne se pouziva VBA (Visual Basic for Applications), Lisp a Lua. Me je nejblizsi JavaScript, navic v nem hodne lidi umi.
Archiv rubriky: programovani
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().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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" |
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 30 31 32 33 34 35 36 37 |
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.
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 |
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) |
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
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:
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 |
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:
Strojove cteni textu pomoci Google prekladace (Text-to-Speech)
Pro zabavu jsem si postavil z Arduina jednoduchou RFID ctecku (MIFARE 13,56MHz). Po prilozeni cipu firmware v Arduinu precte ID karty (blok 0) a posle ho pres seriovy port do PC. Protoze sledovat vypis v PuTTY byla nuda, dodelal jsem strojove cteni.
Java: kompilace do nativniho kodu platformy
Programy v Jave, se na rozdil treba od C nekompiluji primo do nativniho kodu dane platformy, ale do bajt kodu (mezikodu). To muze velka (ne)vyhoda. zalezi na uhlu pohledu. Aplikace je pak multiplatformni, jde spustit na vsech OS, na ktere je portovana Java. Nevyhodnou je mozna trochu mensi rychlost (tohle tema nemam rad ;-)) a relativne snadna moznost dekompilovat zkompilovane class soubory. Malo se to vi a jeste min pouziva, ale i Java se do zkompilovat primo do nativniho kodu.
Skenovani DNS zony, hledani volnych domen
Pred tydnem jsem si chtel koupit 2 znakovou CZ domenu, nakonec se ukazalo, ze jsou vsechny obsazene. 3 znakovych CZ domen je ale volnych obrovske mnozstvi. Protoze nemam moznost prenosu zony pomoci AXFR dotazu (RFC 5936), musel jsem si napsat skenovaciho „robota“.
Jednoduchy Jabber klient v Jave za 5 minut
Celý příspěvek
Java generovani PDF: vytvoreni stitku na obalky z MS Excelu
Nedavno jsem si hral s generovanim PDF v Jave. Napsal jsem jednoduchy kod, ktery vygeneruje seznam adres na obalky do PDF. Data jsou pripavena v MS Excelu. Kod je priserne zpraseny, ale treba se nekomu pro inspiraci bude hodit 😉
Soubor s daty v MS Excelu musi mit presne stejne nadpisy bunek, jako je na obrazku. Tato slova jsou napevne zadratovana v kodu, samozrejme by nebyl problem udelat jednoduche GUI, ve kterem by si uzivatel naklikal, co chce. Data v Excelu je nutne ulozit do formatu CSV.
Vysledny CSV soubor vypada nasledovne:
1 2 3 4 5 6 |
Jmeno;Ulice;Mesto;Pohlavi Karel Smolny;Nadrazni 123;Hradec Kralové III;muz Marek Jurda;Studentska 95;Pardubice 2;muz Pavla Novakova;Zerotinovo nam. 617/9;Brno;zena Martin Pavlasek;17.listopadu 2172/15;Ostrava-Poruba;muz Pavel Jirasek;Technicka 1902/2;Praha 6;muz<br /> |
V Jave vyuzivam knihovnu JavaCSV z CSVReader.com pod LGPL 2 licenci na zpracovani CSV.
S knihovnou na praci s PDF je to mnohem horsi. ASi nejlepsi a nejznamejsi je iText. Jedna se o dualne licencovanou knihovnu. Prvni je licence AGPL 3 (GNU Affero General Public License) – ta je skoro nepouzitelna. Druha je placena, prave pro pripady, kdy nelze pouzit AGPL.
Pred nekolika lety byla open source verze iText dostupna pod mnohem mene restriktivni licenci LGPL 2. Tato verze je uz dost obtizne k sehnani (prekvapive). Nastasti si mi ji podarilo najit na GitHubu. Pro kompatibilitu s novou knihovnou je urcena tato. Knihovna pod LGPL je uz nekolik let neudrzovana a neumi vsechno, co jeji aktualni verze!
Knihovny jako Apache PDFBox jsou jen pekne hracky bez dokumentace a tutorialu – ztrata casu se jimi vubec zabyvat…
Tady je ta prasarna:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.csvreader.CsvReader; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; public class AdresyNaObalky { public static void main(String[] args) { List<String> adresy = new ArrayList<String>(); try { // ############### zpracovani CSV CsvReader adresa = new CsvReader("data.csv", ';'); // oddelovac je strednik adresa.readHeaders(); while (adresa.readRecord()) { String jmeno = adresa.get("Jmeno"); // *musi* odpovidat nadpisum v excel tabulce String ulice = adresa.get("Ulice"); String mesto = adresa.get("Mesto"); String pohlavi = adresa.get("Pohlavi"); if (pohlavi.equals("muz")) { pohlavi = "Pan"; } else if (pohlavi.equals("zena")) { pohlavi = "Pani"; } System.out.println(pohlavi + ":" + jmeno + ":" + ulice + ":" + mesto); adresy.add(pohlavi + "\n" + jmeno + "\n" + ulice + "\n" + mesto); // pridame adresu } adresa.close(); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // ############### zpracovani CSV // ############### generovani PDF Document document = new Document(PageSize.A4, 50, 20, 20, 20); // format papiru a okraje document.addAuthor("Martin Vancl"); // autor PDF document.addCreationDate(); // datum vytvoreni document.addTitle("Seznam adres pro tisk"); // nazev PDF dokumentu try { PdfWriter.getInstance(document, new FileOutputStream("adresy.pdf")); document.open(); Font font1 = new Font(Font.TIMES_ROMAN, 15, Font.BOLD); // (family, size, style) - http://goo.gl/tm5DG int pocet = adresy.size(); System.out.println(adresy.size()); if ((pocet % 2) != 0) { pocet++; } PdfPTable table = new PdfPTable(2); table.setWidthPercentage(100); table.getDefaultCell().setBorder(Rectangle.NO_BORDER); for (String a : adresy) { System.out.println(a); PdfPCell bunka = new PdfPCell(new Paragraph(a, font1)); bunka.setBorder(Rectangle.NO_BORDER); bunka.setPadding(20); table.addCell(bunka); } if (pocet > adresy.size()) { table.addCell(""); } document.add(table); document.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } // ############### generovani PDF } } |
Po spusteni vyplivne takovyto PDF soubor. JAR soubor ke stazeni. Komplet vse ke stazeni (tabulka v Excelu, zdrojak, knihovny, jar).
Vypis aktualni teploty v zadanem meste z Foreca.cz
Nekdy se muze hodit znat aktualni teplotu v urcitem meste. Nektera mesta, jako treba Jicin maji vlastni webovy teplomer. Na webu obechnanice.cz jsem se dozvedel o skvele sluzbe Foreca.cz. Problem je, ze krome aktualni teploty (tu potrebuju) vidim i spoustu dalsich udaju. Nastesti jde teplota ze stranky jednoduse vytahnout. 🙂
Sleep ve Windows
Program sleep pocka pozadovanou dobu a ukonci se. V Linuxu casto pouzivam tento program pri psani skriptu. Ve Windows XP vsak nic podobneho neni. Co by kdo taky cekal od 8 let stareho operacniho systemu (XP je z 25.10.2001)? Jak je to s Windows Vista nevim – nepouzivam.
V Linuxu je syntaxe nasledujici:
sleep 3
pocka 3s
I kdyz ve Windows XP nic podobneho neni, lze si pomoci jinak – programem PING. Kazdeho asi napadne, co ma ping a sleep spolecneho. Odpoved je jednoducha, jestlize se ping spusti se spravnymi parametry, funguje stejne jako sleep. Popis vsech parametru je na strankach Microsoftu.
ping 127.0.0.1 -n 3 -w 1000> nul
pocka 3s
-w doba, po kterou bude ping cekat na odpoved. Zadava se v ms.
-n pocet pozadavku na odpoved. Jelikoz ma ping na localhost (127.0.0.1) prakticky nulovou odezvou, poslouzi jako parametr pro "uspani".
> nul zahodit (nevypisovat) vypisy
Nejjednodussi je vytvorit program, ktery bude vyuzivat funkci sleep. V C by se to dalo napsat nejak podobne:
12345678910111213141516171819202122232425 <font color="#0000ff"><strong>#include <font color="#008000"><stdio.h></font></strong></font><font color="#0000ff"><strong>#include <font color="#008000"><stdlib.h></font></strong></font><font color="#0000ff"><strong>#include <font color="#008000"><Windows.h></font> <font color="#444444"> /* sleep() */</font></strong></font><strong>int</strong> <font color="#2040a0">main</font><font color="#4444ff">(</font><strong>int</strong> <font color="#2040a0">argc</font>, <strong>char</strong> <font color="#4444ff">*</font><font color="#2040a0">argv</font><font color="#4444ff">[</font><font color="#4444ff">]</font><font color="#4444ff">)</font><font color="#4444ff"><strong>{</strong></font><strong>int</strong> <font color="#2040a0">cekat</font><font color="#4444ff">;</font><strong>if</strong> <font color="#4444ff">(</font><font color="#2040a0">argv</font><font color="#4444ff">[</font><font color="#ff0000">1</font><font color="#4444ff">]</font> <font color="#4444ff">=</font><font color="#4444ff">=</font> <font color="#2040a0">NULL</font><font color="#4444ff">)</font><font color="#4444ff"><strong>{</strong></font><font color="#2040a0">printf</font><font color="#4444ff">(</font><font color="#008000">"Jako parametr uvedte cas v sekundach!<font color="#77dd77">\n</font>"</font><font color="#4444ff">)</font><font color="#4444ff">;</font><font color="#4444ff"><strong>}</strong></font><strong>else</strong><font color="#4444ff"><strong>{</strong></font><strong>while</strong> <font color="#4444ff">(</font><font color="#4444ff">(</font><font color="#2040a0">cekat</font> <font color="#4444ff">=</font> <font color="#2040a0">atoi</font><font color="#4444ff">(</font><font color="#2040a0">argv</font><font color="#4444ff">[</font><font color="#ff0000">1</font><font color="#4444ff">]</font><font color="#4444ff">)</font><font color="#4444ff">)</font> <font color="#4444ff">=</font><font color="#4444ff">=</font> <font color="#ff0000">0</font><font color="#4444ff">)</font><font color="#4444ff">;</font><font color="#444444">/* retezec z argv[1] se prevede na cislo */</font><font color="#2040a0">cekat</font> <font color="#4444ff">=</font> <font color="#4444ff">(</font><font color="#2040a0">cekat</font> <font color="#4444ff">*</font> <font color="#ff0000">1000</font><font color="#4444ff">)</font><font color="#4444ff">;</font><font color="#444444">/* funkci sleep se musi zadavat cas v [ms] => * 1000 */</font><font color="#2040a0">sleep</font><font color="#4444ff">(</font><font color="#2040a0">cekat</font><font color="#4444ff">)</font><font color="#4444ff">;</font><font color="#4444ff"><strong>}</strong></font><strong>return</strong> <font color="#ff0000">0</font><font color="#4444ff">;</font><font color="#4444ff"><strong>}</strong></font>
Pokud to nekdo chcete pouzit, tady je 32bit exe. Jestlize ma nekdo 64bit, nebo si to chce nejak upravit, tak tady je projekt v Dev-C++.
Program je dobre nakopirovat do C:\Windows, nebo do jine slozky, ktera je uvedena v promene PATH.