C311 第一次作业 收获/扯淡 by hugzh

单元测试

写测试的好处是不用盯着屏幕看了,需要跑几十个用例的时候,用眼看是不是符合预期是非常二的行为。(商用的东西有几万个测试都很正常。。。)
即便是自己开发,也应该写一些非常简单的、预期函数结果的那种测试。
当然只有测试是不够的,关键是要对自己写下的东西有自信,相信它覆盖了足够多的情况。甚至可以称之为“对的”(在所有情况下都表现出正确的行为)
正如课程要求所说

The objective is not simply to write programs that get the correct answers; it is to write answers in the style of programs written in class.

提前写出测试,然后写实现的做法叫做测试驱动开发(TDD),我觉着 TDD 用在小的函数层次还是很管用的。毕竟一个函数越小,它的行为就越容易预测,吧。

不只是方便验证结果。直接拿测试用例那一行,把对应的实参改成形参的时候,往往能想出更好的参数名字。

Racket 自带的测试框架叫 rackunit
http://docs.racket-lang.org/rackunit/api.html

这个作业自带的测试大概长这样,具体实现请自行研究。

    (test-suite "countdown"
      (test-equal-if-defined countdown
        ((countdown 5) '(5 4 3 2 1 0))))

还有就是测试结果有 failure 和 error 的区分。比如一个函数没定义,认为是failure,确实是函数逻辑错了,认为是error。

Natural Recursion

Natural Recursion ,或者说naturally recursive,直接理解就是自然而然的递归。
这个词我搜了很久都没找到确切的意思

参考了这个http://web.mit.edu/6.005/www/fa15/classes/10-recursion/

Think about several ways to break down the problem, and try to write the recursive steps. You want to find the one that produces the simplest, most natural recursive step.
而且所有的问题都不允许用循环,甚至不让用 accumulator 存储中间结果。

姑且认为是用分治法来解决问题,通过把原问题转化为更小的子问题,以及trivial情况下返回显然的解。来解题。
或者反过来说,在给定更小子问题的解的前提下,如何得到更大问题的解。
也就是所谓递推公式、数学归纳。
举个例子

(define (countdown n)
  (if (= n -1)
      '()
      (cons n (countdown (- n 1)))))

(countdown N) 返回从 N到0 的列表。
我这里的实现是说,n==-1时,trivial case,直接返回空表
否则,返回 把 N cons 到 (countdown (- n 1)) 的结果

很多数据类型都可以看成递归数据类型,
lisp 的 list,其实就是个单链表,链表可以是空表,也可以是Head元素指向另一个链表。这就是所谓递归定义。

字符串,字符串有很多种切碎的方法,
可以看作是首元素+字符串
或者 字符串+末尾元素
或者中间切碎 字符串 + 。。。 + 字符串

自然数 是
0
或者 某个自然数的后继 (所谓后继就是数数,0的后继是1,1的后继是2(0的后继的后继),以此类推)

关于分治法可以去补补算法课,MIT 6.006/6.046 都可以的。

我一直觉着分治和动态规划几乎是一回事。。。
都是转成子问题,然后base case直接有解。

BrainTeaser /Just Dessert

这两个单元都是难题,会遇到各种各样奇怪又好玩的东西。有的太难我根本不会。感叹人要有自知之明啊,如果跟这些东西死磕太久,怕是要耗费大把时光还一无所得。

collatz

(define collatz
  (letrec
      ([odd-case
        (lambda (recur)
          (lambda (x)
            (cond 
              ((and (positive? x) (odd? x)) (collatz (add1 (* x 3)))) 
              (else (recur x)))))]
       [even-case
        (lambda (recur)
          (lambda (x)
            (cond 
              ((and (positive? x) (even? x)) (collatz (/ x 2))) 
              (else (recur x)))))]
       [one-case
        (lambda (recur)
          (lambda (x)
            (cond
              ((zero? (sub1 x)) 1)
              (else (recur x)))))]
       [base
        (lambda (x)
          (error 'error "Invalid value ~s~n" x))])
    (one-case (odd-case (even-case base)));; this should be a single line, without lambda
    ))

这次的BrainTeaser叫 collatz,是个很有意思的程序,注意到每个case都是先拿一个参数作为出口,然后再返回一个 number->number 。 也就是
(number->number)->(number->number)只有base是 number->number

然后就可以把每个case组合起来,得到一个考虑到所有case的number->number

base:number->number
odd-case (number->number)->(number->number)
(even-case base) : (number->number)

后面以此类推

quine

quine是这样一种程序,你对它求值,返回程序原代码本身。也就是说,把得到的东西再求职,还得到原代码本身。然后作业是让你自己构造个quine出来。。。
并不会啊。。。
quine参考链接
https://en.wikipedia.org/wiki/Quine_%28computing%29
http://www.nyx.net/~gthompso/quine.htm

后记/扯淡

厚颜无耻的贴个自己的答案https://github.com/hgztheyoung/c311/blob/master/c311recap/a1.rkt
Racket大法好啊。 #;可以注释掉接下来的一对括号内的内容。语义级别的注释真好用啊
注释可以加图片。多好的功能啊。(当然不能在作业里加,会和测试框架冲突。)
Racket的文档质量真的高。遇到程序里不懂的东西,比如match啊,letrec啊, 直接右键,查看文档就好。当然直接看 the little schemer/the seasoned schemer也可以。
DrRacket有重构表达式的功能,很好用,右键,重命名XXX,即可。不过要求整个文件都没有错误,比如重复定义,语法错误等等。
缩进,全选,Tab。即可。
关于Racket 的( ) 、[ ] 和 { }
一个意思, [ ] 起到美观的作用。我的惯用法是

(let ((x 2)
      (y 3))
  (+ x y))
(cond
    ((eq? #t #t) 1)
    (else 2))
(match x
    (1  2)
    (#t 3))

写成

(let ([x 2]
      [y 3])
  (+ x y))
(cond
    [(eq? #t #t) 1]
    [else 2])
(match x
    [1 2]
    [#t 3])

这破文又扯了好多没用的啊。。。

自己认真做作业才会有收获的。
工作好难找啊。

我在行乞发广告摆摊卖艺寻求捐赠。
唯一指定邮箱是 hgz92929@sina.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容