ปีใหม่นี้ก็เลยหาเครื่องมือมาช่วยจัดการเวลา ได้ solution ลงตัวที่ klok
กับ chandler
เจ้า chandler นี่เอามาใช้จัดการ GTD ส่วน klok นี่เอามาช่วยคุม flow(ทำงานให้ต่อเนื่องไม่ switch ไปมา) กับ balance เวลาที่จัดสรรให้กับแต่ละ project
Javaเร็วส์, Javascript, Erlang, Python, Ruby, Clojure, Groovy, เลี้ยงลูก, วาดภาพ
(defvar *names*)
(setq *names* '(pok bunny pann pune))
(defun next ()
(nth (random (length *names*)) *names*))
nth คือ function ที่ใช้ access list ที่ตำแหน่ง index ที่ต้องการ(random N) จะได้ค่า integer ระหว่าง 0 ถึง (N-1)(defun next ()
(let ((name (nth (random (length *names*)) *names*)))
(setq *names* (remove name *names*))
name))
(defun next ()
(if (null *names*)
(setq *names* '(pok bunny pann pune)))
(let ((name (nth (random (length *names*)) *names*)))
(setq *names* (remove name *names*))
name))
(defn render-level-layer
"my, what an insane level representation i have here"
[target items if-empty if-full]
(loop [target target
remain (seq items)]
(if remain
(let [x (:x (first remain))
y (:y (first remain))
i (level-index x y)
at (target i)]
(recur (assoc target i (if (= at \space) if-empty if-full))
(rest remain)))
target)))
(def factorial
(fn [n]
(loop [cnt n
acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))))))
(defun factorial (n &optional (acc 1))
(if (<= n 1)
acc
(factorial (- n 1) (* acc n))))
(declare bar)
(defn foo [n]
(if (pos? n)
(bar (dec n))
:done-foo))
(defn bar [n]
(if (pos? n)
(foo (dec n))
:done-bar))
(foo 1000000)
-> java.lang.StackOverflowError
instead of actually making a call in the tail, a function returns the function to be called, and a controlling loop calls it
(declare bar)
(defn foo [n]
(if (pos? n)
#(bar (dec n))
:done-foo))
(defn bar [n]
(if (pos? n)
#(foo (dec n))
:done-bar))

(ns test
(:import (java.util.regex Pattern)))
(defstruct pos :x :y)
(defn explode
"return a pos/type seq for each char in the line"
[y line]
(map (fn [x y type] (vector (struct pos x y) type))
(iterate inc 0) (repeat y) line))
(defn line-explode
"call explode on each line with the appropriate y"
[lines]
(let [linesplit (. Pattern compile "\n" (. Pattern MULTILINE))] ; must be a better way?
(reduce into
(map explode
(iterate inc 0)
(. linesplit split lines)))))
(ns test
(:import (java.util.regex Pattern)))
(defn function-name description params body)
เข่น
(defn plus-9 "plus with 9" [x] (+ x 9))
(defn line-explode
"call explode on each line with the appropriate y"
[lines]
(let bindings body)
เช่น
(let [x 9, y 10] (+ x y))
run แล้วได้ผลลัพท์เป็น 19
ใน bindings ของ let นั้น, variable ที่ถูก bind ก่อน สามารถถูกอ้างถึงโดย variable ที่ bind ทีหลังได้
(let [x 9, y (+ x 7)] (+ x y))
run แล้วได้ผลลัพท์เป็น 25
(let [linesplit (. Pattern compile "\n" (. Pattern MULTILINE))] ; must be a better way?
Pattern linesplit = Pattern.compie("\n", Pattern.MULTILINE);
(reduce into
(map explode
(iterate inc 0)
(. linesplit split lines)))
(. linesplit split lines)(iterate inc 0)
(map + '(1 2 3) '(3 4 5))
=> (4 6 8)
(map + '(1 2 3) '(3 4 5 6 7 8))
=> (4 6 8)
explode ดังนั้นเราต้องตามไปดูว่ามันทำอะไร
(defn explode
"return a pos/type seq for each char in the line"
[y line]
(map (fn [x y type] (vector (struct pos x y) type))
(iterate inc 0) (repeat y) line))
fn ในบรรทัดที่ 4 โดยมันคือการ define function อีกแบบหนึ่ง ซึ่งมีคุณสมบัติแบบ closure
test> (def foo
(let [y 10]
(fn [x] (+ x y))))
#=(var test/foo)
test> (foo 7)
17
ลองเปลี่ยน y ให้เป็น 12 ณ ขณะที่ run
test> (let [y 12] (foo 7))
17
repeat นั่นเป็น infinite list อีกตัวหนึ่ง(repeat 7)
=> (7 7 7 7 7 7 7 7 7 .....)
explode มันก็คือการสร้าง list ของ (pos x y) char นั่นเองtest> (explode 0 "hello")
([{:x 0, :y 0} \h] [{:x 1, :y 0} \e] [{:x 2, :y 0} \l] [{:x 3, :y 0} \l] [{:x 4, :y 0} \o])
(reduce into (map ..))(reduce + [1 2 3 4 5])
=> 15
เขียนอีกอย่างก็คือ
(+ (+ (+ (+ 1 2) 3) 4) 5)
into นั้นทำงานแบบนี้(into [1] [2])
=> [1 2]
(into [1 2 3] [2])
=> [1 2 3 2]
(into [1] [1 2 3])
=>[1 1 2 3]
test> (line-explode "hello\nworld\n")
([{:x 4, :y 1} \d] [{:x 3, :y 1} \l] [{:x 2, :y 1} \r] [{:x 1, :y 1} \o] [{:x 0, :y 1} \w] [{:x 0, :y 0} \h] [{:x 1, :y 0} \e] [{:x 2, :y 0} \l] [{:x 3, :y 0} \l] [{:x 4, :y 0} \o])
(def AsciiToDx {72 -1,
76 1,
75 0,
74 0})
(def AsciiToDx (hash-map 72 -1 76 1 75 0 74 0))
(def AsciiToDx (hash-map 72 -1, 76 1, 75 0, 74 0))
getuser> (get AsciiToDx 72)
-1
user> (conj '(1 2 3) 4)
(4 1 2 3)
user> (conj [1 2 3] 4)
[1 2 3 4]
' ที่หน้า list (1 2 3)() อยู่เต็มไปหมด (ชื่อภาษามันบอกอยู่แล้วว่ามันคือ list)(defstruct pos :x :y)
(defstruct pos :x :y) ให้เป็น (def pos (create-struct :x :y))(struct pos 1 2)
(:x (struct pos 1 2))user> (def mypos (struct pos 1 2)) ;; สร้างตัวแปร mypos ที่เก็บตำแหน่ง (1,2)
#=(var user/mypos)
user> (assoc mypos :x 10) ;; เปลี่ยนค่า x ให้เป็น 10
{:x 10, :y 2}
user> (:x mypos) ;; แสดงค่า x
1
user> (def mypos (assoc mypos :x 10)) ;; ถ้าต้องการเปลี่ยนก็หมายถึงว่าต้อง set mypos ให้ชี้ไปที่ StructMap ตัวใหม่ที่ return จาก assoc
#=(var user/mypos)
user> (:x mypos)
10
user> (vals mypos) ;; return values ของ mypos
(10 2)
user> (keys mypos) ;; return keys ของ mypos
(:x :y)
user> (def get-x (accessor pos :x))
#=(var user/get-x)
user> (get-x mypos)
10
(defstruct level
:player ; pos
:boxes ; set-of-pos
:goals ; set-of-pos
:walls ; set-of-pos
)
(struct level a b c d) ได้(struct-map level
:player (first (filter-level expl-level \@ \+))
:boxes (filter-level expl-level \o \*)
:goals (filter-level expl-level \. \* \+)
:walls (filter-level expl-level \# \#))))
log4j.appender.stdout = "org.apache.log4j.ConsoleAppender"
log4j.appender."stdout.layout"="org.apache.log4j.PatternLayout"
def config = new ConfigSlurper().parse(new File('/tmp/x.groovy').toURL())
topic1.subtopic1=1
["topic1":["subtopic1":1]]
topic1.subtopic1=1
topic1.subtopic1.subofsubtopic1="foo"
groovy.lang.MissingPropertyException: No such property: subofsubtopic1 for class: java.lang.Integer
at script1226551599145.run(script1226551599145.groovy:2)
at Script9.run(Script9:1)
topic1.subtopic1.subofsubtopic1 มันจะไป get value โดยใช้ key topic1.subtopic1 จากนั้นก็พยายามจะ set property subofsubtopic1ลงใน value ที่ได้มาก ซึ่งไม่สำเร็จแน่ๆเพราะ value ที่ได้มันไม่ใช่ map อย่างที่ควรจะเป็นtopic1.subtopic1.subofsubtopic1="foo"
topic1.subtopic1=1
["topic1":["subtopic1":1]]
topic1.subtopic1.subofsubtopic1="foo"
["topic1":["subtopic1":["subofsubtopic1":"foo"]]]
topic1.subtopic1=1
topic1."subtopic1.subofsubtopic1"="foo"
["topic1":["subtopic1":1, "subtopic1.subofsubtopic1":"foo"]]
main = withSocketsDo $ do -- enable sockets under windows
putStrLn "Welcome to One-Way Chat version 1.0"
...
input <- untilM -- get input of 'c' or 's'
(\x -> (not $ null x) && toLower (head x) `elem` "cs")
(putStr "Client or server? " >> getLine)
...
-- monadic `until`
untilM p x = x >>= (\y -> if p y then return y else untilM p x)
import Control.Monad.Fix
main = do ...
...
input <- fix (\loop ->
do putStr "Client or server? "
l <- getLine
if head(l) `elem` "cs" then return l else loop)
...
thunks จาก blog ของ Phil Windley$(document).ready(function() {
$("#orderedlist li:last").hover(function() {
$(this).addClass("green");
},function(){
$(this).removeClass("green");
});
});
expr ? Texpr: Fexpr
int ifexpr( int x, int t, int f )
{
if( x ) return t;
return f;
}
reader <- forkIO $ fix $ \loop -> do
(nr', line) <- readChan chan'
when (nr /= nr') $ hPutStrLn hdl line
loop
f = fix $ \again -> do
more <- checkMaskEvent d enterWindowMask ev
when more again
<feed xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
...
<entry>
<title>xxx</title>
<content>yyyy<content>
<author>bact'</author>
<link href="http://feeds.feedburner.com/~r/bact/~3/326895937/hauntedness-management.html"/>
<feedburner:origLink href="http://bact.blogspot.com/2008/07/hauntedness-management.html"/>
</entry>
...
</feed>
origLink ซึ่ง ROME ไม่มี api ให้ใช้public class Parser implements ModuleParser {
public String getNamespaceUri() {
return FeedburnerModule.FEEDBURNER_URI;
}
public Module parse(Element element) {
Element origLink = element.getChild("origLink", FeedburnerModule.FEEDBURNER_NS);
if (origLink != null) {
FeedburnerModuleImpl impl = new FeedburnerModuleImpl(FeedburnerModule.class, FeedburnerModule.FEEDBURNER_URI);
impl.setOrigLink(origLink.getTextTrim());
return impl;
}
return null;
}
}
def entry0 = feed.entries[0]
def module = entry0.getModule('http://rssnamespace.org/feedburner/ext/1.0')
assertEquals 'http://bact.blogspot.com/2008/07/hauntedness-management.html', module.origLink
![]() |
| 25days |
using XMPP to build a decentralized microblogging platform (think Twitter busted apart to run as a distributed network of microblogging providers)
pphetra@[/usr/local/lib/erlang/lib]
$ ls
appmon-2.1.9 dialyzer-1.8.1 mnesia-4.4.3 ssl-3.9
asn1-1.5.2 docbuilder-0.9.8.4 observer-0.9.7.4 stdlib-1.15.3
common_test-1.3.2 edoc-0.7.6 orber-3.6.9 syntax_tools-1.5.5
...
$ ls -l rab*
lrwxr-xr-x 1 root pphetra 40 Aug 27 13:05 rabbitmq_server -> /Users/pphetra/dev/rabbitmq-server-1.4.0
{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
{mod_caps, []},
...
{mod_rabbiter, []},
...
/sbin/ejabberdctl start/sbin/ejabberdctl status
$ ./ejabberdctl status
Node ejabberd@localhost is started. Status: started
ejabberd is running
$ ./ejabberdctl register pphetra localhost mypassword
$ ./ejabberdclt register sugree localhost anypassword
*help ก็จะได้ message แบบนี้
To give me a command, choose one from the list below. Make sure you prefix it with '*', otherwise I'll interpret it as something you want to send to your group of followers. You can say '*help (command)' to get details on a command you're interested in. If you want to actually say 'help', rather than asking for help, type '*say help' instead.
["*help","*follow","*unfollow","*following","*followers",
"*invite"]
*follow sugree@localhost ก็จะได้รับ message แบบนี้
You are now following sugree@localhost.
I don't know that person. Perhaps you could invite them to get in touch?
*follow x@y มันจะแอบเปลี่ยนเป็น *follow x@y <mailto:x@y> ซึ่งส่งผลให้ rabbiter ไม่รู้จักคำสั่งนี้
git checkout HEAD^^
^
Here is an illustration, by Jon Loeliger. Both node B and C are a
commit parents of commit node A. Parent commits are ordered
left-to-right.
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2 = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2