【CS61A 2024秋】Python入门课,全过程记录P7(Week13 Macros开始,更新于2025/2/11)

发布于:2025-02-12 ⋅ 阅读:(88) ⋅ 点赞:(0)

关于

个人博客,里面偶尔更新,最近比较忙。发一些总结的帖子和思考。

江湖有缘相见🤝。如果读者想和我交个朋友可以加我好友(见主页or个人博客),共同学习。笔者是学生,课业还是比较繁重的,可能回复不及时。笔者也正在四处寻找一些可以兼职锻炼知识并且补贴一些生活的工作,如果读者需要一些详细的辅导,或者帮助完成一些简易的lab也可以找我,笔者还是学生,自以为才学有限,也没有高价的理由📖。

新的问题

在这里插入图片描述
可以发现,cs61a归档了,而这个网站是需要Berkeley账号的,还是没法登录。这时候笔者决定使用档案馆网站,去翻网页的归档了。虽然有点难受,但是还能用orz。

对了,textbook是可以直接访问的,在这里

更好的解决方案

我在GitHub上找到了cs61a 2024 fall的归档,这里给出连接link

Week13

Mon Macros

阅读材料

Quasiquotation是反引用,宏展开?

Lab 11: Programs as Data, Macros

Q1: WWSD: Quasiquote

问答题。略。

Q2: If Program

构造if程序。

(define (if-program condition if-true if-false)
  (
    list 'if condition if-true if-false
  )
)
Q3: Exponential Powers

难题啊,太晕了。反引号是给宏展开,列表内元素有逗号的后面的元素所在子列表会进行eval操作。

(define (pow-expr base exp)
  (cond ((= exp 0) 1)  
        ((even? exp) `(square ,(pow-expr base (/ exp 2))))  ; if exp is even, apply square
        (else `(* ,base ,(pow-expr base (- exp 1))))))  ; if exp is odd
Q4: Repeat

宏魔法。

(define-macro (repeat n expr)
  `(repeated-call ,n (lambda () ,expr)))

; Call zero-argument procedure f n times and return the final result.
(define (repeated-call n f)
  (if (= n 1)
      (f)
      (begin (f) (repeated-call (- n 1) f))))

Wed SQL

阅读材料

喜闻乐见SQL。
在这里插入图片描述
居然有ByteDance。
Structured Query Language (SQL)

Disc 11: Macros

Q1: Mystery Macro

神秘的宏。

(define-macro (mystery-macro expr old new)
    (mystery-helper expr old new))

(define (mystery-helper e o n)
  (if (pair? e)
      (cons (mystery-helper (car e) o n) (mystery-helper (cdr e) o n))
      (if (eq? e o) n e)))

功能是把列表中的old替换成new。

Q2: Multiple Assignment

实现同时赋值。

(define-macro (assign sym1 sym2 expr1 expr2)
  `(begin
     (define ,sym1 ,expr1)
     (define ,sym2 ,expr2)))

(assign x y (+ 1 1) 3)
(assign x y y x)
(expect x 3)
(expect y 2)

上面这样简单粗暴的写的。第一次x=2,y=3,第二次,x=3,y=3了。使用eval的话可能是因为优先级比较高。

(define-macro (assign sym1 sym2 expr1 expr2)
  `(begin
     (define ,sym1 ,expr1)
     (define ,sym2 ,(eval expr2))))

(assign x y (+ 1 1) 3)
(assign x y y x)
(expect x 3)
(expect y 2)

Q3: Switch

宏版的Switch。宏真的抽象的黑魔法。这里map内要另外的反引号,引号map递归计算cases里面的元素。

(define-macro (switch expr cases)
    `(let ((val ,expr))
	  ,(cons
	    'cond
	    (map (lambda (case) (cons
	           `(equal? val ,(car case))
		       (cdr case)))
		     cases))))

Optional Contest: Scheme Art

这个貌似是画图的,略了。

Fri Tables

阅读材料

讲解一些SQL知识。

HW 10: SQL

在这里插入图片描述
可以看到sqlite,sqlite是轻量级的数据库。据说大部分的手机APP都使用sqlite,包括微信。

Q1: By Parent Height

创建表格的方法第一次见,是通过UNION实现的。
现在是2025年了,写SQL语句对于AI来说轻而易举,只会CRUD可都得被淘汰。
首先找到有父母的狗,再对应上父母的体重,再根据父母体重排序。

-- All dogs with parents ordered by decreasing height of their parent
CREATE TABLE by_parent_height AS
  SELECT d.name AS dog_name
  FROM dogs d
  JOIN parents p ON d.name = p.child
  JOIN dogs pd ON p.parent = pd.name
  ORDER BY pd.height DESC;
Q2: Size of Dogs

根据体重确定狗的类型。

-- The size of each dog
CREATE TABLE size_of_dogs AS
  SELECT d.name AS name, s.size AS size
  FROM dogs d
  JOIN sizes s
  ON d.height > s.min AND d.height <= s.max;
Q3: Sentences

一堆查表连接。

-- [Optional] Filling out this helper table is recommended
CREATE TABLE siblings AS
  SELECT p1.child AS sibling1, p2.child AS sibling2
  FROM parents p1
  JOIN parents p2 ON p1.parent = p2.parent
  WHERE p1.child < p2.child;

-- Sentences about siblings that are the same size
CREATE TABLE sentences AS
  SELECT "The two siblings, " || s1.name || " and " || s2.name || ", have the same size: " || ss1.size AS sentence
  FROM siblings
  JOIN dogs s1 ON siblings.sibling1 = s1.name
  JOIN dogs s2 ON siblings.sibling2 = s2.name
  JOIN size_of_dogs ss1 ON ss1.name = s1.name
  JOIN size_of_dogs ss2 ON ss2.name = s2.name
  WHERE ss1.size = ss2.size
  ;
Q4: Low Variance

只有满足低方差类型的毛发种类的狗才输出。

-- Height range for each fur type where all of the heights differ by no more than 30% from the average height
CREATE TABLE low_variance AS
  SELECT fur, MAX(height) - MIN(height) AS height_range
  FROM dogs
  WHERE fur IN (
    SELECT d.fur
    FROM dogs d
    JOIN (
      SELECT fur, AVG(height) AS avg_height
      FROM dogs
      GROUP BY fur
    ) AS avg_heights ON d.fur = avg_heights.fur
    GROUP BY d.fur
    HAVING MIN(d.height) >= 0.7 * avg_heights.avg_height
       AND MAX(d.height) <= 1.3 * avg_heights.avg_height
  )
  GROUP BY fur;