Er du en flittig bruker av terminal.app, er du kanskje en som har migrert fra Unix til Mac. Det kan også hende du kommer fra Windows, eller er oppvokst med Mac. Kommandolinjen kan brukes til mange interessante ting, særlig systemadministrasjon og operasjoner på filer. Har du tenkt på andre ting dette forhistoriske datamiljøet kan brukes til?
Dersom man lærer seg litt skripting, er det utrolig hva du kan få til med svært lite innsats. Denne artikkelen viser hvordan du kan lage dine egne kommandolinjesnutter i full fart ved hjelp av Python, som er ferdig installert på din Mac, så det er bare å sette i gang!
Vi går gjennom et eksempler som jeg bruker til daglig på min Mac, og som jeg har blitt like avhengig av som Google og Mail.app: et konverteringsprogram for måleenheter. Selvsagt kan Google gjøre dette, men det er raskere å ha slikt lokalt. Dessuten jobber jeg en del uten nett og da hjelper jo ikke Google meg..
Det vi skal lage er et program som omregner diverse "kjøkkenenheter":
Fahrenhet - Celsius
Pund (lbs) - Kilogram (kg)
Vi vil ha syntaksen slik:
cvrt 20 F
Resultatet blir:
>> 20 F er -6.7 C.
Omregningene skal gå begge veier. La oss gå gjennom dette på en enkel måte. For å starte skriptet, åpne en teksteditor (min favoritt er vim) og legg inn denne linjen på toppen:
#!/usr/bin/env python
Dette sørger for at Mac'en din skjønner at det er et Python-prgram. Dette er UNIX-standard og kalles en shebang-linje. Det neste vi må gjøre er å sørge for at vi får med oss kommandlinjeargumentene. Vi importerer da en modul i Python, som heter sys. Mer spesifikt importerer vi et element fra denne modulen, som heter argv. Dette er en liste med kommandolinjeargumenter:
from sys import argv
Når første argument er måltallet og andre argument er enheten er det neste vi tilføyer skriptet vårt:
maltall = sys.argv[1]
enhet = sys.argv[2]
(Det er også en sys.argv[0], men dette er bare navnet på filen du kjører).
La oss nå lage to funksjoner i programmet vårt. En funksjon er en "maskin" som kan ta inputs og leverer noe annet ut. For å konvertere fra Fahrenheit til Celsius:
def f2c(maltall):
nytt_maltall = (maltall - 32.0)*(5.0/9)
return nytt_maltall
La oss lage en funksjon som konverterer den andre veien også:
def c2f(maltall):
nytt_maltall = maltall*(5.0/9) + 32
return nytt_maltall
Nå er vi klare til å lage litt innmat i skriptet vårt. Vi baserer hvilken funksjon vi skal kalle på enheten. Hele programmet ser så langt slik ut:
#!/usr/bin/env python
from sys import argv
maltall = sys.argv[1]
enhet = sys.argv[2]
#Funksjonsdefinisjoner
def f2c(maltall):
nytt_maltall = (maltall - 32.0)*(5.0/9)
return nytt_maltall
def c2f(maltall):
nytt_maltall = maltall*(5.0/9) + 32
return nytt_maltall
#Regn om:
if enhet == 'F':
nytt_maltall = f2c(maltall)
print str(maltall)+' F er '+str(nytt_maltall)+' C'
elif enhet == 'C':
nytt_maltall = c2f(maltall)
print str(maltall)+' C er '+str(nytt_maltall)+' F'
else:
print 'Enhet ikke implementert'
nytt_maltall = 'Feil'
Her har vi uten nærmere forklaring brukt if-setninger, men det går vel frem av koden hvordan dette fungerer? I tillegg har vi lagt til en feilmelding for ukjent enhet. Det kan være leserens egen oppgave å utvide skriptet med oversetting mellom pund og kilo. Når du har laget dette, kan ingenting stoppe deg: bruk dokumentasjonen på python.org til å oppdatere deg på Python - god dokumentasjon der! Ellers finner du mange gode "miniprogrammer" grundig forklart på http://portablecommandline.blogspot.com.
Tips til andre ting du kan gjøre:
- Lag din egen timeregistrering for terminal.app og slipp å starte Excel
- Gjør klar store datafiler for Excel med tekstprosesseringsredskaper i Python
- Gjør beregninger i Python - for eksempel kan du løse likninger her!
- Plott grafer og eksporter til gangbare formater som png, pdf og eps med matplotlib (en modul til Python).
Du kan til og med lage halvgjennomsiktige forklaringsnøkler:
portablecommandline!
hrdo søn, 14/06/2009 - 21:15
Formatering av innrykk fungerte ikke helt i mac1s skjema. I python må du ha innrykk for å få funksjoner og if-setninger til å fungere. Slik
def minfunksjon():
..........kommando med innrykk
funksjon ferdig når innrykk er ferdig
tjodolv man, 15/06/2009 - 11:58
artig :) Finfin intro til scripting og python
froskenfredrik man, 15/06/2009 - 12:48
For de helt ferske kan det være greit å fortelle litt om hvor dette skal lagres og hva det skal lagres som.
byfixar man, 15/06/2009 - 12:53
Ett lite tips, benytt engelske navn på funksjoner og variabler.
Når man skriver "kom i gang med X-språk", er det viktig at man tar med validering med en gang. Savner validering på sys.argv[1].
luredan man, 15/06/2009 - 14:15
Jeg savnet også validering, men ellers et fint tips :)
Jeg måtte forresten bruke
maltall = float(argv[1])
enhet = argv[2]
for å få det til å fungere.
Fred man, 15/06/2009 - 16:06
Er du en flittig bruker av terminal.app, er du kanskje en som har migrert fra Unix til Mac. Det kan også hende du kommer fra Windows, eller er oppvokst med Mac.
Så du kan i prinsippet være hvem som helst, altså....
morgoth man, 15/06/2009 - 17:34
Etter litt tid så kan man fort ha mange slike script, jeg har funnet det ganske smidig å inkludere en folder til $PATH via .bash_profile der alle mine script ligger...
Om man legger til følgende til .bash_profile (fordrer at script katalogen din heter Script).
if [ -d ~/Script ]; then
export PATH=:~/Script:$PATH
fi
Henrik Lied man, 15/06/2009 - 20:33
Fint med ein liten intro til Python, men ein må alltid passe på å validere args. Det er ikkje så bra å lære bort dårlige vaner fra byrjinga av. :-)
Sjekk ut optfunc fra Simon Willison, det er det beste biblioteket pr. dags dato (etter mi meining).
ggt667 tir, 16/06/2009 - 08:23
Python er det alle trodde java skulle bli.
hrdo ons, 17/06/2009 - 15:10
[quote="tjodolv"]artig :) Finfin intro til scripting og python
Takk for fin kommentar!
Til dere som nevner validering: helt enig! Ville bare ikke komplisere ting fra starten av. Og for å være ærlig: når jeg lager "hurtigløsninger" valideres det ikke. Når folk betaler meg for kode, valideres det. Er dere andre like rigorøse på "hobbyprosjekter" som på "jobbeprosjekter"? Ha en toppers dag!
rafn ons, 17/06/2009 - 15:21
Spennende :-)
Må ta en titt på det her når kvelden kommer :-D
byfixar tor, 18/06/2009 - 19:10
[quote="hrdo"]Er dere andre like rigorøse på "hobbyprosjekter" som på "jobbeprosjekter"? Ha en toppers dag!Jeg er det. Da det er viktig å gjøre alt sikkert. Dessuten laget jeg meg bare en klasse, som validerer, som jeg bruker til alt jeg lager. Hvorfor lage hjulet flere ganger, når man heller kan lage ett, og hente det opp når man trenger det?
Er ikke kjempekomplisert og putte på en funksjon som gjør stringen om til en int.
hrdo fre, 19/06/2009 - 15:35
Jo, det er vel og bra - burde kanskje tatt med validering?
Vel, det er jo godt å se at andre er mer "ordentlige" enn meg når de lager småtterier til "hjemmebruk"! Forøvrig kan vi godt gjøre om stringen til et flyttall, ikke int - greit med kommatall også :-)
HenrikWL fre, 10/07/2009 - 11:31
Jeg håper virkelig ikke det er disse formlene du bruker. Den ene er nemlig feil...
Celsius = (Fahrenheit - 32)*(5/9)
Fahrenheit = Celsius*(9/5) + 32
Du har glemt å snu brøken i Celsius-Fahrenheit konverteringen din.