Itä-Suomen yliopiston weboodissa alkaa olla aika usein kurssi-infot hyvässä kunnossa, ja nyt on myös joensuulaisille olemassa tuota lukkaria, joka on hyvä ratkaisu. No, olisi, jos matematiikat saisi kanssa listoille. Ja valintani on muutenkin org-mode, joten sen kanssa on mentävä. Vaihteeksi uutta Python-koodinpätkää: oodista kopypastettuja aikatauluja org-aikaleimoiksi.
Syöte on tämänlaista:
29.10.-17.12.12 ma 16.00-18.00 31.10.-19.12.12 ke 08.00-10.00 01.11.12 to 08.00-10.00 09.11.12 pe 10.00-12.00
Eli joko on yksittäisiä aikoja tai on isompia välejä, joiden ajat toistuvat viikottain. Org-mode ottaa vastaan kuitenkin vain tämänlaisia aikaleimoja:
<2012-10-15 Mon 16:00-18:00> <2012-10-29 Mon 16:00-18:00 +1w>
Eli yksittäisiä päiviä, joilla on mahdollisesti kellonaika. Org osaa tehdä noita toistuvia aikoja (jälkimmäisessä +1w
viittaa viikottaiseen tapahtumaan).
Pythonin kanssa taistoon
Ensin puntaroin tekeväni tämän Elispillä, koska kuitenkin org-ympäristö on ainut, jossa tätä tarvitsee. Ajattelin, että elispin aika ja paikka on joskus myöhemmin. Arkkitehtuuri sovellukselleni on tyypillinen:
- lue tiedostosta tai standardi-inputista rivit ylös
- (lukee tosin kaiken kerralla koska laiskat tietorakenteet eivät pythonissa loista)
- rivit annetaan delegointifunktiolle, joka päättää, onko rivipari aikajakso vai yksittäinen päivä:
- jos jakso, niin pura pythonin päivämäärätyökaluilla jakso joukoksi yksittäisiä päiviä, ja passaa seuraavalle:
- jos päivä, niin käännä se erinäisten kikkastelujen jälkeen org-aikaleimaksi.
Joitain otteita koodista voisi kaiketi antaa. Sisään mennään tämännäköisellä hirvityksellä. Pythonin fileinput
on loistava, vaikka se vaatiikin kaksi C-d
:tä lopettaakseen.
if __name__ == '__main__': import fileinput inputd = [line.strip() for line in fileinput.input() if line.strip() != ''] finished = [do_line(date, time) for date, time in zip(inputd[::2], inputd[1::2])] print '\n'.join(finished)
Funktio do_line
toimii delegoijana. Mennäänpä nyt päivämääriin. Tämä funktio do_date
hoitaa yksittäistapauksen. Toinen apufunktio, toDate
, on ollut jo käytössä delegaatissa (ankkatyyliin jos saadaan parsintapoikkeus niin tulkitaan teksti intervalliksi), joten do_date
saa datan puoliksi python-olioina ja toinen puoli on tekstiä.
def toDate(string): """ %d.%m.%y -> DateTime. """ return datetime.datetime.strptime(string, "%d.%m.%y") def do_date(date, time): """ convert one date, time pair to org """ return "<" + date.strftime("%Y-%m-%d") + " " + runtime(time) + ">"
Tekstipuoli käännetään runtime
-funktiolla, joka on vain merkkijonokäpistelyä. Viikonpäivät suomesta englantiin ja semmoista. Intervalli oli hieman kiinnostavampi. Sen saa palautettua yksittäisiksi päivämääriksi verraten helposti datetime.timedelta
-luokan voimin:
def do_intervalled_line(interval, time): """ interval is of form "%d.%m.-%d.%m.%y". """ begin, end = interval.split('-') # 'begin' may get the same year as end... I smell trouble begin = begin + end.split('.')[-1] begin = toDate(begin) end = toDate(end) acc = [] week = datetime.timedelta(days=7) while begin <= end: acc.append(do_date(begin, time)) begin = begin + week return acc
Ilmassa on pientä hakkailua, joka tuskin kestää lähempää tarkastelua. Homma lähti kuitenkin ensipolkaisulla käyntiin, joka on aina iloinen yllätys.
Jatkokehittelyä
Tässä yhden hengen katselmoinnissa tosin huomasin, että listoja pitää vielä vähän tasata: testisyötteeni oli kaikki intervalleja ja saattaa paukkua, jos syötteessä on seassa yksittäisiä päiviä. Tai ainakin siltä vähän näyttäisi.
Koodi käyttöön
Vimissä on tyylikäs !
-komento, jolle voi ‘putkittaa’ tekstivalinnan, ja putken päästä tuleva tavara korvaa valinnan. Esimerkiksi !sort
tekee valinnalle sitä, miltä kuulostaakin. Emacsin vastaavaa en heti hoksannutkaan, mutta onneksi Evil hoiti homman kotiin. Googlailujen jälkeen selvisi, että Emacsin oma tapa on C-u M-|
. Saapa olla jatkossakin.
Emacsista toimintakuva (kun kirjoitan tätä blogiviestintapaista):
Hassusti se tuo muotoilut kopioidessaan. Kiva sinänsä blogia tehtaillessaan, mutta jossain vaiheessa tuon on hajottava johonkin. Onhan?
Seuraavalla kerralla voisin kirjoittaa org-agendan ja conkyn yhteensulautumista, jolla korvasin Rainlendarin kokonaan. Koodi ei siellä ole niin nättiä, että…