Programmerer.com

Keeping fun in the house

Top Advantages of our payday loans Payday loans UK But now, you have an extra

Personlige leveregler gir dybde og mening

For noen år siden fant jeg ut at jeg ville prøve å lage et sett «leveregler» for meg selv. Noe som ville inspirere og motivere meg, og som jeg kunne la guide meg når jeg var i tvil om neste trekk.

Hver gang jeg tar dem frem, gir de meg noe nytt. Samtidig gir de en dybde og mening, og er en rød tråd i livet.

Hvis du tar deg tid til ettertanke i dag, kanskje min lille remse kan gi deg noen innspill. Disse er selvfølgelig svært personlige. Dine vil være annerledes.

* * *

Ha integritet.
Med den, søk først suksess hjemme.
Hjelp de jeg er glad i å dyrke det de vil.
Snakk aldri stygt om noen.
Gi fritt av kjærlighet, uten forbehold, uten å skulle ha noe tilbake.
Vær rolig, trygg og støttende.
Gi av din tid – mest til de nærmeste, og mye til de andre, og husk å ta vare på deg selv.
Hvil.
Hold kroppen og hodet i stand. Bygg sakte.
Søk friheten til å gjøre enda viktigere ting, men ikke la det ødelegge for det andre.
Ikke vær redd. –
Vær moden nok til å balansere egne ønsker og behov med andres –
trygg nok på meg selv til å holde på mitt, og stor nok til å gi slipp.
Skriv ditt eget liv. Ta ansvar for det som har skjedd, og for det som skal skje.
Lær av feil – og gi slipp.
Tilgi deg selv og andre.
Vær ditt eget livs visjonær – tenk stort. Tenk i generasjoner.
Basert på prinsipper, verdier og visjoner – planlegg.
Sett planene ut i live.
Gjør de viktigste tingene først.
Gjør deg ferdig med det du har startet på. Ta beslutninger raskt, og endre dem langsomt.
Evaluer. Zig-zag. Rett opp kursen.
Lær.
Mediter.
Vær taknemmelig.
Behold kontakten med naturen.
Verdien kommer innenfra deg – både den menneskelige og den økonomiske.
Tjen menneskene, de som er nå, og de som kommer.
Ta vare på venner.
Menneskene først.

En deilig implementert and

Lite er så godt som en deilig implementert and.

Ta en titt på denne. Dette er en Clojure macro. Hvis du ikke kan Clojure, gjør ikke det noe, dette skal bli veldig forståelig likevel.

(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
  {:added "1.0"}
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

(Hvis du vet hva en macro er i språket C, må du umiddelbart glemme den definisjonen du kan. En macro i et lisp-språk er ikke det samme.)

Macroen er verkøyet som gjør en vanlig, dødlig programmerer til Gud over Gudene.

Nå er det jo slik at ethvert programmeringsspråk, i hendene på Den Rette, er et gudommelig verktøy. Det lar deg Skape: Når du programmerer, tar du en tanke og gjør den til virkelighet.

Det er sterke krefter du besitter. Likevel: macroen hever deg til et nytt nivå. Et meta-nivå, i forhold til der du var.

For mens du før var bundet av mulighetene i det språket du programmerte, er du nå i stand til å forme selve språket.

Du kan skape muligheter som ikke fantes før.

Clojure selv et er godt eksempel, for Clojure er for en stor del skrevet i Clojure. Til og med noe så basalt som operatøren and, er skrevet i språket selv.

Det hadde ikke vært mulig uten macroer. (Prøv å implementere and i ditt språk, uten å bruke den innebygde operatoren. Prøv så å lage unless.)

Så la oss ta en titt på hvordan dette er gjort.

(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
  {:added "1.0"}
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

Denne macroen heter and, og har tre forskjellige «inngangsporter». Den kan ta ingen, ett, eller flere argumenter, og bruker forskjellige «kropper» alt ettersom hvor mange argumenter den blir kalt med. Den første inngangsporten, har en enkel implementasjon:

  ([] true)

Dette sier: Hvis du kaller macroen med ingen argumenter [], så returner true.

Et kall uten argumenter ser slik ut: (and), og det returnerer true.

user> (and)
true

Hvis du kaller and med ett argument, får du verdien av det argumentet tilbake.

  ([x] x)

Det kan vi test ut:

user> (and true)
true
user> (and false)
false
user> (and 3)
3
user> (and wdcd)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: wdcd in this context, compiling:(NO_SOURCE_PATH:1)

Aha. Symboler som har en verdi, i hvert fall, de får vi rett tilbake. (La oss glemme det siste forsøket her, det får være tema for en annen gang. (Hvis du virkelig ønsker å gå i dybden, ta en titt på min implementasjon av lisp, I Groovy, med forklaring.))

Så kommer vi til kjøttet i anda.

  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

Hvis vi sender inn et argument x, og flere argumenter (i en liste som nå heter) next, så skaper vi nå litt kode, on the fly. Clojures «backtick» operator

`

gjør noe vi er vant til fra web templating, men ikke i kode: Den sier at det som kommer nå, skal settes verbatim inn i koden til kalleren. Det betyr «quote», med andre ord.

Når vi ikke ønsker å quote, altså når vi faktisk ønsker oss verdien av noe inne i denne templaten vår, bruker vi unquote:

~

Så når kalleren kjører denne koden, skjer dette: Vi lar symbolet and# (vi bruker # for navngiving av variabler i macroer, for å unngå navnekonflikt med eventuelle variabler kalleren har i sin egen kode)… altså … vi lar symbolet and# være verdien av unqote x — altså x som ble sendt inn i makroen med kallet.

Hvis vi kalte (and true), så er variablen #and == true, nå.

Med dette gitt, kjører kalleren videre.

      (if and# (and ~@next) and#))))

Hvis det er slik at and# == true, så kaller vi macroen and igjen (med noen argumenter ~@next, se neste paragraf). Hvis and# !== true, så returnerer vi and# selv:

user> (and false true)
false
user> (and false 1)
false
user> (and false 3 2 1)
false

Ok, nå vet vi hva som skjer her:

      (if and# (and ~@next) and#))))

når and# er false (vi får den i retur). Hva når and# er true?

Siden det jo er den kjente and-operatoren vi driver og implementerer, så må jo også resten av argumentene være sanne, for at and skal returnere true, sånn alt i alt.

Husker du inngangsporten vår for denne versjonen av and-macroen?

  ([x & next]

Vi sender altså inn ett argument x, pluss en liste med de resterende argumentene, next.

Denne mystiske karen her:

~@next

er Clojure sin syntax for «unsplice». La oss for enkelhets skyld si at den tar hele listen av argumenter som ligger i next, og flater den ut. (Se http://clojuredocs.org/clojure_core/clojure.core/unquote-splicing for en mer nøyaktig beskrivelse av unquote splicing.)

Vi skal jo kalle and igjen, og vi ønsker ikke å sende hele listen med argumenter til x (og ingenting til next), for da blir

  ([x] x)

kalt (og da får vi bare returnert listen av argumenter, og det der jo dumt), istedenfor

  ([x & next]

som fortsetter evalueringen.

Det som er nesten magisk, og som gjør dette til en så vakker implementasjon av and, er at vi nå er ferdige.

Hvordan kan det ha seg?

Jo, Clojure and oppfører seg sånn:

user> (and true)
true
user> (and true true)
true
user> (and true 1 true)
true
user> (and true 1)
1

Altså: Hvis alle verdier er sanne, returner den siste verdien, ellers returner false.

Deilig, deilig, deilig. And.

Tanker er vanedyr

Jeg tok trappen i dag.

Jeg ville ikke. Hele kroppen verket etter en dårlig natt med hostende unger.

Men jeg vet en ting. Jeg vet at tanker er fysiske. Da mener jeg ikke på sånn new age mumbo jumbo måte. Men at det som skjer i hjernen når jeg tenker, er at elektriske impulser blir sendt gjennom fra et neuron til et annet, fra det ene neuronets aksoner til det andre neuronets dendritter. Og at hver gang en slik overføring skjer, så styrkes banen mellom de to nevronene

Det vil si at det neste gang er lettere å tenke nøyaktig den tanken jeg tenkte nå.

Tenk litt på det: Tanker er også vanedyr.

Har du tenkt noe en gang, er det lettere å tenke det igjen. Når du velger ikke å ta trappen i dag, blir det lettere å velge ikke å ta trappen i morgen.

Og det som skjer når du tenker «jeg tar ikke trappen i dag, jeg tar den i morgen», er ikke at du tar trappen i morgen, men at det er lettere for deg å tenke «jeg tar ikke trappen i dag, jeg tar den i morgen» — i morgen også.

Det blir ikke lettere å ta trappen dagen deretter.

Konverst, kan du bruke denne kunnskapen til å gjøre det lettere for deg selv å ta trappen i dag. For ikke bare får du treningen det innebærer å ta trappen i dag, du kan også fortelle deg selv, med rette, at det blir lettere å ta trappen i morgen. Både fysisk og psykisk.

Du vet den følelsen du av og til har, den Eureka- eller «aha»-følelsen, når du plutselig forstår noe du ikke har forstått før? Den følelsen av at «hvorfor har jeg ikke sett denne koblingen, nå skjønner jeg endelig alt» … ?

Hjerneforskere kan med moderne real time, høyoppløslig MRI se at det skjer. Det er nemlig øyeblikket da det dannes en ny kobling mellom neuroner. Forskerne kan se koblingen dannes. Så fysiske er tanker.

Er du vant til å være sint?

Er du vant til å være taknemmelig for de fine tingene i livet ditt?

Hva du tenker er en vanesak. Og det fine er at nye vaner kan bygges. Det krever disiplin i starten. Og vi har en begrenset mengde viljestyrke å bruke hver dag (viser nyere forskning). Så det kan lønne seg å velge én ny vane av gangen. Konsentrere deg på ett felt.

Jeg skal velge trappen hver dag i to uker.

… eller …

Hver morgen når jeg våkner de neste to ukene, skal jeg tenke over hva i livet mitt som gjør meg takknemlig.

Enhver god beslutning vil styrke deg og gjøre det lettere å ta gode beslutninger i fremtiden. Enhver dårlig beslutning vil svekke deg, og gjøre det enklere å ta dårlige beslutninger i fremtiden.

Ta vare på deg.

Syncing av pdf-lesing

Jeg ønsker meg en pdf-leser som kan synke hvor langt jeg har kommet, mellom devicer. Slik som Kindle kan med Amazon-bøker. Kindle-appen selv kunne gjerne gjort det…

Men siden den ikke kan … hvem lager det først? Jeg er villig til å betale kr 35 for en slik leser, tenker jeg. Sånn cirka.

Programmeringsglede

«I think that it’s extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don’t think we are. I think we’re responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don’t become missionaries. Don’t feel as if you’re Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don’t feel as if the key to successful computing is only in your hands. What’s in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.»

Alan J. Perlis (April 1, 1922-February 7, 1990)

Initiativ og skapelse

“Concerning all acts of initiative (and creation), there is one elementary truth, the ignorance of which kills countless ideas and splendid plans: that the moment one definitely commits oneself, then Providence moves too. All sorts of things occur to help one that would never otherwise have occurred. A whole stream of events issues from the decision, raising in one’s favor all manner of unforeseen incidents and meetings and material assistance, which no man could have dreamed would have come his way. Whatever you can do, or dream you can do, begin it. Boldness has genius, power, and magic in it. Begin it now.”

- William Hutchinson Murray, The Scottish Himalayan Expedition (1951)

Dare mighty things

«Far better it is to dare mighty things, to win
glorious triumphs, even though checkered by failure,
than to take rank with those poor souls who neither
enjoy much nor suffer much, because they live in the
gray twilight that knows neither victory nor defeat.»
–Theodore Roosevelt

Wordfeud – En uvelkomneste fråtsing i absurde ord, featuring grep

Etter å ha blitt banket ned i støvlene i Wordfeud av “venner” som synes det er okay å legge ord som gjura (perfektum-form av ordet gjure, norr gyrða, som betyr gjorde) og CIF (som er en engelsk forkortelse: Cost, Insurance, Freight, og betyr at en vare leveres uten at du må betale for omkostninger, forsikringer og frakt), og ikke minst klapr (jupp, en avart av klapre), så jeg meg nødt til å utforske den norske ordboka Wordfeud bruker. Wordfeud har samme ordbok i bånn som Bokmålsordboka på nett, og denne grunnordboka kan du laste ned etter å ha registret deg hos Norsk Ordbank.

Med i zip-filen er et par filer som beskriver den elektroniske ordbokens format, og en paradigme-fil som beskriver ordformer og deres bøyninger, men vi skal ikke gå inn i å sette ordene sammen til en komplett liste ved regelbruk. Istedenfor går vi rett i strupen på filen fullform_bm.txt.

Jeg startet min utforskning med å gjøre enkle søk i TextEdit, et Mac-program som tok frem den svære tekstfilen forbausende raskt, og som også søkte i den raskt. Jeg tror de fleste av oss ville ha noe å lære av å se på hvordan TextEdit er implementert, hvis vi fikk sjansen. For da jeg fant ut at jeg ville bruke regulære uttrykk (også kjent som regular expressions, også kjent som regexp eller regex) i mine søk, og dro opp TextMate, ble maskinen til sirup, og etter noen få søk kræsjet den. Det samme skjedde med AquaEmacs.

Det enkle er ofte det beste. Jeg hadde oversett den åpenbare løsningen: grep. Med grep -e (også kjent som egrep) går det lynraskt å søke med regulære uttrykk i den 82 MB store filen.Gå til kommandolinjen, eller terminalen, eller hva du kaller det. La oss gjøre noen enkle søk.

Finnes Ordet?

Lurer du på et spesifikt ord er i ordboken, før du legger det? Finnes ordet “gnu”?

egrep '\bgnu\b' fullform_bm.txt

\b betyr “en tom string ved kanten av et ord”, og du får listet ut alle treffene der ordet “gnu” står alene:

23846	gnu	gnu	verb inf <trans1> <trans11/p?> <refl9/i> normert	040	1
23847	gnu	gnu	subst mask appell ent ub normert	700	1
23846	gnu	gnur	verb pres <trans1> <trans11/p?> <refl9/i> normert	040	2
23847	gnu	gnuen	subst mask appell ent be normert	700	2
23846	gnu	gnus	verb inf pres pass <trans1> <trans11/p?> <refl9/i> normert	040	3
23847	gnu	gnuer	subst mask appell fl ub normert	700	3
23846	gnu	gnudde	verb pret <trans1> <trans11/p?> <refl9/i> normert	040	4
23847	gnu	gnuene	subst mask appell fl be normert	700	4
23846	gnu	gnudd	verb perf-part <trans1> <trans11/p?> <refl9/i> normert	040	5
23846	gnu	gnudd	adj <perf-part> n?yt ub ent <trans1> <trans11/p?> <refl9/i> normert	040	6
23846	gnu	gnudd	adj <perf-part> m/f ub ent <trans1> <trans11/p?> <refl9/i> normert	040	7
23846	gnu	gnudde	adj <perf-part> be ent <trans1> <trans11/p?> <refl9/i> normert	040	8
23846	gnu	gnudde	adj <perf-part> fl <trans1> <trans11/p?> <refl9/i> normert	040	9
23846	gnu	gnuende	adj <pres-part> <trans1> <trans11/p?> <refl9/i> normert	040	10
23846	gnu	gnu	verb imp <trans1> <trans11/p?> <refl9/i> normert	040	11

Andre kolonne er grunnform av ordet (det er den som har gitt oss treffene på det regulære uttrykket her,) tredje kolonne er fullformen av ordet. Gnu finnes selvfølgelig, med en del uventede avarter. Finnes ordet uvelkomneste, da?

egrep '\buvelkomneste\b' fullform_bm.txt

Jada.75803 uvelkommen uvelkomneste adj sup be normert 562 7

Hvilke ord inneholder bokstaven C?

egrep '\b[a-z]*c[a-z]*\b' fullform_bm.txt

Det vi sier her er: gi meg et ord som har 0 eller flere bokstaver mellom a-z (inklusive) og som så har en c, og som så har 0 eller flere bokstaver mellom a-z (inklusive). Listen er lenger enn du kanskje tror. Opsjonen -c gir oss antall linjer:

egrep -c '\b[a-z]*c[a-z]*\b' fullform_bm.txt

skriver ut 10889. Enjoy!

Finnes det ord som inneholder både C og W?

Oh yes, baby.

egrep -c '\b[a-z]*c[a-z]*w[a-z]*\b|\b[a-z]*w[a-z]*c[a-z]*\b' fullform_bm.txt

gir ikke mindre enn 206. Tegnet | betyr “eller”, så her har jeg kombinert de to uttrykkene:

1) finnes det ord med c og så w, med 0 eller flere bokstaver i mellom dem (\b[a-z]*c[a-z]*w[a-z]*\b) ?

med

2) finnes det ord med w og så c, med 0 eller flere bokstaver i mellom dem (\b[a-z]*w[a-z]*c[a-z]*\b) ?

Fra nr. 1 får vi ord som breitschwans, catwalk, cowboy, crawl, patchwork og rickshaw.

Fra nr. 2 får vi for eksempel worldcup, whitecoat og weltschmerz (men Z har vi vel ikke i Wordfeud, så det blir vanskelig å legge)

Forkortelser

Wordfeud skiller seg fra Scrabble ved at det er lov med forkortelser. Men hvilke forkortelser kan du bruke? CIF er lov, og vi finner det igjen i ordboken. Men jeg har f.eks. prøvd å legge SV, uten å få lov til det. Det fortvilede er at forkortelsen SV finnes i filen vår, fullform_bm.txt. Så hva som er lov og ikke lov i Wordfeud, er jeg ikke sikker på. Men som utgangspunkt kan vi i hvert fall ta alle de ordene som, bekvemt nok, er merket med “fork”. Vi kan altså bare gjøre det enkle søket

egrep '\bfork\b' fullform_bm.txt

… og få listet ut alle forkortelser som er lovlige. 1270 stykker, er det. Her er et lite knippe du kan prøve neste gang du er i en knipe:

AD
ADB
AL
AM
AS
ASA
CA (bekreftet)
CD (bekreftet)
CP (bekreftet)

DS
EDB
EEC
EF
EKG
ES
EU
FM
FN
GMT
GT
HMS
KT
krf
MS
MT
MS (bekreftet)
MM (bekreftet)
OL (bekreftet)
Ng (bekreftet)
PVC
PVRK
SI
SM
SS
UHF
UK
UNESCO
USA
YAP

Om du vil titte selv, og bare ønsker deg kolonne 2, den med ordene i, kan du pipe treffene til awk:

egrep -i '\bfork\b' fullform_bm.txt | awk '{ print $2 }'

Leke Mer?

Kjør

info grep

i kommandolinjen, og se under headingen “Regular Expressions” (du finner den samme informasjonen med Google-søket man:grep http://www.google.no/?q=man:grep ).

FAQ

Q: Uttrykkene over kan skrives mer elegant?

A:  Ja, de kan nok det. Jeg har skrevet de regulære uttrykkene for å være enklest mulig å forstå.

Q: Hva med æ, ø, å?

A: Jeg har droppet det for enkelhets skyld. Dermed mister du endel ord ved å bruke uttrykkene slik de er beskrevet over.