How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

时间:2022-01-06 21:46:06

1 Arithmetic 算数

四种原子数据

  1. numbers
  2. strings
  3. boolean values
  4. images
-----------------------------------------

1.1 The Arithmetic of Numbers 

Exercise 1. Add the following definitions for  x and  y to DrRacket’s definitions area:
(define x 3)
(define y 4)
Now imagine that  x and  y are the coordinates of a Cartesian point. Write down an expression that computes the distance of this point to the origin, that is, a point with the coordinates ( 0, 0).
my code:
(define x 3)
(define y 4)
(define (square x)(* x x))

(sqrt (+ (square x) (square y)))
-----------------------------------------------------------------------------------

1.2 The Arithmetic of Strings

字符串的拼接,像python中的 str1 + str2

> (string-append "what a " "lovely " "day" " 4 BSL")

"what a lovely day 4 BSL"

Exercise 2. Add the following two lines to the definitions area:
(define prefix "hello")
(define suffix "world")
Then use string primitives to create an expression that concatenates  prefix  and  suffix  and adds  "_"  between them. When you run this program, you will see  "hello_world"  in the interactions area.

My code

(define prefix "hello")
(define suffix "world")

(string-append prefix "_" suffix)
--------------------------------------------------------------

1.3 Mixing it Up

Exercise 3. Add the following two lines to the definitions area:

(define str "helloworld")
(define i 5)
Then create an expression using string primitives that adds  "_" at position  i. In general this means the resulting string is longer than the original one; here the expected result is  "hello_world".
Position means  i characters from the left of the string, but programmers start counting at  0. Thus, the 5 th letter in this example is  "w", because the  0th letter is  "h"Hint When you encounter such “counting problems” you may wish to add a string of digits below  str to help with counting:
(define str "helloworld")
(define ind "0123456789")
(define i 5)

My code:

(define str "helloworld")
(define i 5)

(string-append
 (substring str 0 i)
 "_"
 (substring str i))

Exercise 4. Use the same setup as in exercise 3 to create an expression that deletes the ith position from str. Clearly this expression creates a shorter string than the given one. Which values for i are legitimate?

My code:

(define str "helloworld")
(define i 5)

(string-append
 (substring str 0 i)
 (substring str (+ i 1)))

----------------------------------------------------------

1.4 The Arithmetic of Images

(require 2htdp/image)  首先导入图形库

  • circle produces a circle image from a radius, a mode string, and a color string;

  • ellipse produces an ellipse from two radii, a mode string, and a color string;

  • line produces a line from two points and a color string;

  • rectangle produces a rectangle from a width, a height, a mode string, and a color string;

  • text produces a text image from a string, a font size, and a color string; and

  • triangle produces an upward-pointing equilateral triangle from a size, a mode string, and a color string.

> (circle 10 "solid" "green")

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

> (rectangle 10 20 "solid" "blue")

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

> (star 12 "solid" "gray")

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据


除了绘制图形,还能获取图形参数

  • image-width determines the width of an image in terms of pixels;

  • image-height determines the height of an image;

> (image-width (circle 10 "solid" "red"))

20

> (image-height (rectangle 10 20 "solid" "blue"))

20


(+ (image-width (circle 10 "solid" "red"))
   (image-height (rectangle 10 20 "solid" "blue")))

40

>

Exercise 6. Add the following line to the definitions area:

(define cat How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据)

Create an expression that counts the number of pixels in the image.

my code:

(require 2htdp/image)

(define cat How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据)

(image-height cat)
(image-width cat)

--------------------------------------------------------

1.5 The Arithmetic of Booleans 逻辑运算符

 or

> (or #true #true)

#true

> (or #true #false)

#true

> (or #false #true)

#true

> (or #false #false)

#false


and

> (and #true #true)

#true

> (and #true #false)

#false

> (and #false #true)

#false

> (and #false #false)

#false


not

> (not #true)

#false


Exercise 7. Boolean expressions can express some everyday problems. Suppose you want to decide whether today is an appropriate day to go to the mall. You go to the mall either if it is not sunny or ifNadeem Hamid suggested this formulation of the exercise. today is Friday (because that is when stores post new sales items).

Here is how you could go about it using your new knowledge about Booleans. First add these two lines to the definitions area of DrRacket:

(define sunny #true)

(define friday #false)

Now create an expression that computes whether sunny is false or friday is true. So in this particular case, the answer is #false. (Why?)

my code:

(define sunny #t)
(define friday #f)
(or (not sunny) friday)

-------------------------------------------------------

1.6 Mixing It Up with Booleans

--------------------------------------------------------

1.7 Predicates: Kwon The Data

> (number? 4)

#true

> (number? pi)

#true

> (number? #true)

#false

> (number? "fortytwo")

#false


  • number?
  • string?
  • image?
  • boolean?

> (rational? pi)

#true


(inexact? e)

(exact? pi)

Exercise 9. Add the following line to the definitions area of DrRacket:

(define in ...)

Then create an expression that converts the value of  in to a positive number. For a String, it determines how long the  String is; for an  Image, it uses the area; for a  Number, it decrements the number by  1, unless it is already  0 or negative; for  #true it uses  10 and for  #false  20.

my code:

(require 2htdp/image)
;...placehold
(define in ...)
(cond
  [(string? in) (string-length in)]
  [(image? in) (* (image-width in) (image-height in))]
  [(number? in)
   (if (<= in 0) 0 (- in 1))]
  [(boolean? in) (if #t 10 20)])

-------------------------------------------------------------------------------------------------------

2 Functions and Programs

之前的章节将的是"arithmetic"算数,之后讨论"algebra"代数,就像学校教的那样,这两个的概念引入到编程里来。代数需要变量,函数定义,函数应用和函数组合。

2.1 Functions

2种define:

  • constant definitions, of the shape (define Variable Expression), which we encountered in the preceding chapter; and
  • function definitions, which come in many flavors, one of which we used in the Prologue.
Like expressions,  function definitions in BSL come in a uniform shape:
(define (FunctionName Variable ... Variable)
  Expression)

  • (define (f x) 1) ;定义函数,函数名为f,函数变量为x,函数表达式为1

  • (define (g x y) (+ 1 1)) ; 定义函数,函数名为g,函数变量为x y,函数表达式为(+ 1 1)====2

  • (define (h x y z) (+ (* 2 2) 3)) ; 定义函数,函数名为h,函数变量为 x y z,函数表达式为(+ (* 2 2)3)====7

f——one argument function(unary function) 一元函数

g——two-argument function(binary function) 二元函数

h——three-argument function(ternary function) 三元函数

可以看到上述定义的函数,虽然定义的变量,但函数表达式中并没有变量参与,这以为着,函数的输出值和变量值没有关系,我们不这样定义函数。

Variables变量不是数据,他们代表数据。像下面这样定义一个常数

(define x 3)

表明x只是代表了数值3

正确定义函数的方法为

(define (ff a)
  (* 10 a))

函数的调用:

> (f 1)

1

> (f "hello world")

1

> (f #true)

1

函数调用,函数变量的数量必须和定义函数时一样,以下调用是不对的:

> (f)

f:expects 1 argument, found none

> (f 1 2 3 4 5)

f:expects only 1 argument, found 5

> (+)

+:expects at least 2 arguments, found none

可以看出+也是一种函数

函数调用是可以嵌套的,在函数中调用函数

> (+ (ff 3) 2)

32

> (* (ff 4) (+ (ff 3) 2))

1280

> (ff (ff 1))

100


Exercise 11. Define a function that consumes two numbers, x and y, and that computes the distance of point (x,y) to the origin.

my code:

(define (distance x y)
  (sqrt (+ (sqr x) (sqr y))))

(distance 3 4)

Exercise 12. Define the function cvolume, which accepts the length of a side of an equilateral cube and computes its volume. If you have time, consider defining csurface, too.

Hint An equilateral cube is a three-dimensional container bounded by six squares. You can determine the surface of a cube if you know that the square’s area is its length multiplied by itself. Its volume is the length multiplied with the area of one of its squares. (Why?)

my code:

(define (cvolume x)
  (* x x x))

(define (csurface x)
  (* 6 (* x x)))

Exercise 13. Define the function string-first, which extracts the first 1String from anon-empty string.

my code:

(define (string-first s)
  (if (> (string-length s) 0)
      (substring s 0 1)
      ""))

(string-first "string")

Exercise 14. Define the function string-last, which extracts the last 1String from a non-empty string.

my code:

(define (string-first s)
  (if (> (string-length s) 0)
      (substring s (- (string-length s) 1))
      ""))

(string-first "string")

Exercise 15. Define ==>. The function consumes two Boolean values, call them sunnyand friday. Its answer is #true if sunny is false or friday is true. Note Logicians call this Boolean operation implication, and they use the notation sunny => friday for this purpose.

my code:

(define sunny #t)
(define friday #t)
(define (==> sunny friday)
  (or (not sunny) friday))
(==> sunny friday)

Exercise 16. Define the function image-area, which counts the number of pixels in a given image. See exercise 6 for ideas.

my code:

(require 2htdp/image)

(define (image-area IMAGE)
  (* (image-width IMAGE) (image-height IMAGE)))

Exercise 17. Define the function image-classify, which consumes an image and conditionally produces "tall" if the image is taller than wide, "wide" if it is wider than tall, or "square" if its width and height are the same. See exercise 8 for ideas.

my code:

(require 2htdp/image)

(define (image-classify img)
  (cond
    [(> (image-height img) (image-width img)) "tall"]
    [(= (image-height img) (image-width img)) "square"]
    [(< (image-height img) (image-width img)) "wide"]))

Exercise 18. Define the function string-join, which consumes two strings and appends them with "_" in between. See exercise 2 for ideas.

my code:

(define (string-join s1 s2)
  (string-append s1 "_" s2))

(string-join "hello" "world")

Exercise 19. Define the function string-insert, which consumes a string str plus a number i and inserts "_" at the ith position of str. Assume i is a number between 0 and the length of the given string (inclusive). See exercise 3 for ideas. Ponder how string-insert copes with "".

my code:

(define (string-insert str i)
  (string-append (substring str 0 i)
                 "_"
                 (substring str i)))
 
(string-insert "helloworld" 6)

Exercise 20. Define the function string-delete, which consumes a string plus a numberi and deletes the ith position from str. Assume i is a number between 0 (inclusive) and the length of the given string (exclusive). See exercise 4 for ideas. Can string-deletedeal with empty strings?

my code:

(define (string-delete str i)
  (string-append (substring str 0 (- i 1))
                 (substring str i)))
 
(string-delete "helloworld" 6)

-----------------------------------------------------------------------

2.2 computing

(define (f x) 1)

函数调用时的步骤

(f (+ 1 1))
== ; DrRacket knows that (+ 1 1) == 2
(f 2)
== ; DrRacket replaced all occurrences of x with 2
1

(define (ff a)
  (* 10 a))

(ff (+ 1 1))
== ; DrRacket again knows that (+ 1 1) == 2
(ff 2)
== ; DrRacket replaces a with 2 in ff's body
(* 10 2)
== ; and from here, DrRacket uses plain arithmetic
20

(+ (ff (+ 1 2)) 2)
== ; DrRacket knows that (+ 1 2) == 3
(+ (ff 3) 2)
== ; DrRacket replaces a with 3 in ff's body
(+ (* 10 3) 2)
== ; now DrRacket uses the laws of arithmetic
(+ 30 2)
==
32

(* (ff 4) (+ (ff 3) 2))
== ; DrRacket substitutes 4 for a in ff's body
(* (* 10 4) (+ (ff 3) 2))
== ; DrRacket knows that (* 10 4) == 40
(* 40 (+ (ff 3) 2))
== ; now it uses the result of the above calculation
(* 40 32)
==
1280 ; because it is really just math

所有的计算就像代数

编译器中,看一下程序运行步骤

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

点击Step

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

看一下计算步骤是如何一步一步计算的

Exercise 21. Use DrRacket’s stepper to evaluate (ff (ff 1)) step-by-step. Also try (+(ff 1) (ff 1)). Does DrRacket’s stepper reuse the results of computations?

my code:

代码步骤显示:

(define (ff a)
  (* 10 a))

(ff (ff 1))
==;变量a为1
(ff (* 10 1))
==
(ff 10)
==
(* 10 10)
==
100


定义一个函数,打印书信开头格式

(define (opening first-name last-name)

    (string-append "Dear " first-name ","))

调用函数

> (opening "Matthew" "Fisler")

"Dear Matthew,"


看一下程序执行过程

(opening "Matthew" "Fisler")
==  ; DrRacket substitutes "Matthew" for first-name
(string-append "Dear " "Matthew" ",")
==
"Dear Matthew,"

Exercise 22. Use DrRacket’s stepper on this program fragment:
(define (distance-to-origin x y)
  (sqrt (+ (sqr x) (sqr y))))
(distance-to-origin 3 4)
Does the explanation match your intuition?

My answer:Yes

Exercise 23. The first  1String in  "hello world" is  "h". How does the following function compute this result?
(define (string-first s)
  (substring s 0 1))
Use the stepper to confirm your ideas.

Exercise 24. Here is the definition of  ==>:y
(define (==> x y)
  (or (not x) y))
Use the stepper to determine the value of  ( ==>   #true   #false ).

Exercise 25. Take a look at this attempt to solve  exercise 17:
(define (image-classify img)
  (cond
    [(>= (image-height img) (image-width img)) "tall"]
    [(= (image-height img) (image-width img)) "square"]
    [(<= (image-height img) (image-width img)) "wide"]))
Does stepping through an application suggest a fix?

我觉得程序应该这样写:

(define (image-classify img)
  (cond
    [(> (image-height img) (image-width img)) "tall"]
    [(= (image-height img) (image-width img)) "square"]
    [(< (image-height img) (image-width img)) "wide"]))

Exercise 26. What do you expect as the value of this program:
(define (string-insert s i)
  (string-append (substring s 0 i)
                 "_"
                 (substring s i)))
 
(string-insert "helloworld" 6)
Confirm your expectation with DrRacket and its stepper.
--------------------------------------------------------------------------

2.3 Composing Functions 函数的组合

函数的组合

(define (letter fst lst signature-name)
  (string-append
    (opening fst)
    "\n\n"
    (body fst lst)
    "\n\n"
    (closing signature-name)))
 
(define (opening fst)
  (string-append "Dear " fst ","))
 
(define (body fst lst)
  (string-append
   "We have discovered that all people with the" "\n"
   "last name " lst " have won our lottery. So, " "\n"
   fst ", " "hurry and pick up your prize."))
 
(define (closing signature-name)
  (string-append
   "Sincerely,"
   "\n\n"
   signature-name
   "\n"))

Figure 12: A batch program


> (letter "Matthew" "Fisler" "Felleisen")

"Dear Matthew,\n\nWe have discovered that ...\n"

> (letter "Kathi" "Felleisen" "Findler")

"Dear Kathi,\n\nWe have discovered that ...\n"



Sample Problem The owner of a monopolistic movie theater in a small town has complete freedom in setting ticket prices. The more he charges, the fewer people can afford tickets. The less he charges, the more it costs to run a show because attendance goes up. In a recent experiment the owner determined a relationship between the price of a ticket and average attendance.

At a price of $5.00 per ticket, 120 people attend a performance. For each 10-cent change in the ticket price, the average attendance changes by 15 people. That is, if the owner charges $5.10, some 105 people attend on the average; if the price goes down to $4.90, average attendance increases to 135. Let’s translate this idea into a mathematical formula:

How to Design Programs, Second Edition——Chapter 1 Fixed-Size Data 固定尺寸数据

Stop! Explain the minus sign before you proceed.

Unfortunately, the increased attendance also comes at an increased cost. Every performance comes at a fixed cost of $180 to the owner plus a variable cost of $0.04 per attendee.

The owner would like to know the exact relationship between profit and ticket price in order to maximize the profit.



------------------------------------------------------------------------------------

2.4 Global Constants

Examples:

; the current price of a movie ticket:
(define CURRENT-PRICE 5)
 
; useful to compute the area of a disk:
(define ALMOST-PI 3.14)
 
; a blank line:
(define NL "\n")
 
; an empty scene:
(define MT (empty-scene 100 100))

常数使用大写字符,比较容易区分。定义的内容可以是数字,也可以是字符串和图片

Exercise 30. Define constants for the price optimization program at the movie theater so that the price sensitivity of attendance (15 people for every 10 cents) becomes a computed constant


-------------------------------------------------------------------------

2.5 Programs

  • 批处理程序——程序由许多附属程序组合在一起,由main程序来运行,最后给出运行结果
  • 交互式程序——用户会输入内容,并驱动事件(event)

最常见的交互式程序就是GUI

较早的批处理程序主要是读取文件,处理数据,再保存成文件。

这里介绍文件读取read-file和写入write-file的函数,需要添加 2htdp/batch-io 库

  • read-file, which reads the content of an entire file as a string, and

  • write-file, which creates a file from a given string.

> (write-file "sample.dat" "212")

"sample.dat"

> (read-file "sample.dat")

"212"


生成一个sample.dat文件,文件内容为字符串212。read-file,读取sample.dat中的内容。

(define (C f)

  (* 5/9 (- f 32)))

(define (convert in out)
  (write-file out
    (string-append
      (number->string
        (C
          (string->number
            (read-file in))))
      "\n")))

这里的convert函数作为main函


2htdp/universe库中有big-bang可以用来写事件