Metody ilościowe w R, Aplikacje ekonomiczne i finansowe, to książka napisana przez zespół autorów z Uniwersytetu Warszawskiego. Na okładce podpisani są Katarzyna Kopczewska, Tomasz Kopczewski oraz Piotr Wójcik. Na odwrocie strony tytułowej do tego dopisano także: Michała Ejdysa, Piotra Szymańskiego i Jakuba Świniarskiego. W paginie każdej strony parzystej pp. Kopczewska, Kopczewski i Piotr Wójcik są zaś określani zaś jako redaktorzy. Wydawca to CeDeWu.pl [pełna nazwa: CeDeWu wydawnictwa fachowe, która zakrawa na żart, o czym niżej]. Redaktor -- jeżeli w ogóle w tym CeDeWu, ktoś taki jest -- się nie podpisał.
Książka jest po prostu redakcyjnie fatalna a jej czytanie wręcz boli. Jak pisałem wyżej, można mieć wątpliwości czy ktokolwiek toto redagował. Wszystko spieprzono -- za przeproszeniem -- jedną decyzją redakcyjną, mianowicie ktoś wpadł na ,,genialny'' pomysł dziwacznego wyróżniania fragmentów programów w R. [A w tej książce circa połowa objętości to przykłady i fragmenty programów.] Otóż konstrukcje języka R w tekście są wyróżnione przez złożenie ich (wąskim) krojem bezszeryfowym w stopniu optycznie znacząco większym od kroju otaczającego tekstu. Tego się po prostu nie da czytać!
Żeby jeszcze było trudniej czytelnikowi,
to stosując kursywę i pogrubienie, autorzy
usiłują graficznie rozróżnić: zmienne, wartości zmiennych,
nazwy poleceń, argumenty poleceń, nazwy pakietów. Pytanie po co?
Co to daje oprócz mieniącej się w oczach pstrokacizny?
Oczywiście taki skomplikowany schemat skutkuje multum błędów
i niekonsekwencji (co raz jest pochyłe-grube, innym
razem jest proste-chude). Kolejne kuriozum, to
wyśrodkowane krótkich fragmentów
składni umieszczonych w całości w oddzielnym akapicie
(tzw. choinka, po co?).
Jednocześnie w tych wyśrodkowanych akapitach nie ma już
graficznego rozróżnienia co jest zmienną, nazwą polecenia itp...
Pełen chaos... lepiej zaciemnić już nie można
było... Nie prościej było wszystko złożyć Courierem, wyróżniając
nieliteralne fragmenty np. kursywą? Cóś w stylu:
merge(zbiórA, zbiórB, by.X=zmiennaA,
by.Y=zmiennaB,all=TRUE)
.
Inne błędy to już pestka:
Wydawanie takich książek to wstyd, obciach i żenada. Przede wszystkim dotyczy to wydawnictwa (CeDeWu wydawnictwa fachowe), bo to ono odpowiada za redakcję merytoryczną i techniczną. Tak się kończy powielanie maszynopisu przygotowanego przez dyletantów i na dokładkę w programie, który do tego się średnio nadaje. Rekomendacja: Nie kupować, szkoda pieniędzy...
Katarzyna Kopczewska, Tomasz Kopczewski i Piotr Wójcik, Metody ilościowe w R, Aplikacje ekonomiczne i finansowe, CeDeWu Warszawa 2009, ISBN 978-83-7556-150-0.
Trudno jest znaleźć gotowe i działające rozwiązanie pn. jak wysłać (upload) film na YT, nie używając formularza i przeglądarki. Teoretycznie jest API; jest tam nawet to opisane, ale jakoś tak na tyle pokrętnie, że nie mogę się połapać na szybko jak to zaimplementować. Szukałem po linii Pythona, por. Getting comments from youtube via... oraz python uploading scripts for youtube. Nic z tego nie wyszło...
Działa za to skrypt opisany na stronie How to Upload YouTube Videos Programmatically. Nie korzysta on wprawdzie z API--udaje przeglądarkę i analizuje kod HTML metodą data scrapping. Data scrapping ma ten minus, że w każdej chwili może przestać działać ale może nie będzie aż tak źle. Takie sztuczki sam kiedyś stosowałem, zresztą (por. Czy flickr umie liczyć -- rozwiązanie).
Przechodząc do konkretów. Uruchomienie skryptu ytup.pl
wygląda następująco:
perl ytup.pl -l login -p hasło -c nr_kategorii -d opis - t tytuł_filmu -x słowa-kluczowe -f plik
Ja chcę uruchamiać ytup.pl
w nocy, jak wszyscy śpią. W tym celu opis filmu
wstawiam do pliku z rozszerzenie .descr
, np.:
-t Elka plays accordion -d Elka's warm-up exercises -x elka,accordion,weltmaister,rehearsal,music,warm-up -c 24 -f Zi6_0042.MOV
Jak widać, plik zawiera wszystko co trzeba do uruchomienia skryptu ytup.pl
.
Teraz inny plik przegląda wybrane katalogi, czyta pliki .descr
i uruchamia ytup.pl
[pliki Video
i pliki .descr
muszą być w tym samym katalogu]:
#!/usr/bin/perl use File::Spec; use File::Basename; my $YTlogin = 'login'; ## wstaw login my $YTpassword = 'hasło'; ## wstaw hasło my $YTlog_file = "/home/tomek/SD/ytube/logs/YT_Upload.log"; my $PerlProg = "/usr/bin/perl"; my $PerlScript = '/home/tomek/bin/ytup.pl'; my @YT_watch_dirs=('/home/tomek/SD/ytube/upload', '/public/sheeva/winstuff/YTube'); open LOG, ">>$YTlog_file"; for my $dir (@YT_watch_dirs) { # Read directory and collect description files. opendir(DIR, $dir) or die "*** Can't open directory $dir: $!."; print STDERR "*** Processing directory: $dir\n"; my $count = 0; while (defined(my $file = readdir(DIR))) { if ($file =~ /^\./) { next ; } # pomin plik z kropka na poczatku if ($file =~ /\.descr$/) { $file = File::Spec->rel2abs(File::Spec->join($dir,$file)); print STDERR "*** Description file: $file\n"; Upload_video($file); rename($file, "${file}_") || print LOG "Problem ze zmiana $file => ${file}_\n"; $count++; } } closedir(DIR); print STDERR " $count .dscr file" . ($count!=1?'s':'') . ".\n"; } close(LOG); ### ### ### sub Upload_video { # Przeczytaj plik z opisem, wyslij plik video za pomoca system(...) my $file_name = shift ; my $key, $val; my @Options = (); open (DESCRIPTION, $file_name); while (<DESCRIPTION>) { # plik zawiera w kazdym wierszu: opcja spacja wartosc-opcji $_ =~ /([-\w]+)\s+(\S.*)/; $key = $1; $val = $2; # na wszelki wypadek if ($key =~ /-f/) { $val = dirname($file_name) . "/$val" ; } push (@Options, ("$key", "$val")); } my @UploadScript = ($PerlProg, $PerlScript, '-l', $YTlogin, '-p', $YTpassword, @Options); print STDERR "*** Executing: @UploadScript\n"; system ( @UploadScript ) == 0 || print LOG "Problem z zaladowaniem pliku $file_name\n" ; }
Powyższy plik jest uruchamiany -- w stosownym momencie
-- przez crona
,
a przesłany film jest tutaj.
Do podłączenia czujników temperatury DS18B20 firmy Dallas (kupionych za ca 5 PLN/sztuka na Allegro) dokupiłem -- też na Allegro -- Moduł 1Wire na USB, chipset DS2480B + FT232RL, który jest ,,Od strony programowej zgodny z konwerterami opartymi na układach DS2480B, czyli np. z oryginalnymi interfejsami serii DS9097 firmy MAXIM-DALLAS z tą różnicą, że interfejs podłączamy do portu USB zamiast portu szeregowego RS232 [...] Do konwersji ze standardu RS232 na USB zastosowano układ FT232RL firmy FTDI''. Więcej szczegółów można doczytać tutaj (Kod produktu: MP00202).
Teraz uwaga: czujnik DS18B20 ma trzy nogi (aka piny). Skrajne łączę i dolutowuję do jednej żyły (brązowej) przewodu telefonicznego a środkowy do drugiej (żółtej); dwie pozostałe żyły są niepotrzebne. [Kolory oczywiście nie są ważne; podaję je na swój prywatny użytek, gdybym za jakiś czas chciał rozbudować instalacją i dolutować kolejny sensor.] Ponieważ DS18B20 jest bardzo mały, to żeby piny się nie stykały izoluję każdą żyłę cienką rurką termokurczliwą (por. zdjęcie #1, umieszczone obok). Żeby ładniej wyglądało, ale przede wszystkim żeby połączenie czujnik-kabel było mocniejsze (żyły są bardzo cienkie) to na cały przewód naciągam szerszą rurkę (por. zdjęcie #2) i też zgrzewam (por. zdjęcie #3). Zgrzewam zapalniczką....
Moduł MP00202 nie łączę bezpośrednio z przewodem telefonicznym, bo żyły są tak cienkie że wolę zrobić to na dwa pas. Krótki dwużyłowy przewód elektryczny lutuję z żyłami kabla telefonicznego, po czym wzmacniam połączenie naciągając rurkę termokurczliwą. Dużo grubsze żyły kabla elektrycznego znacząco pewniej tkwią w stykach modułu MP00202. Nota bene: żyłę dolutowaną do skrajnych pinów należy połączyć z górnym stykiem, a tą drugą ze stykiem obok (dwa dolne styki są niewykorzystane; por. rys. #4).
Ostatecznie połączyłem równolegle 4 czujniki: pokój, tzw. weranda, kaloryfer i jeden zewnątrzny. Tzn. najpierw podłączyłem jeden i testowałem czy toto w ogóle działa. Ale to tak na marginesie...
Do rejestracji temperatury korzystam z programu digitemp:
sheeva> apt-get install digitemp
Konkurencyjny owfs.org nie jest dostępny w repozytoriach,
zaś jego kompilowanie w wersji na SheevaPlug nie jest prostą sprawą.
Z kolei digitemp nie działa
out of the box, przynajmniej z tą wersją kernela,
która była zainstalowana w moim komputerku...
Sheeva ma ,,odchudzoną wersję'' kernela -- bez wielu modułów, w tym modułu ftdi_sio
do obsługi konwertera USB→Serial, FT232R.
Że coś jest nie ten-teges świadczy brak /dev/ttyUSB0
.
O tym wszystkim zaś
doczytałem tutaj.
Nową wersję jądra, zawierającą stosowny moduł ściągnąłem i zainstalowałem z http://sheeva.with-linux.com/sheeva/:
sheeva> wget http://sheeva.with-linux.com/sheeva/README-2.6.32.7
Uwaga #1: po zainstalowaniu jądra niezbędne są zmiany środowiska Uboota (U-Boot environment variables) -- co trzeba zrobić jest opisane na początku pliku README-2.6.32.7. Aby zainstalować jądro wystarczy:
sheeva> ./README-2.6.32.7
Uwaga #2:
jeżeli na ekranie pojawi się /bin/bash: bad interpreter: Permission denied
,
to sprawdźmy (uruchamiając mount
bez argumentów) czy aby nie uruchomiamy skryptu
w systemie plików montowanym z parametrem noexec
.
Jak wszystko pójdzie dobrze (mi poszło) to teraz należy zaktualizować U-Boot environment variables. W tym celu należy połączyć się z SheevaPlug kablem z wtyczkami USB/miniUSB, wyłączyć komputerek, a po włączeniu połączyć się szybciutko poleceniem:
## jeżeli nie ma /ttyUSB1 spróbuj inny /ttyUSB* cu -s 115200 -l /dev/ttyUSB1
Naciskając dowolny klawisz (należy się spieszyć) spowodujemy wyświetlenie się znaku zachęty U-boota. Wtedy należy wpisać, to co podano w README-2.6.32.7 (lub stosownym innym pliku jeżeli skopiowana była inna wersja jądra). Mówiąc konkretnie wpisać trzeba (działam metodą kopiuj wklej oczywiście; znak ↓ na końcu wiersza oznacza kontynuację):
setenv mainlineLinux yes setenv arcNumber 2097 setenv bootargs rootfstype=jffs2 console=ttyS0,115200 mtdparts=orion_nand:0x400000@0x100000(uImage),↓ 0x1fb00000@0x500000(rootfs) rw root=/dev/mtdblock1 ↓ rw ip=192.168.1.9:192.168.1.4:192.168.1.4:255.255.255.0:DB88FXX81:eth0:none
Teraz
saveenv reset
Reset nie reboot,
por. tutaj.
Powinno się pojawić urządzenie /dev/ttyUSB0
(jeżeli podłączymy
moduł MP00202 oczywiście). Zatem wreszcie:
sheeva> digitemp_DS9097U -a -i -s/dev/ttyUSB0
Program wypisze coś w stylu:
DigiTemp v3.5.0 Copyright 1996-2007 by Brian C. Lane GNU Public License v2.0 - http://www.digitemp.com Turning off all DS2409 Couplers ..... Searching the 1-Wire LAN 10E8EF98010800E6 : DS1820/DS18S20/DS1920 Temperature Sensor 105C1C990108005A : DS1820/DS18S20/DS1920 Temperature Sensor 1029400102080084 : DS1820/DS18S20/DS1920 Temperature Sensor 1065259901080056 : DS1820/DS18S20/DS1920 Temperature Sensor ROM #0 : 10E8EF98010800E6 ROM #1 : 105C1C990108005A ROM #2 : 1029400102080084 ROM #3 : 1065259901080056 Wrote .digitemprc Feb 02 20:18:08 Sensor 0 C: 17.75 F: 63.95 Feb 02 20:18:09 Sensor 1 C: 20.50 F: 68.90 Feb 02 20:18:10 Sensor 2 C: 43.81 F: 110.86 Feb 02 20:18:11 Sensor 3 C: -4.94 F: 23.11
Temperaturę rejestruję uruchamiając digitemp
a co godzinę, via crontab
a:
##0 * * * * /usr/bin/digitemp_DS9097U -a -l/media/sd/tomek/logs/Digitemp/digitemp.log -s/dev/ttyUSB0 0 * * * * /home/tomek/bin/dt2ht.sh
Skrypt dt2ht.sh
uruchamia digitemp_DS9097U
(w sposób jaki podano
w zakomentowanym wierszu wyżej) a następnie
skryptem Perla obrabia plik
/media/sd/tomek/logs/Digitemp/digitemp.log
do formatu HTML.
Wynik można obejrzeć tutaj.
Uwaga #3: aby ,,zwykły'' użytkownik mógł uruchomić digitemp
a trzeba
zmienić domyślne prawa dostępu do /dev/ttyUSB0
:
cat 'KERNEL=="ttyUSB0", MODE="0666"' >> /etc/udev/rules.d/80-ttyusb.rules
Popularne jest wykorzystanie do graficznej prezentacji programu RRDTool
, na co
się -- póki co przynajmniej -- nie zdecydowałem.
Przy okazji zmagań z termometrami
zwiedziłem
różne strony i blogi, niektóre całkiem interesujące (porządek linków dowolny):
1
| 2
| 3
| 4
| 5
| 6
| 7.
Bez Google ale i Piotra Strzelczyka, który wcześniej się okazało już coś takiego zlutował nie dałbym rady...
Dopisane 25 marca 2010 (Rozbudowa instalacji): Dokupiłem kabel energetyczny (dwużyłowy), bo na zewnątrz budynku przewód telefoniczny wydaje się za delikatny. W tym kablu jedna żyła jest niebieska a druga brązowa. Skrajne lutuję do niebieskiej, a środkowy do brązowej.
Globalscaletechnologies zapowiada kilka komputerków będących ulepszonymi wersjami sheevaplug pn. guruPlug.