自动pull全部git工程:技术选择和放弃-故障定位

自动pull全部git工程:技术选择和放弃-故障定位
** git mail
*** mail list
**** http://sourceforge.net/apps/trac/sourceforge/wiki/Git
无动作.配置成本地git也未收到邮件.
**** http://pkill.info/b/1473/setting-up-git-commit-email-notification/
[hooks]
mailinglist = "[email protected] [email protected]"
senderemail = "[email protected]"
**** http://source.winehq.org/git/tools.git/?a=blob_plain;f=git-notify;hb=HEAD
wine开发组用的。执行后停住不动。
** 邮件通知一直失败,做了个脚本,以后每天执行一次,pull更新GIT本地repository。
: echo ------------------------
: echo ec
: cd ec
: git pull .
: cd ..
:
: echo ------------------------
: echo gitadmin/gitosis-admin
: cd gitadmin/gitosis-admin
: git pull origin
: cd ../..
:
: echo ------------------------
: echo gittest/gittest
: cd gittest/gittest
: git pull .
: cd ../..
:
: echo ------------------------
: echo movie
: cd movie
: git pull .
: cd ..
:
: echo ------------------------
: echo patent_monkeyking
: cd patent_monkeyking
: git pull .
: cd ..
:
: echo ------------------------
: echo spr
: cd spr
: git pull .
: cd ..
:
: echo ------------------------
: echo story9000s
: cd story9000s
: git pull .
: cd ..
:
: echo ------------------------
: echo uv
: cd uv
: git pull .
: cd ..
:
: echo web程序设计_网络课程
: cd web程序设计_网络课程
: git pull .
: cd ..
:
: echo ------------------------
: echo 马赛克人名.自动调节曝光时间和电压时间
: cd 马赛克人名.自动调节曝光时间和电压时间
: git pull .
: cd ..
** git pull remote?? config
CLOCK: [2010-09-04 周六 17:20]--[2010-09-04 周六 20:33] => 3:13
*** git bash & gui 不能pull,而tortoise 能
*** git pull -v repository branch ?
*** git remote -v
*** git config -l
*** 找到原因,是因为putty自动载入了[C:Usersibm.ssh]下的 private key [2010-09-04 周六 19:36]
gittest & gitadmin 是用 aa 的账号连接的。
*** tried to copy young.ppk to user ibm's home .ssh directory. failed
for different format.
*** bash uses ssh, not Putty: $ ssh -v git@[马赛克_服务器的IP]
: OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007
: debug1: Connecting to [马赛克_服务器的IP] [[马赛克_服务器的IP]] port 22.
: debug1: Connection established.
: debug1: identity file /c/Users/ibm/.ssh/identity type -1
: debug1: identity file /c/Users/ibm/.ssh/id_rsa type -1
: debug1: identity file /c/Users/ibm/.ssh/id_dsa type -1
: debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
: debug1: match: OpenSSH_4.3 pat OpenSSH*
: debug1: Enabling compatibility mode for protocol 2.0
: debug1: Local version string SSH-2.0-OpenSSH_4.6
: debug1: SSH2_MSG_KEXINIT sent
: debug1: SSH2_MSG_KEXINIT received
: debug1: kex: server->client aes128-cbc hmac-md5 none
: debug1: kex: client->server aes128-cbc hmac-md5 none
: debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
: debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
: debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
: debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
: debug1: Host '[马赛克_服务器的IP]' is known and matches the RSA host key.
: debug1: Found key in /c/Users/ibm/.ssh/known_hosts:1
: debug1: ssh_rsa_verify: signature correct
: debug1: SSH2_MSG_NEWKEYS sent
: debug1: expecting SSH2_MSG_NEWKEYS
: debug1: SSH2_MSG_NEWKEYS received
: debug1: SSH2_MSG_SERVICE_REQUEST sent
: debug1: SSH2_MSG_SERVICE_ACCEPT received
: debug1: Authentications that can continue: publickey,gssapi-with-mic,passwor
: debug1: Next authentication method: publickey
: debug1: Trying private key: /c/Users/ibm/.ssh/identity
: debug1: Trying private key: /c/Users/ibm/.ssh/id_rsa
: debug1: Trying private key: /c/Users/ibm/.ssh/id_dsa
: debug1: Next authentication method: password
: git@[马赛克_服务器的IP]'s password:*** convert young.ppk into young_openssh as OpenSSH Key
:
: ibm@IBM-THINK c:/Users/ibm/Documents/git/ec (master)
: $ ssh -v git@[马赛克_服务器的IP]
: OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007
: debug1: Connecting to [马赛克_服务器的IP] [[马赛克_服务器的IP]] port 22.
: debug1: Connection established.
: debug1: identity file /c/Users/ibm/.ssh/identity type -1
: debug1: identity file /c/Users/ibm/.ssh/id_rsa type -1
: debug1: identity file /c/Users/ibm/.ssh/id_dsa type -1
: debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
: debug1: match: OpenSSH_4.3 pat OpenSSH*
: debug1: Enabling compatibility mode for protocol 2.0
: debug1: Local version string SSH-2.0-OpenSSH_4.6
: debug1: SSH2_MSG_KEXINIT sent
: debug1: SSH2_MSG_KEXINIT received
: debug1: kex: server->client aes128-cbc hmac-md5 none
: debug1: kex: client->server aes128-cbc hmac-md5 none
: debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
: debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
: debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
: debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
: debug1: Host '[马赛克_服务器的IP]' is known and matches the RSA host key.
: debug1: Found key in /c/Users/ibm/.ssh/known_hosts:1
: debug1: ssh_rsa_verify: signature correct
: debug1: SSH2_MSG_NEWKEYS sent
: debug1: expecting SSH2_MSG_NEWKEYS
: debug1: SSH2_MSG_NEWKEYS received
: debug1: SSH2_MSG_SERVICE_REQUEST sent
: debug1: SSH2_MSG_SERVICE_ACCEPT received
: debug1: Authentications that can continue: publickey,gssapi-with-mic,password
: debug1: Next authentication method: publickey
: debug1: Trying private key: /c/Users/ibm/.ssh/identity
: debug1: Trying private key: /c/Users/ibm/.ssh/id_rsa
: debug1: read PEM private key done: type RSA
: debug1: Remote: Forced command: gitosis-serve young_ssh
: debug1: Remote: Port forwarding disabled.
: debug1: Remote: X11 forwarding disabled.
: debug1: Remote: Agent forwarding disabled.
: debug1: Remote: Pty allocation disabled.
: debug1: Authentication succeeded (publickey).
: debug1: channel 0: new [client-session]
: debug1: Entering interactive session.
: debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
: ERROR:gitosis.serve.main:Need SSH_ORIhGINAL_COMMAND in environment.
: debug1: channel 0: free: client-session, nchannels 1
: Connection to [马赛克_服务器的IP] closed.
: debug1: Transferred: stdin 0, stdout 0, stderr 38 bytes in 0.6 seconds
: debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 62.3
: debug1: Exit status 1
:
: ibm@IBM-THINK c:/Users/ibm/Documents/git/ec (master)
: $ git remote show origin
: * remote origin
: Fetch URL: ssh://git@[马赛克_服务器的IP]/ec
: Push URL: ssh://git@[马赛克_服务器的IP]/ec
: HEAD branch: master
: Remote branch:
: master new (next fetch will store in remotes/origin)
: Local ref configured for 'git push':
: master pushes to master (up to date)
*** 总结Convert young.ppk (created by PuTTYGen) as OpenSSH Key;
Copy it into .ssh directory under home directory (of windows ) ;
Name it as id_rsa;
In bash, ssh -v git@[马赛克_服务器的IP];config中的remote被 git pull 忽略了,使用了ssh。
原因不明。可能是安装git时,选择SSH客户端一步,我选择了PuTTY(plink.exe)。当时的屏幕说明中提到,"PuTTY has
better integration with Windows."脚本的最终版本echo ------------------------
echo ec
cd ec
git pull ec master
cd ..echo ------------------------
echo gitadmin/gitosis-admin
cd gitadmin/gitosis-admin
git pull origin master
cd ../..echo ------------------------
echo gittest
cd gittest
git pull gittest master
cd ..echo ------------------------
echo movie
cd movie
git pull movie master
cd ..echo ------------------------
echo patent_monkeyking
cd patent_monkeyking
git pull patent_monkeyking master
cd ..echo ------------------------
echo spr
cd spr
git pull spr master
cd ..echo ------------------------
echo story9000s
cd story9000s
git pull story9000s master
cd ..echo ------------------------
echo uv
cd uv
git pull uv master
cd ..echo web程序设计_网络课程
cd web程序设计_网络课程
git pull web_programming_cai master
cd ..echo ------------------------
echo 马赛克人名.自动调节曝光时间和电压时间
cd 马赛克人名.自动调节曝光时间和电压时间
git pull monkeyking_code master
cd ..

Y-combinator

* Y-combinator[http://www.catonmat.net/blog/derivation-of-ycombinator]
解决在函数中应用匿名函数的问题。1. 使用???替换函名函数,如果执行不到,这代码是可以执行的。: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (
:
: (lambda (list) ; the
: (cond ;
: ((null? list) 0) ; function
: (else ;
: (add1 (??? (cdr list)))))) ; itself
:
: (cdr list))))))2. 以length为参数以后,下面这段代码需要修正后执行,否则报错 "reference to undefined identifier: ???": ((lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list)))))))
: ???)??? 被改为 length 后可执行。
??? 被改为 '(???) 也可以被执行。
??? 被改为 '() 也可以被执行。
看起来,只要???是个可以被引用的东西就行,但是不能是未定义的。
事实上,lambda (length)的参数不管是什么,都会返回 (lambda (list) 这个函数。如下实验:: (((lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (willnot_run_here (cdr list)))))))
: 'place_holer) '() )下面的代码: ((lambda (f)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (f (cdr list)))))))
: ((lambda (g)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (g (cdr list)))))))
: ((lambda (h)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (h (cdr list)))))))
: ???)))"ince the argument names f, g,h in (lambda (f) ...), (lambda (g) ...),
(lambda (h) ...) are independent, we can rename all of them to length,
to make it look more similar to the length function:"以上并非可以替换名字的原因。
真正的原因是,lamda(f)中的参数f,是lamda(g);
lamda(g)中的参数g,是lambda(h);
而h只是占位符,对程序的求值没有任何作用。
以下代码是上面代码的变形,帮助理解。: (((lambda (lambda_lambda_place_holder)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (lambda_lambda_place_holder (cdr list)))))))
: ((lambda (lambda_place_holder)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (lambda_place_holder (cdr list)))))))
: ((lambda (place_holder)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (willnot_run_here (cdr list)))))))
: 'place_holder))) '(a b))下面的代码中,
把lambda(length)作为参数传给lambda (mk-length)
lambda (mk-length) 的执行是以参数作为函数,给这个函数的参数是占位符???;
这个参数此时是 lambda (length)。
lambda (length)的占位符参数没有被求值,函数就结束了。
所以,以下代码能求 '(): ((lambda (mk-length)
: (mk-length ???))
: (lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list))))))))下面的代码中
lambda (mk-length)的执行是,
向mk-length传递参数 (mk-length ???)。
这一参数的解释上面已经提到,执行一次lambda (length)。
执行lambda (length),最后返回的是 length (cdr list)。
即,以lambda (length)作为lambda (length)的参数。
一共执行两次。: ((lambda (mk-length)
: (mk-length
: (mk-length ???)))
: (lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list))))))))既然???是占位符,不会被求值,所以可以: ((lambda (mk-length)
: (mk-length mk-length))
: (lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list))))))))所有的length改在mk-length。
传进来的参数确实是它。
代码略去。然后,length (cdr list) 换成 (mk-length mk-length) (cdr list)。
这样,(mk-length mk-length) 递归地返回 原来的lambda (length) 应用在 (cdr list) 上: ((lambda (mk-length)
: (mk-length mk-length))
: (lambda (mk-length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 ((mk-length mk-length) (cdr list))))))))其实mk-lenth只执行了一次,然后mk-length参数就是占位符了。
但是,"The function works because it keeps adding recursive uses by passing
mk-length to itself, just as it is about to expire."递归的跳出条件是(null? list)。把(lambda (length)移出作为lambda (le)的参数,
(lambda (x)作为le的参数。
代码如下。: ((lambda (le)
: ((lambda (mk-length)
: (mk-length mk-length))
: (lambda (mk-length)
: (le (lambda (x)
: ((mk-length mk-length) x))))))
: (lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list))))))))Y-combinator如下。: (define Y
: (lambda (le)
: ((lambda (f) (f f))
: (lambda (f)
: (le (lambda (x) ((f f) x)))))))匿名函数的应用如下。: ((Y (lambda (length)
: (lambda (list)
: (cond
: ((null? list) 0)
: (else
: (add1 (length (cdr list))))))))
: '(a b c d e f g h i j))另一种Y-combinator的写法,
[http://www.mactech.com/articles/mactech/Vol.07/07.05/LambdaCalculus/]
and [http://www.stanford.edu/class/cs242/readings/vocabulary.html]
"When applied to a function, returns its fixed point."
: (define y
: (lambda (f)
: ((lambda (x) (f (x x)))
: (lambda (x) (f (x x))))))参见TLS书(非pdf页码)pp.171,
如何把lambda (length)移出,从而形成了Y-combinatior的框架。*关键:applying arguemnt lambda on precedure lambda, and eval the
augument lambda in precedure lambda.*另,参考[http://blog.vazexqi.com/2006/07/13/y-combinator]原来看不懂的一个原因是,这本电子书有缺页。
[The Little Schemer - 4th Edition.pdf]是个更完整的版本。

闭包

闭包读 The Little Schemer* pp. 137开始。递归太复杂。** [http://www.michaelharrison.ws/weblog/?p=34]
:
: (define multirember&co
: (lambda (a lat col)
: (cond
: ((null? lat)
: (col '() '()))
: ((eq? (car lat) a)
: (multirember&co a
: (cdr lat)
: (lambda (newlat seen)
: (col newlat
: (cons (car lat) seen)))))
: (else
: (multirember&co a
: (cdr lat)
: (lambda (newlat seen)
: (col (cons (car lat) newlat)
: seen)))))))
基于closures的解释,参见文献[1]。** 文献[2]提到,可以用Dr.Scheme 语言Pretty Big的debug观察。实验。定义multirember&co以后。Dr.Scheme, Pretty Big.
: >(define foo
: (lambda (x y)
: (length x)))
:
: > (multirember&co 'tuna '(tuna aa bb cc) foo)
: 3** 尝试用drscheme"展开"闭包,不支持;求助刘典,用display显示变量,不够直观,只能显示应用求值,不能显示代换的过程。** QUOTE 手动
: (define multirember&co
: (lambda (a lat col)
: (cond
: ((null? lat)
: (col '() '()))
: ((eq? (car lat) a)
: (multirember&co a
: (cdr lat)
: (lambda (newlat seen)
: (col newlat
: (cons (car lat) seen)))))
: (else
: (multirember&co a
: (cdr lat)
: (lambda (newlat seen)
: (col (cons (car lat) newlat)
: seen)))))))
: (define foo
: (lambda (x y)
: (length x)))
:
: ultirember&co 'tuna '(tuna aa bb cc) foo)substitute:The arguments of calling multirember&co:
| calling | current lat | col | col, substituted a and lat
| col, substituted lambda |
| multirember&co | | |
| |
|----------------+-----------------+-----+----------------------------+-------------------------|
| 1st round | (tuna aa bb cc) | col | /
| lambda (x y)(length x) |
The arguments of calling multirember&co:
| calling | current lat | col, before substitution
| col, substituted a and lat
| col, substituted lambda
|
| multirember&co | |
|
|
|
|----------------+-----------------+---------------------------------------------------------+----------------------------------------------------------------------+-------------------------------------------------------------------------------------------|
| 2nd round | (tuna aa bb cc) | lambda (newlat seen) (col newlat
(cons (car lat) seen)) | lambda (newlat seen) (col newlat (cons (car
'(tuna aa bb cc)) seen)) | lambda (newlat seen) ((lambda (x y)(length
x)) newlat (cons (car '(tuna aa bb cc)) seen)) |Note:In the expression
: lambda (newlat seen) (col newlat (cons (car lat) seen))
lat is (tuna aa bb cc), insetead of (aa bb cc).
The substitution happens before multirember&co is called,
so the lat is the original one without cdr applying.
Sic passim.End of the note.The col
lambda (newlat seen) ((lambda (x y)(length x)) newlat (cons (car
'(tuna aa bb cc)) seen))
is from:
lambda (newlat seen)
((lambda (x y)(length x))
newlat
(cons (car '(tuna aa bb cc)) seen))The arguments of calling multirember&co:
| calling | current lat | col, before substitution
| col, substituted a and lat
| col, substituted lambda |
| multirember&co | |
|
| |
|----------------+-------------+---------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------|
| 3rd round | (aa bb cc) | lambda (newlat seen) (col (cons (car
lat) newlat) seen) | lambda (newlat seen) (col (cons (car '(aa bb cc))
newlat) seen) | lambda (newlat seen) ((lambda (newlat seen) ((lambda
(x y)(length x)) newlat (cons (car '(tuna aa bb cc)) seen))) (cons
(car '(aa bb cc)) newlat) seen) |The col
lambda (newlat seen) ((lambda (newlat seen) ((lambda (x y)(length x))
newlat (cons (car '(aa bb cc)) seen))) (cons (car '(bb cc)) newlat)
seen)
is from:
lambda (newlat seen)
((lambda (newlat seen) ((lambda (x y)(length x)) newlat (cons (car
'(aa bb cc)) seen)))
(cons (car '(aa bb cc)) newlat)
seen)The arguments of calling multirember&co:
| calling | current lat | col, before substitution
| col, substituted a and lat
| col, substituted lambda
|
| multirember&co | |
|
|
|
|----------------+-------------+---------------------------------------------------------+--------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 4th round | (bb cc) | lambda (newlat seen) (col (cons (car
lat) newlat) seen) | lambda (newlat seen) (col (cons (car '(bb cc))
newlat) seen) | lambda (newlat seen) ((lambda (newlat seen) ((lambda
(newlat seen) ((lambda (x y)(length x)) newlat (cons (car '(tuna aa bb
cc)) seen))) (cons (car '(aa bb cc)) newlat) seen)) (cons (car '(bb
cc)) newlat) seen) |The col
lambda (newlat seen) ((lambda (newlat seen) ((lambda (newlat seen)
((lambda (x y)(length x)) newlat (cons (car '(tuna aa bb cc)) seen)))
(cons (car '(aa bb cc)) newlat) seen)) (cons (car '(bb cc)) newlat)
seen)
is from:
lambda (newlat seen)
((lambda (newlat seen) ((lambda (newlat seen) ((lambda (x y)(length
x)) newlat (cons (car '(tuna aa bb cc)) seen))) (cons (car '(aa bb
cc)) newlat) seen))
(cons (car '(bb cc)) newlat)
seen)The arguments of calling multirember&co:
| calling | lat | col, before substitution
| col, substituted a and lat
| col, substituted lambda |
| multirember&co | for multirember&co |
|
| |
|----------------+---------------------+---------------------------------------------------------+-----------------------------------------------------------+-------------------------|
| 5th round | (cc) | lambda (newlat seen) (col
(cons (car lat) newlat) seen) | lambda (newlat seen) (col (cons (car
'(cc)) newlat) seen) | |
The col
lambda (newlat seen) ((lambda (newlat seen) ((lambda (newlat seen)
((lambda (newlat seen) ((lambda (x y)(length x)) newlat (cons (car
'(tuna aa bb cc)) seen))) (cons (car '(aa bb cc)) newlat) seen)) (cons
(car '(bb cc)) newlat) seen)) (cons (car '(cc)) newlat) seen)
is from:
lambda (newlat seen)
((lambda (newlat seen) ((lambda (newlat seen) ((lambda (newlat seen)
((lambda (x y)(length x)) newlat (cons (car '(tuna aa bb cc)) seen)))
(cons (car '(aa bb cc)) newlat) seen)) (cons (car '(bb cc)) newlat)
seen))
(cons (car '(cc)) newlat)
seen)There is no 6th round of calling multirember&co, because of cond fullfilled.: ((null? lat)
: (col '() '()))Current lat is (cdr '(cc)), as '().The procedure col has been subsitituted in the previous steps to be
: lambda (newlat seen) ((lambda (newlat seen) ((lambda (newlat seen)
((lambda (newlat seen) ((lambda (x y)(length x)) newlat (cons (car
'(tuna aa bb cc)) seen))) (cons (car '(aa bb cc)) newlat) seen)) (cons
(car '(bb cc)) newlat) seen)) (cons (car '(cc)) newlat) seen)Eval (applying '() '() as arguements on col);(col '() '())
=>
((lambda (newlat seen) ((lambda (newlat seen) ((lambda (newlat seen)
((lambda (newlat seen) ((lambda (x y)(length x)) newlat (cons (car
'(tuna aa bb cc)) seen))) (cons (car '(aa bb cc)) newlat) seen)) (cons
(car '(bb cc)) newlat) seen)) (cons (car '(cc)) newlat) seen))
'()
'()
)* 参考文献[1] [http://www.michaelharrison.ws/weblog/?p=34]Unpacking multirember&co from TLS The purpose of The Little Schemer,
its authors profess, is to teach you to think recursively, and to do
so without presenting too much math or too many computer science
concepts. The book is a ball to read. However, from the perspective of
this reader, who is fairly new to functional programming and totally
new to Scheme, the book gets almost asymptotically more difficult and
complicated towards the end of chapter 8, when we hit the function
multirember&co. Looking around on the web, I noticed quite a few
people had also hit this speed bump and were scratching their heads
about how to go on. I think I can offer some assistance. So, as
threatened yesterday, I now unveil my initial contribution to the wild
world of Lisp, my explication of multirember&co and the concept of
currying. Here's hoping I don't embarrass myself too much.
The Little Schemer, (hereafter "TLS") is the latest iteration of The
Little LISPer, and is presented as a dialogue between teacher and
student. If you take the roll of the student, and try to answer the
teacher's questions, especially those of the form "define this
function whose behavior we've been describing," you can really flex
your neurons. Each chapter is a little more complicated than the
previous, and within each chapter the questions get slightly harder as
you go. It's like walking up a steadily graded hill. Until you get to
page 137 and they hit you with a long function definition, for a
function you've never seen before, and they ask, "What does this do?"Yikes!Here is the code for the function. (Thank you, Geoffrey King, for
transcribing it in your post.)(define multirember&co
(lambda (a lat col)
(cond
((null? lat)
(col '() '()))
((eq? (car lat) a)
(multirember&co a
(cdr lat)
(lambda (newlat seen)
(col newlat
(cons (car lat) seen)))))
(else
(multirember&co a
(cdr lat)
(lambda (newlat seen)
(col (cons (car lat) newlat)
seen)))))))The first clue to dealing with this function is its context. The
previous pages of TLS deal with currying, in which you define a
function like (lambda (x) (lambda(y) (eq? x y) )) — it takes one
argument, parameter x, and then returns the inner function, which also
takes one argument, parameter y. The value you pass as x acts to
customize the inner function by binding the occurance of variable x in
the inner function to the value you passed in. So chapter 8 is about
the practice of wrapping functions in this way.The chapter is also about passing functions as arguments. The first
line of multirember&co, (lambda (a lat col) defines three
parameters. The variables 'a' and 'lat' are by convention used for an
atom and a list of atoms. But 'col' is a function–you have to pass
multirember&co a function that it uses inside its own definition.TLS admits that multirember&co is complicated. "That looks really
complicated!" says the student. But it seeks to simplify the function
by defining functions to stand in for a) the function that will be
passed as 'col'; b) the first inner function defined in the cond
branch (eq? (car lat) a); and c) the inner function defined in the
cond else branch. To try to make you feel better about being up to
your eyelids in deep water, the TLS authors give their functions
friendly names, like "a-friend" and "next-friend." But I prefer names
that tell me what roll the functions play, so here are my renamed
functions:a) the function that will be passed initially as 'col' (and will be
executed last):(define last-function
(lambda(x y) (length x)))b) the function called when a matches (car lat):(define when-match
(lambda (newlat seen) (col newlat (cons (car lat) seen)))c) the function called when the cond else branch executes:(define when-differ
(lambda (newlat seen) (col (cons (car lat) newlat) seen))TLS walks you through an execution of multirember&co, and so will
I. To further simplify things, and reduce the amount of typing I have
to do, I'll change the example in the book. Instead of a four-word lat
with some longer words, let's use (berries tuna fish) for our list,
and we'll keep tuna as our atom argument.Here's multirember&co, with the two inner functions replaced by the
pre-defined helper functions:(define multirember&co
(lambda (a lat col)
(cond
((null? lat)
(col '() '()))
((eq? (car lat) a)
(multirember&co a
(cdr lat)
(when-match)))
(else
(multirember&co a
(cdr lat)
(when-differ))))))When the function is called the first time, a is tuna, lat is (berries
tuna fish), and col is last-function. (car lat) is berries, which does
NOT eq tuna, so the else branch executes: multirember&co is called
with tuna as a, (tuna fish) as lat because we pass (cdr lat) and so we
lose the berries atom at the front of the list, and when-differ as
col.But wait. Actually, we're not just passing the when-differ function we
defined above. Here is that definition:(lambda (newlat seen) (col (cons (car lat) newlat) seen))This definition contains a variable, lat, that has a value at the time
multirember&co is called recursively: (berries tuna fish). So (car
lat) is (quote berries). What we've got here is a version, or an
instance, of when-differ that has a value bound to one of its
variables.This is like currying, this binding of values to the variable of a
function and then using this altered function to do something. I think
that currying, however, refers to wrapping functions so that only one
variable at a time is given a value. What this apparent creation of a
specific instance of the function when-differ DOES have in common with
currying is this: both use closures to encapsulate the instance of the
function with bound variables, or, to be precise, to make a copy of
the function with its own scope that will persist so long as there are
references to the closure. I didn't realize this on my own, of
course. I owe this insight to Richard P. Gabriel's essay The Why of Y,
which you can read in this Dr. Dobb's article or download as a PDF.There's something else in when-differ that will bind to a value:
col. The function passed, remember, is last-function. So we can (and
should) substitute that in for col.Let's give a unique name to the instance (technically the closure) of
the function when-differ that has these two values bound to it:
when-differ-1. Let's write it out, and set it aside for later use:(define when-differ-1
(lambda (newlat seen) (last-function (cons (quote berries) newlat) seen))
)Now, on to iteration two, which we can summarize like this:(multirember&co (quote tuna) (tuna fish) when-differ-1)OK, so this time, (eq? (car lat) a) yields true, and the other branch
of the condexecutes: multirember&co is called with tuna as a, (fish)
as lat, and when-match as col. Once again, thanks to currying, the
definition of when-match contains expressions to which values are
bound:(car lat), which becomes (quote tuna) , and col, which becomes
when-differ-1. Remember, we just recurred by calling multirember&co
with when-differ-1 as the function argument for the parameter col. So
now let's define the resulting instance of when-match as when-match-1:(define when-match-1
(lambda (newlat seen) (when-differ-1 newlat (cons (quote tuna) seen)))
)On on to iteration three–we're nearly there–which we can summarize
like this:(multirember&co (quote tuna) (fish) when-match-1)This time, tuna and fish don't match, which means we're going to recur
with another version of when-differ, when-differ-2:(define when-differ-2
(lambda (newlat seen) (when-match-1 (cons (quote fish) newlat) seen))
)Finally, iteration four:
(multirember&co (quote tuna) () when-differ-2)This time lat is an empty list, which means (null? lat) is true, and
the terminating line (col (quote()) (quote())) is executed. Yay! We're
done!Except…The result of the completed execution (col (quote()) (quote())) has to
be evaluated. Here's where everything turns inside out, or rightside
out if you like.First of all, the value of col in the final iteration was
when-differ-2. So we'll start there.(when-differ-2 (quote()) (quote()))Now, look back up and get the definition of when-differ-2 and
substitute it.((lambda (newlat seen) (when-match-1 (cons (quote
fish) newlat) seen)) (quote()) (quote()))OK, so the parameters newlat and seen both get assigned the value of
an empty list:(when-match-1 (cons (quote fish) (quote())) (quote()))We can simplify this by consing fish onto the empty list:(when-match-1 (fish) (quote()))We have a definition for when-match-1 too. Let's substitute that in now.((lambda (newlat seen) (when-differ-1 newlat (cons (quote tuna)
seen))) (fish) (quote())) )And again assign values, this time (fish) and () to newlat and seen:
(when-differ-1 (fish) (tuna))We're getting somewhere now. Do you see how at each step we're consing
a value onto either seen or newlat? seen has gotten the instance of
tuna, which was the atom we passed to multirember&co at the start,
whereas newlat has gotten the other atom, fish. Guess where berries is
going to go when we get to it.Now, let's substitute our definition of when-differ-1:((lambda (newlat seen) (last-function (cons (quote berries) newlat)
seen)) (fish) (tuna))Which becomes….
(last-function (berries fish) (tuna) )And now we're back where we started, with last-function.( (lambda(x y) (length x)) (berries fish) (tuna) )(length (berries fish) )2So that's how multirember&co works. What does it accomplish? It seems
to separate occurrences of the atom a in the list of atoms lat from
the other atoms in lat, and then it executes last-function using the
list of occurrences and the list of other atoms.In an imperative language like C or Java, you would probably define
two variables, one for each list, and then loop through the list of
atoms, testing each element in the list for equality with a, and then
pushing the element onto either of the two lists. Finally, you would
call the final function with the two lists you built.Consider the differences in this approach. Throughout the loop, you
have several variables remaining in scope, which means you have an
opportunity to munge one of them accidentally. Also, how modular is
this hypothetical code? In C, you could pass the last-function
function as an argument to a procedure that encapsulates the loop, but
try it in Java. No sir, in Java you'd have to call a method to get the
two lists (which would have to come back wrapped into one object,
probably a String[] array) and then call last-function with returnval[
0 ] and returnval[ 1 ]. Not terrible, but not elegant either.That's just scratching the surface, I'm sure. If the example were more
complicated, other implications of the recursive approach might become
clear, at least to smarter people than me. But there is one other
thing to point out.As TLS points out, the function you supply for use with the two lists
is assigned to a parameter names col because "col" stands for
"collector" by convention. What is this function collecting? The two
lists, of course. But more than that each use of col, as it changes
from when-differ to when-match, is persisting the values of the lists
from one step to the next. And that's important because as of page
136, there has been no mention in TLS of an assignment operator. So
even if we wanted to define variables to reference while looping
through the list, we could not. Not yet. After all, such code would
produce what functional programmers refer to, with a sniff, as side
effects.[2] [http://www.rhinocerus.net/forum/lang-scheme/100568-how-why-did-they-do.html]

周末工程 伊阿宋

周末工程 伊阿宋昨天晚上autro和今天上午,花了大约8小时,写了一个小程序。这个小程序的名字叫做Jason,不是英文的詹森,而是希腊神话里大名鼎鼎的伊
阿宋。叫这个名字的原因后面再说,先说说它的作用是这样的。1. 环境和需求
已知电驴支持WEB远程管理。
一台服务器工作在NAT之内,NAT的外网IP是电信链路,动态IP。
在NAT上做电驴和FTP的端口映射(虚拟服务器)。在这种情况下,如果知道NAT 的外网IP,就可以通过IP和端口访问NAT内网的电驴
WEB界面和FTP了。伊阿宋 能回答服务器的外网IP。2. 原理伊阿宋 是Emacs下的lisp程序,
调用了jabber.el。插话,jabber是用于网络聊天的协议,著名的Gtalk使用了这一协议,
另一个著名的聊天工具,MSN,也可以与jabber的服务器群(是这么叫么?)连
起来。还有一个著名的聊天工具 QQ, 也可以与它们相连,不同QQ协议是企业保
密的协议,不公开,反向工具是可能判有期徒刑的。jabber.el是工具在emacs下的jabber客户端,因此也可以视为
gtalk/msn/oicq/qq等的客户端。伊阿宋调用了jabber。当我在NAT外网――也可以是内网,举外网为例是说明它比较强大的意思――或者
任何地方用GTALK联系一下伊阿宋,它已经在NAT内网的一台计算机上运行了。伊阿宋接到GTALK聊天以后,会忽略绝大部分内容,如果没有人操作,看起来就
像一个挂在线上主人离开的GTALK。如果伊阿宋接收到的消息是"/ip",则视为指令,用curl(一个工具,不知请
GOOGLE之)访问某个可以获取外网IP(public IP)的站点,从而得到自己的外
网IP,然后这一IP用消息发送给刚刚发出"/ip"请求的GTALK用户。curl为什么能获取到请求者的外网IP呢?熟悉php/asp/jsp的同学一定知道这些
语言都支持获取浏览器客户端的IP等信息吧。curl在这里扮演了浏览器的角色。
事实上,你可以视curl为命令行的浏览器。伊阿宋把外网IP发送给我的GTALK客户端――上面提到,我在外网。然后我用外网IP加上事先就知道的端口,就可以在世界上任何有网络或有
GPRS/3G的地方,把要下载的电驴资源提交到我的电驴上――运行在NAT内网,配
置了web管理。电驴web管理界面的IP地址是,正是伊阿宋告诉我的。伊阿宋运行
在与电驴相同的NAT内网,具有相同的外网IP。最后,我还可以根据这一外网IP通过FTP下载或移除已经下完成的电驴资源,只
要设置电驴的incoming目录可以被FTP服务器访问就可以了。3. 命名这个小程序为啥叫伊阿宋呢?这个小子当年因为啥啥需要金羊毛,组织了个敢死队,历尽艰险。话说伊阿宋是个牛人,他的老师是个马人,错了,半人马。这匹半人马叫做喀戎,
是比伊阿宋还著名的――最著名的英雄赫拉克勒斯的老师,后来被赫英雄误伤死
了。而赫英雄做了N件伟业,像徒手杀狮子(载于初中语文课本来着),是后来阿喀硫
斯的偶像。阿喀硫斯,这个就牛到大部分人都知道了,就是 布拉德・比特 在特洛伊里扮演
的那个家伙。他的事迹,我就不赘述了。赫英雄的老师也教了伊阿宋。伊阿宋没啥太多的英雄事迹,不过似乎是个领导,
他带了一船人去整金羊毛,这一船人后来有N多都载入了史册。恩,载入了神话。其中有 赫拉克勒斯,刚才我们说过了;还有埃阿斯他爸,埃英雄在特洛伊中戏份
也不少,特洛伊里有两个非亲非故同名的埃阿斯,这个不知道是哪个的爸――查
到了,两位爸爸都在;还有阿喀琉斯他爸,这位兄弟娶了一位女海神,就是她整
出了阿喀硫斯的脚踵;还有忒修斯,后来是雅典的国王……这里N多都是宙斯的
儿子或者波塞东的儿子之类。总之,这么个富二代官二代,及后来的牛人的爹们组成的全明星队,居然拿不到
金羊毛。最后多亏了一位女巫 美狄亚,与我们有关的,她最大的优势就是她是内部人。她
喜欢上了英俊的伊阿宋,背叛了自己的祖国啥的,跟我们的评书里弃暗投明的肖
太后她姑娘有得一拼。伊阿宋答应并兑现诺言娶了美狄亚,但是后来他背信弃义抛弃了她。她诅咒伊阿
宋和并杀害了他们的两个儿子,跑了。后面悲惨的结局不是关键,伊阿宋是通过内部的美狄亚才取得了外网IP,从而得
到金羊毛,这是伊阿宋的故事的亮点。

中国父母的身上藏着十把刀 zz

中国父母的身上藏着十把刀 zz中国父母的身上藏着十把刀:第一刀:砍去民主,种下强权的种子;第二刀:砍去爱心,种下自私的种子;第三刀:砍去诚实,种下说谎的种子
from 牛博山寨 编辑推荐 by (author unknown)
100+ people liked this
Shared by 程颖
我们的家庭教育是磨灭儿童天性的,是把优秀儿童品质赶尽杀绝的钝化教育。是到了反思我们家庭教育的时候了。中国父母的身上藏着十把刀,父母往往在不知不觉
中使用这十把刀,使孩子天生纯真的品性一步步消失怠尽。第一刀:砍去民主,种下强权的种子中国的民主改革应该说已经取得了不小的进展。中国人习惯了在专制下生活。在传统的中国式家庭里父母也就是家里的皇帝。他们说一不二,强行决定孩子应该怎么 样,不能怎么着。现在的孩子估计都不会下跪了,但在家庭生活中我们有没有做到最基本的民主呢?比方说涉及孩子利益的事情父母有没有征求过孩子的意见?当家庭内
部出现争执的时候有没有采用民主的办法来解决问题?父母总是习惯于用简单粗暴的办法,以"都是为了你好"的名义来代替孩子做出决定。而这种行为就是一刀砍去了孩子脑子里的民主意识,而让他觉得强权就能战胜 一切。第二刀:砍去爱心,种下自私的种子当你为如何抚养年迈的父母而与你的兄弟撕破脸皮,为分父母的那点遗产又与你的姐妹大打出手的时候,有没有注意到有一双惶恐的眼睛正疑惑地看着你的表演?当你看到小偷在撬邻居家的门,拉着儿子匆忙离去的时候,有没有发现儿子的另一只手握成了拳头?当女儿告诉你小区花园的水龙头坏了,你是提上工具就去修理或者立即给物业打电话,还是告诉她不要多管闲事?你假装没有看见公共汽车上站不稳的老人,当孩子想起身让座的时候,你却用眼神去制止他。你的这些表现是对孩子潜移默化的家庭教育的一部分,你的每一个行为都在一刀刀砍去孩子的爱心,而在他幼小的心灵里埋下了自私的种子。第三刀:砍去诚实,种下说谎的种子孩子一旦明白说谎就可以不挨揍、不挨骂,或者可以让皮肉之痛尽可能迟一些来临的时候,他就可能慢慢变成说谎专家。小孩子说谎都是被逼出来的。如果我们说实话可以得到实惠,那谁还愿意冒险去说谎呢?很多的孩子都有一个困惑----为什么大人可以说谎,而小孩就不能呢?小孩在思考这个问题的时候说明他已经发觉了大人是经常说谎的。我们给孩子的解释往往是辩解说我们的谎言是"善意"的。但对孩子来讲,善意的也好,恶意的也罢,那都是谎言!第四刀:砍去冒险,种下平庸的种子孩子要下河游泳不是教会他怎样保证自己在水里的安全,而是简单地拒绝——理由当然是危险。孩子要登高也是安全的原因不被允许。孩子都十多岁了,还不敢一个人到门口小卖部去买瓶酱油,因为大街上是危险的。不会自己削苹果,因为刀子是危险的。二十岁的孩子还不会开火做饭,因为煤气是危险的。是啊!现在的社会有些乱,出门有危险,在家也不安全。但俺们就这样一直抱着,他们又如何能长大呢?一点点危险都不能经历的孩子肯定是平庸的。危险处处存
在,躲是不能解决问题的,关键是要教会孩子识别危险,处理危机!第五刀:砍去守纪,种下违法的种子孩子自己过马路很少会去闯红灯。孩子骑车也会规规矩矩地在自行车道里行驶。孩子在幼儿园的时候就背"红灯停,绿灯行"的口诀。可是当他们跟父母一起上街的
时候总是被大人拉扯着不走人行横道线,不走地下通道,也不走人行天桥,而是翻栏杆、横穿马路。大人的借口是我忙,赶时间。殊不知这一刀让孩子体会到的是规则是可以不遵守的,自己的利益大于规则的严肃性。有很多的人已经开上车了,车上带着孩子。脑子
里没有交通规则,眼睛里没有交通标志在街上横冲直撞。非得看到警察叔叔了才收敛一些。这就教会了孩子人治大于法制,在法规的执行者看不见的情况下,我们可以为了自己的利益而肆意践踏法规。哪个人天生就是罪大恶极的呢?不都是从一些占小便宜开始一步步地走向违法的道路的吗?第六刀:砍去善良,种下恶行的种子古人云:勿以恶小而为之,勿以善小而不为。我们不愿意带着孩子去为灾区捐献衣物,因为我们交过税了,那是政府的事情。我们不给街角的乞丐一点施舍,因为他们肮脏。当孩子想给交不起学费又体弱多病的同学捐款的时候,你问他是不是学校规定必须做的,还问学校规定最少捐多少?你在一点一点砍去孩子身上善良的本性。买东西时别人多找了钱,你拖着孩子快速离开。同事得罪了你,你指使孩子偷偷拔掉他自行车的气门心。家里做饭少几棵大葱,你不去找邻居借,而是叫孩子到走廊去"拿"几根。你又一点点地在孩子身上播种着恶行的种子。第七刀:砍去自然,种下破坏的种子在公园游玩时你带着孩子去攀枝摘花。离开的时候孩子要带走垃圾你说不用管有清洁工干。为了让孩子高兴也不管栏杆上禁止的牌子向笼中的猴子投喂食物。喝完饮
料你随手扔瓶子,抽完烟你随地扔烟头。孩子的天性是热爱自然、喜欢动物的。我们却当着孩子的面杀掉了她喜欢的鱼,杀掉了她觉得可爱的鸡鸭。让伤心的孩子怎么也不愿意再吃这些动物了。我们在劝说孩子的时候用的是"万物为我所用"的逻辑。告诉孩子的是为了人类自己的生存,可以戕害一切的生灵!第八刀:砍去创新,种下机械的种子我们可怜的孩子在学校和父母的双重摧残下,已经不懂得什么是创新了。当孩子多问几个为什么的时候,我们或许会因为自己工作的劳累而懒得回答,或许就是他问的问题已经超出了我们的知识范围而敷衍塞责,或许你正在为麻将的不胡 牌而烦恼。而我们惯用的伎俩就是这个等你长大了就懂了!这个不要求掌握,你记住就行了!这个是不会考的!没有为什么!等等等等自以为聪明的说辞。殊不知已经让孩子慢
慢变成了考试动物,脑子机械化了,不会思考了。中国目前最大的悲哀是拥有知识但没有产权。这就是几十年应试教育的恶果。事实上应试教育在很大程度上是父母逼迫的结果。我们在为孩子选择学校的时候首要考
虑的不还是它的升学率吗?我们才不管孩子学到了什么知识,只要能上清华、北大就好!第九刀:砍去欣赏,种下嫉妒的种子孩子小的时候总会毫不掩饰对一个人或者一件东西的欣赏,会毫无顾及地表达出自己的喜爱。孩子告诉父母某某同学多么优秀的时候,父母总是拿孩子的短处去跟他崇拜的人进行比较,要么说看人家多聪明,多努力啊!哪儿像你这么懒啊!要么说要向他学习
啊,给父母争光!这种批评式的比较很容易挫伤孩子的积极性,极大地影响孩子的自尊心。当孩子不知天高地厚的时候会说我要比他还棒。可是一次次地超越不了自己欣赏的对象,又被父母奚落之后,孩子那良好的欣赏的心态就会变成糟糕的嫉妒心了。嫉
妒这个人生的一大公害就被我们天真的孩子学会了!第十刀:砍去竞争,种下仇恨的种子竞争本来是社会发展的动力。一个没有竞争的社会自然就失去了向上的冲劲。人都是在这个竞争的环境中生存的。人类本身就是在动物的竞争中优胜出来的,所以人
天生就有竞争意识。一个再正常不过的事情就是失败者要学会握着优胜者的手真心地向他表示祝贺。我们都可能会在单位被同事超越,在生意场上被对手打败。回到家里我们不是客观地分析失败的原因,争取下次的胜利,更多的是找客观理由,辱骂竞争对手。别以
为你的孩子还小,还听不懂这些大人的事情。他已经从你的身上学会了仇恨超越他的人。学会了为考第一名而在成绩好的同学的水杯里加安眠药!反思吧!我们每个做父母的人都应该反思。当然这一切与社会大环境有关,与统治者有关。但如果我们自己能在培养我们的孩子方面,收起这些刀,让我们的孩子从
小学会真诚、善良、忍让,能够健康地茁壮成长。就能给我们的社会以希望。

独立思考 zz

独立思考

以前,韩寒老师总在博客里强调"独立思考"。大概是看他博客的小孩比较多,当然,傻逼也比较多,所以,时不时提醒一下。以前我没注意人们还不会独立思考,后来写博客,发现确实存在不会独立思考的主儿。连最基本的白话文里解上都有障碍。 什么叫独立思考,这东西说起来很简单,当你有一个正常的价值观判断,你就会独立思考了。但麻烦的是,正常的价值观怎么形成呢?这可不是你经济独立、生活独立就能形成的,需要时间,需要慢慢认识这个世界。新闻里说牛奶里有催性早熟的激素,其实,牛奶里没有激素,别的东西里也有。食品之外的信息,可能也是催性早熟的激素。我常常遇到这样的人,聊天的时候什么都知道,但是什么都不懂。昨天跟土摩托说话,土老师说,那个谁谁谁就代表了这一类人,什么都知道,但什么又都不明白。这也正常,本来,过去,人都成熟了之后才把自己放出来,现在,人都是先把自己放出来再慢慢把自己混熟,总要经历这个过程。熟了总比蒸不熟煮不烂强。 在我看来,很多人的思考是半封建半殖民地思考,不是独立思考。所谓半封建思考,就是不动脑子,但似乎有点体力,就像一有人嚷嚷革命他就跟着喊"同去同去"。所谓半殖民地思考,表现症状是爱动脑子,但只会一个动作,就是寻找对立面,这是典型的山寨版独立思考。这些症状一般体现在愤情身上。打个比方,张三说:牛奶是白色的。但是"山寨独立"由于不喜欢张三,便说:"牛奶是黑色的。"李四说:"牛奶是白色的。"由于"山寨独立"喜欢李四,便说:"牛奶是白色的。"那么,请听题:你们家牛奶是什么颜色的?答案是:看人脸色是什么颜色决定。 在我的祖国,牛奶的颜色确实很难辨别清楚,一般而言,他们说是红色的。这就是在我的祖国,价值观为什么混乱,导致出现那么多半封建半殖民思考型人才的原因。

二猫远征记

二猫远征记去通化。这是二猫的第一次旅游。在这之前,没有去过公园,没有见过山,除了昆虫猫狗和人,没见过别的动物,没坐过火车。在这之后几年,估计她会说:我来我见我征服。远征通化。先是火车。在候车室的时候告诉她,这是长春站,从这上火车。三天后,回程的时候,她说:到了长春站,就到家了。很好的持久记忆。候车的时候,有别的孩子在哭。二猫挺安静。有个妈妈批评她的孩子:你看看那小姐姐多听话,你啥啥啥。我趴二猫耳边:夸你呐。然后是九个小时的火车。好在坐的是两个人的坐,我和二猫妈挤着,二猫有个自己的小空间。伸直小腿一直坐着,怎么劝也不站起来。"停车时才能站起来。"原来是怕摔到。然后是出租车。再加上之前在长春的出租车,总的时间太长了,最终到家还是吐了。抗晕车的训练,看来还任重道远。当天,仍然保持习惯午夜之后才睡。第二天和第三天,每天爬两座山。第二天,准备先爬个小的,家旁边的一座。当年我经常没事的时候爬上去,有的时候还带着狗,基本上十几分钟的事儿。这一次发现太大意啦。刚开始上那条小路我还乐,因为对后面的路满有把握。我抱着二猫先爬一段,回头二猫妈总想拽着草助力。二猫说:"妈妈也上不来啊。"然后很快就发现了问题。草可及肩。而且密不透风。我知道山顶有一块平地,寸草不生的。有这个保底,这及肩的草,也都努力克服了。终于快到山顶。山顶之前的一道沟,发现不对。那沟很浅,跳进去也就是没小腿那么深。可是,草又密又高,还有很多灌木,带刺的也不少。这时早就是背着二猫,而不是抱着了,但是仍然无法通过。回头,万万不可能。那么陡的坡,只要一个失手二猫就满身刺了。向左沿沟走,那有一片庄稼地,估计有路,或者向着记忆中的平台走,希望能走到草少的地方。问二猫。二猫说:向左。我说 我还是去探探前面吧。就是去那块平地,以几棵大树为目标。折了段树枝帮助开路,走一半回来了。灌木开始比我高很多了。还是按二猫的决定,向左。我先踩出一条路。然后再回来抱二猫。二猫妈行走艰难,此时抱二猫已经不安全了。在草不那么密,不需要先开路的地方,我终于想到拍了两张照片。接下来,是向近处的树林还是远处的松林,又犹豫了一阵。原本希望从近处的树林边通过,结果根本不可能通到那里。远处的松林附近,终于发现草矮到腰了。虽然仍然很密。到了庄稼地。小土豆、小辣椒、小茄子、小玉米。二猫收获颇丰。问 二猫怕不怕。答 不怕。妈妈怕了。下山的时候,二猫说:我要上山,我不回家。回家的路上,看到了牛、鸭、鹅。还有鸡,这个以前见过,其余的都是新鲜的。看牛和鸭很认真,比下一天公园看猴感兴趣多了。检查,大家的腿上都挂了彩,我是长裤,好些。用又氧水。二猫怕疼,后来一提腿上的伤就说,都快好了,快看不见了。到家。我妈说另一座山好走些。看天色尚早,又出发。这次路到是不难走,只是远些。从曾经是个小学的地方围墙外,绕到外环线,然后到另一个村子,然后再绕回来。半路上累得休息了好几气。尤其二猫的鞋后来湿了,只能一直抱着。才知道,稍事休息是多么的必要。回去的路上,二猫说 我不累。刚一进家门,认出来了,大喊: 我不回家,我要上山。在这第二座山的路上,碰到条小小的长毛狗,追着我们叫。我看二猫怕,抱着退,狗越是要追。后来见二猫往我身上爬,吓到了,把她交给二猫妈,拿个破蒿子杆冲向那狗。这家伙跑玉米地里没影了,二猫大笑。还有一处。红色的石头,下面是一大片白花点缀的草地。我正扔石头下去,二猫在远处喊:爸爸我也要扔那个球。拿到石头以后,二猫说:我要向没人的地方扔。恩。很懂事。可是此地只有三个人而已。这一天,又是午夜才睡。第三天二猫累了,耍赖。我看书。后来想通了,又要爬山。本来我想对付一下爬个矮的得了,后来发现是误会了,还是按昨天的计划爬了公园,叫玉皇山。二猫这个胆小的孩子,平时都不敢坐一两元钱投币的那种会摇的小动物车。这次主动坐了两种火车。看猴、看鸸MIAO,则没多大兴趣。可能,排除笼子的干扰是件挺吃力的事吧。反正对相机,这事挺难的。然后是望山亭,这已经翻过了山。我妈和哥正好追及。讨论了一下,去看曾经住过的老房子,不知道怎么样了。沿途给二猫讲,这里这里发生过些什么事。老房子,已经完全是平地了。邻居们早都搬走,有几家根本不再住人,大门外荒草丛生。去了小时候哥带我放风筝的山包,那里现在是个凉亭。哥说看到条蛇,我们赶紧又下来了。在凉亭上,哥和我抓着铁条试试能把到此一游写多高(没写)。二猫妈说:你看他们两个淘气呢。二猫说:再淘一个。然后去了黑森森,远看绿得发黑的森林。里面有种一捅就冒烟的真菌。二猫一边捅一边说 冒烟冒烟。后来大家找到好几个,跟二猫一起捅。两天,爬了四座山。后来是亲戚们吃饭。没意思,二猫有同感,先走了。第四天一大清早,返程。在车站排除,二猫要出去玩。我指着入口说:咱们一会从这出去,上火车玩。艰难的九个小时。二猫累趴下了。到长春以后,二猫晕车。后来公共汽车、出租车地倒,一共12个小时。到家了。最后一段,二猫坐在小婴儿推车里说,这是我小时候坐的。小脑袋靠在椅背上。这是艰难的旅程。二猫独立做了一些决定,表达了自己的意见,参与克服困难。后面还会有更多的困难,不过,相信二猫都会像这样一件件征服。所有的困难,克服以后,都成为了回忆,成为你之为你的重要组成部分。想拥有什么样的记忆,什么样的未来,就努力做现在吧。两天八百公里,两天四坐山。是为二猫远征记。

前一段时间写的aurora,用来统计文本文件里单词的数量的

前一段时间写的aurora,用来统计文本文件里单词的数量的。
源代码如下。
//// console版
#include "cai.h"
#include <iostream>
 
using namespace std;
// cai.exe -text file_name -delimiter file_name -skip file_name -dup file_name -sort freq
main(int argc, char* argv[])
{
    ios::sync_with_stdio(false);
    error err = OK;
    cmd_argument cmd;
    cmd = parse_cmd_argument(argc, argv, err);
    cout << "In memeory of Aurora(1984)" << endl;
    cout << "Programming by [email protected]" << endl;    
    if (err!=OK)
    {
        cout << "cmd arguments parsing error." << endl;
        cout << "cai.exe -text file_name -delimiter file_name -skip file_name -dup file_name -sort freq|alph" << endl;
    }
    
    input_text(cmd.text_file_name, err);
    get_skip_table(cmd.skip_table_file_name, err);
    get_dup_table(cmd.dup_table_file_name, err);
    get_delimiter_table(cmd.delimiter_table_file_name, err);
    
    segement();
    remove_skip();
    
    remove_dup();
    output_vocabulary(cmd.sort);
}
 
/////
/// cai.h for console version.
/////
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cctype>
using namespace std;
struct cmd_argument
{
    string text_file_name;
    string delimiter_table_file_name;
    string skip_table_file_name;
    string dup_table_file_name;
    string sort;
};
vector<string> skip_table;
vector<char> delimiter_table;
map<string, string> dup_table;//varint(meaning) for key, root(mean) for value
string whole_text;
vector<string> text_segmented;
vector<string> text_skip_removed;
vector<string> text_dup_removed;
map<string, int> voc_output;
enum error
{
    OK,
    cmd_pasrsing_error
};
// cai.exe -text file_name -delimiter file_name -skip file_name -dup file_name -sort freq
cmd_argument parse_cmd_argument(int argc, char* argv[], error& err)
{
    cmd_argument cmd;
    if (argc != 11)
    {
        err = cmd_pasrsing_error;
    }
    else
    {
        cmd.text_file_name = argv[2];
        cmd.delimiter_table_file_name = argv[4];
        cmd.skip_table_file_name = argv[6];
        cmd.dup_table_file_name = argv[8];
        cmd.sort = argv[10];
    }
    
    return cmd;
}
void input_text(string file_name, error& err)
{
//    cout << "input:" << file_name << endl << endl;
    string line;
    int line_count = 0;
    ifstream f(file_name.c_str());
    while(getline(f, line))
    {
        whole_text += line+" ";
        ++line_count;
    }
    string foo = "Some Mixed Case Text";
    transform(whole_text.begin(), whole_text.end(), whole_text.begin(), ::tolower);
//    cout << line_count << " lines" << endl;
    
}
void get_skip_table(string file_name, error& err)
{
//    cout << "skip:" << file_name << endl << endl;
    string line;
    ifstream f(file_name.c_str());
    while(getline(f, line))
    {
        skip_table.push_back(line);
    }
}
void get_dup_table(string file_name, error& err)
{
//    cout << "dup:" << file_name << endl << endl;
    string line;
    ifstream f(file_name.c_str());
    stringstream ss;
    string variant;
    string root;
    string word;
//    cout << "---" << endl;
    while(getline(f, line))
    {
        ss.clear();
        ss << line;
        for (int i = 0; ss >> word; ++i)
        {
            if (i==0)
            {
                root = word;
            }
            else
            {
                variant = word;
                dup_table[variant]=root;
            }
        }
    }
}
void get_delimiter_table(string file_name, error& err)
{
//    cout << "delimiter:" << file_name << endl << endl;
    char space;
    ifstream f(file_name.c_str());
    while(f >> space)
    {
        delimiter_table.push_back(space);
    }
    
}
// whole_text is fileted with delimiter talbe into text_segmented
void segement()
{
//    cout << "skip:" ;
/*     for (vector<string>::iterator i = skip_table.begin(); i!=skip_table.end() ; ++i) */
/*     { */
/*         cout << *i << "t"; */
/*     } */
//    cout << endl << endl;
//    cout << "dup:" << endl;
/*     for (map<string, string>::iterator i = dup_table.begin(); i!=dup_table.end() ; ++i) */
/*     { */
/*         cout << i->first << "t" << i->second << endl; */
/*     } */
//    cout << endl << endl;
/*     cout << "delimiter:" << endl; */
/*     for (vector<char>::iterator i = delimiter_table.begin(); i!=delimiter_table.end() ; ++i) */
/*     { */
/*         cout << *i << "t"; */
/*     } */
/*     cout << endl << endl; */
    
    
        ///
    for (vector<char>::iterator i=delimiter_table.begin(); i != delimiter_table.end(); ++i)
    {
        replace(whole_text.begin(), whole_text.end(), *i, ' ');
    }
    stringstream ss;
    ss << whole_text;
    string word;
    while(getline(ss, word, ' '))
    {
        if (word!="")
        {
            text_segmented.push_back(word);
        }
    }
/*     cout << "----------" << endl; */
/*     for (vector<string>::iterator i=text_segmented.begin(); i != text_segmented.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
    
}
void remove_skip()
{
    bool skip = false;
    for (vector<string>::iterator i = text_segmented.begin(); i != text_segmented.end(); ++i)
    {
        for (vector<string>::iterator j = skip_table.begin(); j != skip_table.end(); ++j)
        {
            if (*i == *j)
            {
                skip = true;
                break;
            }
        }
        if (skip==false)
        {
            text_skip_removed.push_back(*i);
        }
        else
        {
            skip=false;
        }
    }
/*     for (vector<string>::iterator i=text_skip_removed.begin(); i != text_skip_removed.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
}
    
void remove_dup()
{
    for (map<string, string>::iterator j = dup_table.begin(); j != dup_table.end(); ++j)
    {
        replace(text_skip_removed.begin(), text_skip_removed.end(), j->first, j->second);
    }
    text_dup_removed = text_skip_removed;
/*     for (vector<string>::iterator i=text_dup_removed.begin(); i != text_dup_removed.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
}
bool more_freq (const pair<string,int>& a, const pair<string,int>& b)
{
    return a.second > b.second;
}
void output_vocabulary(string sorting)
{
    for (vector<string>::iterator i=text_dup_removed.begin(); i != text_dup_removed.end(); ++i)
    {
        voc_output[*i]++;
    }
    if (sorting=="freq")
    {
        vector<pair<string, int> > voc; //(voc_output.begin(), voc_output.end());
        for (map<string,int>::iterator i=voc_output.begin();
             i != voc_output.end();
             ++i)
        {
            voc.push_back(*i);
        }
        sort(voc.begin(), voc.end(), more_freq);
        cout << "-------------------" << endl;
        cout << "vocabularytcount sorted by freq" << endl;
        for (vector<pair<string, int> >::iterator i = voc.begin(); i != voc.end(); ++i)
        {
            cout << i->first << "tt" << i->second << endl;
        }
    }
    else
    {
        cout << "-------------------" << endl;
        cout << "vocabularytcount sorted by alph" << endl;
        for (map<string,int>::iterator i=voc_output.begin(); i != voc_output.end(); ++i)
        {
            cout << i->first << "tt" << i->second << endl;
        }
    }
    
    
}
//// GUI version
///auroraDlg.cpp
//////////////
void CAuroraDlg::OnOK() 
{
const char pszFilter[] = _T("TXT File (*.txt)|*.txt|All Files (*.*)|*.*||");
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,  pszFilter, this);
CString strFilePath;
if(dlg.DoModal() == IDOK)
{
strFilePath = dlg.GetPathName();
}
char file_name[1024];
strcpy(file_name,  (LPCTSTR)strFilePath );
 
    error err = OK;
 
m_text_out = "reading...";
UpdateData(FALSE);
    input_text(file_name, err);
m_text_out = "reading...done";
UpdateData(FALSE);
get_skip_table("skip.txt", err);
    get_dup_table("dup.txt", err);
    
get_delimiter_table("space.txt", err);
     
m_text_out = "segmenting the text...";
UpdateData(FALSE);
    segement();
m_text_out = "segmenting the text...done";
UpdateData(FALSE);
m_text_out = "removing spaces...";
UpdateData(FALSE);
    remove_skip();
m_text_out = "removing spaces...done";
UpdateData(FALSE);
m_text_out = "merging the words duplicated...";
UpdateData(FALSE);
    remove_dup();
m_text_out = "merging the words duplicated...done";
UpdateData(FALSE);
 
m_text_out = "sorting...";
UpdateData(FALSE);
    output_vocabulary("freq");
m_text_out = "sorting...done";
UpdateData(FALSE);
m_text_out = text_out.c_str();
UpdateData(FALSE);
}
//// cai.h for GUI.h
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cctype>
using namespace std;
struct cmd_argument
{
    string text_file_name;
    string delimiter_table_file_name;
    string skip_table_file_name;
    string dup_table_file_name;
    string sort;
};
vector<string> skip_table;
vector<char> delimiter_table;
map<string, string> dup_table;//varint(meaning) for key, root(mean) for value
string whole_text;
vector<string> text_segmented;
vector<string> text_skip_removed;
vector<string> text_dup_removed;
map<string, int> voc_output;
string text_out;
enum error
{
    OK,
    cmd_pasrsing_error
};
// cai.exe -text file_name -delimiter file_name -skip file_name -dup file_name -sort freq
cmd_argument parse_cmd_argument(int argc, char* argv[], error& err)
{
    cmd_argument cmd;
    if (argc != 11)
    {
        err = cmd_pasrsing_error;
    }
    else
    {
        cmd.text_file_name = argv[2];
        cmd.delimiter_table_file_name = argv[4];
        cmd.skip_table_file_name = argv[6];
        cmd.dup_table_file_name = argv[8];
        cmd.sort = argv[10];
    }
    
    return cmd;
}
void input_text(string file_name, error& err)
{
//    cout << "input:" << file_name << endl << endl;
    string line;
    int line_count = 0;
    ifstream f(file_name.c_str());
    while(getline(f, line))
    {
        whole_text += line+" ";
        ++line_count;
    }
    string foo = "Some Mixed Case Text";
    transform(whole_text.begin(), whole_text.end(), whole_text.begin(), ::tolower);
//    cout << line_count << " lines" << endl;
    
}
void get_skip_table(string file_name, error& err)
{
//    cout << "skip:" << file_name << endl << endl;
    string line;
    ifstream f(file_name.c_str());
    while(getline(f, line))
    {
        skip_table.push_back(line);
    }
}
void get_dup_table(string file_name, error& err)
{
//    cout << "dup:" << file_name << endl << endl;
    string line;
    ifstream f(file_name.c_str());
    stringstream ss;
    string variant;
    string root;
    string word;
//    cout << "---" << endl;
    while(getline(f, line))
    {
        ss.clear();
        ss << line;
        for (int i = 0; ss >> word; ++i)
        {
            if (i==0)
            {
                root = word;
            }
            else
            {
                variant = word;
                dup_table[variant]=root;
            }
        }
    }
}
void get_delimiter_table(string file_name, error& err)
{
//    cout << "delimiter:" << file_name << endl << endl;
    char space;
    ifstream f(file_name.c_str());
    while(f >> space)
    {
        delimiter_table.push_back(space);
    }
    
}
// whole_text is fileted with delimiter talbe into text_segmented
void segement()
{
//    cout << "skip:" ;
/*     for (vector<string>::iterator i = skip_table.begin(); i!=skip_table.end() ; ++i) */
/*     { */
/*         cout << *i << "t"; */
/*     } */
//    cout << endl << endl;
//    cout << "dup:" << endl;
/*     for (map<string, string>::iterator i = dup_table.begin(); i!=dup_table.end() ; ++i) */
/*     { */
/*         cout << i->first << "t" << i->second << endl; */
/*     } */
//    cout << endl << endl;
/*     cout << "delimiter:" << endl; */
/*     for (vector<char>::iterator i = delimiter_table.begin(); i!=delimiter_table.end() ; ++i) */
/*     { */
/*         cout << *i << "t"; */
/*     } */
/*     cout << endl << endl; */
    
    
        ///
    for (vector<char>::iterator i=delimiter_table.begin(); i != delimiter_table.end(); ++i)
    {
        replace(whole_text.begin(), whole_text.end(), *i, ' ');
    }
    stringstream ss;
    ss << whole_text;
    string word;
    while(getline(ss, word, ' '))
    {
        if (word!="")
        {
            text_segmented.push_back(word);
        }
    }
/*     cout << "----------" << endl; */
/*     for (vector<string>::iterator i=text_segmented.begin(); i != text_segmented.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
    
}
void remove_skip()
{
    bool skip = false;
    for (vector<string>::iterator i = text_segmented.begin(); i != text_segmented.end(); ++i)
    {
        for (vector<string>::iterator j = skip_table.begin(); j != skip_table.end(); ++j)
        {
            if (*i == *j)
            {
                skip = true;
                break;
            }
        }
        if (skip==false)
        {
            text_skip_removed.push_back(*i);
        }
        else
        {
            skip=false;
        }
    }
/*     for (vector<string>::iterator i=text_skip_removed.begin(); i != text_skip_removed.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
}
    
void remove_dup()
{
    for (map<string, string>::iterator j = dup_table.begin(); j != dup_table.end(); ++j)
    {
        replace(text_skip_removed.begin(), text_skip_removed.end(), j->first, j->second);
    }
    text_dup_removed = text_skip_removed;
/*     for (vector<string>::iterator i=text_dup_removed.begin(); i != text_dup_removed.end(); ++i) */
/*     { */
/*         cout << *i << endl; */
/*     } */
}
bool more_freq (const pair<string,int>& a, const pair<string,int>& b)
{
    return a.second > b.second;
}
void output_vocabulary(string sorting)
{
    for (vector<string>::iterator i=text_dup_removed.begin(); i != text_dup_removed.end(); ++i)
    {
        voc_output[*i]++;
    }
    if (sorting=="freq")
    {
        vector<pair<string, int> > voc; //(voc_output.begin(), voc_output.end());
        for (map<string,int>::iterator i=voc_output.begin();
             i != voc_output.end();
             ++i)
        {
            voc.push_back(*i);
        }
        sort(voc.begin(), voc.end(), more_freq);
//        cout << "-------------------" << endl;
//        cout << "vocabularytcount sorted by freq" << endl;
text_out = "vocabularytcount sorted by freqrn";
vector<pair<string, int> >::iterator j;
        for (j = voc.begin(); j != voc.end(); ++j)
        {
            //cout << j->first << "tt" << j->second << endl;
stringstream ss;
string num;
ss << j->second;
ss >> num;
text_out += j->first;
text_out += "tt";
text_out += num;
text_out += "rn";
        }
    }
    else
    {
//        cout << "-------------------" << endl;
//        cout << "vocabularytcount sorted by alph" << endl;
text_out = "vocabularytcount sorted by alphr";
map<string,int>::iterator k;
        for (k=voc_output.begin(); k != voc_output.end(); ++k)
        {
            //cout << k->first << "tt" << k->second << endl;
stringstream ss;
string num;
ss << k->second;
ss >> num;
text_out += k->first;
text_out += "tt";
text_out += num;
text_out += "rn";
        }
    }
    
    
}
/////////////////////////
///////// diff console GUI
$ diff cai.h GUI/aurora/cai.h
29a30
> string text_out;
249,253c250,264
<         cout << "-------------------" << endl;
<         cout << "vocabularytcount sorted by freq" << endl;
<         for (vector<pair<string, int> >::iterator i = voc.begin(); i != voc.end(); ++i)
<         {
<             cout << i->first << "tt" << i->second << endl;
---
> //        cout << "-------------------" << endl;
> //        cout << "vocabularytcount sorted by freq" << endl;
> text_out = "vocabularytcount sorted by freqrn";
> vector<pair<string, int> >::iterator j;
>         for (j = voc.begin(); j != voc.end(); ++j)
>         {
>             //cout << j->first << "tt" << j->second << endl;
> stringstream ss;
> string num;
> ss << j->second;
> ss >> num;
> text_out += j->first;
> text_out += "tt";
> text_out += num;
> text_out += "rn";
258,262c269,283
<         cout << "-------------------" << endl;
<         cout << "vocabularytcount sorted by alph" << endl;
<         for (map<string,int>::iterator i=voc_output.begin(); i != voc_output.end(); ++i)
<         {
<             cout << i->first << "tt" << i->second << endl;
---
> //        cout << "-------------------" << endl;
> //        cout << "vocabularytcount sorted by alph" << endl;
> text_out = "vocabularytcount sorted by alphr";
> map<string,int>::iterator k;
>         for (k=voc_output.begin(); k != voc_output.end(); ++k)
>         {
>             //cout << k->first << "tt" << k->second << endl;
> stringstream ss;
> string num;
> ss << k->second;
> ss >> num;
> text_out += k->first;
> text_out += "tt";
> text_out += num;
> text_out += "rn";

俯卧撑暂停,昨天开始恢复

俯卧撑暂停,昨天开始恢复
一周多以来,俯卧撑暂停,昨天开始恢复。
最初打算停俯卧撑是因为头疼似乎要感冒,这个时候心肺功能差到不能支撑俯卧
撑这等高强度的体力运动,但是勉力支撑了。隔天左手腕疼,用右手腕一顿治疗,
其结果是当天根本不能承重,仅可以敲计算机键盘,于是俯卧撑有理由暂停了。
再隔天,开始发烧。
然后,是一周多不能撑。
牢记"球员一般都是从伤病期或者冬歇期开始堕落的",所以昨天开始恢复。刚
结束的时候心中窃喜,没事儿。然后是接连几分钟倒气儿,估计脸色煞白,因为
恶心够呛。今天又继续,心肺正在恢复,没有昨天那么难受了,只是左腕又开始
疼了。
很郁闷,难道人生最黄金的时段已经在不经意间结束了?
想喝酒,胃不行;想别咖啡,戒了。
唉。
我想没有人能说:我在最艰难的时候没有放弃。因为你并不知道你的更艰难是不
是已经到来了,也许后面有更艰难的,这只是刚刚开始呢。
不过,我们也许可以说:我在比你更艰难的时候没有放弃过。或者,我比你们更
坚韧。
想起个笑话。
当年高中的时候体育课,老师掐表大家比赛屏气。
老师开始数秒:开始,多少多少秒啦,多少多少分啦。
还屏着气的就举着手,不行了就放下。
我眼前都发黑了,还有不少人举着手。我终于败下阵来。
结果老师统计的时候才知道,这帮家伙有不少是从一分钟甚至更晚才开始屏气,
而不是像我从最开始。
所以,我以三分钟排行第一。而那些四五分才放下手的,有的才屏气一分钟而已。
所幸,我没有憋死,终于发现了这个秘密。那就是很少有人像你一样尽力。你特
别难受的时候,有很多人比你更难受。
所以,坚持,是一个秘诀。
当然,后来才知道还有富二代这种事。所以在劝导学生应该如何做人的时候,我
一向非常小心。一是我并不成功,无以教人,二是说不定对面爷是位富二代,心
里不定多鄙视我这点见识呢。
所以,修正,坚持,对于穷小子来说,是一个秘诀。
当然,后来才知道还有 劳动致富已经成了传说 这种事。这太超乎我的想像力
和思考能力了,不提也罢。
就像俯卧撑。就有那种天赋异禀根本不用练也牛得不行的人,还有那种根本不需
要练连喘气都可以有人代劳的人,就有那种连气都可以不喘的人。不过,那对我
有什么意义呢?
虽然俺也是社会动物,但是从没有人能替俺过这生活。大家如此不同,又怎么能
通过相同的路径到达。。。谁知道是否相同的目标呢。
所以,还是努力练下去。每天一百。我没有别的路可走,所以只能依此前行。
当你别无选择,还有什么可以苦恼的。