From 7ec202e0db2a91f3eeebfff403e07f67742bf77a Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Wed, 28 Jun 2017 11:32:22 +0900 Subject: [PATCH 01/13] translation --- book_tx/Makefile | 92 + book_tx/back.png | Bin 0 -> 4440 bytes book_tx/book.tex | 17016 +++++++++++++++++++++++++++++++ book_tx/figs/assign2.eps | 141 + book_tx/figs/assign2.fig | 23 + book_tx/figs/assign2.fig.bak | 25 + book_tx/figs/assign2.pdf | Bin 0 -> 3893 bytes book_tx/figs/banana.eps | 194 + book_tx/figs/banana.fig | 45 + book_tx/figs/banana.pdf | Bin 0 -> 5443 bytes book_tx/figs/card1.eps | 213 + book_tx/figs/card1.fig | 47 + book_tx/figs/card1.pdf | Bin 0 -> 5371 bytes book_tx/figs/class1.eps | 142 + book_tx/figs/class1.fig | 25 + book_tx/figs/class1.pdf | Bin 0 -> 4630 bytes book_tx/figs/compile.eps | 222 + book_tx/figs/compile.fig | 54 + book_tx/figs/compile.pdf | Bin 0 -> 5098 bytes book_tx/figs/dict1.eps | 321 + book_tx/figs/dict1.fig | 91 + book_tx/figs/dict1.pdf | Bin 0 -> 5915 bytes book_tx/figs/dict2.eps | 195 + book_tx/figs/dict2.fig | 42 + book_tx/figs/dict2.pdf | Bin 0 -> 6487 bytes book_tx/figs/fibonacci.eps | 356 + book_tx/figs/fibonacci.fig | 107 + book_tx/figs/fibonacci.pdf | Bin 0 -> 5525 bytes book_tx/figs/flower.test.pdf | Bin 0 -> 17297 bytes book_tx/figs/flowers.eps | 9835 ++++++++++++++++++ book_tx/figs/flowers.pdf | Bin 0 -> 12440 bytes book_tx/figs/interpret.eps | 173 + book_tx/figs/interpret.fig | 37 + book_tx/figs/interpret.pdf | Bin 0 -> 4565 bytes book_tx/figs/koch.eps | 10575 +++++++++++++++++++ book_tx/figs/koch.pdf | Bin 0 -> 8732 bytes book_tx/figs/list1.eps | 166 + book_tx/figs/list1.fig | 32 + book_tx/figs/list1.pdf | Bin 0 -> 4292 bytes book_tx/figs/list2.eps | 128 + book_tx/figs/list2.fig | 21 + book_tx/figs/list2.pdf | Bin 0 -> 4373 bytes book_tx/figs/list3.eps | 140 + book_tx/figs/list3.fig | 20 + book_tx/figs/list3.pdf | Bin 0 -> 4399 bytes book_tx/figs/liststate.eps | 255 + book_tx/figs/liststate.fig | 64 + book_tx/figs/liststate.fig.bak | 64 + book_tx/figs/liststate.pdf | Bin 0 -> 6467 bytes book_tx/figs/listsum1.eps | 1740 ++++ book_tx/figs/listsum1.pdf | Bin 0 -> 11055 bytes book_tx/figs/listsum2.eps | 2086 ++++ book_tx/figs/listsum2.pdf | Bin 0 -> 9928 bytes book_tx/figs/loop.py | 20 + book_tx/figs/loop.py~ | 19 + book_tx/figs/pies.eps | 875 ++ book_tx/figs/pies.pdf | Bin 0 -> 2835 bytes book_tx/figs/point.eps | 147 + book_tx/figs/point.fig | 26 + book_tx/figs/point.pdf | Bin 0 -> 4841 bytes book_tx/figs/rectangle.eps | 206 + book_tx/figs/rectangle.fig | 45 + book_tx/figs/rectangle.pdf | Bin 0 -> 5697 bytes book_tx/figs/rectangle2.eps | 257 + book_tx/figs/rectangle2.fig | 67 + book_tx/figs/rectangle2.pdf | Bin 0 -> 5505 bytes book_tx/figs/stack.eps | 219 + book_tx/figs/stack.fig | 51 + book_tx/figs/stack.pdf | Bin 0 -> 5805 bytes book_tx/figs/stack2.eps | 200 + book_tx/figs/stack2.fig | 44 + book_tx/figs/stack2.pdf | Bin 0 -> 5056 bytes book_tx/figs/stack3.eps | 342 + book_tx/figs/stack3.fig | 96 + book_tx/figs/stack3.pdf | Bin 0 -> 5999 bytes book_tx/figs/stack4.eps | 173 + book_tx/figs/stack4.fig | 41 + book_tx/figs/stack4.pdf | Bin 0 -> 5098 bytes book_tx/figs/stack5.eps | 197 + book_tx/figs/stack5.fig | 41 + book_tx/figs/stack5.pdf | Bin 0 -> 5449 bytes book_tx/figs/state.eps | 143 + book_tx/figs/state.fig | 60 + book_tx/figs/state.pdf | Bin 0 -> 6236 bytes book_tx/figs/state2.eps | 158 + book_tx/figs/state2.fig | 28 + book_tx/figs/state2.pdf | Bin 0 -> 6352 bytes book_tx/figs/state3.eps | 162 + book_tx/figs/state3.fig | 31 + book_tx/figs/state3.pdf | Bin 0 -> 5005 bytes book_tx/figs/state4.eps | 170 + book_tx/figs/state4.fig | 39 + book_tx/figs/state4.pdf | Bin 0 -> 5056 bytes book_tx/figs/state5.eps | 321 + book_tx/figs/state5.fig | 91 + book_tx/figs/state5.pdf | Bin 0 -> 5917 bytes book_tx/figs/time.eps | 173 + book_tx/figs/time.fig | 31 + book_tx/figs/time.pdf | Bin 0 -> 5226 bytes book_tx/figs/towers.eps | 317 + book_tx/figs/towers.fig | 178 + book_tx/figs/towers.pdf | Bin 0 -> 2998 bytes book_tx/figs/tuple1.eps | 135 + book_tx/figs/tuple1.fig | 22 + book_tx/figs/tuple1.pdf | Bin 0 -> 4825 bytes book_tx/footer.html | 55 + book_tx/header.html | 12 + book_tx/hevea.sty | 90 + book_tx/htmlonly | 28 + book_tx/latexonly | 102 + book_tx/localdef.py | 81 + book_tx/next.png | Bin 0 -> 4479 bytes book_tx/up.png | Bin 0 -> 4426 bytes 113 files changed, 50180 insertions(+) create mode 100644 book_tx/Makefile create mode 100644 book_tx/back.png create mode 100644 book_tx/book.tex create mode 100644 book_tx/figs/assign2.eps create mode 100644 book_tx/figs/assign2.fig create mode 100644 book_tx/figs/assign2.fig.bak create mode 100644 book_tx/figs/assign2.pdf create mode 100644 book_tx/figs/banana.eps create mode 100644 book_tx/figs/banana.fig create mode 100644 book_tx/figs/banana.pdf create mode 100644 book_tx/figs/card1.eps create mode 100644 book_tx/figs/card1.fig create mode 100644 book_tx/figs/card1.pdf create mode 100644 book_tx/figs/class1.eps create mode 100644 book_tx/figs/class1.fig create mode 100644 book_tx/figs/class1.pdf create mode 100644 book_tx/figs/compile.eps create mode 100644 book_tx/figs/compile.fig create mode 100644 book_tx/figs/compile.pdf create mode 100644 book_tx/figs/dict1.eps create mode 100644 book_tx/figs/dict1.fig create mode 100644 book_tx/figs/dict1.pdf create mode 100644 book_tx/figs/dict2.eps create mode 100644 book_tx/figs/dict2.fig create mode 100644 book_tx/figs/dict2.pdf create mode 100644 book_tx/figs/fibonacci.eps create mode 100644 book_tx/figs/fibonacci.fig create mode 100644 book_tx/figs/fibonacci.pdf create mode 100644 book_tx/figs/flower.test.pdf create mode 100644 book_tx/figs/flowers.eps create mode 100644 book_tx/figs/flowers.pdf create mode 100644 book_tx/figs/interpret.eps create mode 100644 book_tx/figs/interpret.fig create mode 100644 book_tx/figs/interpret.pdf create mode 100644 book_tx/figs/koch.eps create mode 100644 book_tx/figs/koch.pdf create mode 100644 book_tx/figs/list1.eps create mode 100644 book_tx/figs/list1.fig create mode 100644 book_tx/figs/list1.pdf create mode 100644 book_tx/figs/list2.eps create mode 100644 book_tx/figs/list2.fig create mode 100644 book_tx/figs/list2.pdf create mode 100644 book_tx/figs/list3.eps create mode 100644 book_tx/figs/list3.fig create mode 100644 book_tx/figs/list3.pdf create mode 100644 book_tx/figs/liststate.eps create mode 100644 book_tx/figs/liststate.fig create mode 100644 book_tx/figs/liststate.fig.bak create mode 100644 book_tx/figs/liststate.pdf create mode 100644 book_tx/figs/listsum1.eps create mode 100644 book_tx/figs/listsum1.pdf create mode 100644 book_tx/figs/listsum2.eps create mode 100644 book_tx/figs/listsum2.pdf create mode 100644 book_tx/figs/loop.py create mode 100644 book_tx/figs/loop.py~ create mode 100644 book_tx/figs/pies.eps create mode 100644 book_tx/figs/pies.pdf create mode 100644 book_tx/figs/point.eps create mode 100644 book_tx/figs/point.fig create mode 100644 book_tx/figs/point.pdf create mode 100644 book_tx/figs/rectangle.eps create mode 100644 book_tx/figs/rectangle.fig create mode 100644 book_tx/figs/rectangle.pdf create mode 100644 book_tx/figs/rectangle2.eps create mode 100644 book_tx/figs/rectangle2.fig create mode 100644 book_tx/figs/rectangle2.pdf create mode 100644 book_tx/figs/stack.eps create mode 100644 book_tx/figs/stack.fig create mode 100644 book_tx/figs/stack.pdf create mode 100644 book_tx/figs/stack2.eps create mode 100644 book_tx/figs/stack2.fig create mode 100644 book_tx/figs/stack2.pdf create mode 100644 book_tx/figs/stack3.eps create mode 100644 book_tx/figs/stack3.fig create mode 100644 book_tx/figs/stack3.pdf create mode 100644 book_tx/figs/stack4.eps create mode 100644 book_tx/figs/stack4.fig create mode 100644 book_tx/figs/stack4.pdf create mode 100644 book_tx/figs/stack5.eps create mode 100644 book_tx/figs/stack5.fig create mode 100644 book_tx/figs/stack5.pdf create mode 100644 book_tx/figs/state.eps create mode 100644 book_tx/figs/state.fig create mode 100644 book_tx/figs/state.pdf create mode 100644 book_tx/figs/state2.eps create mode 100644 book_tx/figs/state2.fig create mode 100644 book_tx/figs/state2.pdf create mode 100644 book_tx/figs/state3.eps create mode 100644 book_tx/figs/state3.fig create mode 100644 book_tx/figs/state3.pdf create mode 100644 book_tx/figs/state4.eps create mode 100644 book_tx/figs/state4.fig create mode 100644 book_tx/figs/state4.pdf create mode 100644 book_tx/figs/state5.eps create mode 100644 book_tx/figs/state5.fig create mode 100644 book_tx/figs/state5.pdf create mode 100644 book_tx/figs/time.eps create mode 100644 book_tx/figs/time.fig create mode 100644 book_tx/figs/time.pdf create mode 100644 book_tx/figs/towers.eps create mode 100644 book_tx/figs/towers.fig create mode 100644 book_tx/figs/towers.pdf create mode 100644 book_tx/figs/tuple1.eps create mode 100644 book_tx/figs/tuple1.fig create mode 100644 book_tx/figs/tuple1.pdf create mode 100644 book_tx/footer.html create mode 100644 book_tx/header.html create mode 100644 book_tx/hevea.sty create mode 100644 book_tx/htmlonly create mode 100644 book_tx/latexonly create mode 100644 book_tx/localdef.py create mode 100644 book_tx/next.png create mode 100644 book_tx/up.png diff --git a/book_tx/Makefile b/book_tx/Makefile new file mode 100644 index 0000000..a4f841b --- /dev/null +++ b/book_tx/Makefile @@ -0,0 +1,92 @@ +LATEX = latex + +DVIPS = dvips + +PDFFLAGS = -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress \ + -dCompressPages=true -dUseFlateCompression=true \ + -dEmbedAllFonts=true -dSubsetFonts=true -dMaxSubsetPct=100 + + +%.dvi: %.tex + $(LATEX) $< + +%.ps: %.dvi + $(DVIPS) -o $@ $< + +%.pdf: %.ps + ps2pdf $(PDFFLAGS) $< + +all: book.tex + pdflatex book + makeindex book.idx + pdflatex book + mv book.pdf thinkpython2.pdf + +hevea: book.tex header.html footer.html + # replace the pdfs with eps + sed s/.pdf/.eps/g book.tex > thinkpython2.tex + latex thinkpython2 + rm -rf html + mkdir html + hevea -fix -O -e latexonly htmlonly thinkpython2 +# the following greps are a kludge to prevent imagen from seeing +# the definitions in latexonly, and to avoid headers on the images + grep -v latexonly thinkpython2.image.tex > a; mv a thinkpython2.image.tex + sed s/\\\\usepackage{fancyhdr}// < thinkpython2.image.tex > a; mv a thinkpython2.image.tex + imagen -png thinkpython2 + hacha thinkpython2.html + cp up.png next.png back.png html + mv index.html thinkpython2.css thinkpython2*.html thinkpython2*.png *motif.gif html + +DEST = /home/downey/public_html/greent/thinkpython2 + +epub: + cd html; ebook-convert index.html thinkpython2.epub + +distrib: + rm -rf dist + mkdir dist dist/tex dist/tex/figs + rsync -a thinkpython2.pdf html dist + rsync -a dist/* $(DEST) + chmod -R o+r $(DEST)/* + cd $(DEST)/..; sh back + +# UPDATE THE PATHS BELOW BEFORE RUNNING PLASTEX + +plastex: + # Before running plastex, we need the current directory in PYTHONPATH + # export PYTHONPATH=$PYTHONPATH:. + python Filist.py book.tex > book.plastex + rm -rf /home/downey/thinkpython2/trunk/book + plastex --renderer=DocBook --theme=book --image-resolution=300 --filename=book.xml book.plastex + rm -rf /home/downey/thinkpython2/trunk/book/.svn + +plastest: + # Before running plastex, we need the current directory in PYTHONPATH + # export PYTHONPATH=$PYTHONPATH:. + python Filist.py test.tex > test.plastex + rm -rf /home/downey/thinkpython2/trunk/test + plastex --renderer=DocBook --theme=test --filename=test.xml test.plastex + rm -rf /home/downey/thinkpython2/trunk/test/.svn + +xxe: + xmlcopyeditor ~/ThinkPython2/book/book/book.xml & + +lint: + xmllint -noout book/book.xml + +OREILLY = atlas + +oreilly: + rsync -a book.tex $(OREILLY) + rsync -a book/ $(OREILLY) + rsync -a figs/* $(OREILLY)/figs + cd $(OREILLY); git add . + cd $(OREILLY); git commit -m "Automated check in." + cd $(OREILLY); git push + +clean: + rm -f *~ *.aux *.log *.dvi *.idx *.ilg *.ind *.toc + + + diff --git a/book_tx/back.png b/book_tx/back.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8847276dd18dcd520cc71e98ff2e3afd274ff1 GIT binary patch literal 4440 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 en0>7Fe**wS+$OWW%>Lp40000>> +\end{verbatim} +% +처음 세 줄은 인터프리터에 대한 정보와 사용 중인 운영체제를 나타내기 +때문에 환경에 따라 다르게 나타날 수 있다. 하지만, 버전은 확인해야 +한다. 이 예제에서는 {\tt 3.4.0}으로 되어 있고, 3으로 시작한다. 즉, +Python 3을 실행 중이라는 것을 뜻한다. 만약 2로 시작한다면 (예상한 +것처럼) Python 2를 실행중이다. + +마지막 줄은 {\bf 프롬프트(prompt)}로서 인터프리터가 코드를 입력받을 +준비가 되었다는 것을 뜻한다. 코드 한 줄을 쓰고 엔터를 치면 +인터프리터가 결과를 보여준다. +\index{prompt} + +\begin{verbatim} +>>> 1 + 1 +2 +\end{verbatim} +% +이제 시작할 준비가 되었다. 이제부터는 Python 인터프리터를 시작하는 +방법과 코드를 실행하는 방법을 안다고 가정하겠다. + + +\section{최초의 프로그램} +\label{hello} +\index{Hello, World} + +전통적으로 새로운 언어를 사용하여 작성하는 최초의 프로그램을 ``Hello, +World!''라고 부른다. ``Hello, World!''라고 표시하는 것이 전부인 프로그램이기 때문이다. Python으로 만든 이 프로그램은 다음과 같다. + + +\begin{verbatim} +>>> print('Hello, World!') +\end{verbatim} +% +이것은 {\bf print 문장}의 예제이다. 실제 종이 인쇄하는 것이 아니고 +화면에 결과를 표시한다. 이 경우에는 결과는 다음의 단어들이다. + +\begin{verbatim} +Hello, World! +\end{verbatim} +% +프로그램에 사용된 따옴표가 표시될 글씨의 시작과 끝을 나타내며 결과에는 +표시되지 않는다. +\index{quotation mark} +\index{print statement} +\index{statement!print} + +괄호는 {\tt print}가 함수라는 것을 나타낸다. 함수에 대해서는 +\ref{funcchap} 장에서 다룰 것이다. +\index{function} \index{print function} + +Python 2에서는 \texttt{print} 문장은 함수가 아니라서 괄호를 사용하지 +않는다는 것이 약간 다르다. +\index{Python 2} + +\begin{verbatim} +>>> print 'Hello, World!' +\end{verbatim} +% +이러한 차이는 차차 이해하게 될 것이다. 하지만 이 정도만 알아도 +시작하는데는 충분하다. + + +\section{Arithmetic operators} +\index{operator!arithmetic} +\index{arithmetic operator} + +``Hello, World'' 다음으로 해 볼 것은 산수이다. Python은 덧셈과 곱셉의 +연산을 나타내는 특수한 기호들을 {\bf 연산자(operators)}를 제공한다. + +{\tt +}와 {\tt -} 그리고 {\tt *} 연산자는 덧셈과 뺄셈 그리고 곱셉을 +나타낸다. 다음의 예제를 살펴보자. + +\begin{verbatim} +>>> 40 + 2 +42 +>>> 43 - 1 +42 +>>> 6 * 7 +42 +\end{verbatim} +% +{\tt /} 연산자로 나눗셈을 할 수 있다. + +\begin{verbatim} +>>> 84 / 2 +42.0 +\end{verbatim} +% +이 계산의 결과가 왜 {\tt 42}이 아니고 {\tt 42.0}인지 궁금할 +것이다. 그것에 대해서는 다음 절에서 설명하도록 하겠다. + +마지막으로 {\tt **} 연산자는 거듭제곱을 계산할 때 사용된다. 그 수를 +지수로 사용한다. + +\begin{verbatim} +>>> 6**2 + 6 +42 +\end{verbatim} +% +어떤 언어들에서는 \verb"^"가 거듭제곱 연산에 사용되기도 하지만 +Python에서는 그 기호는 비트단위의 연산자인 \texttt{XOR}을 +나타낸다. 비트단위 연산자들이 익숙하지 않다면 연산 결과에 놀라워할 +것이다. + +\begin{verbatim} +>>> 6 ^ 2 +4 +\end{verbatim} +% +이 책에서는 비트단위 연산자들에 대해서는 다루지 않겠지만, 더 알고 +싶다면 \url{http://wiki.python.org/moin/BitwiseOperators}에서 읽을 수 +있다. +\index{bitwise operator} +\index{operator!bitwise} + + +\section{값과 형} +%Values and types +\index{value} +\index{type} +\index{string} + +{\bf 값(value)}은 프로그램이 다루는 글자와 숫자와 같은 기본적인 것 중 +하나이다. 지금까지 본 것 중에는 {\tt 2}, {\tt 42.0} 그리고 +\verb"'Hello, World!'"가 있다. + +이 값들은 서로 다른 {\bf 형(type)}에 속한다: {\tt 2}은 {\bf + 정수(integer)}형, {\tt 42.0}은 {\bf 부동 소수점(floating-point)}형의 +숫자이다. \verb"'Hello, World!'"는 {\bf 문자열(string)}형으로 불리는데 +마치 글자들이 줄에 매달린 듯하기 때문이다. +\index{integer} +\index{floating-point} + +만약에 값이 어떤 형인지 알고 싶다면, 인터프리터가 알려줄 수 있다: + +\begin{verbatim} +>>> type(2) + +>>> type(42.0) + +>>> type('Hello, World!') + +\end{verbatim} +% +이 결과들을 보면 ``클래스(class)''라는 단어가 종류 또는 범주를 나타내는 +의미로 사용되고 있음을 알 수 있다. 형이라는 것은 값의 종류이다. +\index{class} + +놀랍지않게도, 정수는 {\tt int} 형에 속해있고 문자열은 {\tt str}에 +속했으며 부동 소수점은 {\tt float}에 속해 있다. +\index{type} +\index{string type} +\index{type!str} +\index{int type} +\index{type!int} +\index{float type} +\index{type!float} + +그러면 \verb"'2'"나 \verb"'42.0'"과 같은 값들은 어떤 형을 갖을까? +숫자처럼 보이지만 따옴표 안에 있기 때문에 문자열 형에 속한다. +\index{quotation mark} + +\begin{verbatim} +>>> type('2') + +>>> type('42.0') + +\end{verbatim} +% +확인한 것처럼 문자열이다. + +매우 큰 정수를 입력할 때 {\tt 1,000,000}처럼 숫자 사이에 쉼표를 넣고 싶은 유혹이 일 수도 있다. 이와 같은 표현은 유효한 {\em 정수}형은 아니기는 하지만, Python에서 유효한 표현이기는 하다: + +\begin{verbatim} +>>> 1,000,000 +(1, 0, 0) +\end{verbatim} +% +이 결과는 우리가 기대한 것이 전혀 아니다! Python은 {\tt 1,000,000}을 +쉼표로 구분된 수열로 해석한다. 이와 같은 수열에 대해서는 +이후에 더 자세히 살펴보도록 하겠다. +\index{sequence} + +%This is the first example we have seen of a semantic error: the code +%runs without producing an error message, but it doesn't do the +%``right'' thing. +%\index{semantic error} +%\index{error!semantic} +%\index{error message} +% TODO: use this as an example of a semantic error later + + + +\section{형식 언어 그리고 자연어} +%Formal and natural languages +\index{formal language} +\index{natural language} +\index{language!formal} +\index{language!natural} + +{\bf 자연어(Natural language)}는 사람들이 말하는 영어, 스페인어와 +프랑스어와 같은 언어이다. 사람들에 의해 설계된 것은 아니지만(사람들이 +언어에 대해 체계를 정립하기는하였지만) 언어는 자연적으로 발달되었다. + +{\bf 형식 언어(Formal language)}는 특정 응용처를 위해서 사람들이 설계한 +것이다. 예를 들어 수학자들이 사용하는 표기법이 형식 언어의 일종으로 +숫자와 기호들의 관계를 나타내기에 좋다. 화학자들은 형식언어를 사용하여 +분자들의 화학 구조를 나타낸다. 그리고 가장 중요한 것은: + +\begin{quote} +{\bf 프로그래밍 언어는 연산을 표현하기 위해 설계된 형식 언어이다. } +\end{quote} + +형식 언어는 문장의 구조를 결정하는 엄격한 {\bf 문법(syntax)} 규칙을 갖고 있다. +예를 들어 수학에서 $3 + 3 = 6$이라는 문장은 올바른 문법으로 작성되었지만 $3 + = 3 \$ 6$은 그렇지 않다. 화학에서는 $H_2O$는 문법적으로 올바른 식이지만 $_2Zz$은 아니다. +\index{syntax} + +문법 규칙은 {\bf 토큰(token)}과 구조의 두 형태를 갖고 있다. 토큰은 +언어의 기본적인 구성 요소로서 단어나 숫자 그리고 화학에서의 원소들과 +같은 것이다. $3 += 3 \$ 6$라는 식에서의 문제점은 \( \$ \)이 (최소한 +내가 알기로는) 수학에서 유효한 토큰은 아니라는 것이다. 유사하게 +$_2Zz$도 유효하지 않다. $Zz$를 약어로 갖는 원소가 없기 때문이다. +\index{token} +\index{structure} + +두 번째 종류의 문법 규칙은 토큰들을 결합하는 것과 관련이 있다. $3 += +3$는 규칙에 어긋난다. 이 식에서 $+$와 $=$이 유효한 토큰이기는 하지만 +연이어서 두 개를 사용할 수가 없다. 화학 식에서도 마찬가지로 아래 첨자는 +이름 뒤에 나타나지 그 앞에 나타나지 않는다. + +이 문장은 @ 구조적으로 잘 정의되었z만 유효하지 않은 t*ken이 +사용되었다. 이 문장의 토큰은 모두 유효하지만 갖고 있다 구조를 잘못된. + +모국어로 문장을 읽거나 형식 언어로 문장을 읽을 때에는 그 구조를 +파악해야 한다(자연어를 파악하는 과정은 무의식적으로 일어나기는 한다). +프로그래밍에서 구조를 파악하는 과정을 {\bf 파싱(parsing)}이라고 +부른다. +\index{parse} + +형식 언어와 자연어 사이에는 토큰과 구조 그리고 문법과 같은 많은 공통적 기능들이 있지만 차이점도 분명하다: +\index{ambiguity} +\index{redundancy} +\index{literalness} + +\begin{description} + +\item[모호성(ambiguity):] 자연어는 모호하기 때문에 맥락과 다른 정보들을 + 통해 이해를 한다. 형식 언어의 경우 거의 또는 완전하게 그 모호성의 + 없애도록 설계되었기 때문에 문맥과 상관없이 유일한 의미를 갖고 있다. + +\item[중복성(redundancy):] 자연어가 갖고 있는 모호성을 없애고 오해를 + 줄이기 위해서 엄청난 중복성을 허용하고 있다. 그 결과로 인해 + 장황해지기 쉽다. 형식 언어는 훨씬 간결하다. + +\item[직역성(literalness):] 자연어는 숙어와 은유적 표현으로 + 넘쳐난다. ``The penny doppred(돈 떨어졌다)''라고 말을 하면 실제 뜻은 + 돈에 관한 것도 아니고 실제로 무언가가 떨어지는 것도 아니다(이 숙어는 + 뜻은 `이제야 알아 들었다'는 것이다). 형식 언어에서는 말하는 그대로가 + 의도한 뜻한다. + +\end{description} + +자라면서 자연어를 구사하였기 때문에 형식 언어에 익숙해지는데 많은 시간이 걸리곤 한다. 자연어와 형식 언어간의 차이는 시와 산문 간의 차이와도 유사하다. + \index{poetry} \index{prose} + +\begin{description} + +\item[시:] 사용되는 단어의 소리도 그 단어의 의미만큼 중요하며, 시 전체 + 봐야만 어떤 감정적 반응을 하거나 또는 영향을 느낄 수가 있다. + 애매모호한 표현이 흔할 뿐만 아니라 의도된 것일 때도 있다. + +\item[산문:] 단어가 갖고 있는 의미가 좀 더 중요하다. 그렇기 때문에 + 구조에 의미가 더 많이 담겨 있다. 산문은 시보다는 분석하기에 더 + 쉽기는 하지만 모호할 때가 많다. + +\item[프로그램:] 컴퓨터 프로그램의 의미는 모호하지 않아며 문자적으로 + 이해할 수 있어서 구조와 토큰을 분석하는 것만으로 모든 것을 이해할 수 + 있다. + +\end{description} + +형식 언어는 자연어보다 좀 더 난해해서 읽는데 오래 걸린다. 또한, 구조가 +중요하기 때문에 위에서 아래로 왼쪽에서 오른쪽으로 읽는 것이 늘 최선의 +방식은 아니다. 대신에 프로그램을 상상의 공간에서 분석하고 토큰은 +구별해 내고 구조를 해석하는 방법을 익혀야 한다. 마지막으로 세부사항이 +중요하다. 철자나 구두점의 표기를 잘못하는 것과 같은 작은 실수를 +자연어에서는 지나쳐도 문제가 되지 않았겠지만 형식 언어에서는 큰 차이를 +만들어 낸다. + + +\section{디버깅} +%Debugging +\index{debugging} + +프로그래머들은 실수를 한다. 황당하게도 프로그래밍 오류를 {\bf + 버그(bug)}라고 부르고 그것들을 해결하는 과정을 {\bf + 디버깅(debugging)}이라고 부른다. +\index{debugging} +\index{bug} + +프로그래밍과 특히 디버깅 때문에 감정이 격해질 수가 있다. 매우 어려운 +버그로 고생을 하고 있다면 화가나거나 무기력해지기도 또는 당혹스러워질 +수도 있다. + +사람들이 컴퓨터를 대할 때 아주 자연스럽게 컴퓨터가 마치 사람인양 +대한다는 결과들이 있다. 잘 동작한다면 한 팀원으로 여기기도 하고 +외고집스럽고 무례할 정도로 말을 안듯는다면 그런 사람을 대하는 것과 +동일하게 대한다고 한다(Reeves와 Nass, {\it The Media Equation: How + People Treat Computers, Television, and New Media Like Real People + and Places}). +\index{debugging!emotional response} +\index{emotional debugging} + +이와 같은 경우에 대응하는 방법들을 미리 생각해 놓는 것이 이후에 그런 +일들을 당했을 때 대처하기가 쉬워진다. 한 가지 방법은 컴퓨터를 마치 +일정한 능력을, 예를 들어 속도와 정확도, 갖고 있지만 공감 능력과 전체를 +보는 시각이 전혀 없는 직원이라고 생각하면 된다. + +당신이 할 일은 좋은 관리자가 되는 것이다: 직원의 장점을 파악하고 단점을 +완화시켜주는 것이다. 그 후에 할 일은 문제 해결 과정에서 말 안듣는 +컴퓨터와 감정적 씨름을 하는 대신 작업을 효율적으로 처리할 수 있는 +방법들을 찾아야 한다. + +디버깅 방법을 배우는 것은 좌절스러운 경험이 될 수 있겠지만, 이 기술은 +프로그래밍 외에도 여러 방면에서 적용할 수 있는 매우 가치 있는 +기술이기도 하다. 각 장의 끝에 있는 절에는 디버깅에 대한 조언이 적혀 +있다. 도움이 되길 바란다! + + +\section{용어 해설} + +\begin{description} + +\item[문제 해결(Problem solving):] 문제를 정의하고 해법을 찾고 표현하는 과정. +\index{problem solving} + +\item[고수준 언어(high-level language):] Python과 같은 언어로 사람이 + 읽고 쓰기 쉽게 설계된 언어. +\index{high-level language} + +\item[저수준 언어(low-level language):] 컴퓨터가 실행시키기 쉽게 설계된 + 프로그램 언어로서 ``기계어'' 또는 ``어셈블리어''라고도 불림. +\index{low-level language} + +\item[이식성(portatiblity):] 한 종류의 컴퓨터 이상에서 프로그램이 실행 가능한 성질. +\index{portability} + +\item[해석 프로그램(인터프리터/interpreter):] 프로그램을 읽고 실행시키는 프로그램. +\index{interpret} + +\item[프롬프트(prompt):] 사용자로부터 입력을 받을 준비가 되었다는 것을 + 알려주기 위한 인터프리터가 표시하는 글자들. +\index{prompt} + +\item[프로그램(program):] 연산을 지정해놓은 명령어들의 집합. +\index{program} + +\item[print 문장(print statment):] Python 인터프리터가 화면에 어떤 값을 + 표시하도록 하는 명령어. +\index{print statement} +\index{statement!print} + +\item[연산자(operator):] 덧셈, 곱셉, 또는 문자열 연결과 같은 간단한 + 연산을 뜻하는 특수 기호 +\index{operator} + +\item[값(value):] 프로그램이 조작하는 숫자나 문자열 데이터의 기본 단위 중 하나 +\index{value} + +\item[형(type):] 값들의 분류. 정수({\tt int}형), 부동-소수점 숫자({\tt + float}형)과 문자열({\tt str}형)이 우리가 지금까지 살펴본 데이터의 + 형이다. +\index{type} + +\item[정수(integer):] 자연수를 나타내는 데이터 형이다. +\index{integer} + +\item[부동 소수점(floating-point):] 분수 부분을 표현하는 숫자들. +\index{floating-point} + +\item[문자열(string):] 연속된 글자들을 표현하는 데이터 형. +\index{string} + +\item[자연어(natural language):] 사람들이 말하는 자연적으로 발전한 모든 언어. +\index{natural language} + +\item[형식 언어(formal language):] 수학적 개념을 표현하기 위해서나 + 컴퓨터 프로그램을 표현하기 위한 언어처럼 사람들이 특정 목적을 갖고 + 설계한 모든 언어. 모든 프로그래밍 언어는 형식 언어이다. +\index{formal language} + +\item[토큰(token):] 자연어의 단어와 대응되는 개념으로 프로그램의 문법적 + 구조를 이루는 기본적인 요소 +\index{token} + +\item[문법(syntax):] 프로그램의 구조를 결정하는 규칙 +\index{syntax} + +\item[구문 해석(파싱, parse):] 프로그램을 조사하여 문법적 구조를 분석하는 것 +\index{parse} + +\item[버그(bug):] 프로그램에 있는 오류 +\index{bug} + +\item[디버깅(debugging):] 버그를 찾아 고치는 과정 +\index{debugging} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + + 이 책을 컴퓨터 앞에서 읽는 것을 권한다. 예제들을 만날 때마다 시도 + 해볼 수 있기 때문이다. + +새로운 기능을 실험할 때에는 실수를 많이 할 수록 좋다. 예를 들어 +``Hello, world!'' 프로그램에서 둘 중의 하나의 따옴표를 입력하지 않으면 +어떤 일이 생길까? 둘 다 입력하지 않으면 어떻게 될까? {\tt print}를 +잘못 입력하면 어떻게 될까? \index{error message} + +이런 류의 실험은 읽은 내용을 오랫동안 기억에 남게 할뿐만 아니라 각 오류 +메시지가 어떤 의미를 갖는지 알 수 있기 때문에 프로그래밍할 때에도 +도움이 되나. 지금 의도적으로 실수를 만들어 내는 것이 나중에 우연히 +실수를 범하는 것보다 낫다. + +\begin{enumerate} + +\item \texttt{print} 문장에서 괄호 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? + +\item 문자열을 출력한다고 했을 때 따옴표 중 하나 또는 둘 다 입력하지 + 않으면 어떻게 될까? + +\item 음수를 표현하기 위해 {\tt -2}처럼 빼기 부호를 사용할 수 + 있다. 예를 들어 {\tt 2++2}처럼 더하기 부호를 숫자 앞에 넣은 경우에는 + 어떻게 될까? + +\item 수학에서는 {\tt 02}처럼 숫자 앞에 있는 0들이 있어도 괜찮다. Python에서 동일한 방식으로 입력한다면 어떻게 될까? + +\item 두 값을 입력할 때에 사이에 연산자가 없는 경우는 어떻게 될까? + +\end{enumerate} + +\end{exercise} + + + +\begin{exercise} + +Python 인터프리터를 실행시키고 계산기처럼 사용해보자. + +\begin{enumerate} + +\item 42분 42초는 모두 몇 초일까? + +\item 10 킬로미터는 몇 마일일까? 참고로 1.61 킬로미터가 1 마일이다. + +\item 10 킬로미터를 42분 42초만에 달렸다면 평균 보폭언 얼마나 + 될까(마일당 시간을 분과 초로 표시)? 평균 속도는 시간당 마일로 + 표기하면 몇인가? +\index{calculator} +\index{running pace} + +\end{enumerate} + +\end{exercise} + + + + +\chapter{변수와 수식 그리고 문장} +%Variables, expressions and statements + + +프로그래밍 언어의 가장 강력한 기능 중 하나는 {\bf 변수(variable)}가 +조작 가능하다는 것이다. 변수는 값에 부여하는 이름이다. +\index{variable} + + +\section{할당 문장} +%Assignment statements +\label{variables} +\index{assignment statement} +\index{statement!assignment} + +{\bf 할당 문장(assignment statement)}은 새로운 변수를 생성하고 값을 부여한다. + +\begin{verbatim} +>>> message = 'And now for something completely different' +>>> n = 17 +>>> pi = 3.141592653589793 +\end{verbatim} +% +이 예제에서는 세 개의 변수에 값을 할당했다. 첫 번째는 {\tt + message}라는 이름의 변수에 문자열을 할당하였다. 두 번째는 {\tt n}에 +정수 {\tt 17}을 부여하였고 세 번째에는 $\pi$의 값을 {\tt pi}라는 변수에 +할당하였다. +\index{state diagram} +\index{diagram!state} + +종이에 변수를 표현하는 방법은 이름과 값을 적고 화살표를 이름에서 값으로 +향하게 그리면 된다. 이와 같은 그림을 {\bf 상태도(state diagram)}이라 +부른다. 각 변수의 상태를 나타내기 때문이다(변수 마음 상태로 +생각해보자) +%수정필요 (think of it as the variable's state of mind). +그림~\ref{fig.state2}는 방금의 예제의 상태도를 보여준다. + + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/state2.pdf}} +\caption{상태도.} +\label{fig.state2} +\end{figure} + + + +\section{변수명} +%Variable names +\index{variable} + +일반적으로 프로그래머는 변수에 의미있는 이름을 부여하며, 그 변수가 +무엇에 이용되는지 문서화하기도 한다. + +이름은 길게 만들고 싶은만큼 길게 만들 수 있다. 글자와 숫자로 이루어질 +수 있지만 숫자로 시작될 수는 없다. 대문자를 못 쓰는 것은 아니지만 +관례적으로 변수명으로는 소문자만을 쓴다. + +밑 줄 표시를, \verb"_", 이름에서 볼 수도 있다 대체적으로 +\verb"your_name"이나 \verb"airspeed_of_unladen_swallow"처럼 여러 단어로 +이루어진 이름에서 사용된다. +\index{underscore character} + +무효한 이름을 변수에 할당하게 되면 문법 오류 메시지가 뜬다: + +\begin{verbatim} +>>> 76trombones = 'big parade' +SyntaxError: invalid syntax +>>> more@ = 1000000 +SyntaxError: invalid syntax +>>> class = 'Advanced Theoretical Zymurgy' +SyntaxError: invalid syntax +\end{verbatim} +% +{\tt 76trombones}가 잘못된 이유는 숫자로 시작하기 때문이고 {\tt + more@}에서 오류가 발생한 이유는 변수명으로 쓸 수 없는 글자 {\tt @}를 +사용했기 때문이다. 그렇다면 {\tt class}에는 무슨 문제가 있는 걸까? + +{\tt class}는 Python이 정의해 놓은 {\bf 키워드(keyword)}이기 때문이다. +인터프리터는 키워드들을 사용하여 프로그램의 구조를 파악하기 때문에 +변수명으로 사용할 수 없다. +\index{keyword} + +Python 3에는 다음과 같은 키워드들이 있다: + +\begin{verbatim} +False class finally is return +None continue for lambda try +True def from nonlocal while +and del global not with +as elif if or yield +assert else import pass +break except in raise +\end{verbatim} +% +이 목록을 외울 필요는 없다. 대부분의 개발 환경은 키워드들을 다른 +색으로 표현해 준다. 이 목록에 있는 키워드 중 하나를 변수 명으 +사용하려 한다면 알 수 밖에 없다. + + +\section{수식과 문장} +%Expressions and statements + +{\bf 수식(expression)}은 값과 변수 그리고 연산자들의 +조합이다. 값으로만 이루어진 그 자체도 수식으로 인식되며 변수도 +마찬가지이다. 다음의 유효한 수식들을 살펴보자. +\index{expression} + +\begin{verbatim} +>>> 42 +42 +>>> n +17 +>>> n + 25 +42 +\end{verbatim} +% +프롬프트에 수식을 입력하면 인터프리터는 수식을 {\bf +계산(evaluate)}하여 그 안에 있는 값을 찾는다. 이 예제에서는 {\tt n}은 +17이라는 값을 갖고 있고 {\tt n + 25} 는 42라는 값을 갖고 있다. +\index{evaluate} + +{\bf 문장(statement)}은 변수를 생성한다거나 값을 표시하는 것과 같이 +결과가 있는 코드의 단위이다. +\index{statement} + +\begin{verbatim} +>>> n = 17 +>>> print(n) +\end{verbatim} +% +첫 줄은 할당 문장으로 {\tt n}에 값을 부여하고 있고 두 번째 줄은 {\tt + n}에 할당된 값을 출력하는 \texttt{print} 문장이다. + +문장을 입력하면, 인터프리터는 {\bf 실행(excute)}한다. 실행한다는 의미는 +그 문장이 뜻하는 데로 동작한다는 것이다. 일반적으로 문장에는 값이 할당되지 않는다. +\index{execute} + + +\section{스크립트 모드} +%Script mode + +지금까지 Python을 {\bf 대화식 모드(interactive mode)}로 인터프리터에 +입력한 결과를 즉시 확인할 수 있었다. 대화식 모드는 감을 잡고 +시작하기에는 유용하지만 여러 줄의 코드를 사용하기에는 불편하다. +\index{interactive mode} + +그 대안으로 {\bf 스크립트(script)}라고 부르는 파일에 코드를 저장해 놓고 인터프리터를 +{\bf 스크립트 모드(script mode)}로 동작시켜서 스크립트를 실행시키는 것이다. +통상적으로 Python 스크립트 파일의 이름은 {\tt .py}로 끝이 난다. +\index{script} +\index{script mode} + +컴퓨터에서 스크립트를 생성하고 실행시키는 방법을 안되면 이제 제대로 +시작할 준비가 되었다. 그게 아니라면 \texttt{PythonAnywere}를 다시 한 +번 사용하기를 권한다. 스크립트 모드를 실행하는 방법을 +\url{http://tinyurl.com/thinkpython2e}에 기록해 놓았다. + +Python이 두 가지 모드를 지원하기 때문에 스크립트로 저장하기 전에 대화식 +모드로 실험해볼 수 있다. 하지만 대화식 모드와 스크립트 모드간의 차이가 +있기 때문에 그렇게 사용하면 혼란스러울 수 있다. +\index{interactive mode} +\index{script mode} + +예를 들어 Python을 계산기로 사용하여 다음과 같이 입력하였다고 해보자. + +\begin{verbatim} +>>> miles = 26.2 +>>> miles * 1.61 +42.182 +\end{verbatim} + +첫 줄은 {\tt miles}에 값을 할당하였지만, 그 자체로는 가시적인 결과가 +보이지 않는다. 두 번째 줄은 수식이기 때문에 인터프리터가 계산하여 +결과를 표시한다. 이 결과를 보면 마라톤의 길이는 42 킬로미터 정도된다. + +이 똑같은 코드를 스크립트로 저장하여 실행시켜 보면 어떤 결과도 출력되지 +않는다. 스크립트 모드에서의 수식 그 자체로는 어떠한 가시적인 결과가 +나타나지 않는다. 사실 Python은 수식을 계산하지만 값을 출력하라는 +말을 듣기 전까지는 그 결과를 표시하지 않는다. + + +\begin{verbatim} +miles = 26.2 +print(miles * 1.61) +\end{verbatim} + +이 같은 동작이 처음에는 이해가 안될 수 있다. + +스크립트는 대체적을 연속된 문장들로 구성되어 있다. 하나 이상의 문장이 +있는 경우에 각 문장이 실행될 때마다 하나씩 결과를 나타낸다. + +예를 들어, 다음 같은 스크립를 살펴보자. + +\begin{verbatim} +print(1) +x = 2 +print(x) +\end{verbatim} +% +이 스크립트를 실행하면 다음의 결과를 얻는다. + +\begin{verbatim} +1 +2 +\end{verbatim} +% +할당 문장은 결과를 표시하지 않는다. + +이해를 했는지 확인해보기 위해 다음의 문장들을 Python 인터프리터에 입력하여 어떻게 동작하는지 살펴보라. + +\begin{verbatim} +5 +x = 5 +x + 1 +\end{verbatim} + +그리고 이 문장들을 스크립트로 저장하여 실행해보자. 결과가 어떻게 +되는가? 스크립트의 각 수식을 \texttt{print} 문장으로 변환하여 다시 +실행해보자. + + + +\section{연산의 우선순위} +%Order of operations +\index{order of operations} +\index{PEMDAS} + +어떤 수식에 하나 이상의 연산자가 있다면 연산의 순서는 {\bf 연산의 + 우선순위(order of operations)}에 의존한다. 수학 연산자의 경우 +Python은 일반적인 수학 연산자의 우선순위를 따른다. 한 가지 방법으로 +{\bf PEMDAS}라는 두문문자로 우선순위를 기억하면 쉽다. + + +\begin{itemize} + +\item {\bf P}arentheses(괄호)는 가장 높은 우선순위를 갖고 있기 때문에 + 괄호를 사용하면 원하는 데로 연산의 순서를 조작할 수가 있다. 수식에서 + 괄호는 가장 먼저 계산되기 때문에 {\tt 2 * (3-1)}은 4가 되고 {\tt + (1+1)**(5-2)}는 8이 된다. 또한 {\tt (minute * 100) / 60}라는 + 식처럼 괄호를 사용하여 계산 결과는 바꾸지 않으면서 수식을 좀 더 읽기 + 쉽게 만들 수도 있다. + +\item {\bf E}xponentiation(거듭제곱)이 그 다음으로 높은 우선 순위를 + 갖고 있다. {\tt 1 + 2**3}의 결과는 9이지 27이 아니며, {\tt 2 * + 3**2}의 결과는 36이 아니라 18이다. + + +\item {\bf M}ultiplication(곱셉)과 {\bf D}ivision(나눗셈)은 {\bf + A}ddition(덧셈)과 {\bf S}ubtraction(뺄셈)보다 더 높은 우선순위를 + 갖고 있다. {\tt 2*3-1}의 연산 결과는 4가 아니라 5이며 {\tt 6+4/2}의 + 결과는 8이지 5가 아니다. + + +\item 같은 연산 우선순위를 갖는 연산자는 왼쪽부터 오른쪽으로(거듭제곱은 예외) 계산된다. +{\tt degrees / 2 * pi}라는 식에서는 나눗셈이 먼저 계산되고 그 결과에 {\tt pi}가 곱해진다. 만약 $2 \pi$로 나누기 원한다면 괄호를 쓰거나 {\tt degrees / 2 / pi}로 식을 고치면 된다. + +\end{itemize} + + +일부러 연산 우선순위를 외우려고 엄청나게 노력할 필요는 없다. 수식이 +바로 파악이 안된다면 괄호를 써서 그 식이 당연해지도록 바꾸면 되기 때문이다. + + +\section{문자열 연산} +%String operations +\index{string!operation} +\index{operator!string} + + +일반적으로 문자열에 수학적 연산을 쓸 수 없다. 설령 문자열이 숫자처럼 +보일지라도 그렇게 쓰는 것은 불법이다. + + +\begin{verbatim} +'2'-'1' 'eggs'/'easy' 'third'*'a charm' +\end{verbatim} +% +그 규칙에는 두 가지 예외가 있다. {\tt +}와 {\tt *}이다. + + +{\tt +} 연산자는 {\bf 문자열 연결(string concatenation)}할 때 사용하는 +것으로 문자열들을 앞뒤로 붙여준다. 예를 들어 보자: +\index{concatenation} + +\begin{verbatim} +>>> first = 'throat' +>>> second = 'warbler' +>>> first + second +throatwarbler +\end{verbatim} +% +{\tt *} 연산자도 역시 문자열을 다룰 때 쓸 수 있다. {\tt *}는 반복할 때 +사용된다. 예를 들어 \verb"'Spam'*3"의 결과는 +\verb"'SpamSpamSpam'"이다. 이것을 사용할 때는 한 값이 문자열이어야 +하고 다른 값은 정수여야 한다. + +{\tt +}와 {\tt *}의 문자열에 대한 용법은 수식에서의 덧셈과 곱셉의 +용법과 연결지어 생각하면 좋다. {\tt 4*3}은 {\tt 4+4+4}와 동치이기 +때문에 \verb"'Spam'*3"의 결과로 \verb"'Spam'+'Spam'+'Spam'"과 같은 +결과를 기대할 것이고, 실제로 같은 결과를 갖고 있다. 물론, 문자열 +연결과 반복은 정수의 덧셈과 곱셉과 다른 면이 많이 있다. 정수의 덧셈의 +성질 중 문자열 연결의 성질과 다른 것을 생각해볼 수 있겠는가? +\index{commutativity} + + +\section{주석} +%Comments +\index{comment} + + +프로그램의 크기가 커지고 복잡해지게되면 읽기가 어려워진다. 형식 언어는 +난해하다고 말을 했었다. 그렇기 때문에 코드의 일부분을 보고 무슨 일을 +하는지 또는 왜 그 일을 하는지 이해하지 못할 때가 많다. + + +그렇기 때문에 프로그램에 자연어로 이 프로그램이 어떤 일을 하는지 기록해 +놓는 것은 언제나 좋은 생각이다. 이렇게 기록하는 것을 보고 {\bf + 주석(comment)}라고 부른다. 주석은 \verb"#" 기호로 시작한다. + +\begin{verbatim} +# 한 시간에 몇 퍼센트가 지났는지 계산 +percentage = (minute * 100) / 60 +\end{verbatim} +% +이 경우에는 주석이 혼자 한 줄을 다 쓰고 있다. 주석을 그 줄의 끝에 +적을 수도 있다. + +\begin{verbatim} +percentage = (minute * 100) / 60 # 시간의 퍼센트 +\end{verbatim} +% +인터프리터는 {\tt \#} 이후부터 그 줄의 끝까지의 모든 내용을 무시한다. +프로그램 실행에 전혀 영향을 주지 않는다. + +주석이 가장 빛을 발하는 순간은 코드 중에 불명확한 기능을 설명할 때이다. 코드를 읽었을 때 그 프로그램이 {\em 무엇}을 하는지는 알아 낼 수 있을 것이다. 그렇기 때문에 {\em 왜} 그 일을 하는지를 설명하는 것이 가장 유익하다. + +다음의 주석은 코드가 하는 일에 대한 중복 설명이라 불필요하다. + +\begin{verbatim} +v = 5 # assign 5 to v +\end{verbatim} +% +반면 다음의 코드는 코드에서 알아 낼 수 없는 유익한 정보를 담고 있다. + +\begin{verbatim} +v = 5 # meters/second 단위의 속도 +\end{verbatim} +% +변수 명을 잘 정하면 주석을 달아야 할 필요가 없어지지만 너무 긴 이름으로 +지으면 읽기가 어려워지기 때문에 적당한 지점에서 타협을 해야 한다. + + +\section{디버깅} +%Debugging +\index{debugging} +\index{bug} + + +프로그램에는 문법(syntax) 오류, 실행시간(runtime) 오류, 그리고 +문맥(semantic) 오류라는 세 가지 종류의 오류가 있을 수 있다. 이 셋을 +구분할 줄 아는 것은 그 오류를 추적하는데 큰 도움을 준다. + + +\begin{description} + +\item[문법(Syntax) 오류:] ``문법(Syntax)''은 프로그램의 구조와 그 + 구조에 대한 규칙을 뜻한다. 예를 들어 괄호는 두 개가 한 쌍으로 + 사용되어야 하기 때문에 {\tt (1+2)}는 유효하지만, {\tt 8)}는 {\bf문법 + 오류}로 사용할 수 없다. + \index{syntax error}\index{error!syntax} + \index{error message}\index{syntax} + + 만약 프로그램 어딘가에 문법 오류가 있다면 Python은 오류 메시지를 + 출력하고 종료하기 때문에 그 이후의 프로그램은 더 실행 할 수 없다. + 프로그래밍에 입문한지 얼마지나지 않은 몇 주 동안은 문법 오류를 + 해결하는데 대부분의 시간을 활애할 것이다. 좀 더 연륜이 쌓인다면 + 오류의 수가 더 적어 질 것이고 그런 오류를 더 빨리 찾아 낼 수 있게 된다. + + +\item[실행시간(Runtime) 오류:] 두 번째 오류는 실행시간 오류라고 + 불리는데, 그렇게 불리는 이유는 프로그램이 실행되기 전까지는 있는지 알 + 수 없기 때문이다. 이러한 오류들은 {\bf 예외(exception)}이라고 + 불리기도 한다. 예외적인(그리고 나쁜) 일이 발생했다는 것을 나타내기 + 때문이다. \index{runtime error} \index{error!runtime} + \index{exception} \index{safe language} \index{language!safe} + + 실행시간 오류는 이 책의 처음 몇 장을 다루는 동안에는 보게 되는 간단한 + 프로그램에서는 드물게 나타난다. 실제 이런 류의 오류를 만나려면 + 시간이 좀 흘러야 할 것이다. + + +\item[문맥(Semantic) 오류:] 세 번째 종류의 오류는 ``문맥(semantic)'' + 오류로서 사용된 문장들의 의미와 관련이 있다. 프로그램에 문맥 오류가 + 있다면 오류 메시지 없이 실행이 잘 되지만 그렇다고 제대로 동작하는 + 것은 아니다. 엉뚱하게 동작을 한다. 정확하게 말하자면, 프로그래머가 + 시킨 일을 그대로 한다. \index{semantic error} + \index{error!semantic} \index{error message} + + 문맥 오류를 찾아내는 것은 까다로운 일인 이유는 프로그램이 어디서 + 어떻게 잘못되었는지를 프로그램의 실행 결과를 통해 역 추적해야하기 + 때문이다. + +\end{description} + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[변수(variable):] 값을 가리키는 이름. +\index{variable} + +\item[할당(assignment):] 변수에 값을 지정하는 문장. +\index{assignment} + +\item[상태도(state diagram):] 변수와 그 변수가 가리키는 값을 표현한 그림 +\index{state diagram} + +\item[키워드(keyword):] 프로그래밍 언어에서 미리 예약해 놓은 단어로서 + 프로그램을 구문해석하는 과정에 사용된다. {\tt if}, {\tt def}와 {\tt + while}과 같은 키워드는 변수 명으로 사용할 수 없다. +\index{keyword} + +\item[피연산자(operand):] 연산자를 사용하여 계산할 때 사용되는 값 +\index{operand} + +\item[수식(expression):] 변수와 연산자 그리고 값들의 조합으로 하나의 + 결과를 나타냄. +\index{expression} + +\item[계산(evaluate):] 하나의 값을 얻기 위해 연산하여 수식을 간단화하는 것 + +\item[문장(statement):] 명령이나 어떤 동작을 뜻하는 코드의 일부분. + 지금까지는 봐왔던 문장은 할당하는 것과 \texttt{print} 문장이 있다. +\index{statement} + +\item[실행(execute):] 문장에 적힌 그대로를 수행 +\index{execute} + +\item[대화식 모드(interactive mode):] 프롬프트에 코드를 입력하여 + Python 인터프리터를 사용하는 방식 +\index{interactive mode} + +\item[스크립트 모드(script mode):] 스크린트 파일에 저장되어 있는 코드를 + 읽어 실행하도록 Python 인터프리터를 사용하는 방식 +\index{script mode} + +\item[스크립트(script):] 파일에 저장되어 있는 프로그램 +\index{script} + +\item[연산의 우선순위(order of operations):] 여러 개의 연산자와 + 피연산자로 이루어진 수식이 계산되는 순서를 결정하는 규칙 +\index{order of operations} + +\item[연결(concatenate):] 두 개의 피 연산자를 앞뒤로 합치는 것 +\index{concatenation} + +\item[주석(comment):] 다른 프로그래머(또는 소스 코드를 읽는 누군가)를 + 위해 프로그램에 기록되어 있는 정보. 프로그램의 실행에는 아무런 영향이 + 없음. \index{comment} + +\item[문법 오류(syntax error):] 프로그램 해석이 불가능하게 만드는 + 프로그램 내의 오류(구문해석이 불가능함) +\index{syntax error} + +\item[예외(exception):] 프로그램이 실행 중에 발견되는 오류 +\index{exception} + +\item[문맥(semantics):] 프로그램의 의미 +% The meaning of a program. +\index{semantics} + +\item[문맥 오류(semantic error):] 프로그램의 의도와 다르게 프로그램이 + 동작하게 만드는 오류 +\index{semantic error} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + + 앞 장에서 했던 조언처럼 새로운 기능을 배우면 대화식 모드에서 + 실험해보고 의도적으로 실수를 해서 무엇이 잘못되는가를 살펴봐야 한다. + +\begin{itemize} + +\item {\tt n = 42}는 유효하다는 것을 보았다. {\tt 42 = n}은 어떨까? + +\item {\tt x = y = 1 }은 유효한가? + +\item 어떤 프로그래밍 언어는 세미콜론({\tt ;})으로 문장이 끝난다. + Python의 문장의 끝을 세미콜론으로 끝을 내면 어떻게 되는가? + +\item 문장의 끝을 구두점으로 끝을 내면 어떻게 되는가? + +\item 수학에서는 $x$와 $y$의 곱을 표기 할 때 $x y$로 써도 된다. Python에서 이렇게 쓰면 어떻게 될까? + +\end{itemize} + +\end{exercise} + + +\begin{exercise} + +Python의 인터프리터를 계산기처럼 사용하여 다음 문제를 실습해보자. +\index{calculator} + +\begin{enumerate} + +\item 반지름이 $r$인 구의 부피는 $\frac{4}{3} \pi r^3$ 이다. 이때 구의 + 반지름이 5라면 부피가 어떻게 되는가? + +\item 책의 가격이 27,500원으로 책정되어 있는데, 책 방에서 40\% + 도서할인전을 하고 있다. 한 권일 때는 배송비가 2,500원인데, 추가 + 구입을 할 때마다 150원이 추가된다. 60권을 산다면 배송비를 포함한 총 + 금액이 얼마인가? + + +\item 집에서 6시52분에 나와서 1마일을 천천히 8분 15초에 달리고, 그 다음 + 3마일은 마일당 7분 12초가 걸렸다. 그리고 1마일은 처음처럼 천천히 + 달렸다. 운동을 마치고 집에 도착하면 몇 시에 아침 식사를 할 수 + 있을까? +\index{running pace} + +\end{enumerate} +\end{exercise} + + +\chapter{함수} +%Functions +\label{funcchap} + +프로그래밍이라는 문맥에서 {\bf 함수(function)}은 연산을 수행하기 위한 +일련의 문장들에 이름을 붙여 놓은 것이다. 함수를 정의할 때는 이름과 +문장들 지정해야 한다. 그 다음에 함수를 지정한 이름으로 +``호출(call)''할 수 있다 . +\index{function} + +\section{함수 호출} +%Function calls +\label{functionchap} +\index{function call} + +우리는 이미 {\bf 함수 호출(function call)}의 예를 보았다: + +\begin{verbatim} +>>> type(42) + +\end{verbatim} +% +함수의 이름은 {\tt type}이다. 괄호 안의 표현은 함수의 {\bf + 인자(argument)}라고 불린다. 이 함수의 결과로 인자의 분류를 +알려준다. +\index{parentheses!argument in} + +흔히 함수가 인자를 ``받아서(take)'' 결과를 ``리턴(return)''한다고 +말한다. 그리고 함수의 결과를 {\bf 리턴 값(return value)}이라고 +부른다. +\index{argument} +\index{return value} + +Python은 어떤 값을 한 분류에서 다른 분류로 변환하는 함수들을 제공한다. +{\tt int} 함수는 어떤 값이든 받아서 정수로 변환할 수 있으면 변환하고 +그렇지 못하는 경우는 불평을 한다. +%complain 불평 +\index{conversion!type} +\index{type conversion} +\index{int function} +\index{function!int} + +\begin{verbatim} +>>> int('32') +32 +>>> int('Hello') +ValueError: invalid literal for int(): Hello +\end{verbatim} +% +{\tt int} 함수는 부동 소수점 숫자를 정수로 변환할 수 있지만 반올림을 하지 +않는다. 소수점 부분을 잘라 버리기만 한다. + +\begin{verbatim} +>>> int(3.99999) +3 +>>> int(-2.3) +-2 +\end{verbatim} +% +{\tt float} 함수는 정수와 문자열을 부동 소수점 숫자로 변환한다. +\index{float function} +\index{function!float} + +\begin{verbatim} +>>> float(32) +32.0 +>>> float('3.14159') +3.14159 +\end{verbatim} +% +마지막으로 {\tt str} 함수는 인자를 문자열로 변환한다. +\index{str function} +\index{function!str} + +\begin{verbatim} +>>> str(32) +'32' +>>> str(3.14159) +'3.14159' +\end{verbatim} +% + +\section{수학 함수} +%Math functions +\index{math function} +\index{function, math} + +Python은 대부분의 익숙한 수학 함수들을 포함하는 수학 모듈을 갖고 있다. +{\bf 모듈(module)}은 관련된 함수들을 모아 놓은 파일이다. +\index{module} +\index{module object} + +모듈에 포함된 함수를 사용하기 전에 {\bf import 문장}으로 읽어들여야 한다. + +\begin{verbatim} +>>> import math +\end{verbatim} +% +이 문장은 \texttt{math}라고 불리는 {\bf 모듈 객체(module object)}를 +생성한다. 모듈 객체를 표시하도록 하면 객체에 관한 정볼르 얻을 수 +있다. + + +\begin{verbatim} +>>> math + +\end{verbatim} +% +모듈 객체는 모듈에 정의된 함수들과 변수들을 포함하고 있다. 모듈에 +포함된 함수를 사용하고 싶으면 모듈과 사용하기 원하는 함수의 이름을 +구두점(닷, dot)으로 구분하여 지정해야 한다. 이와 같은 형식을 {\bf 닷 + 표기법(dot notation)}이라고 부른다. +\index{dot notation} + +\begin{verbatim} +>>> ratio = signal_power / noise_power +>>> decibels = 10 * math.log10(ratio) + +>>> radians = 0.7 +>>> height = math.sin(radians) +\end{verbatim} +% +첫 예제에서는 \verb"math.log10"을 사용하여 \verb"signal_power" 와 +\verb"noise_power"의 변수가 정의되어 있다고 가정했을 때의 신호대잡음비를 +데시벨로 변환한다. 수학 모듈은 밑 수를 {\tt e}로 하는 {\tt log}도 제공한다. +\index{log function} +\index{function!log} +\index{sine function} +\index{radian} +\index{trigonometric function} +\index{function, trigonometric} + +두 번째 예제에서는 {\tt radians} 변수에 대한 사인 값을 계산한다. {\tt + sin}, {\tt cos} 그리고 {\tt tan}와 같은 삼각함수와 관련된 함수들의 +인자 값은 이 예제에서 사용한 변수 명처럼 라디안을 쓴다. 도를 +라디안으로 변환하려면 180으로 나누고 $\pi$로 곱하면 된다. + + +\begin{verbatim} +>>> degrees = 45 +>>> radians = degrees / 180.0 * math.pi +>>> math.sin(radians) +0.707106781187 +\end{verbatim} +% +{\tt math.pi}라고 쓰면 {\tt pi} 변수를 수학 모듈에서 가져온다. 이 값은 +소수점 15자리까지 정확한 근사값이다. +\index{pi} + +삼각함수 식에 따라 45도의 사인 값은 2분의 루트 2이기 때문에 예제의 +결과가 맞는지 비교해 볼 수 있다. +\index{sqrt function} +\index{function!sqrt} + +\begin{verbatim} +>>> math.sqrt(2) / 2.0 +0.707106781187 +\end{verbatim} +% + +\section{구성} +%Composition +\index{composition} + +지금까지 변수와 수식 그리고 문장이라는 프로그램의 요소들을 독립적으로만 +다루었기 때문에 구성 요소들을 화합하여 쓰는 것에 대해서는 다루지 +않았다. + +프로그래밍 언어의 가장 유익한 기능 중 하나는 작은 단위의 필요한 +부분들을 모아서 {\bf 구성(compose)}할 수 있다는 것이다. 예를 들면, +함수의 인자로 산술 연산자들을 포함하는 어떤 수식이라도 다 받을 수 있다. + + +\begin{verbatim} +x = math.sin(degrees / 360.0 * 2 * math.pi) +\end{verbatim} +% +함수 호출도 할 수 있다. + +\begin{verbatim} +x = math.exp(math.log(x+1)) +\end{verbatim} +% +거의 모든 곳에 값을 넣을 수 있으며 임의의 수식을 쓸 수 있다. 단, 한 +가지 예외가 있다. 할당 문장의 왼쪽에는 변수의 이름이 있어야 한다. +왼쪽에 다른 어떤 수식이라도 오면 문법 오류가 발생한다 (이것에 +대한 예외 상황을 이후에 살펴 보자). + + +\begin{verbatim} +>>> minutes = hours * 60 # 맞음 +>>> hours * 60 = minutes # 틀림! +SyntaxError: can't assign to operator +\end{verbatim} +% +\index{SyntaxError} +\index{exception!SyntaxError} + + +\section{새로운 함수의 추가} +%Adding new functions + +지금까지는 Python이 제공하는 함수들만 사용했었는데, 새로운 함수도 추가 +할 수 있다. {\bf 함수 정의(function definition)}로 새로운 함수에 +이름을 부여하고 그 함수를 호출했을 때 실행될 일련의 문장들을 지정할 수 +있다. +\index{function} +\index{function definition} +\index{definition!function} + +여기 그 예가 있다. + +\begin{verbatim} +def print_lyrics(): + print("I'm a lumberjack, and I'm okay.") + print("I sleep all night and I work all day.") +\end{verbatim} +% +{\tt def}라는 키워드가 함수 정의를 표시한다. 이 함수의 이름은 +\verb"print_lyrics"이다. 함수 이름에 대한 규칙은 변수명에 대한 규칙과 +똑같다. 글자와 숫자 그리고 밑줄 표시는 사용 가능하지만 숫자가 첫 +글자로 오면 안된다. 키워드로 예약되어 있는 단어들은 함수명으로 쓸 수 +없으며 변수와 함수를 동일한 이름으로 짓는 것은 피해야 한다. +\index{def keyword} +\index{keyword!def} +\index{argument} + +함수명 다음에 빈 괄호를 사용한 것은 이 함수가 아무런 인자도 사용하지 +않는다는 것을 뜻한다. +\index{parentheses!empty} +\index{header} +\index{body} +\index{indentation} +\index{colon} + +함수 정의의 첫 줄을 {\bf 헤더(header)}라고 부르고 그 나머지 부분을 +{\bf 내용(바디, body)}라고 부른다. 헤더의 끝은 콜론이고 내용은 +들여쓰기를 해야 한다. 관례적으로 항상 4개의 공백으로 들여쓰기를 한다. +내용에는 몇 개의 문장이든 포함될 수 있다. +%body 내용 + + +\texttt{print} 문장에 문자열은 큰따옴표로 싸여있다. 작은 따옴표나 +큰따옴표나 동일하다. 대부분의 사람들은 작은 따옴표를 사용하지만, +예외적으로 작은 따옴표(아포스트로피 또는 생략 기호)가 문자열 중에 +포함된 경우에만 큰따옴표를 사용한다. + +모든 인용부호(작은 따옴표와 큰따옴표)는 대체적으로 키보드의 엔터 키 +옆에 있는 ``반듯한 인용부호''를 사용해야 한다. 이 문장에서 쓰고 있는 +``휘어진 인용부호''는 Python에서 쓸 수 없다. + +대화식 모드에서 함수 정의를 입력하면 인터프리터는 함수의 내용 부분에 +점({\tt ...})을 표시하여 정의가 끝나지 않았다는 것을 표시한다. +\index{ellipses} + +\begin{verbatim} +>>> def print_lyrics(): +... print("I'm a lumberjack, and I'm okay.") +... print("I sleep all night and I work all day.") +... +\end{verbatim} +% +함수의 정의를 끝내려면 빈 줄을 입력하면 된다. 이렇게 정의된 함수 객체는 +\verb"function"으로 분류된다. +\index{function type} +\index{type!function} + +\begin{verbatim} +>>> print(print_lyrics) + +>>> type(print_lyrics) + +\end{verbatim} +% +새로운 함수를 호출하는 문법은 내장된 함수들을 호출하는 방식과 똑같다. + +\begin{verbatim} +>>> print_lyrics() +I'm a lumberjack, and I'm okay. +I sleep all night and I work all day. +\end{verbatim} +% +이렇게 정의된 함수는 다른 함수 내에서 사용될 수 있다. 예를 들어 방금 +출력한 후렴구를 반복적으로 호출하도록 \verb"repeat_lyrics"라는 함수를 +작성해 보자 + + +\begin{verbatim} +def repeat_lyrics(): + print_lyrics() + print_lyrics() +\end{verbatim} +% +그리고 \verb"repeat_lyrics"을 호출해보자. + +\begin{verbatim} +>>> repeat_lyrics() +I'm a lumberjack, and I'm okay. +I sleep all night and I work all day. +I'm a lumberjack, and I'm okay. +I sleep all night and I work all day. +\end{verbatim} +% +실제 노래가 이렇게 흘러가지는 않는다. + + +\section{정의와 활용} +%Definitions and uses +\index{function definition} + +이전 절에서 사용한 코드를 다시 가져와 보자. 전체 코드는 다음과 같다. + +\begin{verbatim} +def print_lyrics(): + print("I'm a lumberjack, and I'm okay.") + print("I sleep all night and I work all day.") + +def repeat_lyrics(): + print_lyrics() + print_lyrics() + +repeat_lyrics() +\end{verbatim} +% +이 프로그램은 \verb"print_lyrics" 와 \verb"repeat_lyrics"라는 두 개의 +함수를 정의하고 있다. 함수 정의는 다른 문장처럼 실행되지만, 실행의 +결과로 함수 객체만 생성이 된다. 실제 함수 정의의 내용은 그 함수가 +호출되기 전까지는 실행되지 않으며 함수 정의 자체는 어떠한 결과도 출력하지 않는다. +\index{use before def} + +예상한 것처럼, 함수를 생성한 후에야 함수를 실행할 수 있다. 다시 +말하면, 함수가 호출되기 이전에 함수가 정의되어야 한다. + +연습을 해보자. 두 번쨰 함수의 마지막 줄을 이 프로그램의 가장 처음으로 +옮겨보자. 프로그램을 실행해서 함수 정의보다 먼저 함수 호출 문장이 +나타나면 어떤 오류 메시지를 출력하는지 보자. + +함수 호출 문장을 원상복귀 한 후, 이번에는 \verb"repeat_lyrics" +다음에 \verb"print_lyrics"를 배치해보자. 이 상태로 프로그램을 +실행시키면 어떻게 되나? + + + +\section{실행의 흐름} +%Flow of execution +\index{flow of execution} + +함수를 정의한 후에 사용되도록 만들려면 어떤 순서로 문장들이 +실행되는지를 알아야 한다. 이를 {\bf 실행의 흐름(flow of + execution)}이라고 부른다. + + +실행의 순서는 언제 프로그램의 첫 문장부터 시작된다. 가장 위에서부터 +밑까지 문장은 한 번에 하나씩 실행된다. + +함수 정의는 프로그램의 실행의 흐름을 변경시키지 않지만 함수 정의 내의 +문장들은 해당 함수가 호출되기 이전에는 실행되지 않는다는 것을 기억해야 +한다. + +함수 호출은 실행 흐름의 우회로와 같다. 다음 문장을 실행시키는 대신 +함수의 내용으로 이동하여 그 안의 문장들을 실행시킨 후 이전에 멈췄던 +부분부터 실행한다. + +매우 간단하게 들리겠지만, 함수가 또 다른 함수를 호출 할 수 있다는 것을 +되새겨 보면 그렇지 않다는 것을 깨달을 것이다. 함수의 중간에서 다른 +함수의 문장들을 호출할 수 있다. 그러는 중에 또 다른 함수를 호출할 수도 +있다! + +다행스러운 것은, Python은 현재 실행 중이던 위치를 파악하는 것에 +능숙하다. 함수의 실행이 완료되면 호출했던 함수에서 마지막 실행 중이던 +위치를 찾아 계속 진행할 수 있다. 마침내 프로그램의 끝에 도달하면 +종료한다. + +정리하면, 프로그램을 읽을 때에는 프로그램의 처음부터 한 줄 씩 읽으려 할 +필요가 없다. 오히려 실행의 흐름을 따르는 것이 이해하기 더 쉬울 수 있다. + + +\section{매개 변수와 인자값} +%Parameters and arguments +\label{parameters} +\index{parameter} +\index{function parameter} +\index{argument} +\index{function argument} + +어떤 함수들은 인자를 사용한다는 것을 보았다. 예를 들어 {\tt + math.sin}을 쓸 때 숫자를 인자로 입력했었다. 어떤 함수는 하나 이상의 +인자를 받기도 한다. {\tt math.pow}는 밑수와 지수라는 두 개의 인자를 +받는다. + +함수 내에서는 전달 받은 인자를 {\bf 매개 변수(파라미터, parameter)}라는 +변수로 할당된다. 인자를 받는 어떤 함수의 정의를 살펴보자. +\index{parentheses!parameters in} + +\begin{verbatim} +def print_twice(bruce): + print(bruce) + print(bruce) +\end{verbatim} +% +이 함수는 전달 받은 인자를 {\tt bruce}라는 매개 변수로 할당한다. +함수가 호출되면 그 매개 변수가 무엇이든 간에 두 번 출력하고 있다. + +다음의 함수는 출력 가능한 모든 값에 쓸 수 있다. + +\begin{verbatim} +>>> print_twice('Spam') +Spam +Spam +>>> print_twice(42) +42 +42 +>>> print_twice(math.pi) +3.14159265359 +3.14159265359 +\end{verbatim} +% +내장된 함수들에 적용되었던 구성에 관한 규칙들은 프로그래머가 정의한 +함수들에도 똑같이 적용된다. 그러므로, \verb"print_twice"의 인자 +값으로 어떤 수식이라도 쓸 수 있다. +\index{composition} +\index{programmer-defined function} +\index{function!programmer defined} + +\begin{verbatim} +>>> print_twice('Spam '*4) +Spam Spam Spam Spam +Spam Spam Spam Spam +>>> print_twice(math.cos(math.pi)) +-1.0 +-1.0 +\end{verbatim} +% +함수가 호출되기 전에 인자 값을 계산한다. 예에서 사용한 \verb"'Spam'*4"와 +{\tt math.cos(math.pi)}라는 수식은 한 번씩 계산된다. +\index{argument} + +변수 역시도 인자로 사용할 수 있다. + +\begin{verbatim} +>>> michael = 'Eric, the half a bee.' +>>> print_twice(michael) +Eric, the half a bee. +Eric, the half a bee. +\end{verbatim} +% +인자로 전달한 ({\tt michael})이라는 병수명은 함수를 정의할 때 사용한 +매개 변수({\tt bruce})와는 아무런 관계가 없다. 호출되기 전 코드(호출자, caller) 어떤 +값이었든 상관없다. \verb"print_twice" 함수 내에서는 {\tt bruce}라 +부른다. +%caller 호출자 + + +\section{변수와 매개 변수의 지역성} +%Variables and parameters are local +\index{local variable} +\index{variable!local} + +함수 내에서 변수를 생성하면 {\bf 지역 또는 로컬(local)} 변수라고 +부른다. 함수 내에서만 존재하기 때문이다. 예를 들어 보자. +\index{parentheses!parameters in} + +\begin{verbatim} +def cat_twice(part1, part2): + cat = part1 + part2 + print_twice(cat) +\end{verbatim} +% +이 함수는 두 개의 인자를 받아서 연결하고, 그 결과를 두 번 출력한다. 이 +함수 정의를 쓰는 예를 살펴 보자. +\index{concatenation} + +\begin{verbatim} +>>> line1 = 'Bing tiddle ' +>>> line2 = 'tiddle bang.' +>>> cat_twice(line1, line2) +Bing tiddle tiddle bang. +Bing tiddle tiddle bang. +\end{verbatim} +% +\verb"cat_twice" 가 종료하면 함수 내에서 사용되었던 변수 {\tt cat}은 +없어진다. 출력해보려고 하면 예외처리 된다. +\index{NameError} +\index{exception!NameError} + +\begin{verbatim} +>>> print(cat) +NameError: name 'cat' is not defined +\end{verbatim} +% +매개 변수도 지역에서만 정의된다. 예를 들어 \verb"print_twice" 밖에서는 +{\tt bruce}라는 것은 존재하지 않는다. +\index{parameter} + + +\section{스택 상태도} +%Stack diagrams +\label{stackdiagram} +\index{stack diagram} +\index{function frame} +\index{frame} + +각 변수의 사용 범위 파악에 {\bf 스택 상태도(stack diagram)}을 그려보는 +것이 도움이 된다. 상태도와 유사하게 스택 상태도는 각 변수의 값을 +나타낸다. 추가적으로 각 변수가 어떤 함수에 포함되는지도 나타낸다. +\index{stack diagram} +\index{diagram!stack} + +각 함수는 {\bf 프레임(frame)}이라는 단위로 구분된다. 여기서 프레임은 +하나의 상자로 함수의 이름이 곁에 적혀 있고 상자 내부에는 변수와 매개 +변수가 적혀 있다. 앞서 본 예제의 스택 상태도는 +그림~\ref{fig.stack}에 나타나 있다. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/stack.pdf}} +\caption{스택 상태도.} +\label{fig.stack} +\end{figure} + +어떤 함수가 어떤 함수를 호출 했는지를 알아 볼 수 있도록 프레임들이 +스택에 정리되어 있다. 이 예제에서는 \verb"print_twice" 함수는 +\verb"cat_twice" 함수에 의해 호출되었으며 \verb"cat_twice" 함수는 +\verb"__main__"에 의해 호출이 되었다. \verb"__main__"라는 함수는 +최상위 프레임에게 부여하는 특별한 이름이다. 함수 밖에서 생성된 변수는 +\verb"__main__" 함수에 속해 있다. +\index{main} + +각 매개 변수는 해당 인자가 갖고 있는 값과 똑같은 값을 갖고 있다. +그렇기 때문에 {\tt part1}가 같고 있는 값은 {\tt line1}이 갖고 있는 값고 +똑같으며, {\tt part2}가 같고 있는 값은 {\tt line2}와 동일하다. 그리고, +{\tt bruce}는 {\tt cat}과 똑같다. + +함수 호출 중에 오류가 발생하면 Python은 함수의 이름과 호출을 시도한 +함수명을 출력한다. 그리고 다시 그 함수를 호출한 상위 프레임의 함수명을 +출력한다. 이 과정을 \verb"__main__"에 도달 할 때까지 반복한다. + +예를 들어, \verb"print_twice" 내에서 {\tt cat}를 접근하려고 시도 한다면 +{\tt NameError}이라는 오류 메시지를 받을 것이다. + +\begin{verbatim} +Traceback (innermost last): + File "test.py", line 13, in __main__ + cat_twice(line1, line2) + File "test.py", line 5, in cat_twice + print_twice(cat) + File "test.py", line 9, in print_twice + print(cat) +NameError: name 'cat' is not defined +\end{verbatim} +% +이런 식으로 함수의 리스트를 보여주는 것을 {\bf 추적(트레이스백, + traceback)}이라고 부른다. 오류가 발생했을 때 어떤 프로그램 파일에서 +오류가 발생했는지 그리고 실행 중이던 함수와 오류를 일으킨 줄 번호에 대한 +정보를 보여준다. 그리고 오류를 일으킨 코드도 보여준다. +\index{traceback} + + +트레이스백의 함수의 순서는 스택 상태도에서 나타난 프레임의 순서와 +똑같다. 현재 실행 중이던 함수가 가장 아래에 표시된다. + + + +\section{열매가 있는 함수들과 비어 있는 함수} +%Fruitful functions and void functions} +\index{fruitful function} +\index{void function} +\index{function, fruitful} +\index{function, void} + +수학 함수들과 같은 우리가 사용해본 함수들은 결과를 리턴한다. 이런 +종류의 함수를 구분하는 좋은 이름이 따로 없어서 {\bf 열매가 있는 + 함수(fruitful function)}이라고 부른다. \verb"print_twice"와 같은 +류의 다른 함수들은 어떤 동작을 하지만 결과 값을 리턴하지는 않는다. +이런 류는 {\bf 비어 있는 함수(void function)}라고 부른다. + +열매가 있는 함수를 호출하면 거의 모든 경우에 리턴받은 결과를 활용하기를 +원한다. 예를 들어, 그 결과에 변수를 할당하거나 수식의 일부로 +사용하기도 한다. + +\begin{verbatim} +x = math.cos(radians) +golden = (math.sqrt(5) + 1) / 2 +\end{verbatim} +% +대화식 모드에서 함수를 호출할 때 Python은 결과를 표시한다. + +\begin{verbatim} +>>> math.sqrt(5) +2.2360679774997898 +\end{verbatim} +% +스크립트로 실행했을 때, 열매가 있는 함수를 그 자체로만 호출하면 리턴 받은 결과는 영원히 잃어버리고 만다! + +\begin{verbatim} +math.sqrt(5) +\end{verbatim} +% +이 스크립트는 루트 5를 계산하지만 결과를 저장하지도 표시하지도 않기 +때문에 그렇게 유용하지는 않다. +\index{interactive mode} +\index{script mode} + +비어 있는 함수는 화면에 무언가를 표시하거나 다른 어떤 영향이 있는 +것처럼 보이지만 리턴할 결과 값이 없다. 만약 결과 값을 변수에 +할당하려고 시도한다면 {\tt None}이라는 특수한 값을 돌려 받는다. +\index{None special value} +\index{special value!None} + +\begin{verbatim} +>>> result = print_twice('Bing') +Bing +Bing +>>> print(result) +None +\end{verbatim} +% +{\tt None}이라는 값은 \verb"'None'"이라는 문자열과 같은 것이 아니다. +그 자체가 특수한 값을 같은 또 다른 분류이다. + +\begin{verbatim} +>>> type(None) + +\end{verbatim} +% +지금까지 우리가 작성한 모든 함수들은 모두 비어 있는 함수들이었다. 이제 +앞으로 다룰 장들에서 열매가 있는 함수들을 작성하기 시작할 것이다. +\index{NoneType type} +\index{type!NoneType} + + +\section{왜 함수인가?} +%Why functions? +\index{function, reasons for} + +프로그램의 내용을 왜 함수들로 나눠야 하는지에 대한 이유가 아직은 명확하지 않을 것이다. 그럴만한 이유는 많이 있다. + +\begin{itemize} + +\item 새로운 함수를 생성하면 문장들의 묶음에 이름을 지어줄 수 있다. + 그러면 프로그램을 읽거나 디버깅하기가 쉬워진다. + +\item 함수들을 활용하면 반복적인 코드들을 제거할 수 있기 때문에 + 프로그램의 길이가 짧아진다. 나중에 반복되는 코드를 수정을 할 일이 + 생긴다면 한 곳에서만 수정을 하면 된다. + +\item 긴 프로그램을 함수들로 나누어 놓으면 한 번에 한 부분씩 디버깅을 + 할 수 있으며, 디버깅이 완료되면 제대로 동작하는 전체로 다시 모을 + 수있다. + +\item 잘 설계된 함수들은 여러 프로그램들에 유용하게 사용될 수 있다. + 하나를 잘 작성해 놓고 디버깅을 해 놓으면 다른 곳에서도 그 부분을 + 재활용할 수 있다. + +\end{itemize} + + +\section{디버깅} +%Debugging + +가장 중요한 기술 중에 하나인 디버깅 기술을 가져야 한다. 좌절스럽게 +만들 때도 있지만 디버깅은 지적으로 풍부하고 도전적고 또한 프로그래밍을 +흥미롭게 만드는 것이기도 하다. +\index{experimental debugging} +\index{debugging!experimental} + +디버깅은 어떤 면에서 탐정이 수사를 펼치는 것과 같다. 현재 발생한 +결과를 이끌어 낸 과정과 사건들을 유추할 있는 여러 단서들과 만나게 +된다. + +디버깅은 실험에 기반한 과학과도 같다. 무엇인 잘못된 것 같단 아이디어가 +떠 오르면 프로그램을 수정해보고 다시 시도 해 보면 된다. 가정이 옳다면 +수정에 대한 결과를 예측해 볼 수 있게 되고 동작하는 프로그램으로 한 걸음 +더 가까이 다가갈 수 있게 된다. 만약 가정이 틀렸다면 다른 방법을 +시도해봐야 한다. 셜록 홈즈가 말하듯이 ``불가능한 것들을 하나씩 제거한 뒤에 +남은 것이 아무리 불가능해 보일지라도 그게 사실일 것이다.''(A. 코난 도일, +{\em 4개의 서명}) +\index{Holmes, Sherlock} +\index{Doyle, Arthur Conan} + +어떤 이들에게는 프로그래밍과 디버깅은 똑같은 것이다. 그들에게 +프로그래밍이라는 것은 원하는 동작을 할 때까지 프로그램을 조금씩 +디버깅해 나가는 것이다. 동작 가능한 프로그램을 먼저 작성한 후에 조금씩 +변형을 만들어 내고 디버깅하는 것이 기본 접근 방식이다. + +예를 들어, 리눅스라는 운영체제는 지금은 수 백만 줄의 코드로 +이루어져있지만, 최초에는 리누스 토발즈가 인텔 80386 CPU를 사용하는 +간단한 프로그램으로 시작되었다. 래리 그린필드에 의하면 ``리누스의 초기 +프로젝트 중에 하나는 AAAA를 BBBB로 변환하는 프로그램을 만드는 +것이었다. 이게 나중에는 발전하여 리눅스가 되었다.'' ({\em The Linux + Users' Guide(리눅스 사용자 가이드)} 베타 1판). +\index{Linux} + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[(function):] 이름이 있는 일련의 문장들로 유용한 작업을 수행한다. + 함수는 인자를 받을 수도 안 받을 수도 있으며 실행하였을 때 결과 돌려 + 줄 수도 있고 그렇지 않을 수도 있음 +\index{function} + +\item[함수 정의(function definition):] 새로운 함수를 생성하는 문장으로 함수의 이름과 매개 변수들을 지정하고 그리고 문장들을 포함함 +\index{function definition} + +\item[함수 객체(function object):] 함수 정의에 의해 생성되는 값. + 함수의 이름이 함수 객체를 가리키는 변수임 + \index{function definition} + +\item[헤더(header):] 함수 정의의 첫 줄 +\index{header} + +\item[내용(바디, body):] 함수 정의 내의 일련의 문장들 +\index{body} + +\item[매개 변수(parameter):] 함수 내에서 인자로 전달된 값을 가리키는 이름 +\index{parameter} + +\item[함수 호출(function call):] 함수를 실행시키는 문장. 함수의 이름과 + 괄호로 싸여있는 인자들의 목록으로 구성되어 있음 +\index{function call} + +\item[인자(argument):] 함수가 호출되었을 때 함수에 제공되는 값. 이 + 값은 해당 함수에 매개 변수에 할당됨 +\index{argument} + +\item[지역 변수(local variable):] 함수 내에서 정의된 변수. 지역 변수는 + 정의된 함수 내에서만 사용될 수 있음 +\index{local variable} + +\item[리턴 값(return value):] 함수의 결과. 함수 호출이 수식의 일부로 + 사용되었다면 리턴 값은 수식이 사용하는 값이 됨 +\index{return value} + +\item[열매가 있는 함수(fruitful function):] 결과를 리턴하는 함수 +\index{fruitful function} + +\item[비어 있는 함수(void function):] {\tt None}을 리턴하는 함수 +\index{void function} + +\item[{\tt None}:] 비어 있는 함수가 리턴하는 특수한 값 +\index{None special value} +\index{special value!None} + +\item[모듈(module):] A file that contains a +collection of related functions and other definitions. +\index{module} + +\item[읽어들이기 문장(import statement):] 모듈 파일을 읽어서 모듈 + 객체를 생성하는 문장 +\index{import statement} +\index{statement!import} + +\item[모듈 객체(module object):] {\tt import} 문장으로 생성되는 값으로 + 모듈에서 정의한 값들을 사용할 수 있도록 함 +\index{module} + +\item[닷 표기법(dot notation):] 다른 모듈의 함수를 호출하는 문법으로 + 모듈의 이름과 함수의 이름을 점(닷, 구두점)으로 연결하는 표기법 +\index{dot notation} + +\item[구성(composition):] 더 큰 수식의 일부로 수식을 쓰거나 더 큰 + 문장의 일부로 문장을 작성하는 것 +\index{composition} + +\item[실행의 흐름(flow of execution):] 문장들의 실행 순서 +\index{flow of execution} + +\item[스택 상태도(stack diagram):] 함수가 사용하고 있는 스택의 상태를 + 그림으로 표기하는 방법으로 변수와 각 변수가 가리키는 값을 나타나냄 +\index{stack diagram} + +\item[프레임(frame):] 스택 상태도의 상자로 함수 호출을 나타냄. 상자는 + 지역 변수와 함수의 매개 변수를 포함함. +\index{function frame} +\index{frame} + +\item[트레이스백(추적, traceback):] 실행 중인 함수들의 목록으로 예외가 + 발생할 때 출력이 됨 +\index{traceback} + + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +\index{len function} +\index{function!len} + +\verb"right_justify"(오른쪽 정렬이라는 의미)라는 이름과 문자열 {\tt + s}를 매개 변수로 사용하는 함수를 작성하여라. 문자열 앞에 충분한 +공백을 두어서 문자열의 마지막 글자가 70번째 열에 보이도록 하라. + +\begin{verbatim} +>>> right_justify('monty') + monty +\end{verbatim} + +힌트: 문자열 연결과 반복을 사용하라. Python은 {\tt len}이라는 내장 +함수를 갖고 있다. 이 함수는 문자열의 길이를 리턴한다. +\verb"len('monty')"의 값은 5이다. + +\end{exercise} + + +\begin{exercise} +\index{function object} +\index{object!function} + +함수 객체는 값이기 때문에 변수에 할당할 수도 있고 인자로 전달할 수도 +있다. 예를 들어, \verb"do_twice"는 함수 객체를 인자로 전달 받아 두 번 +호출하는 함수이다. + +\begin{verbatim} +def do_twice(f): + f() + f() +\end{verbatim} + +다음 예제는 \verb"do_twice"를 사용하여 \verb"print_spam"라는 함수를 두 번 호출한다. + + +\begin{verbatim} +def print_spam(): + print('spam') + +do_twice(print_spam) +\end{verbatim} + +\begin{enumerate} + +\item 이 예제를 스크립트로 작성하여 제대로 동작하는지 확인해보라 + +\item \verb"do_twice"를 두 개의 인자를 받도록 수정하여라. 함수 객체와 + 값을 전달받아 해당 함수는 두 번 호출하고 값은 인자로 전달하도록 + 만들라. + +\item 이 장의 처음에 다뤘던 \verb"print_twice" 함수의 정의를 복사하여 + 스크립트에 포함시켜라 + +\item 수정한 \verb"do_twice" 함수를 사용하여 \verb"print_twice"를 두 번 + 호출하여라. 이 때, \verb"print_twice" 함수의 인자는 \verb"'spam'"을 + 사용하여라. + +\item 함수 객체와 값을 전달 받아 해당 함수를 4번 호출하고 값은 매개 변수로 사용하는 \verb"do_four"라는 새로운 함수를 정의하여라. 이 함수의 내용에는 네 개가 아니라 두 개의 문장만 있어야 한다. + +\end{enumerate} + +해답: \url{http://thinkpython2.com/code/do_four.py}. + +\end{exercise} + + + +\begin{exercise} + + 메모: 이 연습 문제는 지금까지 우리가 배운 문장들과 기능들만을 + 사용하여 해결해야 한다. + +\begin{enumerate} + +\item 아래와 같은 격자 무늬를 만드는 함수를 작성하라: +\index{grid} + +\begin{verbatim} ++ - - - - + - - - - + +| | | +| | | +| | | +| | | ++ - - - - + - - - - + +| | | +| | | +| | | +| | | ++ - - - - + - - - - + +\end{verbatim} +% +힌트: 한 줄에 하나 이상의 값을 출력하려면 값을 쉼표로 구분지으면 된다. + +\begin{verbatim} +print('+', '-') +\end{verbatim} +% +기본적으로 {\tt print}는 출력이 끝나면 다음 줄로 넘어간다. 이 같은 +동작을 수정하려면 다음과 같은 방법으로 동작을 변경할 수 있다. + +\begin{verbatim} +print('+', end=' ') +print('-') +\end{verbatim} +% +이 문장들의 결과는 \verb"'+ -'"이다. + +{\tt print} 문장에 인자가 없다면 현재 출력 중이던 줄을 종료하고 다음 +줄로 넘어간다. + +\item 네 개의 행과 열이 있는 격자 무늬를 그리는 함수를 작성하여라. + +\end{enumerate} + +해답: \url{http://thinkpython2.com/code/grid.py}. + +출처: 이 예제는 스티브 오우알린의 ({\em Practical C Programming, 3판}, +오라일리 출판사, 1997), 연습 문제를 기초로 하였다. + +\end{exercise} + + + + + +\chapter{사례 연구: 인터페이스 설계} +%Case study: interface design +\label{turtlechap} + +이 장은 함께 동작하는 함수들을 설계하는 과정을 사례를 들어 살펴보자. + +{\tt turtle}이라는 모듈을 소개하고자 한다. 이 모듈은 거북이 그래픽스를 +사용하여 이미지를 생성해 준다. Python을 설치하면 {\tt turtle} 모듈이 +내장되어 있지만 PythonAnywhere을 사용 중이라면 이 모듈을 사용할 수 +없다(최소한 이 글을 쓰는 중에는 불가능했다). + +Python을 컴퓨터에 설치했다면 여기의 예제들을 실행할 수 있다. 아직 설치 +안했다면 이제는 설치를 해보자. 설치하는 방법은 +\url{http://tinyurl.com/thinkpython2e}에 나와 있다. + +이 장에서 사용한 예제들의 코드는 +\url{http://thinkpython2.com/code/polygon.py} 에서 얻을 수 있다. + + +\section{Turtle 모듈} +%The turtle module +\label{turtle} + +{\tt turtle} 모듈이 포함되어 있는지 확인해보고 싶으면 Python을 +인터프리터를 열어서 다음을 입력해보자. + + +\begin{verbatim} +>>> import turtle +>>> bob = turtle.Turtle() +\end{verbatim} + +이 코드를 실행하면 거북이를 나타내는 작은 화살표가 포함된 새로운 창이 +열린다. 확인했다면 창을 닫자. + +{\tt mypolygon.py}이라는 파일을 생성해서 다음의 내용을 입력해보자. + + +\begin{verbatim} +import turtle +bob = turtle.Turtle() +print(bob) +turtle.mainloop() +\end{verbatim} +% +{\tt turtle} 모듈 (소문자 't')은 {\tt Turtle}(대문자 'T')이라는 함수를 +제공한다. 이 함수는 Turtle 객체를 생성하는데 {\tt bob} 이라는 변수에 +할당했다. {\tt bob}을 출력하면 다음의 내용이 표시된다. + +\begin{verbatim} + +\end{verbatim} +% +{\tt bob} 이라는 변수는 {\tt turtle} 모듈에 정의되어 있는 {\tt + Turtle}이라는 객체를 가리킨다. + +마지막으로 \verb"mainloop"이 하는 일은 사용자가 무언가를 하기까지 새로 +뜬 창을 대기시킨다. 지금의 경우에는 창을 닫는 것 외에는 더 할 수 있는 +일이 없기는 한다. + +\texttt{Turtle}을 생성했다면 {\bf 메소드(method)}를 호출하여 거북이를 +창에서 움직일 수 있다. 메소드는 함수와 비슷한데 사용하는 문법이 약간 +다르다. 거북이를 전진시켜 보자. + +\begin{verbatim} +bob.fd(100) +\end{verbatim} +% +{\tt fd}라는 메소드는 {\tt bob}이라는 Turtle 객체와 연결되어 있다. +메소드의 호출은 마치 요청하는 것과 같다. {\tt bob}에게 전진 요청을 하는 +것이다. + +{\tt fd}의 인자는 픽셀단위의 거리이기 때문에 디스플레이 장치에 따라 다를 수 있다. + +\texttt{Turtle} 객체에서 호출 할 수 있는 메소드는 세 가지이다. {\tt + bk}는 뒤로 가기, {\tt lk}와 {\tt rk}는 각각 왼쪽과 오른쪽으로 +회전하기 메소드이다. {\tt lk}와 {\tt rk}의 인자 값은 각도이다. + +각 \texttt{Turtle}은 펜을 갖고 있는데, 이 펜을 들거나 내려 놓을 수 +있다. 펜을 내리면 \texttt{Turtle}이 이동한 흔적을 남길 수 있다. {\tt + pu}와 {\tt pd}는 각각 펜을 들기와 펜 내리기를 뜻한다. + +직각을 그리려면 다음의 줄들을 프로그램에 추가하자(위치는 {\tt bob}을 생성한 줄과 \verb"mainloop"를 호출하는 줄 사이에 삽입하면 된다. + +\begin{verbatim} +bob.fd(100) +bob.lt(90) +bob.fd(100) +\end{verbatim} +% +이 프로그램을 실행하면, {\tt bob}이 동쪽으로 가다가 북으로 이동하고, 그 +길에 두 개의 줄을 남긴다. + +이제 프로그램을 수정하여 정사각형을 그려 보자. 정사각형 그리기를 +성공하기 전까지는 다음으로 넘어가지 말자. + +%\newpage + +\section{간단한 반복} +%Simple repetition +\label{repetition} +\index{repetition} + +정사각형을 그리기 위해 아마도 다음과 같이 작성했을 것이다. + +\begin{verbatim} +bob.fd(100) +bob.lt(90) + +bob.fd(100) +bob.lt(90) + +bob.fd(100) +bob.lt(90) + +bob.fd(100) +\end{verbatim} +% +{\tt for} 문장을 쓰면 훨씬 간결하게 똑같은 일을 해 낼 수 있다. 다음의 +예제를 {\tt mypolygon.py}에 추가하고 다시 실행시켜보자. +\index{for loop} +\index{loop!for} +\index{statement!for} + +\begin{verbatim} +for i in range(4): + print('Hello!') +\end{verbatim} +% +그 결과는 다음과 같은 것이다. + +\begin{verbatim} +Hello! +Hello! +Hello! +Hello! +\end{verbatim} +% +이 예제가 {\tt for} 문장을 쓰는 가장 간단한 형태이다. 나중에 좀 더 +살펴보자. 지금의 예제만으로도 정사각형을 그리는 프로그램을 더 단순하게 +다시 작성할 수 있을 것이다. 성공할 때까지 시도해보자. + +여기에 {\tt for} 문장을 써서 정사각형을 그리는 코드가 있다. + + +\begin{verbatim} +for i in range(4): + bob.fd(100) + bob.lt(90) +\end{verbatim} +% +{\tt for} 문장의 문법은 함수 정의와 유사하다. 콜론으로 끝이 나는 +헤더와 들여쓰기된 내용으로 구성된다. 내용에는 문장이 몇 개라도 포함될 +수 있다. + +{\tt for} 문장은 {\bf 반복문(루프, loop)}이라고도 불린다. 실행의 +흐름이 내용을 한 번 다 실행하고 다시 처음으로 돌아가서 실행하기 +때문이다. 이 경우에는 내용을 4번 반복한다. +\index{loop} + +이 버전은 이전의 정사각형을 그리는 코드와 약간 다르다. 정사각형의 +마지막 면을 그리고 난 뒤에 회전을 한 번 더 하기 때문이다. 추가 회전이 +있어 시간은 더 들지만 반복문 내에서 동일한 동작을 반복하기 때문에 코드 +복잡도는 낮아 지는 장점이 있다. 반복문을 사용하는 버전은 거북이를 +처음에 시작했던 위치와 방향으로 다시 돌려놓는 기능도 한다. + +\section{연습 문제} +%Exercises + +TurtleWorld를 활용하는 연습 문제들을 풀어 보자. 재미있을 뿐만 아니라 +의미도 있다. 하나씩 해결 할 때마다 어떤 의미를 갖는지 생각해보자. + +다음 절에는 연습 문제들의 해답이 있으니 다 풀기 전까지는 해답을 보지 +말자(최소한 시도는 해보자). + + +\begin{enumerate} + +\item {\tt square}라는 이름의 함수를 작성하고 거북이를 대신할 매개 + 변수는 {\tt t}로 하자. 거북이로 정사각형을 그려보자. + + {\tt bob}을 {\tt square}의 인자로 전달하여 호출하도록 수정하고 + 프로그램을 다시 실행해보자. + + +\item {\tt square} 함수에 {\tt length}라는 매개 변수를 추가 해보자. + 정사각형의 변이 {\tt length}가 되도록 수정하고, 함수를 호출하는 + 문장도 인자를 두 개를 받도록 수정하자. 프로그램을 재실행해보라. + {\tt length}에 다양한 값을 넣어 프로그램을 실험해보자. + + +\item {\tt square} 함수를 복사해서 {\tt polygon}이라는 함수를 만들자. + 그리고 {\tt n}이라는 매개 변수를 추가한 후 함수의 내용에 면이 n인 + 다각형을 그리도록 수정하자. 힌트: 다각형의 외각은 + $360/n$도이다. + \index{polygon function} \index{function!polygon} + +\item 거북이({\tt t})와 반지름({\tt r})을 매개 변수로 하는 {\tt + circle}이라는 함수를 작성해보자. 이 때 {\tt polygon} 함수를 + 활용하여 원에 근사한 도형을 그려보자. {\tt r}의 변경해보면서 함수를 + 검사해보자. + \index{circle function} \index{function!circle} + + 힌트: {\tt length * n = 둘레}를 만족하도록 값을 정하면 된다. + +\item {\tt circle}보다 좀 더 일반적인 {\tt arc}라는 함수를 만들어 + 보자. 이 함수는 추가로 {\tt angle}이라는 매개 변수를 받는다. {\tt + angle}는 몇 도 크기의 호를 그릴지 정하는 매개 변수이다. 단위는 + 도이다. {\tt angle=360}이라면 완전한 원을 그리게 된다. +\index{arc function} +\index{function!arc} + +\end{enumerate} + + +\section{캡슐화} +%Encapsulation + +첫 번째 연습 문제에서 정사각형 그리기 코드를 함수 정의로 만들고, +거북이를 매개 변수로 하여 함수를 호출하라고 했다. 여기 그 해답이 +있다. + + +\begin{verbatim} +def square(t): + for i in range(4): + t.fd(100) + t.lt(90) + +square(bob) +\end{verbatim} +% +가장 안쪽의 문장의 {\tt fd}와 {\tt lt}는 두 번 들여쓰기가 되어 {\tt + for} 반복문 안에 있다는 것과 반복문은 함수 정의 내에 있다는 것을 +나타낸다. 그 다음 줄의 {\tt square(bob)} 문장은 왼쪽 끝에 있기 때문에 +{\tt for} 반복문이나 함수 정의 내에 있지 않다는 것을 뜻한다. + +함수 내의 {\tt t}는 {\tt bob}과 동일한 거북이를 가리키기 때문에 {\tt + t.lt(90)}과 {\tt bob.lt(90)}는 서로 똑같은 결과를 갖는다. 그렇다면 +매개 변수를 {\tt bob}이라 부르지 않는 이유는 무엇일까? 그 이유는 {\tt + t}라고 쓰면 {\tt bob} 외에도 다른 거북이 객체들을 받을 수 있기 +때문이다. 두 번째 거북이를 만들고 {\tt square}의 인자로 전달 할 수도 +있을 것이다. + + +\begin{verbatim} +alice = turtle.Turtle() +square(alice) +\end{verbatim} +% +함수 내에 어떤 코드를 넣는 것을 보고 {\bf 캡슐화(encapsulation)}이라고 +한다. 캡슐화의 장점 중 하나는 코드에 이름을 붙일 수가 있다는 것이다. +또 다른 장점은 코드의 재활용이다. 함수의 내용을 복사 붙이기 보다 함수 +호출이 훨씬 간결하다! +\index{encapsulation} + + +\section{일반화} +%Generalization + +그 다음 과정은 {\tt square} 함수에 매개 변수 {\tt length}를 추가하는 +것이다. 해답은 다음과 같다. + + +\begin{verbatim} +def square(t, length): + for i in range(4): + t.fd(length) + t.lt(90) + +square(bob, 100) +\end{verbatim} +% +함수에 매개 변수를 추가하는 것을 {\bf 일반화(generalization)}이라 +한다. 함수를 좀 더 범용적으로 쓸 수 있기 때문이다. 이전의 버전에서는 +\texttt{square}는 언제나 동일한 크기를 가졌지만, 이번 버전에서는 길이를 +변경할 수 있게 되었다. +\index{generalization} + +다음 과정도 마찬가지로 일반화다. 정사각형만 그리는 대신 다각형를 +그릴 수 있는 {\tt polygon}을 만드는 것이다. 해답을 살펴보자. + +\begin{verbatim} +def polygon(t, n, length): + angle = 360 / n + for i in range(n): + t.fd(length) + t.lt(angle) + +polygon(bob, 7, 70) +\end{verbatim} +% +이 예제에서는 면의 길이기 70인 정칠각형을 그렸다. + +Python 2를 사용 중이라면 정수 나눗셈으로 인해 {\tt angle}의 값이 다를 +수 있다. 간단한 해결책으로 {\tt angle = 360.0 / n}으로 계산식을 바꿀 +수 있다. 분자가 소수점이기 때문에 결과도 소수점이 된다. +\index{Python 2} + +함수가 여러 개의 숫자를 인자로 받는다면 그 값이 어떤 값이 어떤 순서로 +써야하는지 잊기 쉽다. 그런 경우에는 이름과 매개 변수를 인자 목록에 +함께 적으면 좋다. + + +\begin{verbatim} +polygon(bob, n=7, length=70) +\end{verbatim} +% +매개 변수의 이름을 ``키워드''로서 포함시켰기 때문에 {\bf 키워드 + 인자}라고 부른다({\tt while}이나 {\tt def}와 같은 Python의 키워드와 +혼돈하면 안된다.) +\index{keyword argument} +\index{argument!keyword} + + +이 문법이 프로그램을 좀 더 읽기 쉽게 만든다. 또한 인자와 매개 변수가 +함수에서 어떻게 연관있는지를 알려주기도 한다. 함수를 호출하면 인자 +값이 매개 변수에 할당된다는 것이 명확해진다. + + + +\section{인터페이스 설계} +%Interface design + +그 다음 과정은 반지름을 매개 변수 {\tt r}로 하는 {\tt circle} 함수를 +작성하는 것이다. 이 해법은 {\tt polygon} 함수를 이용해 50각형을 그린다. + +\begin{verbatim} +import math + +def circle(t, r): + circumference = 2 * math.pi * r + n = 50 + length = circumference / n + polygon(t, n, length) +\end{verbatim} +% +첫 줄은 반지름을 {\tt r}로 하는 원의 둘레를 $ 2 \pi r$로 계산한다. +{\tt math.pi}를 쓰기 때문에 {\tt math} 모듈을 불러와야 한다. +{\tt import} 문장은 관례적으로 항상 스크립트의 첫 줄에 적는다. + +근사한 원의 둘레는 {\tt n}개의 선으로 표현하였고, {\tt length}는 그 +선의 길이를 나타낸다. 결과적으로 {\tt polygon}은 50각형을 그려서 +반지름 {\tt r}인 원을 근사화하고 있다. + +이 해법의 한계점은 {\tt n}이 상수라는 것이다. 그렇기 때문에 매우 큰 +원을 그릴 때는 다각형의 면이 매우 길어 질 것이고 아주 작은 원이라면 +매우 짧은 선을 그리는 시간 낭비를 한다. 이를 해결하려면 {\tt n}을 매개 +변수로 받으 일반화를 해야 한다. 인터페이스가 좀 복잡해지겠지만, {\tt + circle} 함수를 부르는 사용자가 제어권을 갖도록 한다. +\index{interface} + +{\bf 인터페이스(interface)}는 함수를 어떻게 쓸 수 있는지 알려주는 요약이다. 어떤 매개 변수가 있고, 함수가 무엇을 하는지 그리고 어떤 결과를 리턴하는지 알려준다. 인터페이스가 ``단순하면'' 불필요한 세부 내용을 신경 쓰지 않고 원하는 것을 얻을 수 있다. + +이 예제에서는 그리려는 원의 크기를 정하기 위해 {\tt r}이 인터페이스에 +포함되어 있다. {\tt n}은 원이 어떻게 표현되어야 하는가에 대한 정보를 +담고 있기 때문에 적절하지는 않다. + +인터페이스를 복잡하게 만드는 대신 {\tt n}의 값을 둘레 {\tt + circumference}에 비례하도록 적절하게 정하는게 더 낫다. + + + +\begin{verbatim} +def circle(t, r): + circumference = 2 * math.pi * r + n = int(circumference / 3) + 3 + length = circumference / n + polygon(t, n, length) +\end{verbatim} +% +원을 이루는 선의 개수를 {\tt circumference/3}에 가까운 정수로 바꿨다. +한 선의 길이가 대략 3이 되도록 하였다. 원처럼 보일 수 있도록 충분히 +작고 효율적일 만큼 충분히 크며 어떤 원에도 무난한 길이이다. + + +그리고 삼격형보다 작은 다각형은 만들지 않도록 {\tt n}에 3을 더했다. + + +\section{리팩터링} +%Refactoring +\label{refactoring} +\index{refactoring} + +{\tt circle} 함수를 작성할 때 {\tt polygon} 함수를 재사용할 수 있었던 +이유는 다각형으로 원을 근사화할 수 있기 때문이다. {\tt arc}의 경우는 +{\tt polygon}나 {\tt circle}를 그대로 가져다 쓸 수 없다. + +대안으로 {\tt polygon}의 사본에서 시작해서 {\tt arc}로 내용을 변형하는 +방법이 있다. 그 결과는 다음과 같다. + +\begin{verbatim} +def arc(t, r, angle): + arc_length = 2 * math.pi * r * angle / 360 + n = int(arc_length / 3) + 1 + step_length = arc_length / n + step_angle = angle / n + + for i in range(n): + t.fd(step_length) + t.lt(step_angle) +\end{verbatim} +% +이 함수의 하반부는 {\tt polygon}과 유사하게 생겼다. 그렇지만, {\tt + polygon}의 인터페이스를 변형하기 전에는 쓸 수가 없다. 각도가 {\tt + polygon} 함수의 세 번째 인자가 되도록 인터페이스를 수정할 수 있을 +것이다. 그렇게 되면 {\tt polygon}이라는 이름은 부적절 해진다! 대신 +변형된 이 함수의 이름을 {\tt 폴리라인(polyline)}이라 부르자. + +\begin{verbatim} +def polyline(t, n, length, angle): + for i in range(n): + t.fd(length) + t.lt(angle) +\end{verbatim} +% +이제 {\tt polygon}와 {\tt arc}가 {\tt polyline}를 사용하도록 변형해보자. + +\begin{verbatim} +def polygon(t, n, length): + angle = 360.0 / n + polyline(t, n, length, angle) + +def arc(t, r, angle): + arc_length = 2 * math.pi * r * angle / 360 + n = int(arc_length / 3) + 1 + step_length = arc_length / n + step_angle = float(angle) / n + polyline(t, n, step_length, step_angle) +\end{verbatim} +% +이제 {\tt arc}를 쓰도록 {\tt circle}를 수정할 수 있다. + +\begin{verbatim} +def circle(t, r): + arc(t, r, 360) +\end{verbatim} +% +인터페이스를 개선하고 코드의 재사용을 높이기 위한 프로그램의 재배치 +과정을 {\bf 리팩터링(refactoring)}이라 부른다. 지금의 경우, {\tt + arc}와 {\tt polygon}에 유사한 코드 부분이 있었기 때문에 {\tt + polyline}으로 ``공통 부분을 분리''했다. +\index{refactoring} + +미리 계획하여 {\tt polyline}을 작성했더라면 리팩터링 과정이 필요 없었을 +것이다. 하지만, 대체적으로 프로젝트 초반부에는 모든 인터페이스를 +설계하기에는 정보가 충분하지 않다. 코딩을 시작하면 그제야 문제에 대해 +좀 더 이해하게 된다. 때로는 리팩터링이 무언가를 배웠다는 것을 +반증해주기도 한다. + + +\section{개발 계획} +%A development plan +\index{development plan!encapsulation and generalization} + +{\bf 개발 계획}은 프로그램을 만드는 과정이다. 이 사례 연구에서 사용한 +``캡슐화와 일반화''도 프로그램 개발 과정의 일부다. 우리가 사용한 +과정을 정리해보자. + +\begin{enumerate} + +\item 함수 정의가 없는 작은 프로그램으로부터 시작한다. + +\item 동작하는 프로그램을 만들고 나면 서로 상관있는 코드들을 구분한다. + 그 코드를 함수로 캡슐화하고 이름을 붙있다. + +\item 함수에 적절한 매개 변수를 추가해서 일반화를 한다. + +\item 동작하는 함수가 될 때까지 과정 1에서 3을 반복한다. 재입력(그리고 + 디버깅)을 하지 않도록 동작하는 코드는 복사 붙이기 한다. + +\item 리팩터링을 통해 프로그램을 개선할 수 있는지 검토한다. 예를 + 들어, 유사한 코드가 여기 저기에 보이면 일반화된 함수로 리팩터링할 수 + 있는지 생각해본다. + +\end{enumerate} + +이 과정에는 몇 가지 단점이 있다. 그 대안들은 이후에 살펴볼 것이다. 그래도 이 방법은 프로그램을 함수로 나누는 어떻게 나눌지 개발 전에 미리 알 수 없는 경우라면 충분히 의미있다. 개발하면서 설계도 같이 할 수 있기 때문이다. + + +\section{docstring} +\label{docstring} +\index{docstring} + +A {\bf docstring} is a string at the beginning of a function that +explains the interface (``doc'' is short for ``documentation''). Here +is an example: + +\begin{verbatim} +def polyline(t, n, length, angle): + """Draws n line segments with the given length and + angle (in degrees) between them. t is a turtle. + """ + for i in range(n): + t.fd(length) + t.lt(angle) +\end{verbatim} +% +By convention, all docstrings are triple-quoted strings, also known +as multiline strings because the triple quotes allow the string +to span more than one line. +\index{quotation mark} +\index{triple-quoted string} +\index{string!triple-quoted} +\index{multiline string} +\index{string!multiline} + +It is terse, but it contains the essential information +someone would need to use this function. It explains concisely what +the function does (without getting into the details of how it does +it). It explains what effect each parameter has on the behavior of +the function and what type each parameter should be (if it is not +obvious). + +Writing this kind of documentation is an important part of interface +design. A well-designed interface should be simple to explain; +if you have a hard time explaining one of your functions, +maybe the interface could be improved. + + +\section{Debugging} +\index{debugging} +\index{interface} + +An interface is like a contract between a function and a caller. +The caller agrees to provide certain parameters and the function +agrees to do certain work. + +For example, {\tt polyline} requires four arguments: {\tt t} has to be +a Turtle; {\tt n} has to be an +integer; {\tt length} should be a positive number; and {\tt + angle} has to be a number, which is understood to be in degrees. + +These requirements are called {\bf preconditions} because they +are supposed to be true before the function starts executing. +Conversely, conditions at the end of the function are +{\bf postconditions}. Postconditions include the intended +effect of the function (like drawing line segments) and any +side effects (like moving the Turtle or making other changes). +\index{precondition} +\index{postcondition} + +Preconditions are the responsibility of the caller. If the caller +violates a (properly documented!) precondition and the function +doesn't work correctly, the bug is in the caller, not the function. + +If the preconditions are satisfied and the postconditions are +not, the bug is in the function. If your pre- and postconditions +are clear, they can help with debugging. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[method:] A function that is associated with an object and called +using dot notation. +\index{method} + +\item[loop:] A part of a program that can run repeatedly. +\index{loop} + +\item[encapsulation:] The process of transforming a sequence of +statements into a function definition. +\index{encapsulation} + +\item[generalization:] The process of replacing something +unnecessarily specific (like a number) with something appropriately +general (like a variable or parameter). +\index{generalization} + +\item[keyword argument:] An argument that includes the name of +the parameter as a ``keyword''. +\index{keyword argument} +\index{argument!keyword} + +\item[interface:] A description of how to use a function, including +the name and descriptions of the arguments and return value. +\index{interface} + +\item[refactoring:] The process of modifying a working program to + improve function interfaces and other qualities of the code. +\index{refactoring} + +\item[development plan:] A process for writing programs. +\index{development plan} + +\item[docstring:] A string that appears at the top of a function + definition to document the function's interface. +\index{docstring} + +\item[precondition:] A requirement that should be satisfied by +the caller before a function starts. +\index{precondition} + +\item[postcondition:] A requirement that should be satisfied by +the function before it ends. +\index{precondition} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Download the code in this chapter from +\url{http://thinkpython2.com/code/polygon.py}. + +\begin{enumerate} + +\item Draw a stack diagram that shows the state of the program +while executing {\tt circle(bob, radius)}. You can do the +arithmetic by hand or add {\tt print} statements to the code. +\index{stack diagram} + +\item The version of {\tt arc} in Section~\ref{refactoring} is not +very accurate because the linear approximation of the +circle is always outside the true circle. As a result, +the Turtle ends up a few pixels away from the correct +destination. My solution shows a way to reduce +the effect of this error. Read the code and see if it makes +sense to you. If you draw a diagram, you might see how it works. + +\end{enumerate} + +\end{exercise} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/flowers.pdf}} +\caption{Turtle flowers.} +\label{fig.flowers} +\end{figure} + +\begin{exercise} +\index{flower} + +Write an appropriately general set of functions that +can draw flowers as in Figure~\ref{fig.flowers}. + +Solution: \url{http://thinkpython2.com/code/flower.py}, +also requires \url{http://thinkpython2.com/code/polygon.py}. + +\end{exercise} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/pies.pdf}} +\caption{Turtle pies.} +\label{fig.pies} +\end{figure} + + +\begin{exercise} +\index{pie} + +Write an appropriately general set of functions that +can draw shapes as in Figure~\ref{fig.pies}. + +Solution: \url{http://thinkpython2.com/code/pie.py}. + +\end{exercise} + +\begin{exercise} +\index{alphabet} +\index{turtle typewriter} +\index{typewriter, turtle} + +The letters of the alphabet can be constructed from a moderate number +of basic elements, like vertical and horizontal lines and a few +curves. Design an alphabet that can be drawn with a minimal +number of basic elements and then write functions that draw the letters. + +You should write one function for each letter, with names +\verb"draw_a", \verb"draw_b", etc., and put your functions +in a file named {\tt letters.py}. You can download a +``turtle typewriter'' from \url{http://thinkpython2.com/code/typewriter.py} +to help you test your code. + +You can get a solution from \url{http://thinkpython2.com/code/letters.py}; +it also requires +\url{http://thinkpython2.com/code/polygon.py}. + +\end{exercise} + +\begin{exercise} + +Read about spirals at \url{http://en.wikipedia.org/wiki/Spiral}; then +write a program that draws an Archimedian spiral (or one of the other +kinds). Solution: \url{http://thinkpython2.com/code/spiral.py}. +\index{spiral} +\index{Archimedian spiral} + +\end{exercise} + + +\chapter{Conditionals and recursion} + +The main topic of this chapter is the {\tt if} statement, which +executes different code depending on the state of the program. +But first I want to introduce two new operators: floor division +and modulus. + + +\section{Floor division and modulus} + +The {\bf floor division} operator, \verb"//", divides +two numbers and rounds down to an integer. For example, suppose the +run time of a movie is 105 minutes. You might want to know how +long that is in hours. Conventional division +returns a floating-point number: + +\begin{verbatim} +>>> minutes = 105 +>>> minutes / 60 +1.75 +\end{verbatim} + +But we don't normally write hours with decimal points. Floor +division returns the integer number of hours, dropping the +fraction part: + +\begin{verbatim} +>>> minutes = 105 +>>> hours = minutes // 60 +>>> hours +1 +\end{verbatim} + +To get the remainder, you could subtract off one hour in minutes: + +\begin{verbatim} +>>> remainder = minutes - hours * 60 +>>> remainder +45 +\end{verbatim} + +\index{floor division} +\index{floating-point division} +\index{division!floor} +\index{division!floating-point} +\index{modulus operator} +\index{operator!modulus} + +An alternative is to use the {\bf modulus operator}, \verb"%", which +divides two numbers and returns the remainder. + +\begin{verbatim} +>>> remainder = minutes % 60 +>>> remainder +45 +\end{verbatim} +% +The modulus operator is more useful than it seems. For +example, you can check whether one number is divisible by another---if +{\tt x \% y} is zero, then {\tt x} is divisible by {\tt y}. +\index{divisibility} + +Also, you can extract the right-most digit +or digits from a number. For example, {\tt x \% 10} yields the +right-most digit of {\tt x} (in base 10). Similarly {\tt x \% 100} +yields the last two digits. + +If you are using Python 2, division works differently. The +division operator, \verb"/", performs floor division if both +operands are integers, and floating-point division if either +operand is a {\tt float}. +\index{Python 2} + + +\section{Boolean expressions} +\index{boolean expression} +\index{expression!boolean} +\index{logical operator} +\index{operator!logical} + +A {\bf boolean expression} is an expression that is either true +or false. The following examples use the +operator {\tt ==}, which compares two operands and produces +{\tt True} if they are equal and {\tt False} otherwise: + +\begin{verbatim} +>>> 5 == 5 +True +>>> 5 == 6 +False +\end{verbatim} +% +{\tt True} and {\tt False} are special +values that belong to the type {\tt bool}; they are not strings: +\index{True special value} +\index{False special value} +\index{special value!True} +\index{special value!False} +\index{bool type} +\index{type!bool} + +\begin{verbatim} +>>> type(True) + +>>> type(False) + +\end{verbatim} +% +The {\tt ==} operator is one of the {\bf relational operators}; the +others are: + +\begin{verbatim} + x != y # x is not equal to y + x > y # x is greater than y + x < y # x is less than y + x >= y # x is greater than or equal to y + x <= y # x is less than or equal to y +\end{verbatim} +% +Although these operations are probably familiar to you, the Python +symbols are different from the mathematical symbols. A common error +is to use a single equal sign ({\tt =}) instead of a double equal sign +({\tt ==}). Remember that {\tt =} is an assignment operator and +{\tt ==} is a relational operator. There is no such thing as +{\tt =<} or {\tt =>}. +\index{relational operator} +\index{operator!relational} + + +\section {Logical operators} +\index{logical operator} +\index{operator!logical} + +There are three {\bf logical operators}: {\tt and}, {\tt +or}, and {\tt not}. The semantics (meaning) of these operators is +similar to their meaning in English. For example, +{\tt x > 0 and x < 10} is true only if {\tt x} is greater than 0 +{\em and} less than 10. +\index{and operator} +\index{or operator} +\index{not operator} +\index{operator!and} +\index{operator!or} +\index{operator!not} + +{\tt n\%2 == 0 or n\%3 == 0} is true if {\em either or both} of the +conditions is true, that is, if the number is divisible by 2 {\em or} +3. + +Finally, the {\tt not} operator negates a boolean +expression, so {\tt not (x > y)} is true if {\tt x > y} is false, +that is, if {\tt x} is less than or equal to {\tt y}. + +Strictly speaking, the operands of the logical operators should be +boolean expressions, but Python is not very strict. +Any nonzero number is interpreted as {\tt True}: + +\begin{verbatim} +>>> 42 and True +True +\end{verbatim} +% +This flexibility can be useful, but there are some subtleties to +it that might be confusing. You might want to avoid it (unless +you know what you are doing). + + +\section{Conditional execution} +\label{conditional.execution} + +\index{conditional statement} +\index{statement!conditional} +\index{if statement} +\index{statement!if} +\index{conditional execution} +In order to write useful programs, we almost always need the ability +to check conditions and change the behavior of the program +accordingly. {\bf Conditional statements} give us this ability. The +simplest form is the {\tt if} statement: + +\begin{verbatim} +if x > 0: + print('x is positive') +\end{verbatim} +% +The boolean expression after {\tt if} is +called the {\bf condition}. If it is true, the indented +statement runs. If not, nothing happens. +\index{condition} +\index{compound statement} +\index{statement!compound} + +{\tt if} statements have the same structure as function definitions: +a header followed by an indented body. Statements like this are +called {\bf compound statements}. + +There is no limit on the number of statements that can appear in +the body, but there has to be at least one. +Occasionally, it is useful to have a body with no statements (usually +as a place keeper for code you haven't written yet). In that +case, you can use the {\tt pass} statement, which does nothing. +\index{pass statement} +\index{statement!pass} + +\begin{verbatim} +if x < 0: + pass # TODO: need to handle negative values! +\end{verbatim} +% + +\section{Alternative execution} +\label{alternative.execution} +\index{alternative execution} +\index{else keyword} +\index{keyword!else} + +A second form of the {\tt if} statement is ``alternative execution'', +in which there are two possibilities and the condition determines +which one runs. The syntax looks like this: + +\begin{verbatim} +if x % 2 == 0: + print('x is even') +else: + print('x is odd') +\end{verbatim} +% +If the remainder when {\tt x} is divided by 2 is 0, then we know that +{\tt x} is even, and the program displays an appropriate message. If +the condition is false, the second set of statements runs. +Since the condition must be true or false, exactly one of the +alternatives will run. The alternatives are called {\bf + branches}, because they are branches in the flow of execution. +\index{branch} + + + +\section{Chained conditionals} +\index{chained conditional} +\index{conditional!chained} + +Sometimes there are more than two possibilities and we need more than +two branches. One way to express a computation like that is a {\bf +chained conditional}: + +\begin{verbatim} +if x < y: + print('x is less than y') +elif x > y: + print('x is greater than y') +else: + print('x and y are equal') +\end{verbatim} +% +{\tt elif} is an abbreviation of ``else if''. Again, exactly one +branch will run. There is no limit on the number of {\tt +elif} statements. If there is an {\tt else} clause, it has to be +at the end, but there doesn't have to be one. +\index{elif keyword} +\index{keyword!elif} + +\begin{verbatim} +if choice == 'a': + draw_a() +elif choice == 'b': + draw_b() +elif choice == 'c': + draw_c() +\end{verbatim} +% +Each condition is checked in order. If the first is false, +the next is checked, and so on. If one of them is +true, the corresponding branch runs and the statement +ends. Even if more than one condition is true, only the +first true branch runs. + + +\section{Nested conditionals} +\index{nested conditional} +\index{conditional!nested} + +One conditional can also be nested within another. We could have +written the example in the previous section like this: + +\begin{verbatim} +if x == y: + print('x and y are equal') +else: + if x < y: + print('x is less than y') + else: + print('x is greater than y') +\end{verbatim} +% +The outer conditional contains two branches. The +first branch contains a simple statement. The second branch +contains another {\tt if} statement, which has two branches of its +own. Those two branches are both simple statements, +although they could have been conditional statements as well. + +Although the indentation of the statements makes the structure +apparent, {\bf nested conditionals} become difficult to read very +quickly. It is a good idea to avoid them when you can. + +Logical operators often provide a way to simplify nested conditional +statements. For example, we can rewrite the following code using a +single conditional: + +\begin{verbatim} +if 0 < x: + if x < 10: + print('x is a positive single-digit number.') +\end{verbatim} +% +The {\tt print} statement runs only if we make it past both +conditionals, so we can get the same effect with the {\tt and} operator: + +\begin{verbatim} +if 0 < x and x < 10: + print('x is a positive single-digit number.') +\end{verbatim} + +For this kind of condition, Python provides a more concise option: + +\begin{verbatim} +if 0 < x < 10: + print('x is a positive single-digit number.') +\end{verbatim} + + +\section{Recursion} +\label{recursion} +\index{recursion} + +It is legal for one function to call another; +it is also legal for a function to call itself. It may not be obvious +why that is a good thing, but it turns out to be one of the most +magical things a program can do. +For example, look at the following function: + +\begin{verbatim} +def countdown(n): + if n <= 0: + print('Blastoff!') + else: + print(n) + countdown(n-1) +\end{verbatim} +% +If {\tt n} is 0 or negative, it outputs the word, ``Blastoff!'' +Otherwise, it outputs {\tt n} and then calls a function named {\tt +countdown}---itself---passing {\tt n-1} as an argument. + +What happens if we call this function like this? + +\begin{verbatim} +>>> countdown(3) +\end{verbatim} +% +The execution of {\tt countdown} begins with {\tt n=3}, and since +{\tt n} is greater than 0, it outputs the value 3, and then calls itself... + +\begin{quote} +The execution of {\tt countdown} begins with {\tt n=2}, and since +{\tt n} is greater than 0, it outputs the value 2, and then calls itself... + +\begin{quote} +The execution of {\tt countdown} begins with {\tt n=1}, and since +{\tt n} is greater than 0, it outputs the value 1, and then calls itself... + +\begin{quote} +The execution of {\tt countdown} begins with {\tt n=0}, and since {\tt +n} is not greater than 0, it outputs the word, ``Blastoff!'' and then +returns. +\end{quote} + +The {\tt countdown} that got {\tt n=1} returns. +\end{quote} + +The {\tt countdown} that got {\tt n=2} returns. +\end{quote} + +The {\tt countdown} that got {\tt n=3} returns. + +And then you're back in \verb"__main__". So, the +total output looks like this: +\index{main} + +\begin{verbatim} +3 +2 +1 +Blastoff! +\end{verbatim} +% +A function that calls itself is {\bf recursive}; the process of +executing it is called {\bf recursion}. +\index{recursion} +\index{function!recursive} + +As another example, we can write a function that prints a +string {\tt n} times. + +\begin{verbatim} +def print_n(s, n): + if n <= 0: + return + print(s) + print_n(s, n-1) +\end{verbatim} +% +If {\tt n <= 0} the {\bf return statement} exits the function. The +flow of execution immediately returns to the caller, and the remaining +lines of the function don't run. +\index{return statement} +\index{statement!return} + +The rest of the function is similar to {\tt countdown}: it displays +{\tt s} and then calls itself to display {\tt s} $n-1$ additional +times. So the number of lines of output is {\tt 1 + (n - 1)}, which +adds up to {\tt n}. + +For simple examples like this, it is probably easier to use a {\tt +for} loop. But we will see examples later that are hard to write +with a {\tt for} loop and easy to write with recursion, so it is +good to start early. +\index{for loop} +\index{loop!for} + + +\section{Stack diagrams for recursive functions} +\label{recursive.stack} +\index{stack diagram} +\index{function frame} +\index{frame} + +In Section~\ref{stackdiagram}, we used a stack diagram to represent +the state of a program during a function call. The same kind of +diagram can help interpret a recursive function. + +Every time a function gets called, Python creates a +frame to contain the function's local variables and parameters. +For a recursive function, there might be more than one frame on the +stack at the same time. + +Figure~\ref{fig.stack2} shows a stack diagram for {\tt countdown} called with +{\tt n = 3}. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/stack2.pdf}} +\caption{Stack diagram.} +\label{fig.stack2} +\end{figure} + + +As usual, the top of the stack is the frame for \verb"__main__". +It is empty because we did not create any variables in +\verb"__main__" or pass any arguments to it. +\index{base case} +\index{recursion!base case} + +The four {\tt countdown} frames have different values for the +parameter {\tt n}. The bottom of the stack, where {\tt n=0}, is +called the {\bf base case}. It does not make a recursive call, so +there are no more frames. + +As an exercise, draw a stack diagram for \verb"print_n" called with +\verb"s = 'Hello'" and {\tt n=2}. +Then write a function called \verb"do_n" that takes a function +object and a number, {\tt n}, as arguments, and that calls +the given function {\tt n} times. + + +\section{Infinite recursion} +\index{infinite recursion} +\index{recursion!infinite} +\index{runtime error} +\index{error!runtime} +\index{traceback} + +If a recursion never reaches a base case, it goes on making +recursive calls forever, and the program never terminates. This is +known as {\bf infinite recursion}, and it is generally not +a good idea. Here is a minimal program with an infinite recursion: + +\begin{verbatim} +def recurse(): + recurse() +\end{verbatim} +% +In most programming environments, a program with infinite recursion +does not really run forever. Python reports an error +message when the maximum recursion depth is reached: +\index{exception!RuntimeError} +\index{RuntimeError} + +\begin{verbatim} + File "", line 2, in recurse + File "", line 2, in recurse + File "", line 2, in recurse + . + . + . + File "", line 2, in recurse +RuntimeError: Maximum recursion depth exceeded +\end{verbatim} +% +This traceback is a little bigger than the one we saw in the +previous chapter. When the error occurs, there are 1000 +{\tt recurse} frames on the stack! + +If you encounter an infinite recursion by accident, review +your function to confirm that there is a base case that does not +make a recursive call. And if there is a base case, check whether +you are guaranteed to reach it. + + +\section{Keyboard input} +\index{keyboard input} + +The programs we have written so far accept no input from the user. +They just do the same thing every time. + +Python provides a built-in function called {\tt input} that +stops the program and +waits for the user to type something. When the user presses {\sf + Return} or {\sf Enter}, the program resumes and \verb"input" +returns what the user typed as a string. In Python 2, the same +function is called \verb"raw_input". +\index{Python 2} +\index{input function} +\index{function!input} + +\begin{verbatim} +>>> text = input() +What are you waiting for? +>>> text +'What are you waiting for?' +\end{verbatim} +% +Before getting input from the user, it is a good idea to print a +prompt telling the user what to type. \verb"input" can take a +prompt as an argument: +\index{prompt} + +\begin{verbatim} +>>> name = input('What...is your name?\n') +What...is your name? +Arthur, King of the Britons! +>>> name +'Arthur, King of the Britons!' +\end{verbatim} +% +The sequence \verb"\n" at the end of the prompt represents a {\bf + newline}, which is a special character that causes a line break. +That's why the user's input appears below the prompt. \index{newline} + +If you expect the user to type an integer, you can try to convert +the return value to {\tt int}: + +\begin{verbatim} +>>> prompt = 'What...is the airspeed velocity of an unladen swallow?\n' +>>> speed = input(prompt) +What...is the airspeed velocity of an unladen swallow? +42 +>>> int(speed) +42 +\end{verbatim} +% +But if the user types something other than a string of digits, +you get an error: + +\begin{verbatim} +>>> speed = input(prompt) +What...is the airspeed velocity of an unladen swallow? +What do you mean, an African or a European swallow? +>>> int(speed) +ValueError: invalid literal for int() with base 10 +\end{verbatim} +% +We will see how to handle this kind of error later. +\index{ValueError} +\index{exception!ValueError} + + +\section{Debugging} +\label{whitespace} +\index{debugging} +\index{traceback} + +When a syntax or runtime error occurs, the error message contains +a lot of information, but it can be overwhelming. The most +useful parts are usually: + +\begin{itemize} + +\item What kind of error it was, and + +\item Where it occurred. + +\end{itemize} + +Syntax errors are usually easy to find, but there are a few +gotchas. Whitespace errors can be tricky because spaces and +tabs are invisible and we are used to ignoring them. +\index{whitespace} + +\begin{verbatim} +>>> x = 5 +>>> y = 6 + File "", line 1 + y = 6 + ^ +IndentationError: unexpected indent +\end{verbatim} +% +In this example, the problem is that the second line is indented by +one space. But the error message points to {\tt y}, which is +misleading. In general, error messages indicate where the problem was +discovered, but the actual error might be earlier in the code, +sometimes on a previous line. +\index{error!runtime} +\index{runtime error} + +The same is true of runtime errors. Suppose you are trying +to compute a signal-to-noise ratio in decibels. The formula +is $SNR_{db} = 10 \log_{10} (P_{signal} / P_{noise})$. In Python, +you might write something like this: + +\begin{verbatim} +import math +signal_power = 9 +noise_power = 10 +ratio = signal_power // noise_power +decibels = 10 * math.log10(ratio) +print(decibels) +\end{verbatim} +% +When you run this program, you get an exception: +% +\index{exception!OverflowError} +\index{OverflowError} + +\begin{verbatim} +Traceback (most recent call last): + File "snr.py", line 5, in ? + decibels = 10 * math.log10(ratio) +ValueError: math domain error +\end{verbatim} +% +The error message indicates line 5, but there is nothing +wrong with that line. To find the real error, it might be +useful to print the value of {\tt ratio}, which turns out to +be 0. The problem is in line 4, which uses floor division +instead of floating-point division. +\index{floor division} +\index{division!floor} + +You should take the time to read error messages carefully, but don't +assume that everything they say is correct. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[floor division:] An operator, denoted {\tt //}, that divides two + numbers and rounds down (toward negative infinity) to an integer. + \index{floor division} + \index{division!floor} + +\item[modulus operator:] An operator, denoted with a percent sign +({\tt \%}), that works on integers and returns the remainder when one +number is divided by another. +\index{modulus operator} +\index{operator!modulus} + +\item[boolean expression:] An expression whose value is either +{\tt True} or {\tt False}. +\index{boolean expression} +\index{expression!boolean} + +\item[relational operator:] One of the operators that compares +its operands: {\tt ==}, {\tt !=}, {\tt >}, {\tt <}, {\tt >=}, and {\tt <=}. + +\item[logical operator:] One of the operators that combines boolean +expressions: {\tt and}, {\tt or}, and {\tt not}. + +\item[conditional statement:] A statement that controls the flow of +execution depending on some condition. +\index{conditional statement} +\index{statement!conditional} + +\item[condition:] The boolean expression in a conditional statement +that determines which branch runs. +\index{condition} + +\item[compound statement:] A statement that consists of a header +and a body. The header ends with a colon (:). The body is indented +relative to the header. +\index{compound statement} + +\item[branch:] One of the alternative sequences of statements in +a conditional statement. +\index{branch} + +\item[chained conditional:] A conditional statement with a series +of alternative branches. +\index{chained conditional} +\index{conditional!chained} + +\item[nested conditional:] A conditional statement that appears +in one of the branches of another conditional statement. +\index{nested conditional} +\index{conditional!nested} + +\item[return statement:] A statement that causes a function to +end immediately and return to the caller. + +\item[recursion:] The process of calling the function that is +currently executing. +\index{recursion} + +\item[base case:] A conditional branch in a +recursive function that does not make a recursive call. +\index{base case} + +\item[infinite recursion:] A recursion that doesn't have a +base case, or never reaches it. Eventually, an infinite recursion +causes a runtime error. +\index{infinite recursion} + +\end{description} + +\section{연습 문제} +%Exercises + +\begin{exercise} + +The {\tt time} module provides a function, also named {\tt time}, that +returns the current Greenwich Mean Time in ``the epoch'', which is +an arbitrary time used as a reference point. On UNIX systems, the +epoch is 1 January 1970. + +\begin{verbatim} +>>> import time +>>> time.time() +1437746094.5735958 +\end{verbatim} + +Write a script that reads the current time and converts it to +a time of day in hours, minutes, and seconds, plus the number of +days since the epoch. + +\end{exercise} + + +\begin{exercise} +\index{Fermat's Last Theorem} + +Fermat's Last Theorem says that there are no positive integers +$a$, $b$, and $c$ such that + +\[ a^n + b^n = c^n \] +% +for any values of $n$ greater than 2. + +\begin{enumerate} + +\item Write a function named \verb"check_fermat" that takes four +parameters---{\tt a}, {\tt b}, {\tt c} and {\tt n}---and +checks to see if Fermat's theorem holds. If +$n$ is greater than 2 and + +\[a^n + b^n = c^n \] +% +the program should print, ``Holy smokes, Fermat was wrong!'' +Otherwise the program should print, ``No, that doesn't work.'' + +\item Write a function that prompts the user to input values +for {\tt a}, {\tt b}, {\tt c} and {\tt n}, converts them to +integers, and uses \verb"check_fermat" to check whether they +violate Fermat's theorem. + +\end{enumerate} + +\end{exercise} + + +\begin{exercise} +\index{triangle} + +If you are given three sticks, you may or may not be able to arrange +them in a triangle. For example, if one of the sticks is 12 inches +long and the other two are one inch long, you will +not be able to get the short sticks to meet in the middle. For any +three lengths, there is a simple test to see if it is possible to form +a triangle: + +\begin{quotation} +If any of the three lengths is greater than the sum of the other + two, then you cannot form a triangle. Otherwise, you + can. (If the sum of two lengths equals the third, they form + what is called a ``degenerate'' triangle.) +\end{quotation} + +\begin{enumerate} + +\item Write a function named \verb"is_triangle" that takes three + integers as arguments, and that prints either ``Yes'' or ``No'', depending + on whether you can or cannot form a triangle from sticks with the + given lengths. + +\item Write a function that prompts the user to input three stick + lengths, converts them to integers, and uses \verb"is_triangle" to + check whether sticks with the given lengths can form a triangle. + +\end{enumerate} + +\end{exercise} + +\begin{exercise} +What is the output of the following program? +Draw a stack diagram that shows the state of the program +when it prints the result. + +\begin{verbatim} +def recurse(n, s): + if n == 0: + print(s) + else: + recurse(n-1, n+s) + +recurse(3, 0) +\end{verbatim} + +\begin{enumerate} + +\item What would happen if you called this function like this: {\tt + recurse(-1, 0)}? + +\item Write a docstring that explains everything someone would need to + know in order to use this function (and nothing else). + +\end{enumerate} + +\end{exercise} + + +The following exercises use the {\tt turtle} module, described in +Chapter~\ref{turtlechap}: +\index{TurtleWorld} + +\begin{exercise} + +Read the following function and see if you can figure out +what it does (see the examples in Chapter~\ref{turtlechap}). Then run it +and see if you got it right. + +\begin{verbatim} +def draw(t, length, n): + if n == 0: + return + angle = 50 + t.fd(length*n) + t.lt(angle) + draw(t, length, n-1) + t.rt(2*angle) + draw(t, length, n-1) + t.lt(angle) + t.bk(length*n) +\end{verbatim} + +\end{exercise} + + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/koch.pdf}} +\caption{A Koch curve.} +\label{fig.koch} +\end{figure} + +\begin{exercise} +\index{Koch curve} + +The Koch curve is a fractal that looks something like +Figure~\ref{fig.koch}. To draw a Koch curve with length $x$, all you +have to do is + +\begin{enumerate} + +\item Draw a Koch curve with length $x/3$. + +\item Turn left 60 degrees. + +\item Draw a Koch curve with length $x/3$. + +\item Turn right 120 degrees. + +\item Draw a Koch curve with length $x/3$. + +\item Turn left 60 degrees. + +\item Draw a Koch curve with length $x/3$. + +\end{enumerate} + +The exception is if $x$ is less than 3: in that case, +you can just draw a straight line with length $x$. + +\begin{enumerate} + +\item Write a function called {\tt koch} that takes a turtle and +a length as parameters, and that uses the turtle to draw a Koch +curve with the given length. + +\item Write a function called {\tt snowflake} that draws three +Koch curves to make the outline of a snowflake. + +Solution: \url{http://thinkpython2.com/code/koch.py}. + +\item The Koch curve can be generalized in several ways. See +\url{http://en.wikipedia.org/wiki/Koch_snowflake} for examples and +implement your favorite. + +\end{enumerate} +\end{exercise} + + +\chapter{Fruitful functions} +\label{fruitchap} + +Many of the Python functions we have used, such as the math +functions, produce return values. But the functions we've written +are all void: they have an effect, like printing a value +or moving a turtle, but they don't have a return value. In +this chapter you will learn to write fruitful functions. + + +\section{Return values} +\index{return value} + +Calling the function generates a return +value, which we usually assign to a variable or use as part of an +expression. + +\begin{verbatim} +e = math.exp(1.0) +height = radius * math.sin(radians) +\end{verbatim} +% +The functions we have written so far are void. Speaking casually, +they have no return value; more precisely, +their return value is {\tt None}. + +In this chapter, we are (finally) going to write fruitful functions. +The first example is {\tt area}, which returns the area of a circle +with the given radius: + +\begin{verbatim} +def area(radius): + a = math.pi * radius**2 + return a +\end{verbatim} +% +We have seen the {\tt return} statement before, but in a fruitful +function the {\tt return} statement includes +an expression. This statement means: ``Return immediately from +this function and use the following expression as a return value.'' +The expression can be arbitrarily complicated, so we could +have written this function more concisely: +\index{return statement} +\index{statement!return} + +\begin{verbatim} +def area(radius): + return math.pi * radius**2 +\end{verbatim} +% +On the other hand, {\bf temporary variables} like {\tt a} can make +debugging easier. +\index{temporary variable} +\index{variable!temporary} + +Sometimes it is useful to have multiple return statements, one in each +branch of a conditional: + +\begin{verbatim} +def absolute_value(x): + if x < 0: + return -x + else: + return x +\end{verbatim} +% +Since these {\tt return} statements are in an alternative conditional, +only one runs. + +As soon as a return statement runs, the function +terminates without executing any subsequent statements. +Code that appears after a {\tt return} statement, or any other place +the flow of execution can never reach, is called {\bf dead code}. +\index{dead code} + +In a fruitful function, it is a good idea to ensure +that every possible path through the program hits a +{\tt return} statement. For example: + +\begin{verbatim} +def absolute_value(x): + if x < 0: + return -x + if x > 0: + return x +\end{verbatim} +% +This function is incorrect because if {\tt x} happens to be 0, +neither condition is true, and the function ends without hitting a +{\tt return} statement. If the flow of execution gets to the end +of a function, the return value is {\tt None}, which is not +the absolute value of 0. +\index{None special value} +\index{special value!None} + +\begin{verbatim} +>>> print(absolute_value(0)) +None +\end{verbatim} +% +By the way, Python provides a built-in function called +{\tt abs} that computes absolute values. +\index{abs function} +\index{function!abs} + +As an exercise, write a {\tt compare} function +takes two values, {\tt x} and {\tt y}, and returns {\tt 1} if {\tt x > y}, +{\tt 0} if {\tt x == y}, and {\tt -1} if {\tt x < y}. +\index{compare function} +\index{function!compare} + + +\section{Incremental development} +\label{incremental.development} +\index{development plan!incremental} + +As you write larger functions, you might find yourself +spending more time debugging. + +To deal with increasingly complex programs, +you might want to try a process called +{\bf incremental development}. The goal of incremental development +is to avoid long debugging sessions by adding and testing only +a small amount of code at a time. +\index{testing!incremental development} +\index{Pythagorean theorem} + +As an example, suppose you want to find the distance between two +points, given by the coordinates $(x_1, y_1)$ and $(x_2, y_2)$. +By the Pythagorean theorem, the distance is: + +\begin{displaymath} +\mathrm{distance} = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} +\end{displaymath} +% +The first step is to consider what a {\tt distance} function should +look like in Python. In other words, what are the inputs (parameters) +and what is the output (return value)? + +In this case, the inputs are two points, which you can represent +using four numbers. The return value is the distance represented by +a floating-point value. + +Immediately you can write an outline of the function: + +\begin{verbatim} +def distance(x1, y1, x2, y2): + return 0.0 +\end{verbatim} +% +Obviously, this version doesn't compute distances; it always returns +zero. But it is syntactically correct, and it runs, which means that +you can test it before you make it more complicated. + +To test the new function, call it with sample arguments: + +\begin{verbatim} +>>> distance(1, 2, 4, 6) +0.0 +\end{verbatim} +% +I chose these values so that the horizontal distance is 3 and the +vertical distance is 4; that way, the result is 5, the hypotenuse +of a 3-4-5 triangle. When testing a function, it is +useful to know the right answer. +\index{testing!knowing the answer} + +At this point we have confirmed that the function is syntactically +correct, and we can start adding code to the body. +A reasonable next step is to find the differences +$x_2 - x_1$ and $y_2 - y_1$. The next version stores those values in +temporary variables and prints them. + +\begin{verbatim} +def distance(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + print('dx is', dx) + print('dy is', dy) + return 0.0 +\end{verbatim} +% +If the function is working, it should display \verb"dx is 3" and +\verb"dy is 4". If so, we know that the function is getting the right +arguments and performing the first computation correctly. If not, +there are only a few lines to check. + +Next we compute the sum of squares of {\tt dx} and {\tt dy}: + +\begin{verbatim} +def distance(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + dsquared = dx**2 + dy**2 + print('dsquared is: ', dsquared) + return 0.0 +\end{verbatim} +% +Again, you would run the program at this stage and check the output +(which should be 25). +Finally, you can use {\tt math.sqrt} to compute and return the result: +\index{sqrt} +\index{function!sqrt} + +\begin{verbatim} +def distance(x1, y1, x2, y2): + dx = x2 - x1 + dy = y2 - y1 + dsquared = dx**2 + dy**2 + result = math.sqrt(dsquared) + return result +\end{verbatim} +% +If that works correctly, you are done. Otherwise, you might +want to print the value of {\tt result} before the return +statement. + +The final version of the function doesn't display anything when it +runs; it only returns a value. The {\tt print} statements we wrote +are useful for debugging, but once you get the function working, you +should remove them. Code like that is called {\bf scaffolding} +because it is helpful for building the program but is not part of the +final product. +\index{scaffolding} + +When you start out, you should add only a line or two of code at a +time. As you gain more experience, you might find yourself writing +and debugging bigger chunks. Either way, incremental development +can save you a lot of debugging time. + +The key aspects of the process are: + +\begin{enumerate} + +\item Start with a working program and make small incremental changes. +At any point, if there is an error, you should have a good idea +where it is. + +\item Use variables to hold intermediate values so you can +display and check them. + +\item Once the program is working, you might want to remove some of +the scaffolding or consolidate multiple statements into compound +expressions, but only if it does not make the program difficult to +read. + +\end{enumerate} + +As an exercise, use incremental development to write a function +called {\tt hypotenuse} that returns the length of the hypotenuse of a +right triangle given the lengths of the other two legs as arguments. +Record each stage of the development process as you go. +\index{hypotenuse} + + + +\section{Composition} +\index{composition} +\index{function composition} + +As you should expect by now, you can call one function from within +another. As an example, we'll write a function that takes two points, +the center of the circle and a point on the perimeter, and computes +the area of the circle. + +Assume that the center point is stored in the variables {\tt xc} and +{\tt yc}, and the perimeter point is in {\tt xp} and {\tt yp}. The +first step is to find the radius of the circle, which is the distance +between the two points. We just wrote a function, {\tt +distance}, that does that: + +\begin{verbatim} +radius = distance(xc, yc, xp, yp) +\end{verbatim} +% +The next step is to find the area of a circle with that radius; +we just wrote that, too: + +\begin{verbatim} +result = area(radius) +\end{verbatim} +% +Encapsulating these steps in a function, we get: +\index{encapsulation} + +\begin{verbatim} +def circle_area(xc, yc, xp, yp): + radius = distance(xc, yc, xp, yp) + result = area(radius) + return result +\end{verbatim} +% +The temporary variables {\tt radius} and {\tt result} are useful for +development and debugging, but once the program is working, we can +make it more concise by composing the function calls: + +\begin{verbatim} +def circle_area(xc, yc, xp, yp): + return area(distance(xc, yc, xp, yp)) +\end{verbatim} +% + +\section{Boolean functions} +\label{boolean} + +Functions can return booleans, which is often convenient for hiding +complicated tests inside functions. \index{boolean function} +For example: + +\begin{verbatim} +def is_divisible(x, y): + if x % y == 0: + return True + else: + return False +\end{verbatim} +% +It is common to give boolean functions names that sound like yes/no +questions; \verb"is_divisible" returns either {\tt True} or {\tt False} +to indicate whether {\tt x} is divisible by {\tt y}. + +Here is an example: + +\begin{verbatim} +>>> is_divisible(6, 4) +False +>>> is_divisible(6, 3) +True +\end{verbatim} +% +The result of the {\tt ==} operator is a boolean, so we can write the +function more concisely by returning it directly: + +\begin{verbatim} +def is_divisible(x, y): + return x % y == 0 +\end{verbatim} +% +Boolean functions are often used in conditional statements: +\index{conditional statement} +\index{statement!conditional} + +\begin{verbatim} +if is_divisible(x, y): + print('x is divisible by y') +\end{verbatim} +% +It might be tempting to write something like: + +\begin{verbatim} +if is_divisible(x, y) == True: + print('x is divisible by y') +\end{verbatim} +% +But the extra comparison is unnecessary. + +As an exercise, write a function \verb"is_between(x, y, z)" that +returns {\tt True} if $x \le y \le z$ or {\tt False} otherwise. + + +\section{More recursion} +\label{more.recursion} +\index{recursion} +\index{Turing complete language} +\index{language!Turing complete} +\index{Turing, Alan} +\index{Turing Thesis} + +We have only covered a small subset of Python, but you might +be interested to know that this subset is a {\em complete} +programming language, which means that anything that can be +computed can be expressed in this language. Any program ever written +could be rewritten using only the language features you have learned +so far (actually, you would need a few commands to control devices +like the mouse, disks, etc., but that's all). + +Proving that claim is a nontrivial exercise first accomplished by Alan +Turing, one of the first computer scientists (some would argue that he +was a mathematician, but a lot of early computer scientists started as +mathematicians). Accordingly, it is known as the Turing Thesis. +For a more complete (and accurate) discussion of the Turing Thesis, +I recommend Michael Sipser's book {\em Introduction to the +Theory of Computation}. + +To give you an idea of what you can do with the tools you have learned +so far, we'll evaluate a few recursively defined mathematical +functions. A recursive definition is similar to a circular +definition, in the sense that the definition contains a reference to +the thing being defined. A truly circular definition is not very +useful: + +\begin{description} + +\item[vorpal:] An adjective used to describe something that is vorpal. +\index{vorpal} +\index{circular definition} +\index{definition!circular} + +\end{description} + +If you saw that definition in the dictionary, you might be annoyed. On +the other hand, if you looked up the definition of the factorial +function, denoted with the symbol $!$, you might get something like +this: +% +\begin{eqnarray*} +&& 0! = 1 \\ +&& n! = n (n-1)! +\end{eqnarray*} +% +This definition says that the factorial of 0 is 1, and the factorial +of any other value, $n$, is $n$ multiplied by the factorial of $n-1$. + +So $3!$ is 3 times $2!$, which is 2 times $1!$, which is 1 times +$0!$. Putting it all together, $3!$ equals 3 times 2 times 1 times 1, +which is 6. +\index{factorial function} +\index{function!factorial} +\index{recursive definition} + +If you can write a recursive definition of something, you can +write a Python program to evaluate it. The first step is to decide +what the parameters should be. In this case it should be clear +that {\tt factorial} takes an integer: + +\begin{verbatim} +def factorial(n): +\end{verbatim} +% +If the argument happens to be 0, all we have to do is return 1: + +\begin{verbatim} +def factorial(n): + if n == 0: + return 1 +\end{verbatim} +% +Otherwise, and this is the interesting part, we have to make a +recursive call to find the factorial of $n-1$ and then multiply it by +$n$: + +\begin{verbatim} +def factorial(n): + if n == 0: + return 1 + else: + recurse = factorial(n-1) + result = n * recurse + return result +\end{verbatim} +% +The flow of execution for this program is similar to the flow of {\tt +countdown} in Section~\ref{recursion}. If we call {\tt factorial} +with the value 3: + +Since 3 is not 0, we take the second branch and calculate the factorial +of {\tt n-1}... + +\begin{quote} +Since 2 is not 0, we take the second branch and calculate the factorial of +{\tt n-1}... + + + \begin{quote} + Since 1 is not 0, we take the second branch and calculate the factorial + of {\tt n-1}... + + + \begin{quote} + Since 0 equals 0, we take the first branch and return 1 + without making any more recursive calls. + \end{quote} + + + The return value, 1, is multiplied by $n$, which is 1, and the + result is returned. + \end{quote} + + +The return value, 1, is multiplied by $n$, which is 2, and the +result is returned. +\end{quote} + + +The return value (2) is multiplied by $n$, which is 3, and the result, 6, +becomes the return value of the function call that started the whole +process. +\index{stack diagram} + +Figure~\ref{fig.stack3} shows what the stack diagram looks like for +this sequence of function calls. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/stack3.pdf}} +\caption{Stack diagram.} +\label{fig.stack3} +\end{figure} + +The return values are shown being passed back up the stack. In each +frame, the return value is the value of {\tt result}, which is the +product of {\tt n} and {\tt recurse}. +\index{function frame} +\index{frame} + +In the last frame, the local +variables {\tt recurse} and {\tt result} do not exist, because +the branch that creates them does not run. + + +\section{Leap of faith} +\index{recursion} +\index{leap of faith} + +Following the flow of execution is one way to read programs, but +it can quickly become overwhelming. An +alternative is what I call the ``leap of faith''. When you come to a +function call, instead of following the flow of execution, you {\em +assume} that the function works correctly and returns the right +result. + +In fact, you are already practicing this leap of faith when you use +built-in functions. When you call {\tt math.cos} or {\tt math.exp}, +you don't examine the bodies of those functions. You just +assume that they work because the people who wrote the built-in +functions were good programmers. + +The same is true when you call one of your own functions. For +example, in Section~\ref{boolean}, we wrote a function called +\verb"is_divisible" that determines whether one number is divisible by +another. Once we have convinced ourselves that this function is +correct---by examining the code and testing---we can use the function +without looking at the body again. +\index{testing!leap of faith} + +The same is true of recursive programs. When you get to the recursive +call, instead of following the flow of execution, you should assume +that the recursive call works (returns the correct result) and then ask +yourself, ``Assuming that I can find the factorial of $n-1$, can I +compute the factorial of $n$?'' It is clear that you +can, by multiplying by $n$. + +Of course, it's a bit strange to assume that the function works +correctly when you haven't finished writing it, but that's why +it's called a leap of faith! + + +\section{One more example} +\label{one.more.example} + +\index{fibonacci function} +\index{function!fibonacci} +After {\tt factorial}, the most common example of a recursively +defined mathematical function is {\tt fibonacci}, which has the +following definition (see + \url{http://en.wikipedia.org/wiki/Fibonacci_number}): +% +\begin{eqnarray*} +&& \mathrm{fibonacci}(0) = 0 \\ +&& \mathrm{fibonacci}(1) = 1 \\ +&& \mathrm{fibonacci}(n) = \mathrm{fibonacci}(n-1) + \mathrm{fibonacci}(n-2) +\end{eqnarray*} +% +Translated into Python, it looks like this: + +\begin{verbatim} +def fibonacci(n): + if n == 0: + return 0 + elif n == 1: + return 1 + else: + return fibonacci(n-1) + fibonacci(n-2) +\end{verbatim} +% +If you try to follow the flow of execution here, even for fairly +small values of $n$, your head explodes. But according to the +leap of faith, if you assume that the two recursive calls +work correctly, then it is clear that you get +the right result by adding them together. +\index{flow of execution} + + +\section{Checking types} +\label{guardian} + +What happens if we call {\tt factorial} and give it 1.5 as an argument? +\index{type checking} +\index{error checking} +\index{factorial function} +\index{RuntimeError} + +\begin{verbatim} +>>> factorial(1.5) +RuntimeError: Maximum recursion depth exceeded +\end{verbatim} +% +It looks like an infinite recursion. How can that be? The function +has a base case---when {\tt n == 0}. But if {\tt n} is not an integer, +we can {\em miss} the base case and recurse forever. +\index{infinite recursion} +\index{recursion!infinite} + +In the first recursive call, the value of {\tt n} is 0.5. +In the next, it is -0.5. From there, it gets smaller +(more negative), but it will never be 0. + +We have two choices. We can try to generalize the {\tt factorial} +function to work with floating-point numbers, or we can make {\tt + factorial} check the type of its argument. The first option is +called the gamma function and it's a +little beyond the scope of this book. So we'll go for the second. +\index{gamma function} + +We can use the built-in function {\tt isinstance} to verify the type +of the argument. While we're at it, we can also make sure the +argument is positive: +\index{isinstance function} +\index{function!isinstance} + +\begin{verbatim} +def factorial(n): + if not isinstance(n, int): + print('Factorial is only defined for integers.') + return None + elif n < 0: + print('Factorial is not defined for negative integers.') + return None + elif n == 0: + return 1 + else: + return n * factorial(n-1) +\end{verbatim} +% +The first base case handles nonintegers; the +second handles negative integers. In both cases, the program prints +an error message and returns {\tt None} to indicate that something +went wrong: + +\begin{verbatim} +>>> print(factorial('fred')) +Factorial is only defined for integers. +None +>>> print(factorial(-2)) +Factorial is not defined for negative integers. +None +\end{verbatim} +% +If we get past both checks, we know that $n$ is positive or +zero, so we can prove that the recursion terminates. +\index{guardian pattern} +\index{pattern!guardian} + +This program demonstrates a pattern sometimes called a {\bf guardian}. +The first two conditionals act as guardians, protecting the code that +follows from values that might cause an error. The guardians make it +possible to prove the correctness of the code. + +In Section~\ref{raise} we will see a more flexible alternative to printing +an error message: raising an exception. + + +\section{Debugging} +\label{factdebug} + +Breaking a large program into smaller functions creates natural +checkpoints for debugging. If a function is not +working, there are three possibilities to consider: +\index{debugging} + +\begin{itemize} + +\item There is something wrong with the arguments the function +is getting; a precondition is violated. + +\item There is something wrong with the function; a postcondition +is violated. + +\item There is something wrong with the return value or the +way it is being used. + +\end{itemize} + +To rule out the first possibility, you can add a {\tt print} statement +at the beginning of the function and display the values of the +parameters (and maybe their types). Or you can write code +that checks the preconditions explicitly. +\index{precondition} +\index{postcondition} + +If the parameters look good, add a {\tt print} statement before each +{\tt return} statement and display the return value. If +possible, check the result by hand. Consider calling the +function with values that make it easy to check the result +(as in Section~\ref{incremental.development}). + +If the function seems to be working, look at the function call +to make sure the return value is being used correctly (or used +at all!). +\index{flow of execution} + +Adding print statements at the beginning and end of a function +can help make the flow of execution more visible. +For example, here is a version of {\tt factorial} with +print statements: + +\begin{verbatim} +def factorial(n): + space = ' ' * (4 * n) + print(space, 'factorial', n) + if n == 0: + print(space, 'returning 1') + return 1 + else: + recurse = factorial(n-1) + result = n * recurse + print(space, 'returning', result) + return result +\end{verbatim} +% +{\tt space} is a string of space characters that controls the +indentation of the output. Here is the result of {\tt factorial(4)} : + +\begin{verbatim} + factorial 4 + factorial 3 + factorial 2 + factorial 1 + factorial 0 + returning 1 + returning 1 + returning 2 + returning 6 + returning 24 +\end{verbatim} +% +If you are confused about the flow of execution, this kind of +output can be helpful. It takes some time to develop effective +scaffolding, but a little bit of scaffolding can save a lot of debugging. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[temporary variable:] A variable used to store an intermediate value in +a complex calculation. +\index{temporary variable} +\index{variable!temporary} + +\item[dead code:] Part of a program that can never run, often because +it appears after a {\tt return} statement. +\index{dead code} + +\item[incremental development:] A program development plan intended to +avoid debugging by adding and testing only +a small amount of code at a time. +\index{incremental development} + +\item[scaffolding:] Code that is used during program development but is +not part of the final version. +\index{scaffolding} + +\item[guardian:] A programming pattern that uses a conditional +statement to check for and handle circumstances that +might cause an error. +\index{guardian pattern} +\index{pattern!guardian} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Draw a stack diagram for the following program. What does the program print? +\index{stack diagram} + +\begin{verbatim} +def b(z): + prod = a(z, z) + print(z, prod) + return prod + +def a(x, y): + x = x + 1 + return x * y + +def c(x, y, z): + total = x + y + z + square = b(total)**2 + return square + +x = 1 +y = x + 1 +print(c(x, y+3, x+y)) +\end{verbatim} + +\end{exercise} + + +\begin{exercise} +\label{ackermann} + +The Ackermann function, $A(m, n)$, is defined: + +\begin{eqnarray*} +A(m, n) = \begin{cases} + n+1 & \mbox{if } m = 0 \\ + A(m-1, 1) & \mbox{if } m > 0 \mbox{ and } n = 0 \\ +A(m-1, A(m, n-1)) & \mbox{if } m > 0 \mbox{ and } n > 0. +\end{cases} +\end{eqnarray*} +% +See \url{http://en.wikipedia.org/wiki/Ackermann_function}. +Write a function named {\tt ack} that evaluates the Ackermann function. +Use your function to evaluate {\tt ack(3, 4)}, which should be 125. +What happens for larger values of {\tt m} and {\tt n}? +Solution: \url{http://thinkpython2.com/code/ackermann.py}. +\index{Ackermann function} +\index{function!ack} + +\end{exercise} + + +\begin{exercise} +\label{palindrome} + +A palindrome is a word that is spelled the same backward and +forward, like ``noon'' and ``redivider''. Recursively, a word +is a palindrome if the first and last letters are the same +and the middle is a palindrome. +\index{palindrome} + +The following are functions that take a string argument and +return the first, last, and middle letters: + +\begin{verbatim} +def first(word): + return word[0] + +def last(word): + return word[-1] + +def middle(word): + return word[1:-1] +\end{verbatim} +% +We'll see how they work in Chapter~\ref{strings}. + +\begin{enumerate} + +\item Type these functions into a file named {\tt palindrome.py} +and test them out. What happens if you call {\tt middle} with +a string with two letters? One letter? What about the empty +string, which is written \verb"''" and contains no letters? + +\item Write a function called \verb"is_palindrome" that takes +a string argument and returns {\tt True} if it is a palindrome +and {\tt False} otherwise. Remember that you can use the +built-in function {\tt len} to check the length of a string. + +\end{enumerate} + +Solution: \url{http://thinkpython2.com/code/palindrome_soln.py}. + +\end{exercise} + +\begin{exercise} + +A number, $a$, is a power of $b$ if it is divisible by $b$ +and $a/b$ is a power of $b$. Write a function called +\verb"is_power" that takes parameters {\tt a} and {\tt b} +and returns {\tt True} if {\tt a} is a power of {\tt b}. +Note: you will have to think about the base case. + +\end{exercise} + + +\begin{exercise} +\index{greatest common divisor (GCD)} +\index{GCD (greatest common divisor)} + +The greatest common divisor (GCD) of $a$ and $b$ is the largest number +that divides both of them with no remainder. + +One way to find the GCD of two numbers is based on the observation +that if $r$ is the remainder when $a$ is divided by $b$, then $gcd(a, +b) = gcd(b, r)$. As a base case, we can use $gcd(a, 0) = a$. + +Write a function called +\verb"gcd" that takes parameters {\tt a} and {\tt b} +and returns their greatest common divisor. + +Credit: This exercise is based on an example from Abelson and +Sussman's {\em Structure and Interpretation of Computer Programs}. + +\end{exercise} + + +\chapter{Iteration} + +This chapter is about iteration, which is the ability to run +a block of statements repeatedly. We saw a kind of iteration, +using recursion, in Section~\ref{recursion}. +We saw another kind, using a {\tt for} loop, +in Section~\ref{repetition}. In this chapter we'll see yet another +kind, using a {\tt while} statement. +But first I want to say a little more about variable assignment. + + +\section{Reassignment} +\index{assignment} +\index{statement!assignment} +\index{reassignment} + +As you may have discovered, it is legal to make more than one +assignment to the same variable. A new assignment makes an existing +variable refer to a new value (and stop referring to the old value). + +\begin{verbatim} +>>> x = 5 +>>> x +5 +>>> x = 7 +>>> x +7 +\end{verbatim} +% +The first time we display +{\tt x}, its value is 5; the second time, its +value is 7. + +Figure~\ref{fig.assign2} shows what {\bf reassignment} looks +like in a state diagram. \index{state diagram} \index{diagram!state} + +At this point I want to address a common source of +confusion. +Because Python uses the equal sign ({\tt =}) for assignment, it is +tempting to interpret a statement like {\tt a = b} as a +mathematical +proposition of equality; that is, the claim that {\tt a} and +{\tt b} are equal. But this interpretation is wrong. +\index{equality and assignment} + +First, equality is a symmetric relationship and assignment is not. For +example, in mathematics, if $a=7$ then $7=a$. But in Python, the +statement {\tt a = 7} is legal and {\tt 7 = a} is not. + +Also, in mathematics, a proposition of equality is either true or +false for all time. If $a=b$ now, then $a$ will always equal $b$. +In Python, an assignment statement can make two variables equal, but +they don't have to stay that way: + +\begin{verbatim} +>>> a = 5 +>>> b = a # a and b are now equal +>>> a = 3 # a and b are no longer equal +>>> b +5 +\end{verbatim} +% +The third line changes the value of {\tt a} but does not change the +value of {\tt b}, so they are no longer equal. + +Reassigning variables is often useful, but you should use it +with caution. If the values of variables change frequently, it can +make the code difficult to read and debug. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/assign2.pdf}} +\caption{State diagram.} +\label{fig.assign2} +\end{figure} + + + +\section{Updating variables} +\label{update} + +\index{update} +\index{variable!updating} + +A common kind of reassignment is an {\bf update}, +where the new value of the variable depends on the old. + +\begin{verbatim} +>>> x = x + 1 +\end{verbatim} +% +This means ``get the current value of {\tt x}, add one, and then +update {\tt x} with the new value.'' + +If you try to update a variable that doesn't exist, you get an +error, because Python evaluates the right side before it assigns +a value to {\tt x}: + +\begin{verbatim} +>>> x = x + 1 +NameError: name 'x' is not defined +\end{verbatim} +% +Before you can update a variable, you have to {\bf initialize} +it, usually with a simple assignment: +\index{initialization (before update)} + +\begin{verbatim} +>>> x = 0 +>>> x = x + 1 +\end{verbatim} +% +Updating a variable by adding 1 is called an {\bf increment}; +subtracting 1 is called a {\bf decrement}. +\index{increment} +\index{decrement} + + + + +\section{The {\tt while} statement} +\index{statement!while} +\index{while loop} +\index{loop!while} +\index{iteration} + +Computers are often used to automate repetitive tasks. Repeating +identical or similar tasks without making errors is something that +computers do well and people do poorly. In a computer program, +repetition is also called {\bf iteration}. + +We have already seen two functions, {\tt countdown} and +\verb"print_n", that iterate using recursion. Because iteration is so +common, Python provides language features to make it easier. +One is the {\tt for} statement we saw in Section~\ref{repetition}. +We'll get back to that later. + +Another is the {\tt while} statement. Here is a version of {\tt +countdown} that uses a {\tt while} statement: + +\begin{verbatim} +def countdown(n): + while n > 0: + print(n) + n = n - 1 + print('Blastoff!') +\end{verbatim} +% +You can almost read the {\tt while} statement as if it were English. +It means, ``While {\tt n} is greater than 0, +display the value of {\tt n} and then decrement +{\tt n}. When you get to 0, display the word {\tt Blastoff!}'' +\index{flow of execution} + +More formally, here is the flow of execution for a {\tt while} statement: + +\begin{enumerate} + +\item Determine whether the condition is true or false. + +\item If false, exit the {\tt while} statement +and continue execution at the next statement. + +\item If the condition is true, run the +body and then go back to step 1. + +\end{enumerate} + +This type of flow is called a loop because the third step +loops back around to the top. +\index{condition} +\index{loop} +\index{body} + +The body of the loop should change the value of one or more variables +so that the condition becomes false eventually and the loop +terminates. Otherwise the loop will repeat forever, which is called +an {\bf infinite loop}. An endless source of amusement for computer +scientists is the observation that the directions on shampoo, +``Lather, rinse, repeat'', are an infinite loop. +\index{infinite loop} +\index{loop!infinite} + +In the case of {\tt countdown}, we can prove that the loop +terminates: if {\tt n} is zero or negative, the loop never runs. +Otherwise, {\tt n} gets smaller each time through the +loop, so eventually we have to get to 0. + +For some other loops, it is not so easy to tell. For example: + +\begin{verbatim} +def sequence(n): + while n != 1: + print(n) + if n % 2 == 0: # n is even + n = n / 2 + else: # n is odd + n = n*3 + 1 +\end{verbatim} +% +The condition for this loop is {\tt n != 1}, so the loop will continue +until {\tt n} is {\tt 1}, which makes the condition false. + +Each time through the loop, the program outputs the value of {\tt n} +and then checks whether it is even or odd. If it is even, {\tt n} is +divided by 2. If it is odd, the value of {\tt n} is replaced with +{\tt n*3 + 1}. For example, if the argument passed to {\tt sequence} +is 3, the resulting values of {\tt n} are 3, 10, 5, 16, 8, 4, 2, 1. + +Since {\tt n} sometimes increases and sometimes decreases, there is no +obvious proof that {\tt n} will ever reach 1, or that the program +terminates. For some particular values of {\tt n}, we can prove +termination. For example, if the starting value is a power of two, +{\tt n} will be even every time through the loop +until it reaches 1. The previous example ends with such a sequence, +starting with 16. +\index{Collatz conjecture} + +The hard question is whether we can prove that this program terminates +for {\em all} positive values of {\tt n}. So far, no one has +been able to prove it {\em or} disprove it! (See + \url{http://en.wikipedia.org/wiki/Collatz_conjecture}.) + +As an exercise, rewrite the function \verb"print_n" from +Section~\ref{recursion} using iteration instead of recursion. + + +\section{{\tt break}} +\index{break statement} +\index{statement!break} + +Sometimes you don't know it's time to end a loop until you get half +way through the body. In that case you can use the {\tt break} +statement to jump out of the loop. + +For example, suppose you want to take input from the user until they +type {\tt done}. You could write: + +\begin{verbatim} +while True: + line = input('> ') + if line == 'done': + break + print(line) + +print('Done!') +\end{verbatim} +% +The loop condition is {\tt True}, which is always true, so the +loop runs until it hits the break statement. + +Each time through, it prompts the user with an angle bracket. +If the user types {\tt done}, the {\tt break} statement exits +the loop. Otherwise the program echoes whatever the user types +and goes back to the top of the loop. Here's a sample run: + +\begin{verbatim} +> not done +not done +> done +Done! +\end{verbatim} +% +This way of writing {\tt while} loops is common because you +can check the condition anywhere in the loop (not just at the +top) and you can express the stop condition affirmatively +(``stop when this happens'') rather than negatively (``keep going +until that happens''). + + +\section{Square roots} +\label{squareroot} +\index{square root} + +Loops are often used in programs that compute +numerical results by starting with an approximate answer and +iteratively improving it. +\index{Newton's method} + +For example, one way of computing square roots is Newton's method. +Suppose that you want to know the square root of $a$. If you start +with almost any estimate, $x$, you can compute a better +estimate with the following formula: + +\[ y = \frac{x + a/x}{2} \] +% +For example, if $a$ is 4 and $x$ is 3: + +\begin{verbatim} +>>> a = 4 +>>> x = 3 +>>> y = (x + a/x) / 2 +>>> y +2.16666666667 +\end{verbatim} +% +The result is closer to the correct answer ($\sqrt{4} = 2$). If we +repeat the process with the new estimate, it gets even closer: + +\begin{verbatim} +>>> x = y +>>> y = (x + a/x) / 2 +>>> y +2.00641025641 +\end{verbatim} +% +After a few more updates, the estimate is almost exact: +\index{update} + +\begin{verbatim} +>>> x = y +>>> y = (x + a/x) / 2 +>>> y +2.00001024003 +>>> x = y +>>> y = (x + a/x) / 2 +>>> y +2.00000000003 +\end{verbatim} +% +In general we don't know ahead of time how many steps it takes +to get to the right answer, but we know when we get there +because the estimate +stops changing: + +\begin{verbatim} +>>> x = y +>>> y = (x + a/x) / 2 +>>> y +2.0 +>>> x = y +>>> y = (x + a/x) / 2 +>>> y +2.0 +\end{verbatim} +% +When {\tt y == x}, we can stop. Here is a loop that starts +with an initial estimate, {\tt x}, and improves it until it +stops changing: + +\begin{verbatim} +while True: + print(x) + y = (x + a/x) / 2 + if y == x: + break + x = y +\end{verbatim} +% +For most values of {\tt a} this works fine, but in general it is +dangerous to test {\tt float} equality. +Floating-point values are only approximately right: +most rational numbers, like $1/3$, and irrational numbers, like +$\sqrt{2}$, can't be represented exactly with a {\tt float}. +\index{floating-point} +\index{epsilon} + +Rather than checking whether {\tt x} and {\tt y} are exactly equal, it +is safer to use the built-in function {\tt abs} to compute the +absolute value, or magnitude, of the difference between them: + +\begin{verbatim} + if abs(y-x) < epsilon: + break +\end{verbatim} +% +Where \verb"epsilon" has a value like {\tt 0.0000001} that +determines how close is close enough. + + +\section{Algorithms} +\index{algorithm} + +Newton's method is an example of an {\bf algorithm}: it is a +mechanical process for solving a category of problems (in this +case, computing square roots). + +To understand what an algorithm is, it might help to start with +something that is not an algorithm. When you learned to multiply +single-digit numbers, you probably memorized the multiplication table. +In effect, you memorized 100 specific solutions. That kind of +knowledge is not algorithmic. + +But if you were ``lazy'', you might have learned a few +tricks. For example, to find the product of $n$ and 9, you can +write $n-1$ as the first digit and $10-n$ as the second +digit. This trick is a general solution for multiplying any +single-digit number by 9. That's an algorithm! +\index{addition with carrying} +\index{carrying, addition with} +\index{subtraction!with borrowing} +\index{borrowing, subtraction with} + +Similarly, the techniques you learned for addition with carrying, +subtraction with borrowing, and long division are all algorithms. One +of the characteristics of algorithms is that they do not require any +intelligence to carry out. They are mechanical processes where +each step follows from the last according to a simple set of rules. + +Executing algorithms is boring, but designing them is interesting, +intellectually challenging, and a central part of computer science. + +Some of the things that people do naturally, without difficulty or +conscious thought, are the hardest to express algorithmically. +Understanding natural language is a good example. We all do it, but +so far no one has been able to explain {\em how} we do it, at least +not in the form of an algorithm. + + +\section{Debugging} +\label{bisectbug} + +As you start writing bigger programs, you might find yourself +spending more time debugging. More code means more chances to +make an error and more places for bugs to hide. +\index{debugging!by bisection} +\index{bisection, debugging by} + +One way to cut your debugging time is ``debugging by bisection''. +For example, if there are 100 lines in your program and you +check them one at a time, it would take 100 steps. + +Instead, try to break the problem in half. Look at the middle +of the program, or near it, for an intermediate value you +can check. Add a {\tt print} statement (or something else +that has a verifiable effect) and run the program. + +If the mid-point check is incorrect, there must be a problem in the +first half of the program. If it is correct, the problem is +in the second half. + +Every time you perform a check like this, you halve the number of +lines you have to search. After six steps (which is fewer than 100), +you would be down to one or two lines of code, at least in theory. + +In practice it is not always clear what +the ``middle of the program'' is and not always possible to +check it. It doesn't make sense to count lines and find the +exact midpoint. Instead, think about places +in the program where there might be errors and places where it +is easy to put a check. Then choose a spot where you +think the chances are about the same that the bug is before +or after the check. + + + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[reassignment:] Assigning a new value to a variable that +already exists. +\index{reassignment} + +\item[update:] An assignment where the new value of the variable +depends on the old. +\index{update} + +\item[initialization:] An assignment that gives an initial value to +a variable that will be updated. +\index{initialization!variable} + +\item[increment:] An update that increases the value of a variable +(often by one). +\index{increment} + +\item[decrement:] An update that decreases the value of a variable. +\index{decrement} + +\item[iteration:] Repeated execution of a set of statements using +either a recursive function call or a loop. +\index{iteration} + +\item[infinite loop:] A loop in which the terminating condition is +never satisfied. +\index{infinite loop} + +\item[algorithm:] A general process for solving a category of +problems. +\index{algorithm} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +\index{algorithm!square root} + +Copy the loop from Section~\ref{squareroot} +and encapsulate it in a function called +\verb"mysqrt" that takes {\tt a} as a parameter, chooses a +reasonable value of {\tt x}, and returns an estimate of the square +root of {\tt a}. \index{encapsulation} + +To test it, write a function named \verb"test_square_root" +that prints a table like this: + +\begin{verbatim} +a mysqrt(a) math.sqrt(a) diff +- --------- ------------ ---- +1.0 1.0 1.0 0.0 +2.0 1.41421356237 1.41421356237 2.22044604925e-16 +3.0 1.73205080757 1.73205080757 0.0 +4.0 2.0 2.0 0.0 +5.0 2.2360679775 2.2360679775 0.0 +6.0 2.44948974278 2.44948974278 0.0 +7.0 2.64575131106 2.64575131106 0.0 +8.0 2.82842712475 2.82842712475 4.4408920985e-16 +9.0 3.0 3.0 0.0 +\end{verbatim} +% +The first column is a number, $a$; the second column is the square +root of $a$ computed with \verb"mysqrt"; the third column is the +square root computed by {\tt math.sqrt}; the fourth column is the +absolute value of the difference between the two estimates. +\end{exercise} + + +\begin{exercise} +\index{eval function} +\index{function!eval} + +The built-in function {\tt eval} takes a string and evaluates +it using the Python interpreter. For example: + +\begin{verbatim} +>>> eval('1 + 2 * 3') +7 +>>> import math +>>> eval('math.sqrt(5)') +2.2360679774997898 +>>> eval('type(math.pi)') + +\end{verbatim} +% +Write a function called \verb"eval_loop" that iteratively +prompts the user, takes the resulting input and evaluates +it using {\tt eval}, and prints the result. + +It should continue until the user enters \verb"'done'", and then +return the value of the last expression it evaluated. + +\end{exercise} + + +\begin{exercise} +\index{Ramanujan, Srinivasa} + +The mathematician Srinivasa Ramanujan found an +infinite series +that can be used to generate a numerical +approximation of $1 / \pi$: +\index{pi} + +\[ \frac{1}{\pi} = \frac{2\sqrt{2}}{9801} +\sum^\infty_{k=0} \frac{(4k)!(1103+26390k)}{(k!)^4 396^{4k}} \] + +Write a function called \verb"estimate_pi" that uses this formula +to compute and return an estimate of $\pi$. It should use a {\tt while} +loop to compute terms of the summation until the last term is +smaller than {\tt 1e-15} (which is Python notation for $10^{-15}$). +You can check the result by comparing it to {\tt math.pi}. + +Solution: \url{http://thinkpython2.com/code/pi.py}. + +\end{exercise} + + +\chapter{Strings} +\label{strings} + +Strings are not like integers, floats, and booleans. A string +is a {\bf sequence}, which means it is +an ordered collection of other values. In this chapter you'll see +how to access the characters that make up a string, and you'll +learn about some of the methods strings provide. +\index{sequence} + + +\section{A string is a sequence} + +\index{sequence} +\index{character} +\index{bracket operator} +\index{operator!bracket} +A string is a sequence of characters. +You can access the characters one at a time with the +bracket operator: + +\begin{verbatim} +>>> fruit = 'banana' +>>> letter = fruit[1] +\end{verbatim} +% +The second statement selects character number 1 from {\tt +fruit} and assigns it to {\tt letter}. +\index{index} + +The expression in brackets is called an {\bf index}. +The index indicates which character in the sequence you +want (hence the name). + +But you might not get what you expect: + +\begin{verbatim} +>>> letter +'a' +\end{verbatim} +% +For most people, the first letter of \verb"'banana'" is {\tt b}, not +{\tt a}. But for computer scientists, the index is an offset from the +beginning of the string, and the offset of the first letter is zero. + +\begin{verbatim} +>>> letter = fruit[0] +>>> letter +'b' +\end{verbatim} +% +So {\tt b} is the 0th letter (``zero-eth'') of \verb"'banana'", {\tt + a} is the 1th letter (``one-eth''), and {\tt n} is the 2th letter +(``two-eth''). \index{index!starting at zero} \index{zero, index + starting at} + +As an index you can use an expression that contains variables and +operators: +\index{index} + +\begin{verbatim} +>>> i = 1 +>>> fruit[i] +'a' +>>> fruit[i+1] +'n' +\end{verbatim} +% + +But the value of the index has to be an integer. Otherwise you +get: +\index{exception!TypeError} +\index{TypeError} + +\begin{verbatim} +>>> letter = fruit[1.5] +TypeError: string indices must be integers +\end{verbatim} +% + +\section{{\tt len}} +\index{len function} +\index{function!len} + +{\tt len} is a built-in function that returns the number of characters +in a string: + +\begin{verbatim} +>>> fruit = 'banana' +>>> len(fruit) +6 +\end{verbatim} +% +To get the last letter of a string, you might be tempted to try something +like this: +\index{exception!IndexError} +\index{IndexError} + +\begin{verbatim} +>>> length = len(fruit) +>>> last = fruit[length] +IndexError: string index out of range +\end{verbatim} +% +The reason for the {\tt IndexError} is that there is no letter in {\tt +'banana'} with the index 6. Since we started counting at zero, the +six letters are numbered 0 to 5. To get the last character, you have +to subtract 1 from {\tt length}: + +\begin{verbatim} +>>> last = fruit[length-1] +>>> last +'a' +\end{verbatim} +% +Or you can use negative indices, which count backward from +the end of the string. The expression {\tt fruit[-1]} yields the last +letter, {\tt fruit[-2]} yields the second to last, and so on. +\index{index!negative} +\index{negative index} + + +\section{Traversal with a {\tt for} loop} +\label{for} +\index{traversal} +\index{loop!traversal} +\index{for loop} +\index{loop!for} +\index{statement!for} +\index{traversal} + +A lot of computations involve processing a string one character at a +time. Often they start at the beginning, select each character in +turn, do something to it, and continue until the end. This pattern of +processing is called a {\bf traversal}. One way to write a traversal +is with a {\tt while} loop: + +\begin{verbatim} +index = 0 +while index < len(fruit): + letter = fruit[index] + print(letter) + index = index + 1 +\end{verbatim} +% +This loop traverses the string and displays each letter on a line by +itself. The loop condition is {\tt index < len(fruit)}, so +when {\tt index} is equal to the length of the string, the +condition is false, and the body of the loop doesn't run. The +last character accessed is the one with the index {\tt len(fruit)-1}, +which is the last character in the string. + +As an exercise, write a function that takes a string as an argument +and displays the letters backward, one per line. + +Another way to write a traversal is with a {\tt for} loop: + +\begin{verbatim} +for letter in fruit: + print(letter) +\end{verbatim} +% +Each time through the loop, the next character in the string is assigned +to the variable {\tt letter}. The loop continues until no characters are +left. +\index{concatenation} +\index{abecedarian} +\index{McCloskey, Robert} + +The following example shows how to use concatenation (string addition) +and a {\tt for} loop to generate an abecedarian series (that is, in +alphabetical order). In Robert McCloskey's book {\em Make +Way for Ducklings}, the names of the ducklings are Jack, Kack, Lack, +Mack, Nack, Ouack, Pack, and Quack. This loop outputs these names in +order: + +\begin{verbatim} +prefixes = 'JKLMNOPQ' +suffix = 'ack' + +for letter in prefixes: + print(letter + suffix) +\end{verbatim} +% +The output is: + +\begin{verbatim} +Jack +Kack +Lack +Mack +Nack +Oack +Pack +Qack +\end{verbatim} +% +Of course, that's not quite right because ``Ouack'' and ``Quack'' are +misspelled. As an exercise, modify the program to fix this error. + + + +\section{String slices} +\label{slice} +\index{slice operator} \index{operator!slice} \index{index!slice} +\index{string!slice} \index{slice!string} + +A segment of a string is called a {\bf slice}. Selecting a slice is +similar to selecting a character: + +\begin{verbatim} +>>> s = 'Monty Python' +>>> s[0:5] +'Monty' +>>> s[6:12] +'Python' +\end{verbatim} +% +The operator {\tt [n:m]} returns the part of the string from the +``n-eth'' character to the ``m-eth'' character, including the first but +excluding the last. This behavior is counterintuitive, but it might +help to imagine the indices pointing {\em between} the +characters, as in Figure~\ref{fig.banana}. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/banana.pdf}} +\caption{Slice indices.} +\label{fig.banana} +\end{figure} + +If you omit the first index (before the colon), the slice starts at +the beginning of the string. If you omit the second index, the slice +goes to the end of the string: + +\begin{verbatim} +>>> fruit = 'banana' +>>> fruit[:3] +'ban' +>>> fruit[3:] +'ana' +\end{verbatim} +% +If the first index is greater than or equal to the second the result +is an {\bf empty string}, represented by two quotation marks: +\index{quotation mark} + +\begin{verbatim} +>>> fruit = 'banana' +>>> fruit[3:3] +'' +\end{verbatim} +% +An empty string contains no characters and has length 0, but other +than that, it is the same as any other string. + +Continuing this example, what do you think +{\tt fruit[:]} means? Try it and see. +\index{copy!slice} +\index{slice!copy} + + + +\section{Strings are immutable} +\index{mutability} +\index{immutability} +\index{string!immutable} + +It is tempting to use the {\tt []} operator on the left side of an +assignment, with the intention of changing a character in a string. +For example: +\index{TypeError} +\index{exception!TypeError} + +\begin{verbatim} +>>> greeting = 'Hello, world!' +>>> greeting[0] = 'J' +TypeError: 'str' object does not support item assignment +\end{verbatim} +% +The ``object'' in this case is the string and the ``item'' is +the character you tried to assign. For now, an object is +the same thing as a value, but we will refine that definition +later (Section~\ref{equivalence}). +\index{object} +\index{item} +\index{item assignment} +\index{assignment!item} +\index{immutability} + +The reason for the error is that +strings are {\bf immutable}, which means you can't change an +existing string. The best you can do is create a new string +that is a variation on the original: + +\begin{verbatim} +>>> greeting = 'Hello, world!' +>>> new_greeting = 'J' + greeting[1:] +>>> new_greeting +'Jello, world!' +\end{verbatim} +% +This example concatenates a new first letter onto +a slice of {\tt greeting}. It has no effect on +the original string. +\index{concatenation} + + +\section{Searching} +\label{find} + +What does the following function do? +\index{find function} +\index{function!find} + +\begin{verbatim} +def find(word, letter): + index = 0 + while index < len(word): + if word[index] == letter: + return index + index = index + 1 + return -1 +\end{verbatim} +% +In a sense, {\tt find} is the inverse of the {\tt []} operator. +Instead of taking an index and extracting the corresponding character, +it takes a character and finds the index where that character +appears. If the character is not found, the function returns {\tt +-1}. + +This is the first example we have seen of a {\tt return} statement +inside a loop. If {\tt word[index] == letter}, the function breaks +out of the loop and returns immediately. + +If the character doesn't appear in the string, the program +exits the loop normally and returns {\tt -1}. + +This pattern of computation---traversing a sequence and returning +when we find what we are looking for---is called a {\bf search}. +\index{traversal} +\index{search pattern} +\index{pattern!search} + +As an exercise, modify {\tt find} so that it has a +third parameter, the index in {\tt word} where it should start +looking. + + +\section{Looping and counting} +\label{counter} +\index{counter} +\index{counting and looping} +\index{looping and counting} +\index{looping!with strings} + +The following program counts the number of times the letter {\tt a} +appears in a string: + +\begin{verbatim} +word = 'banana' +count = 0 +for letter in word: + if letter == 'a': + count = count + 1 +print(count) +\end{verbatim} +% +This program demonstrates another pattern of computation called a {\bf +counter}. The variable {\tt count} is initialized to 0 and then +incremented each time an {\tt a} is found. +When the loop exits, {\tt count} +contains the result---the total number of {\tt a}'s. + +\index{encapsulation} +As an exercise, encapsulate this code in a function named {\tt +count}, and generalize it so that it accepts the string and the +letter as arguments. + +Then rewrite the function so that instead of +traversing the string, it uses the three-parameter version of {\tt +find} from the previous section. + + +\section{String methods} +\label{optional} + +Strings provide methods that perform a variety of useful operations. +A method is similar to a function---it takes arguments and +returns a value---but the syntax is different. For example, the +method {\tt upper} takes a string and returns a new string with +all uppercase letters. +\index{method} +\index{string!method} + +Instead of the function syntax {\tt upper(word)}, it uses +the method syntax {\tt word.upper()}. + +\begin{verbatim} +>>> word = 'banana' +>>> new_word = word.upper() +>>> new_word +'BANANA' +\end{verbatim} +% +This form of dot notation specifies the name of the method, {\tt +upper}, and the name of the string to apply the method to, {\tt +word}. The empty parentheses indicate that this method takes no +arguments. +\index{parentheses!empty} +\index{dot notation} + +A method call is called an {\bf invocation}; in this case, we would +say that we are invoking {\tt upper} on {\tt word}. +\index{invocation} + +As it turns out, there is a string method named {\tt find} that +is remarkably similar to the function we wrote: + +\begin{verbatim} +>>> word = 'banana' +>>> index = word.find('a') +>>> index +1 +\end{verbatim} +% +In this example, we invoke {\tt find} on {\tt word} and pass +the letter we are looking for as a parameter. + +Actually, the {\tt find} method is more general than our function; +it can find substrings, not just characters: + +\begin{verbatim} +>>> word.find('na') +2 +\end{verbatim} +% +By default, {\tt find} starts at the beginning of the string, but +it can take a second argument, the index where it should start: +\index{optional argument} +\index{argument!optional} + +\begin{verbatim} +>>> word.find('na', 3) +4 +\end{verbatim} +% +This is an example of an {\bf optional argument}; +{\tt find} can +also take a third argument, the index where it should stop: + +\begin{verbatim} +>>> name = 'bob' +>>> name.find('b', 1, 2) +-1 +\end{verbatim} +% +This search fails because {\tt b} does not +appear in the index range from {\tt 1} to {\tt 2}, not including {\tt +2}. Searching up to, but not including, the second index makes +{\tt find} consistent with the slice operator. + + + +\section{The {\tt in} operator} +\label{inboth} +\index{in operator} +\index{operator!in} +\index{boolean operator} +\index{operator!boolean} + +The word {\tt in} is a boolean operator that takes two strings and +returns {\tt True} if the first appears as a substring in the second: + +\begin{verbatim} +>>> 'a' in 'banana' +True +>>> 'seed' in 'banana' +False +\end{verbatim} +% +For example, the following function prints all the +letters from {\tt word1} that also appear in {\tt word2}: + +\begin{verbatim} +def in_both(word1, word2): + for letter in word1: + if letter in word2: + print(letter) +\end{verbatim} +% +With well-chosen variable names, +Python sometimes reads like English. You could read +this loop, ``for (each) letter in (the first) word, if (the) letter +(appears) in (the second) word, print (the) letter.'' + +Here's what you get if you compare apples and oranges: + +\begin{verbatim} +>>> in_both('apples', 'oranges') +a +e +s +\end{verbatim} +% + +\section{String comparison} +\index{string!comparison} +\index{comparison!string} + +The relational operators work on strings. To see if two strings are equal: + +\begin{verbatim} +if word == 'banana': + print('All right, bananas.') +\end{verbatim} +% +Other relational operations are useful for putting words in alphabetical +order: + +\begin{verbatim} +if word < 'banana': + print('Your word, ' + word + ', comes before banana.') +elif word > 'banana': + print('Your word, ' + word + ', comes after banana.') +else: + print('All right, bananas.') +\end{verbatim} +% +Python does not handle uppercase and lowercase letters the same way +people do. All the uppercase letters come before all the +lowercase letters, so: + +\begin{verbatim} +Your word, Pineapple, comes before banana. +\end{verbatim} +% +A common way to address this problem is to convert strings to a +standard format, such as all lowercase, before performing the +comparison. Keep that in mind in case you have to defend yourself +against a man armed with a Pineapple. + + +\section{Debugging} +\index{debugging} +\index{traversal} + +When you use indices to traverse the values in a sequence, +it is tricky to get the beginning and end of the traversal +right. Here is a function that is supposed to compare two +words and return {\tt True} if one of the words is the reverse +of the other, but it contains two errors: + +\begin{verbatim} +def is_reverse(word1, word2): + if len(word1) != len(word2): + return False + + i = 0 + j = len(word2) + + while j > 0: + if word1[i] != word2[j]: + return False + i = i+1 + j = j-1 + + return True +\end{verbatim} +% +The first {\tt if} statement checks whether the words are the +same length. If not, we can return {\tt False} immediately. +Otherwise, for the rest of the function, we can assume that the words +are the same length. This is an example of the guardian pattern +in Section~\ref{guardian}. +\index{guardian pattern} +\index{pattern!guardian} +\index{index} + +{\tt i} and {\tt j} are indices: {\tt i} traverses {\tt word1} +forward while {\tt j} traverses {\tt word2} backward. If we find +two letters that don't match, we can return {\tt False} immediately. +If we get through the whole loop and all the letters match, we +return {\tt True}. + +If we test this function with the words ``pots'' and ``stop'', we +expect the return value {\tt True}, but we get an IndexError: +\index{IndexError} +\index{exception!IndexError} + +\begin{verbatim} +>>> is_reverse('pots', 'stop') +... + File "reverse.py", line 15, in is_reverse + if word1[i] != word2[j]: +IndexError: string index out of range +\end{verbatim} +% +For debugging this kind of error, my first move is to +print the values of the indices immediately before the line +where the error appears. + +\begin{verbatim} + while j > 0: + print(i, j) # print here + + if word1[i] != word2[j]: + return False + i = i+1 + j = j-1 +\end{verbatim} +% +Now when I run the program again, I get more information: + +\begin{verbatim} +>>> is_reverse('pots', 'stop') +0 4 +... +IndexError: string index out of range +\end{verbatim} +% +The first time through the loop, the value of {\tt j} is 4, +which is out of range for the string \verb"'pots'". +The index of the last character is 3, so the +initial value for {\tt j} should be {\tt len(word2)-1}. + +If I fix that error and run the program again, I get: + +\begin{verbatim} +>>> is_reverse('pots', 'stop') +0 3 +1 2 +2 1 +True +\end{verbatim} +% +This time we get the right answer, but it looks like the loop only ran +three times, which is suspicious. To get a better idea of what is +happening, it is useful to draw a state diagram. During the first +iteration, the frame for \verb"is_reverse" is shown in +Figure~\ref{fig.state4}. \index{state diagram} \index{diagram!state} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/state4.pdf}} +\caption{State diagram.} +\label{fig.state4} +\end{figure} + +I took some license by arranging the variables in the frame +and adding dotted lines to show that the values of {\tt i} and +{\tt j} indicate characters in {\tt word1} and {\tt word2}. + +Starting with this diagram, run the program on paper, changing the +values of {\tt i} and {\tt j} during each iteration. Find and fix the +second error in this function. +\label{isreverse} + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[object:] Something a variable can refer to. For now, +you can use ``object'' and ``value'' interchangeably. +\index{object} + +\item[sequence:] An ordered collection of +values where each value is identified by an integer index. +\index{sequence} + +\item[item:] One of the values in a sequence. +\index{item} + +\item[index:] An integer value used to select an item in +a sequence, such as a character in a string. In Python +indices start from 0. +\index{index} + +\item[slice:] A part of a string specified by a range of indices. +\index{slice} + +\item[empty string:] A string with no characters and length 0, represented +by two quotation marks. +\index{empty string} + +\item[immutable:] The property of a sequence whose items cannot +be changed. +\index{immutability} + +\item[traverse:] To iterate through the items in a sequence, +performing a similar operation on each. +\index{traversal} + +\item[search:] A pattern of traversal that stops +when it finds what it is looking for. +\index{search pattern} +\index{pattern!search} + +\item[counter:] A variable used to count something, usually initialized +to zero and then incremented. +\index{counter} + +\item[invocation:] A statement that calls a method. +\index{invocation} + +\item[optional argument:] A function or method argument that is not +required. +\index{optional argument} +\index{argument!optional} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +\index{string method} +\index{method!string} + +Read the documentation of the string methods at +\url{http://docs.python.org/3/library/stdtypes.html#string-methods}. +You might want to experiment with some of them to make sure you +understand how they work. {\tt strip} and {\tt replace} are +particularly useful. + +The documentation uses a syntax that might be confusing. +For example, in \verb"find(sub[, start[, end]])", the brackets +indicate optional arguments. So {\tt sub} is required, but +{\tt start} is optional, and if you include {\tt start}, +then {\tt end} is optional. +\index{optional argument} +\index{argument!optional} + +\end{exercise} + + +\begin{exercise} +\index{count method} +\index{method!count} + +There is a string method called {\tt count} that is similar +to the function in Section~\ref{counter}. Read the documentation +of this method +and write an invocation that counts the number of {\tt a}'s +in \verb"'banana'". +\end{exercise} + + +\begin{exercise} +\index{step size} +\index{slice operator} +\index{operator!slice} + +A string slice can take a third index that specifies the ``step +size''; that is, the number of spaces between successive characters. +A step size of 2 means every other character; 3 means every third, +etc. + +\begin{verbatim} +>>> fruit = 'banana' +>>> fruit[0:5:2] +'bnn' +\end{verbatim} + +A step size of -1 goes through the word backwards, so +the slice \verb"[::-1]" generates a reversed string. +\index{palindrome} + +Use this idiom to write a one-line version of \verb"is_palindrome" +from Exercise~\ref{palindrome}. +\end{exercise} + + +\begin{exercise} + +The following functions are all {\em intended} to check whether a +string contains any lowercase letters, but at least some of them are +wrong. For each function, describe what the function actually does +(assuming that the parameter is a string). + +\begin{verbatim} +def any_lowercase1(s): + for c in s: + if c.islower(): + return True + else: + return False + +def any_lowercase2(s): + for c in s: + if 'c'.islower(): + return 'True' + else: + return 'False' + +def any_lowercase3(s): + for c in s: + flag = c.islower() + return flag + +def any_lowercase4(s): + flag = False + for c in s: + flag = flag or c.islower() + return flag + +def any_lowercase5(s): + for c in s: + if not c.islower(): + return False + return True +\end{verbatim} + +\end{exercise} + + +\begin{exercise} +\index{letter rotation} +\index{rotation, letter} + +\label{exrotate} +A Caesar cypher is a weak form of encryption that involves ``rotating'' each +letter by a fixed number of places. To rotate a letter means +to shift it through the alphabet, wrapping around to the beginning if +necessary, so 'A' rotated by 3 is 'D' and 'Z' rotated by 1 is 'A'. + +To rotate a word, rotate each letter by the same amount. +For example, ``cheer'' rotated by 7 is ``jolly'' and ``melon'' rotated +by -10 is ``cubed''. In the movie {\em 2001: A Space Odyssey}, the +ship computer is called HAL, which is IBM rotated by -1. + +%For example ``sleep'' +%rotated by 9 is ``bunny'' and ``latex'' rotated by 7 is ``shale''. + +Write a function called \verb"rotate_word" +that takes a string and an integer as parameters, and returns +a new string that contains the letters from the original string +rotated by the given amount. + +You might want to use the built-in function {\tt ord}, which converts +a character to a numeric code, and {\tt chr}, which converts numeric +codes to characters. Letters of the alphabet are encoded in alphabetical +order, so for example: + +\begin{verbatim} +>>> ord('c') - ord('a') +2 +\end{verbatim} + +Because \verb"'c'" is the two-eth letter of the alphabet. But +beware: the numeric codes for upper case letters are different. + +Potentially offensive jokes on the Internet are sometimes encoded in +ROT13, which is a Caesar cypher with rotation 13. If you are not +easily offended, find and decode some of them. Solution: +\url{http://thinkpython2.com/code/rotate.py}. + +\end{exercise} + + +\chapter{Case study: word play} +\label{wordplay} + +This chapter presents the second case study, which involves +solving word puzzles by searching for words that have certain +properties. For example, we'll find the longest palindromes +in English and search for words whose letters appear in +alphabetical order. And I will present another program development +plan: reduction to a previously solved problem. + + +\section{Reading word lists} +\label{wordlist} + +For the exercises in this chapter we need a list of English words. +There are lots of word lists available on the Web, but the one most +suitable for our purpose is one of the word lists collected and +contributed to the public domain by Grady Ward as part of the Moby +lexicon project (see \url{http://wikipedia.org/wiki/Moby_Project}). It +is a list of 113,809 official crosswords; that is, words that are +considered valid in crossword puzzles and other word games. In the +Moby collection, the filename is {\tt 113809of.fic}; you can download +a copy, with the simpler name {\tt words.txt}, from +\url{http://thinkpython2.com/code/words.txt}. +\index{Moby Project} +\index{crosswords} + +This file is in plain text, so you can open it with a text +editor, but you can also read it from Python. The built-in +function {\tt open} takes the name of the file as a parameter +and returns a {\bf file object} you can use to read the file. +\index{open function} +\index{function!open} +\index{plain text} +\index{text!plain} +\index{object!file} +\index{file object} + +\begin{verbatim} +>>> fin = open('words.txt') +\end{verbatim} +% +{\tt fin} is a common name for a file object used for input. The file +object provides several methods for reading, including {\tt readline}, +which reads characters from the file until it gets to a newline and +returns the result as a string: \index{readline method} +\index{method!readline} + +\begin{verbatim} +>>> fin.readline() +'aa\r\n' +\end{verbatim} +% +The first word in this particular list is ``aa'', which is a kind of +lava. The sequence \verb"\r\n" represents two whitespace characters, +a carriage return and a newline, that separate this word from the +next. + +The file object keeps track of where it is in the file, so +if you call {\tt readline} again, you get the next word: + +\begin{verbatim} +>>> fin.readline() +'aah\r\n' +\end{verbatim} +% +The next word is ``aah'', which is a perfectly legitimate +word, so stop looking at me like that. +Or, if it's the whitespace that's bothering you, +we can get rid of it with the string method {\tt strip}: +\index{strip method} +\index{method!strip} + +\begin{verbatim} +>>> line = fin.readline() +>>> word = line.strip() +>>> word +'aahed' +\end{verbatim} +% +You can also use a file object as part of a {\tt for} loop. +This program reads {\tt words.txt} and prints each word, one +per line: +\index{open function} +\index{function!open} + +\begin{verbatim} +fin = open('words.txt') +for line in fin: + word = line.strip() + print(word) +\end{verbatim} +% + +\section{연습 문제} +%Exercises + +There are solutions to these exercises in the next section. +You should at least attempt each one before you read the solutions. + +\begin{exercise} +Write a program that reads {\tt words.txt} and prints only the +words with more than 20 characters (not counting whitespace). +\index{whitespace} + +\end{exercise} + +\begin{exercise} + +In 1939 Ernest Vincent Wright published a 50,000 word novel called +{\em Gadsby} that does not contain the letter ``e''. Since ``e'' is +the most common letter in English, that's not easy to do. + +In fact, it is difficult to construct a solitary thought without using +that most common symbol. It is slow going at first, but with caution +and hours of training you can gradually gain facility. + +All right, I'll stop now. + +Write a function called \verb"has_no_e" that returns {\tt True} if +the given word doesn't have the letter ``e'' in it. + +Modify your program from the previous section to print only the words +that have no ``e'' and compute the percentage of the words in the list +that have no ``e''. +\index{lipogram} + +\end{exercise} + + +\begin{exercise} + +Write a function named {\tt avoids} +that takes a word and a string of forbidden letters, and +that returns {\tt True} if the word doesn't use any of the forbidden +letters. + +Modify your program to prompt the user to enter a string +of forbidden letters and then print the number of words that +don't contain any of them. +Can you find a combination of 5 forbidden letters that +excludes the smallest number of words? + +\end{exercise} + + + +\begin{exercise} + +Write a function named \verb"uses_only" that takes a word and a +string of letters, and that returns {\tt True} if the word contains +only letters in the list. Can you make a sentence using only the +letters {\tt acefhlo}? Other than ``Hoe alfalfa?'' + +\end{exercise} + + +\begin{exercise} + +Write a function named \verb"uses_all" that takes a word and a +string of required letters, and that returns {\tt True} if the word +uses all the required letters at least once. How many words are there +that use all the vowels {\tt aeiou}? How about {\tt aeiouy}? + +\end{exercise} + + +\begin{exercise} + +Write a function called \verb"is_abecedarian" that returns +{\tt True} if the letters in a word appear in alphabetical order +(double letters are ok). +How many abecedarian words are there? + +\index{abecedarian} + +\end{exercise} + + + +\section{Search} +\label{search} +\index{search pattern} +\index{pattern!search} + +All of the exercises in the previous section have something +in common; they can be solved with the search pattern we saw +in Section~\ref{find}. The simplest example is: + +\begin{verbatim} +def has_no_e(word): + for letter in word: + if letter == 'e': + return False + return True +\end{verbatim} +% +The {\tt for} loop traverses the characters in {\tt word}. If we find +the letter ``e'', we can immediately return {\tt False}; otherwise we +have to go to the next letter. If we exit the loop normally, that +means we didn't find an ``e'', so we return {\tt True}. +\index{traversal} + +\index{in operator} +\index{operator!in} +You could write this function more concisely using the {\tt in} +operator, but I started with this version because it +demonstrates the logic of the search pattern. + +\index{generalization} +{\tt avoids} is a more general version of \verb"has_no_e" but it +has the same structure: + +\begin{verbatim} +def avoids(word, forbidden): + for letter in word: + if letter in forbidden: + return False + return True +\end{verbatim} +% +We can return {\tt False} as soon as we find a forbidden letter; +if we get to the end of the loop, we return {\tt True}. + +\verb"uses_only" is similar except that the sense of the condition +is reversed: + +\begin{verbatim} +def uses_only(word, available): + for letter in word: + if letter not in available: + return False + return True +\end{verbatim} +% +Instead of a list of forbidden letters, we have a list of available +letters. If we find a letter in {\tt word} that is not in +{\tt available}, we can return {\tt False}. + +\verb"uses_all" is similar except that we reverse the role +of the word and the string of letters: + +\begin{verbatim} +def uses_all(word, required): + for letter in required: + if letter not in word: + return False + return True +\end{verbatim} +% +Instead of traversing the letters in {\tt word}, the loop +traverses the required letters. If any of the required letters +do not appear in the word, we can return {\tt False}. +\index{traversal} + +If you were really thinking like a computer scientist, you would +have recognized that \verb"uses_all" was an instance of a +previously solved problem, and you would have written: + +\begin{verbatim} +def uses_all(word, required): + return uses_only(required, word) +\end{verbatim} +% +This is an example of a program development plan called {\bf + reduction to a previously solved problem}, which means that you +recognize the problem you are working on as an instance of a solved +problem and apply an existing solution. \index{reduction to a + previously solved problem} \index{development plan!reduction} + + +\section{Looping with indices} +\index{looping!with indices} +\index{index!looping with} + +I wrote the functions in the previous section with {\tt for} +loops because I only needed the characters in the strings; I didn't +have to do anything with the indices. + +For \verb"is_abecedarian" we have to compare adjacent letters, +which is a little tricky with a {\tt for} loop: + +\begin{verbatim} +def is_abecedarian(word): + previous = word[0] + for c in word: + if c < previous: + return False + previous = c + return True +\end{verbatim} + +An alternative is to use recursion: + +\begin{verbatim} +def is_abecedarian(word): + if len(word) <= 1: + return True + if word[0] > word[1]: + return False + return is_abecedarian(word[1:]) +\end{verbatim} + +Another option is to use a {\tt while} loop: + +\begin{verbatim} +def is_abecedarian(word): + i = 0 + while i < len(word)-1: + if word[i+1] < word[i]: + return False + i = i+1 + return True +\end{verbatim} +% +The loop starts at {\tt i=0} and ends when {\tt i=len(word)-1}. Each +time through the loop, it compares the $i$th character (which you can +think of as the current character) to the $i+1$th character (which you +can think of as the next). + +If the next character is less than (alphabetically before) the current +one, then we have discovered a break in the abecedarian trend, and +we return {\tt False}. + +If we get to the end of the loop without finding a fault, then the +word passes the test. To convince yourself that the loop ends +correctly, consider an example like \verb"'flossy'". The +length of the word is 6, so +the last time the loop runs is when {\tt i} is 4, which is the +index of the second-to-last character. On the last iteration, +it compares the second-to-last character to the last, which is +what we want. +\index{palindrome} + +Here is a version of \verb"is_palindrome" (see +Exercise~\ref{palindrome}) that uses two indices; one starts at the +beginning and goes up; the other starts at the end and goes down. + +\begin{verbatim} +def is_palindrome(word): + i = 0 + j = len(word)-1 + + while i>> cheeses = ['Cheddar', 'Edam', 'Gouda'] +>>> numbers = [42, 123] +>>> empty = [] +>>> print(cheeses, numbers, empty) +['Cheddar', 'Edam', 'Gouda'] [42, 123] [] +\end{verbatim} +% +\index{assignment} + + +\section{Lists are mutable} +\label{mutable} +\index{list!element} +\index{access} +\index{index} +\index{bracket operator} +\index{operator!bracket} + +The syntax for accessing the elements of a list is the same as for +accessing the characters of a string---the bracket operator. The +expression inside the brackets specifies the index. Remember that the +indices start at 0: + +\begin{verbatim} +>>> cheeses[0] +'Cheddar' +\end{verbatim} +% +Unlike strings, lists are mutable. When the bracket operator appears +on the left side of an assignment, it identifies the element of the +list that will be assigned. +\index{mutability} + +\begin{verbatim} +>>> numbers = [42, 123] +>>> numbers[1] = 5 +>>> numbers +[42, 5] +\end{verbatim} +% +The one-eth element of {\tt numbers}, which +used to be 123, is now 5. +\index{index!starting at zero} +\index{zero, index starting at} + +Figure~\ref{fig.liststate} shows +the state diagram for {\tt +cheeses}, {\tt numbers} and {\tt empty}: +\index{state diagram} +\index{diagram!state} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/liststate.pdf}} +\caption{State diagram.} +\label{fig.liststate} +\end{figure} + +Lists are represented by boxes with the word ``list'' outside +and the elements of the list inside. {\tt cheeses} refers to +a list with three elements indexed 0, 1 and 2. +{\tt numbers} contains two elements; the diagram shows that the +value of the second element has been reassigned from 123 to 5. +{\tt empty} refers to a list with no elements. +\index{item assignment} +\index{assignment!item} +\index{reassignment} + +List indices work the same way as string indices: + +\begin{itemize} + +\item Any integer expression can be used as an index. + +\item If you try to read or write an element that does not exist, you +get an {\tt IndexError}. +\index{exception!IndexError} +\index{IndexError} + +\item If an index has a negative value, it counts backward from the +end of the list. + +\end{itemize} +\index{list!index} + +\index{list!membership} +\index{membership!list} +\index{in operator} +\index{operator!in} + +The {\tt in} operator also works on lists. + +\begin{verbatim} +>>> cheeses = ['Cheddar', 'Edam', 'Gouda'] +>>> 'Edam' in cheeses +True +>>> 'Brie' in cheeses +False +\end{verbatim} + + +\section{Traversing a list} +\index{list!traversal} +\index{traversal!list} +\index{for loop} +\index{loop!for} +\index{statement!for} + +The most common way to traverse the elements of a list is +with a {\tt for} loop. The syntax is the same as for strings: + +\begin{verbatim} +for cheese in cheeses: + print(cheese) +\end{verbatim} +% +This works well if you only need to read the elements of the +list. But if you want to write or update the elements, you +need the indices. A common way to do that is to combine +the built-in functions {\tt range} and {\tt len}: +\index{looping!with indices} +\index{index!looping with} + +\begin{verbatim} +for i in range(len(numbers)): + numbers[i] = numbers[i] * 2 +\end{verbatim} +% +This loop traverses the list and updates each element. {\tt len} +returns the number of elements in the list. {\tt range} returns +a list of indices from 0 to $n-1$, where $n$ is the length of +the list. Each time through the loop {\tt i} gets the index +of the next element. The assignment statement in the body uses +{\tt i} to read the old value of the element and to assign the +new value. +\index{item update} +\index{update!item} + +A {\tt for} loop over an empty list never runs the body: + +\begin{verbatim} +for x in []: + print('This never happens.') +\end{verbatim} +% +Although a list can contain another list, the nested +list still counts as a single element. The length of this list is +four: +\index{nested list} +\index{list!nested} + +\begin{verbatim} +['spam', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]] +\end{verbatim} + + + +\section{List operations} +\index{list!operation} + +The {\tt +} operator concatenates lists: +\index{concatenation!list} +\index{list!concatenation} + +\begin{verbatim} +>>> a = [1, 2, 3] +>>> b = [4, 5, 6] +>>> c = a + b +>>> c +[1, 2, 3, 4, 5, 6] +\end{verbatim} +% +The {\tt *} operator repeats a list a given number of times: +\index{repetition!list} +\index{list!repetition} + +\begin{verbatim} +>>> [0] * 4 +[0, 0, 0, 0] +>>> [1, 2, 3] * 3 +[1, 2, 3, 1, 2, 3, 1, 2, 3] +\end{verbatim} +% +The first example repeats {\tt [0]} four times. The second example +repeats the list {\tt [1, 2, 3]} three times. + + +\section{List slices} +\index{slice operator} +\index{operator!slice} +\index{index!slice} +\index{list!slice} +\index{slice!list} + +The slice operator also works on lists: + +\begin{verbatim} +>>> t = ['a', 'b', 'c', 'd', 'e', 'f'] +>>> t[1:3] +['b', 'c'] +>>> t[:4] +['a', 'b', 'c', 'd'] +>>> t[3:] +['d', 'e', 'f'] +\end{verbatim} +% +If you omit the first index, the slice starts at the beginning. +If you omit the second, the slice goes to the end. So if you +omit both, the slice is a copy of the whole list. +\index{list!copy} +\index{slice!copy} +\index{copy!slice} + +\begin{verbatim} +>>> t[:] +['a', 'b', 'c', 'd', 'e', 'f'] +\end{verbatim} +% +Since lists are mutable, it is often useful to make a copy +before performing operations that modify lists. +\index{mutability} + +A slice operator on the left side of an assignment +can update multiple elements: +\index{slice!update} +\index{update!slice} + +\begin{verbatim} +>>> t = ['a', 'b', 'c', 'd', 'e', 'f'] +>>> t[1:3] = ['x', 'y'] +>>> t +['a', 'x', 'y', 'd', 'e', 'f'] +\end{verbatim} +% + +% You can add elements to a list by squeezing them into an empty +% slice: + +% % \begin{verbatim} +% >>> t = ['a', 'd', 'e', 'f'] +% >>> t[1:1] = ['b', 'c'] +% >>> print t +% ['a', 'b', 'c', 'd', 'e', 'f'] +% \end{verbatim} +% \afterverb +% +% And you can remove elements from a list by assigning the empty list to +% them: + +% % \begin{verbatim} +% >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] +% >>> t[1:3] = [] +% >>> print t +% ['a', 'd', 'e', 'f'] +% \end{verbatim} +% \afterverb +% +% But both of those operations can be expressed more clearly +% with list methods. + + +\section{List methods} +\index{list!method} +\index{method, list} + +Python provides methods that operate on lists. For example, +{\tt append} adds a new element to the end of a list: +\index{append method} +\index{method!append} + +\begin{verbatim} +>>> t = ['a', 'b', 'c'] +>>> t.append('d') +>>> t +['a', 'b', 'c', 'd'] +\end{verbatim} +% +{\tt extend} takes a list as an argument and appends all of +the elements: +\index{extend method} +\index{method!extend} + +\begin{verbatim} +>>> t1 = ['a', 'b', 'c'] +>>> t2 = ['d', 'e'] +>>> t1.extend(t2) +>>> t1 +['a', 'b', 'c', 'd', 'e'] +\end{verbatim} +% +This example leaves {\tt t2} unmodified. + +{\tt sort} arranges the elements of the list from low to high: +\index{sort method} +\index{method!sort} + +\begin{verbatim} +>>> t = ['d', 'c', 'e', 'b', 'a'] +>>> t.sort() +>>> t +['a', 'b', 'c', 'd', 'e'] +\end{verbatim} +% +Most list methods are void; they modify the list and return {\tt None}. +If you accidentally write {\tt t = t.sort()}, you will be disappointed +with the result. +\index{void method} +\index{method!void} +\index{None special value} +\index{special value!None} + + +\section{Map, filter and reduce} +\label{filter} + +To add up all the numbers in a list, you can use a loop like this: + +% see add.py + +\begin{verbatim} +def add_all(t): + total = 0 + for x in t: + total += x + return total +\end{verbatim} +% +{\tt total} is initialized to 0. Each time through the loop, +{\tt x} gets one element from the list. The {\tt +=} operator +provides a short way to update a variable. This +{\bf augmented assignment statement}, +\index{update operator} +\index{operator!update} +\index{assignment!augmented} +\index{augmented assignment} + +\begin{verbatim} + total += x +\end{verbatim} +% +is equivalent to + +\begin{verbatim} + total = total + x +\end{verbatim} +% +As the loop runs, {\tt total} accumulates the sum of the +elements; a variable used this way is sometimes called an +{\bf accumulator}. +\index{accumulator!sum} + +Adding up the elements of a list is such a common operation +that Python provides it as a built-in function, {\tt sum}: + +\begin{verbatim} +>>> t = [1, 2, 3] +>>> sum(t) +6 +\end{verbatim} +% +An operation like this that combines a sequence of elements into +a single value is sometimes called {\bf reduce}. +\index{reduce pattern} +\index{pattern!reduce} +\index{traversal} + +Sometimes you want to traverse one list while building +another. For example, the following function takes a list of strings +and returns a new list that contains capitalized strings: + +\begin{verbatim} +def capitalize_all(t): + res = [] + for s in t: + res.append(s.capitalize()) + return res +\end{verbatim} +% +{\tt res} is initialized with an empty list; each time through +the loop, we append the next element. So {\tt res} is another +kind of accumulator. +\index{accumulator!list} + +An operation like \verb"capitalize_all" is sometimes called a {\bf +map} because it ``maps'' a function (in this case the method {\tt +capitalize}) onto each of the elements in a sequence. +\index{map pattern} +\index{pattern!map} +\index{filter pattern} +\index{pattern!filter} + +Another common operation is to select some of the elements from +a list and return a sublist. For example, the following +function takes a list of strings and returns a list that contains +only the uppercase strings: + +\begin{verbatim} +def only_upper(t): + res = [] + for s in t: + if s.isupper(): + res.append(s) + return res +\end{verbatim} +% +{\tt isupper} is a string method that returns {\tt True} if +the string contains only upper case letters. + +An operation like \verb"only_upper" is called a {\bf filter} because +it selects some of the elements and filters out the others. + +Most common list operations can be expressed as a combination +of map, filter and reduce. + + +\section{Deleting elements} +\index{element deletion} +\index{deletion, element of list} + +There are several ways to delete elements from a list. If you +know the index of the element you want, you can use +{\tt pop}: +\index{pop method} +\index{method!pop} + +\begin{verbatim} +>>> t = ['a', 'b', 'c'] +>>> x = t.pop(1) +>>> t +['a', 'c'] +>>> x +'b' +\end{verbatim} +% +{\tt pop} modifies the list and returns the element that was removed. +If you don't provide an index, it deletes and returns the +last element. + +If you don't need the removed value, you can use the {\tt del} +operator: +\index{del operator} +\index{operator!del} + +\begin{verbatim} +>>> t = ['a', 'b', 'c'] +>>> del t[1] +>>> t +['a', 'c'] +\end{verbatim} +% +If you know the element you want to remove (but not the index), you +can use {\tt remove}: +\index{remove method} +\index{method!remove} + +\begin{verbatim} +>>> t = ['a', 'b', 'c'] +>>> t.remove('b') +>>> t +['a', 'c'] +\end{verbatim} +% +The return value from {\tt remove} is {\tt None}. +\index{None special value} +\index{special value!None} + +To remove more than one element, you can use {\tt del} with +a slice index: + +\begin{verbatim} +>>> t = ['a', 'b', 'c', 'd', 'e', 'f'] +>>> del t[1:5] +>>> t +['a', 'f'] +\end{verbatim} +% +As usual, the slice selects all the elements up to but not +including the second index. + + + +\section{Lists and strings} +\index{list} +\index{string} +\index{sequence} + +A string is a sequence of characters and a list is a sequence +of values, but a list of characters is not the same as a +string. To convert from a string to a list of characters, +you can use {\tt list}: +\index{list!function} +\index{function!list} + +\begin{verbatim} +>>> s = 'spam' +>>> t = list(s) +>>> t +['s', 'p', 'a', 'm'] +\end{verbatim} +% +Because {\tt list} is the name of a built-in function, you should +avoid using it as a variable name. I also avoid {\tt l} because +it looks too much like {\tt 1}. So that's why I use {\tt t}. + +The {\tt list} function breaks a string into individual letters. If +you want to break a string into words, you can use the {\tt split} +method: +\index{split method} +\index{method!split} + +\begin{verbatim} +>>> s = 'pining for the fjords' +>>> t = s.split() +>>> t +['pining', 'for', 'the', 'fjords'] +\end{verbatim} +% +An optional argument called a {\bf delimiter} specifies which +characters to use as word boundaries. +The following example +uses a hyphen as a delimiter: +\index{optional argument} +\index{argument!optional} +\index{delimiter} + +\begin{verbatim} +>>> s = 'spam-spam-spam' +>>> delimiter = '-' +>>> t = s.split(delimiter) +>>> t +['spam', 'spam', 'spam'] +\end{verbatim} +% +{\tt join} is the inverse of {\tt split}. It +takes a list of strings and +concatenates the elements. {\tt join} is a string method, +so you have to invoke it on the delimiter and pass the +list as a parameter: +\index{join method} +\index{method!join} +\index{concatenation} + +\begin{verbatim} +>>> t = ['pining', 'for', 'the', 'fjords'] +>>> delimiter = ' ' +>>> s = delimiter.join(t) +>>> s +'pining for the fjords' +\end{verbatim} +% +In this case the delimiter is a space character, so +{\tt join} puts a space between words. To concatenate +strings without spaces, you can use the empty string, +\verb"''", as a delimiter. +\index{empty string} +\index{string!empty} + + +\section{Objects and values} +\label{equivalence} +\index{object} +\index{value} + +If we run these assignment statements: + +\begin{verbatim} +a = 'banana' +b = 'banana' +\end{verbatim} +% +We know that {\tt a} and {\tt b} both refer to a +string, but we don't +know whether they refer to the {\em same} string. +There are two possible states, shown in Figure~\ref{fig.list1}. +\index{aliasing} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/list1.pdf}} +\caption{State diagram.} +\label{fig.list1} +\end{figure} + +In one case, {\tt a} and {\tt b} refer to two different objects that +have the same value. In the second case, they refer to the same +object. +\index{is operator} +\index{operator!is} + +To check whether two variables refer to the same object, you can +use the {\tt is} operator. + +\begin{verbatim} +>>> a = 'banana' +>>> b = 'banana' +>>> a is b +True +\end{verbatim} +% +In this example, Python only created one string object, and both {\tt + a} and {\tt b} refer to it. But when you create two lists, you get +two objects: + +\begin{verbatim} +>>> a = [1, 2, 3] +>>> b = [1, 2, 3] +>>> a is b +False +\end{verbatim} +% +So the state diagram looks like Figure~\ref{fig.list2}. +\index{state diagram} +\index{diagram!state} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/list2.pdf}} +\caption{State diagram.} +\label{fig.list2} +\end{figure} + +In this case we would say that the two lists are {\bf equivalent}, +because they have the same elements, but not {\bf identical}, because +they are not the same object. If two objects are identical, they are +also equivalent, but if they are equivalent, they are not necessarily +identical. +\index{equivalence} +\index{identity} + +Until now, we have been using ``object'' and ``value'' +interchangeably, but it is more precise to say that an object has a +value. If you evaluate {\tt [1, 2, 3]}, you get a list +object whose value is a sequence of integers. If another +list has the same elements, we say it has the same value, but +it is not the same object. +\index{object} +\index{value} + + +\section{Aliasing} +\index{aliasing} +\index{reference!aliasing} + +If {\tt a} refers to an object and you assign {\tt b = a}, +then both variables refer to the same object: + +\begin{verbatim} +>>> a = [1, 2, 3] +>>> b = a +>>> b is a +True +\end{verbatim} +% +The state diagram looks like Figure~\ref{fig.list3}. +\index{state diagram} +\index{diagram!state} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/list3.pdf}} +\caption{State diagram.} +\label{fig.list3} +\end{figure} + +The association of a variable with an object is called a {\bf +reference}. In this example, there are two references to the same +object. +\index{reference} + +An object with more than one reference has more +than one name, so we say that the object is {\bf aliased}. +\index{mutability} + +If the aliased object is mutable, changes made with one alias affect +the other: + +\begin{verbatim} +>>> b[0] = 42 +>>> a +[42, 2, 3] +\end{verbatim} +% +Although this behavior can be useful, it is error-prone. In general, +it is safer to avoid aliasing when you are working with mutable +objects. +\index{immutability} + +For immutable objects like strings, aliasing is not as much of a +problem. In this example: + +\begin{verbatim} +a = 'banana' +b = 'banana' +\end{verbatim} +% +It almost never makes a difference whether {\tt a} and {\tt b} refer +to the same string or not. + + +\section{List arguments} +\label{list.arguments} +\index{list!as argument} +\index{argument} +\index{argument!list} +\index{reference} +\index{parameter} + +When you pass a list to a function, the function gets a reference to +the list. If the function modifies the list, the caller sees +the change. For example, \verb"delete_head" removes the first element +from a list: + +\begin{verbatim} +def delete_head(t): + del t[0] +\end{verbatim} +% +Here's how it is used: + +\begin{verbatim} +>>> letters = ['a', 'b', 'c'] +>>> delete_head(letters) +>>> letters +['b', 'c'] +\end{verbatim} +% +The parameter {\tt t} and the variable {\tt letters} are +aliases for the same object. The stack diagram looks like +Figure~\ref{fig.stack5}. +\index{stack diagram} +\index{diagram!stack} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/stack5.pdf}} +\caption{Stack diagram.} +\label{fig.stack5} +\end{figure} + +Since the list is shared by two frames, I drew +it between them. + +It is important to distinguish between operations that +modify lists and operations that create new lists. For +example, the {\tt append} method modifies a list, but the +{\tt +} operator creates a new list. +\index{append method} +\index{method!append} +\index{list!concatenation} +\index{concatenation!list} + +Here's an example using {\tt append}: +% +\begin{verbatim} +>>> t1 = [1, 2] +>>> t2 = t1.append(3) +>>> t1 +[1, 2, 3] +>>> t2 +None +\end{verbatim} +% +The return value from {\tt append} is {\tt None}. + +Here's an example using the {\tt +} operator: +% +\begin{verbatim} +>>> t3 = t1 + [4] +>>> t1 +[1, 2, 3] +>>> t3 +[1, 2, 3, 4] +\end{verbatim} +% +The result of the operator is a new list, and the original list is +unchanged. + +This difference is important when you write functions that +are supposed to modify lists. For example, this function +{\em does not} delete the head of a list: +% +\begin{verbatim} +def bad_delete_head(t): + t = t[1:] # WRONG! +\end{verbatim} +% +The slice operator creates a new list and the assignment +makes {\tt t} refer to it, but that doesn't affect the caller. +\index{slice operator} +\index{operator!slice} +% +\begin{verbatim} +>>> t4 = [1, 2, 3] +>>> bad_delete_head(t4) +>>> t4 +[1, 2, 3] +\end{verbatim} +% +At the beginning of \verb"bad_delete_head", {\tt t} and {\tt t4} +refer to the same list. At the end, {\tt t} refers to a new list, +but {\tt t4} still refers to the original, unmodified list. + +An alternative is to write a function that creates and +returns a new list. For +example, {\tt tail} returns all but the first +element of a list: + +\begin{verbatim} +def tail(t): + return t[1:] +\end{verbatim} +% +This function leaves the original list unmodified. +Here's how it is used: + +\begin{verbatim} +>>> letters = ['a', 'b', 'c'] +>>> rest = tail(letters) +>>> rest +['b', 'c'] +\end{verbatim} + + + +\section{Debugging} +\index{debugging} + +Careless use of lists (and other mutable objects) +can lead to long hours of debugging. Here are some common +pitfalls and ways to avoid them: + +\begin{enumerate} + +\item Most list methods modify the argument and + return {\tt None}. This is the opposite of the string methods, + which return a new string and leave the original alone. + +If you are used to writing string code like this: + +\begin{verbatim} +word = word.strip() +\end{verbatim} + +It is tempting to write list code like this: + +\begin{verbatim} +t = t.sort() # WRONG! +\end{verbatim} +\index{sort method} +\index{method!sort} + +Because {\tt sort} returns {\tt None}, the +next operation you perform with {\tt t} is likely to fail. + +Before using list methods and operators, you should read the +documentation carefully and then test them in interactive mode. + +\item Pick an idiom and stick with it. + +Part of the problem with lists is that there are too many +ways to do things. For example, to remove an element from +a list, you can use {\tt pop}, {\tt remove}, {\tt del}, +or even a slice assignment. + +To add an element, you can use the {\tt append} method or +the {\tt +} operator. Assuming that {\tt t} is a list and +{\tt x} is a list element, these are correct: + +\begin{verbatim} +t.append(x) +t = t + [x] +t += [x] +\end{verbatim} + +And these are wrong: + +\begin{verbatim} +t.append([x]) # WRONG! +t = t.append(x) # WRONG! +t + [x] # WRONG! +t = t + x # WRONG! +\end{verbatim} + +Try out each of these examples in interactive mode to make sure +you understand what they do. Notice that only the last +one causes a runtime error; the other three are legal, but they +do the wrong thing. + + +\item Make copies to avoid aliasing. +\index{aliasing!copying to avoid} +\index{copy!to avoid aliasing} + +If you want to use a method like {\tt sort} that modifies +the argument, but you need to keep the original list as +well, you can make a copy. + +\begin{verbatim} +>>> t = [3, 1, 2] +>>> t2 = t[:] +>>> t2.sort() +>>> t +[3, 1, 2] +>>> t2 +[1, 2, 3] +\end{verbatim} + +In this example you could also use the built-in function {\tt sorted}, +which returns a new, sorted list and leaves the original alone. +\index{sorted!function} +\index{function!sorted} + +\begin{verbatim} +>>> t2 = sorted(t) +>>> t +[3, 1, 2] +>>> t2 +[1, 2, 3] +\end{verbatim} + +\end{enumerate} + + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[list:] A sequence of values. +\index{list} + +\item[element:] One of the values in a list (or other sequence), +also called items. +\index{element} + +\item[nested list:] A list that is an element of another list. +\index{nested list} + +\item[accumulator:] A variable used in a loop to add up or +accumulate a result. +\index{accumulator} + +\item[augmented assignment:] A statement that updates the value +of a variable using an operator like \verb"+=". +\index{assignment!augmented} +\index{augmented assignment} +\index{traversal} + +\item[reduce:] A processing pattern that traverses a sequence +and accumulates the elements into a single result. +\index{reduce pattern} +\index{pattern!reduce} + +\item[map:] A processing pattern that traverses a sequence and +performs an operation on each element. +\index{map pattern} +\index{pattern!map} + +\item[filter:] A processing pattern that traverses a list and +selects the elements that satisfy some criterion. +\index{filter pattern} +\index{pattern!filter} + +\item[object:] Something a variable can refer to. An object +has a type and a value. +\index{object} + +\item[equivalent:] Having the same value. +\index{equivalent} + +\item[identical:] Being the same object (which implies equivalence). +\index{identical} + +\item[reference:] The association between a variable and its value. +\index{reference} + +\item[aliasing:] A circumstance where two or more variables refer to the same +object. +\index{aliasing} + +\item[delimiter:] A character or string used to indicate where a +string should be split. +\index{delimiter} + +\end{description} + + +\section{연습 문제} +%Exercises + +You can download solutions to these exercises from +\url{http://thinkpython2.com/code/list_exercises.py}. + +\begin{exercise} + +Write a function called \verb"nested_sum" that takes a list of lists +of integers and adds up the elements from all of the nested lists. +For example: + +\begin{verbatim} +>>> t = [[1, 2], [3], [4, 5, 6]] +>>> nested_sum(t) +21 +\end{verbatim} + +\end{exercise} + +\begin{exercise} +\label{cumulative} +\index{cumulative sum} + +Write a function called {\tt cumsum} that takes a list of numbers and +returns the cumulative sum; that is, a new list where the $i$th +element is the sum of the first $i+1$ elements from the original list. +For example: + +\begin{verbatim} +>>> t = [1, 2, 3] +>>> cumsum(t) +[1, 3, 6] +\end{verbatim} + +\end{exercise} + +\begin{exercise} + +Write a function called \verb"middle" that takes a list and +returns a new list that contains all but the first and last +elements. For example: + +\begin{verbatim} +>>> t = [1, 2, 3, 4] +>>> middle(t) +[2, 3] +\end{verbatim} + +\end{exercise} + +\begin{exercise} + +Write a function called \verb"chop" that takes a list, modifies it +by removing the first and last elements, and returns {\tt None}. +For example: + +\begin{verbatim} +>>> t = [1, 2, 3, 4] +>>> chop(t) +>>> t +[2, 3] +\end{verbatim} + +\end{exercise} + + +\begin{exercise} +Write a function called \verb"is_sorted" that takes a list as a +parameter and returns {\tt True} if the list is sorted in ascending +order and {\tt False} otherwise. For example: + +\begin{verbatim} +>>> is_sorted([1, 2, 2]) +True +>>> is_sorted(['b', 'a']) +False +\end{verbatim} + +\end{exercise} + + +\begin{exercise} +\label{anagram} +\index{anagram} + +Two words are anagrams if you can rearrange the letters from one +to spell the other. Write a function called \verb"is_anagram" +that takes two strings and returns {\tt True} if they are anagrams. +\end{exercise} + + + +\begin{exercise} +\label{duplicate} +\index{duplicate} +\index{uniqueness} + +Write a function called \verb"has_duplicates" that takes +a list and returns {\tt True} if there is any element that +appears more than once. It should not modify the original +list. + +\end{exercise} + + +\begin{exercise} + +This exercise pertains to the so-called Birthday Paradox, which you +can read about at \url{http://en.wikipedia.org/wiki/Birthday_paradox}. +\index{birthday paradox} + +If there are 23 students in your class, what are the chances +that two of you have the same birthday? You can estimate this +probability by generating random samples of 23 birthdays +and checking for matches. Hint: you can generate random birthdays +with the {\tt randint} function in the {\tt random} module. +\index{random module} +\index{module!random} +\index{randint function} +\index{function!randint} + +You can download my +solution from \url{http://thinkpython2.com/code/birthday.py}. + +\end{exercise} + + + +\begin{exercise} +\index{append method} +\index{method append} +\index{list!concatenation} +\index{concatenation!list} + +Write a function that reads the file {\tt words.txt} and builds +a list with one element per word. Write two versions of +this function, one using the {\tt append} method and the +other using the idiom {\tt t = t + [x]}. Which one takes +longer to run? Why? + +Solution: \url{http://thinkpython2.com/code/wordlist.py}. +\index{time module} +\index{module!time} + +\end{exercise} + + +\begin{exercise} +\label{wordlist1} +\label{bisection} +\index{membership!bisection search} +\index{bisection search} +\index{search, bisection} +\index{membership!binary search} +\index{binary search} +\index{search, binary} + +To check whether a word is in the word list, you could use +the {\tt in} operator, but it would be slow because it searches +through the words in order. + +Because the words are in alphabetical order, we can speed things up +with a bisection search (also known as binary search), which is +similar to what you do when you look a word up in the dictionary. You +start in the middle and check to see whether the word you are looking +for comes before the word in the middle of the list. If so, you +search the first half of the list the same way. Otherwise you search +the second half. + +Either way, you cut the remaining search space in half. If the +word list has 113,809 words, it will take about 17 steps to +find the word or conclude that it's not there. + +Write a function called \verb"in_bisect" that takes a sorted list +and a target value and returns the index of the value +in the list if it's there, or {\tt None} if it's not. +\index{bisect module} +\index{module!bisect} + +Or you could read the documentation of the {\tt bisect} module +and use that! Solution: \url{http://thinkpython2.com/code/inlist.py}. + +\end{exercise} + +\begin{exercise} +\index{reverse word pair} + +Two words are a ``reverse pair'' if each is the reverse of the +other. Write a program that finds all the reverse pairs in the +word list. Solution: \url{http://thinkpython2.com/code/reverse_pair.py}. + +\end{exercise} + +\begin{exercise} +\index{interlocking words} + +Two words ``interlock'' if taking alternating letters from each forms +a new word. For example, ``shoe'' and ``cold'' +interlock to form ``schooled''. +Solution: \url{http://thinkpython2.com/code/interlock.py}. +Credit: This exercise is inspired by an example at \url{http://puzzlers.org}. + +\begin{enumerate} + +\item Write a program that finds all pairs of words that interlock. + Hint: don't enumerate all pairs! + +\item Can you find any words that are three-way interlocked; that is, + every third letter forms a word, starting from the first, second or + third? + +\end{enumerate} +\end{exercise} + + +\chapter{Dictionaries} + +This chapter presents another built-in type called a dictionary. +Dictionaries are one of Python's best features; they are the +building blocks of many efficient and elegant algorithms. + + +\section{A dictionary is a mapping} + +\index{dictionary} +\index{dictionary} +\index{type!dict} +\index{key} +\index{key-value pair} +\index{index} +A {\bf dictionary} is like a list, but more general. In a list, +the indices have to be integers; in a dictionary they can +be (almost) any type. + +A dictionary contains a collection of indices, which are called {\bf + keys}, and a collection of values. Each key is associated with a +single value. The association of a key and a value is called a {\bf + key-value pair} or sometimes an {\bf item}. \index{item} + +In mathematical language, a dictionary represents a {\bf mapping} +from keys to values, so you can also say that each key +``maps to'' a value. +As an example, we'll build a dictionary that maps from English +to Spanish words, so the keys and the values are all strings. + +The function {\tt dict} creates a new dictionary with no items. +Because {\tt dict} is the name of a built-in function, you +should avoid using it as a variable name. +\index{dict function} +\index{function!dict} + +\begin{verbatim} +>>> eng2sp = dict() +>>> eng2sp +{} +\end{verbatim} + +The squiggly-brackets, \verb"{}", represent an empty dictionary. +To add items to the dictionary, you can use square brackets: +\index{squiggly bracket} +\index{bracket!squiggly} + +\begin{verbatim} +>>> eng2sp['one'] = 'uno' +\end{verbatim} +% +This line creates an item that maps from the key +\verb"'one'" to the value \verb"'uno'". If we print the +dictionary again, we see a key-value pair with a colon +between the key and value: + +\begin{verbatim} +>>> eng2sp +{'one': 'uno'} +\end{verbatim} +% +This output format is also an input format. For example, +you can create a new dictionary with three items: + +\begin{verbatim} +>>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'} +\end{verbatim} +% +But if you print {\tt eng2sp}, you might be surprised: + +\begin{verbatim} +>>> eng2sp +{'one': 'uno', 'three': 'tres', 'two': 'dos'} +\end{verbatim} +% +The order of the key-value pairs might not be the same. If +you type the same example on your computer, you might get a +different result. In general, the order of items in +a dictionary is unpredictable. + +But that's not a problem because +the elements of a dictionary are never indexed with integer indices. +Instead, you use the keys to look up the corresponding values: + +\begin{verbatim} +>>> eng2sp['two'] +'dos' +\end{verbatim} +% +The key \verb"'two'" always maps to the value \verb"'dos'" so the order +of the items doesn't matter. + +If the key isn't in the dictionary, you get an exception: +\index{exception!KeyError} +\index{KeyError} + +\begin{verbatim} +>>> eng2sp['four'] +KeyError: 'four' +\end{verbatim} +% +The {\tt len} function works on dictionaries; it returns the +number of key-value pairs: +\index{len function} +\index{function!len} + +\begin{verbatim} +>>> len(eng2sp) +3 +\end{verbatim} +% +The {\tt in} operator works on dictionaries, too; it tells you whether +something appears as a {\em key} in the dictionary (appearing +as a value is not good enough). +\index{membership!dictionary} +\index{in operator} +\index{operator!in} + +\begin{verbatim} +>>> 'one' in eng2sp +True +>>> 'uno' in eng2sp +False +\end{verbatim} +% +To see whether something appears as a value in a dictionary, you +can use the method {\tt values}, which returns a collection of +values, and then use the {\tt in} operator: +\index{values method} +\index{method!values} + +\begin{verbatim} +>>> vals = eng2sp.values() +>>> 'uno' in vals +True +\end{verbatim} +% +The {\tt in} operator uses different algorithms for lists and +dictionaries. For lists, it searches the elements of the list in +order, as in Section~\ref{find}. As the list gets longer, the search +time gets longer in direct proportion. + +For dictionaries, Python uses an +algorithm called a {\bf hashtable} that has a remarkable property: the +{\tt in} operator takes about the same amount of time no matter how +many items are in the dictionary. I explain how that's possible +in Section~\ref{hashtable}, but the explanation might not make +sense until you've read a few more chapters. + + +\section{Dictionary as a collection of counters} +\label{histogram} +\index{counter} + +Suppose you are given a string and you want to count how many +times each letter appears. There are several ways you could do it: + +\begin{enumerate} + +\item You could create 26 variables, one for each letter of the +alphabet. Then you could traverse the string and, for each +character, increment the corresponding counter, probably using +a chained conditional. + +\item You could create a list with 26 elements. Then you could +convert each character to a number (using the built-in function +{\tt ord}), use the number as an index into the list, and increment +the appropriate counter. + +\item You could create a dictionary with characters as keys +and counters as the corresponding values. The first time you +see a character, you would add an item to the dictionary. After +that you would increment the value of an existing item. + +\end{enumerate} + +Each of these options performs the same computation, but each +of them implements that computation in a different way. +\index{implementation} + +An {\bf implementation} is a way of performing a computation; +some implementations are better than others. For example, +an advantage of the dictionary implementation is that we don't +have to know ahead of time which letters appear in the string +and we only have to make room for the letters that do appear. + +Here is what the code might look like: + +\begin{verbatim} +def histogram(s): + d = dict() + for c in s: + if c not in d: + d[c] = 1 + else: + d[c] += 1 + return d +\end{verbatim} +% +The name of the function is {\tt histogram}, which is a statistical +term for a collection of counters (or frequencies). +\index{histogram} +\index{frequency} +\index{traversal} + +The first line of the +function creates an empty dictionary. The {\tt for} loop traverses +the string. Each time through the loop, if the character {\tt c} is +not in the dictionary, we create a new item with key {\tt c} and the +initial value 1 (since we have seen this letter once). If {\tt c} is +already in the dictionary we increment {\tt d[c]}. +\index{histogram} + +Here's how it works: + +\begin{verbatim} +>>> h = histogram('brontosaurus') +>>> h +{'a': 1, 'b': 1, 'o': 2, 'n': 1, 's': 2, 'r': 2, 'u': 2, 't': 1} +\end{verbatim} +% +The histogram indicates that the letters \verb"'a'" and \verb"'b'" +appear once; \verb"'o'" appears twice, and so on. + + +\index{get method} +\index{method!get} +Dictionaries have a method called {\tt get} that takes a key +and a default value. If the key appears in the dictionary, +{\tt get} returns the corresponding value; otherwise it returns +the default value. For example: + +\begin{verbatim} +>>> h = histogram('a') +>>> h +{'a': 1} +>>> h.get('a', 0) +1 +>>> h.get('b', 0) +0 +\end{verbatim} +% +As an exercise, use {\tt get} to write {\tt histogram} more concisely. You +should be able to eliminate the {\tt if} statement. + + +\section{Looping and dictionaries} +\index{dictionary!looping with} +\index{looping!with dictionaries} +\index{traversal} + +If you use a dictionary in a {\tt for} statement, it traverses +the keys of the dictionary. For example, \verb"print_hist" +prints each key and the corresponding value: + +\begin{verbatim} +def print_hist(h): + for c in h: + print(c, h[c]) +\end{verbatim} +% +Here's what the output looks like: + +\begin{verbatim} +>>> h = histogram('parrot') +>>> print_hist(h) +a 1 +p 1 +r 2 +t 1 +o 1 +\end{verbatim} +% +Again, the keys are in no particular order. To traverse the keys +in sorted order, you can use the built-in function {\tt sorted}: +\index{sorted!function} +\index{function!sorted} + +\begin{verbatim} +>>> for key in sorted(h): +... print(key, h[key]) +a 1 +o 1 +p 1 +r 2 +t 1 +\end{verbatim} + +%TODO: get this on Atlas + + +\section{Reverse lookup} +\label{raise} +\index{dictionary!lookup} +\index{dictionary!reverse lookup} +\index{lookup, dictionary} +\index{reverse lookup, dictionary} + +Given a dictionary {\tt d} and a key {\tt k}, it is easy to +find the corresponding value {\tt v = d[k]}. This operation +is called a {\bf lookup}. + +But what if you have {\tt v} and you want to find {\tt k}? +You have two problems: first, there might be more than one +key that maps to the value {\tt v}. Depending on the application, +you might be able to pick one, or you might have to make +a list that contains all of them. Second, there is no +simple syntax to do a {\bf reverse lookup}; you have to search. + +Here is a function that takes a value and returns the first +key that maps to that value: + +\begin{verbatim} +def reverse_lookup(d, v): + for k in d: + if d[k] == v: + return k + raise LookupError() +\end{verbatim} +% +This function is yet another example of the search pattern, but it +uses a feature we haven't seen before, {\tt raise}. The +{\bf raise statement} causes an exception; in this case it causes a +{\tt LookupError}, which is a built-in exception used to indicate +that a lookup operation failed. +\index{search} +\index{pattern!search} \index{raise statement} \index{statement!raise} +\index{exception!LookupError} \index{LookupError} + +If we get to the end of the loop, that means {\tt v} +doesn't appear in the dictionary as a value, so we raise an +exception. + +Here is an example of a successful reverse lookup: + +\begin{verbatim} +>>> h = histogram('parrot') +>>> key = reverse_lookup(h, 2) +>>> key +'r' +\end{verbatim} +% +And an unsuccessful one: + +\begin{verbatim} +>>> key = reverse_lookup(h, 3) +Traceback (most recent call last): + File "", line 1, in + File "", line 5, in reverse_lookup +LookupError +\end{verbatim} +% +The effect when you raise an exception is the same as when +Python raises one: it prints a traceback and an error message. +\index{traceback} +\index{optional argument} +\index{argument!optional} + +The {\tt raise} statement can take a detailed error message as an +optional argument. For example: + +\begin{verbatim} +>>> raise LookupError('value does not appear in the dictionary') +Traceback (most recent call last): + File "", line 1, in ? +LookupError: value does not appear in the dictionary +\end{verbatim} +% +A reverse lookup is much slower than a forward lookup; if you +have to do it often, or if the dictionary gets big, the performance +of your program will suffer. + + +\section{Dictionaries and lists} +\label{invert} + +Lists can appear as values in a dictionary. For example, if you +are given a dictionary that maps from letters to frequencies, you +might want to invert it; that is, create a dictionary that maps +from frequencies to letters. Since there might be several letters +with the same frequency, each value in the inverted dictionary +should be a list of letters. +\index{invert dictionary} +\index{dictionary!invert} + +Here is a function that inverts a dictionary: + +\begin{verbatim} +def invert_dict(d): + inverse = dict() + for key in d: + val = d[key] + if val not in inverse: + inverse[val] = [key] + else: + inverse[val].append(key) + return inverse +\end{verbatim} +% +Each time through the loop, {\tt key} gets a key from {\tt d} and +{\tt val} gets the corresponding value. If {\tt val} is not in {\tt + inverse}, that means we haven't seen it before, so we create a new +item and initialize it with a {\bf singleton} (a list that contains a +single element). Otherwise we have seen this value before, so we +append the corresponding key to the list. \index{singleton} + +Here is an example: + +\begin{verbatim} +>>> hist = histogram('parrot') +>>> hist +{'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1} +>>> inverse = invert_dict(hist) +>>> inverse +{1: ['a', 'p', 't', 'o'], 2: ['r']} +\end{verbatim} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/dict1.pdf}} +\caption{State diagram.} +\label{fig.dict1} +\end{figure} + +Figure~\ref{fig.dict1} is a state diagram showing {\tt hist} and {\tt inverse}. +A dictionary is represented as a box with the type {\tt dict} above it +and the key-value pairs inside. If the values are integers, floats or +strings, I draw them inside the box, but I usually draw lists +outside the box, just to keep the diagram simple. +\index{state diagram} +\index{diagram!state} + +Lists can be values in a dictionary, as this example shows, but they +cannot be keys. Here's what happens if you try: +\index{TypeError} +\index{exception!TypeError} + + +\begin{verbatim} +>>> t = [1, 2, 3] +>>> d = dict() +>>> d[t] = 'oops' +Traceback (most recent call last): + File "", line 1, in ? +TypeError: list objects are unhashable +\end{verbatim} +% +I mentioned earlier that a dictionary is implemented using +a hashtable and that means that the keys have to be {\bf hashable}. +\index{hash function} +\index{hashable} + +A {\bf hash} is a function that takes a value (of any kind) +and returns an integer. Dictionaries use these integers, +called hash values, to store and look up key-value pairs. +\index{immutability} + +This system works fine if the keys are immutable. But if the +keys are mutable, like lists, bad things happen. For example, +when you create a key-value pair, Python hashes the key and +stores it in the corresponding location. If you modify the +key and then hash it again, it would go to a different location. +In that case you might have two entries for the same key, +or you might not be able to find a key. Either way, the +dictionary wouldn't work correctly. + +That's why keys have to be hashable, and why mutable types like +lists aren't. The simplest way to get around this limitation is to +use tuples, which we will see in the next chapter. + +Since dictionaries are mutable, they can't be used as keys, +but they {\em can} be used as values. + + +\section{Memos} +\label{memoize} + +If you played with the {\tt fibonacci} function from +Section~\ref{one.more.example}, you might have noticed that the bigger +the argument you provide, the longer the function takes to run. +Furthermore, the run time increases quickly. +\index{fibonacci function} +\index{function!fibonacci} + +To understand why, consider Figure~\ref{fig.fibonacci}, which shows +the {\bf call graph} for {\tt fibonacci} with {\tt n=4}: + +\begin{figure} +\centerline +{\includegraphics[scale=0.7]{figs/fibonacci.pdf}} +\caption{Call graph.} +\label{fig.fibonacci} +\end{figure} + +A call graph shows a set of function frames, with lines connecting each +frame to the frames of the functions it calls. At the top of the +graph, {\tt fibonacci} with {\tt n=4} calls {\tt fibonacci} with {\tt +n=3} and {\tt n=2}. In turn, {\tt fibonacci} with {\tt n=3} calls +{\tt fibonacci} with {\tt n=2} and {\tt n=1}. And so on. +\index{function frame} +\index{frame} +\index{call graph} + +Count how many times {\tt fibonacci(0)} and {\tt fibonacci(1)} are +called. This is an inefficient solution to the problem, and it gets +worse as the argument gets bigger. +\index{memo} + +One solution is to keep track of values that have already been +computed by storing them in a dictionary. A previously computed value +that is stored for later use is called a {\bf memo}. Here is a +``memoized'' version of {\tt fibonacci}: + +\begin{verbatim} +known = {0:0, 1:1} + +def fibonacci(n): + if n in known: + return known[n] + + res = fibonacci(n-1) + fibonacci(n-2) + known[n] = res + return res +\end{verbatim} +% +{\tt known} is a dictionary that keeps track of the Fibonacci +numbers we already know. It starts with +two items: 0 maps to 0 and 1 maps to 1. + +Whenever {\tt fibonacci} is called, it checks {\tt known}. +If the result is already there, it can return +immediately. Otherwise it has to +compute the new value, add it to the dictionary, and return it. + +If you run this version of {\tt fibonacci} and compare it with +the original, you will find that it is much faster. + + + +\section{Global variables} +\index{global variable} +\index{variable!global} + +In the previous example, {\tt known} is created outside the function, +so it belongs to the special frame called \verb"__main__". +Variables in \verb"__main__" are sometimes called {\bf global} +because they can be accessed from any function. Unlike local +variables, which disappear when their function ends, global variables +persist from one function call to the next. +\index{flag} +\index{main} + +It is common to use global variables for {\bf flags}; that is, +boolean variables that indicate (``flag'') whether a condition +is true. For example, some programs use +a flag named {\tt verbose} to control the level of detail in the +output: + +\begin{verbatim} +verbose = True + +def example1(): + if verbose: + print('Running example1') +\end{verbatim} +% +If you try to reassign a global variable, you might be surprised. +The following example is supposed to keep track of whether the +function has been called: +\index{reassignment} + +\begin{verbatim} +been_called = False + +def example2(): + been_called = True # WRONG +\end{verbatim} +% +But if you run it you will see that the value of \verb"been_called" +doesn't change. The problem is that {\tt example2} creates a new local +variable named \verb"been_called". The local variable goes away when +the function ends, and has no effect on the global variable. +\index{global statement} +\index{statement!global} +\index{declaration} + +To reassign a global variable inside a function you have to +{\bf declare} the global variable before you use it: + +\begin{verbatim} +been_called = False + +def example2(): + global been_called + been_called = True +\end{verbatim} +% +The {\bf global statement} tells the interpreter +something like, ``In this function, when I say \verb"been_called", I +mean the global variable; don't create a local one.'' +\index{update!global variable} +\index{global variable!update} + +Here's an example that tries to update a global variable: + +\begin{verbatim} +count = 0 + +def example3(): + count = count + 1 # WRONG +\end{verbatim} +% +If you run it you get: +\index{UnboundLocalError} +\index{exception!UnboundLocalError} + +\begin{verbatim} +UnboundLocalError: local variable 'count' referenced before assignment +\end{verbatim} +% +Python assumes that {\tt count} is local, and under that assumption +you are reading it before writing it. The solution, again, +is to declare {\tt count} global. +\index{counter} + +\begin{verbatim} +def example3(): + global count + count += 1 +\end{verbatim} +% +If a global variable refers to a mutable value, you can modify +the value without declaring the variable: +\index{mutability} + +\begin{verbatim} +known = {0:0, 1:1} + +def example4(): + known[2] = 1 +\end{verbatim} +% +So you can add, remove and replace elements of a global list or +dictionary, but if you want to reassign the variable, you +have to declare it: + +\begin{verbatim} +def example5(): + global known + known = dict() +\end{verbatim} +% +Global variables can be useful, but if you have a lot of them, +and you modify them frequently, they can make programs +hard to debug. + + +\section{Debugging} +\index{debugging} + +As you work with bigger datasets it can become unwieldy to +debug by printing and checking the output by hand. Here are some +suggestions for debugging large datasets: + +\begin{description} + +\item[Scale down the input:] If possible, reduce the size of the +dataset. For example if the program reads a text file, start with +just the first 10 lines, or with the smallest example you can find. +You can either edit the files themselves, or (better) modify the +program so it reads only the first {\tt n} lines. + +If there is an error, you can reduce {\tt n} to the smallest +value that manifests the error, and then increase it gradually +as you find and correct errors. + +\item[Check summaries and types:] Instead of printing and checking the +entire dataset, consider printing summaries of the data: for example, +the number of items in a dictionary or the total of a list of numbers. + +A common cause of runtime errors is a value that is not the right +type. For debugging this kind of error, it is often enough to print +the type of a value. + +\item[Write self-checks:] Sometimes you can write code to check +for errors automatically. For example, if you are computing the +average of a list of numbers, you could check that the result is +not greater than the largest element in the list or less than +the smallest. This is called a ``sanity check'' because it detects +results that are ``insane''. +\index{sanity check} +\index{consistency check} + +Another kind of check compares the results of two different +computations to see if they are consistent. This is called a +``consistency check''. + +\item[Format the output:] Formatting debugging output +can make it easier to spot an error. We saw an example in +Section~\ref{factdebug}. Another tool you might find useful is the {\tt pprint} module, which provides +a {\tt pprint} function that displays built-in types in +a more human-readable format ({\tt pprint} stands for +``pretty print''). +\index{pretty print} +\index{pprint module} +\index{module!pprint} + +\end{description} + +Again, time you spend building scaffolding can reduce +the time you spend debugging. +\index{scaffolding} + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[mapping:] A relationship in which each element of one set +corresponds to an element of another set. +\index{mapping} + +\item[dictionary:] A mapping from keys to their +corresponding values. +\index{dictionary} + +\item[key-value pair:] The representation of the mapping from +a key to a value. +\index{key-value pair} + +\item[item:] In a dictionary, another name for a key-value + pair. +\index{item!dictionary} + +\item[key:] An object that appears in a dictionary as the +first part of a key-value pair. +\index{key} + +\item[value:] An object that appears in a dictionary as the +second part of a key-value pair. This is more specific than +our previous use of the word ``value''. +\index{value} + +\item[implementation:] A way of performing a computation. +\index{implementation} + +\item[hashtable:] The algorithm used to implement Python +dictionaries. +\index{hashtable} + +\item[hash function:] A function used by a hashtable to compute the +location for a key. +\index{hash function} + +\item[hashable:] A type that has a hash function. Immutable +types like integers, +floats and strings are hashable; mutable types like lists and +dictionaries are not. +\index{hashable} + +\item[lookup:] A dictionary operation that takes a key and finds +the corresponding value. +\index{lookup} + +\item[reverse lookup:] A dictionary operation that takes a value and finds +one or more keys that map to it. +\index{reverse lookup} + +\item[raise statement:] A statement that (deliberately) raises an exception. +\index{raise statement} +\index{statement!raise} + +\item[singleton:] A list (or other sequence) with a single element. +\index{singleton} + +\item[call graph:] A diagram that shows every frame created during +the execution of a program, with an arrow from each caller to +each callee. +\index{call graph} +\index{diagram!call graph} + +\item[memo:] A computed value stored to avoid unnecessary future +computation. +\index{memo} + +\item[global variable:] A variable defined outside a function. Global +variables can be accessed from any function. +\index{global variable} + +\item[global statement:] A statement that declares a variable name +global. +\index{global statement} +\index{statement!global} + +\item[flag:] A boolean variable used to indicate whether a condition +is true. +\index{flag} + +\item[declaration:] A statement like {\tt global} that tells the +interpreter something about a variable. +\index{declaration} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +\label{wordlist2} +\index{set membership} +\index{membership!set} + +Write a function that reads the words in {\tt words.txt} and +stores them as keys in a dictionary. It doesn't matter what the +values are. Then you can use the {\tt in} operator +as a fast way to check whether a string is in +the dictionary. + +If you did Exercise~\ref{wordlist1}, you can compare the speed +of this implementation with the list {\tt in} operator and the +bisection search. + +\end{exercise} + + +\begin{exercise} +\label{setdefault} + +Read the documentation of the dictionary method {\tt setdefault} +and use it to write a more concise version of \verb"invert_dict". +Solution: \url{http://thinkpython2.com/code/invert_dict.py}. +\index{setdefault method} +\index{method!setdefault} + +\end{exercise} + + +\begin{exercise} +Memoize the Ackermann function from Exercise~\ref{ackermann} and see if +memoization makes it possible to evaluate the function with bigger +arguments. Hint: no. +Solution: \url{http://thinkpython2.com/code/ackermann_memo.py}. +\index{Ackermann function} +\index{function!ack} + +\end{exercise} + + + +\begin{exercise} +\index{duplicate} + +If you did Exercise~\ref{duplicate}, you already have +a function named \verb"has_duplicates" that takes a list +as a parameter and returns {\tt True} if there is any object +that appears more than once in the list. + +Use a dictionary to write a faster, simpler version of +\verb"has_duplicates". +Solution: \url{http://thinkpython2.com/code/has_duplicates.py}. + +\end{exercise} + + +\begin{exercise} +\label{exrotatepairs} +\index{letter rotation} +\index{rotation!letters} + +Two words are ``rotate pairs'' if you can rotate one of them +and get the other (see \verb"rotate_word" in Exercise~\ref{exrotate}). + +Write a program that reads a wordlist and finds all the rotate +pairs. Solution: \url{http://thinkpython2.com/code/rotate_pairs.py}. + +\end{exercise} + + +\begin{exercise} +\index{Car Talk} +\index{Puzzler} + +Here's another Puzzler from {\em Car Talk} +(\url{http://www.cartalk.com/content/puzzlers}): + +\begin{quote} +This was sent in by a fellow named Dan O'Leary. He came upon a common +one-syllable, five-letter word recently that has the following unique +property. When you remove the first letter, the remaining letters form +a homophone of the original word, that is a word that sounds exactly +the same. Replace the first letter, that is, put it back and remove +the second letter and the result is yet another homophone of the +original word. And the question is, what's the word? + +Now I'm going to give you an example that doesn't work. Let's look at +the five-letter word, `wrack.' W-R-A-C-K, you know like to `wrack with +pain.' If I remove the first letter, I am left with a four-letter +word, 'R-A-C-K.' As in, `Holy cow, did you see the rack on that buck! +It must have been a nine-pointer!' It's a perfect homophone. If you +put the `w' back, and remove the `r,' instead, you're left with the +word, `wack,' which is a real word, it's just not a homophone of the +other two words. + +But there is, however, at least one word that Dan and we know of, +which will yield two homophones if you remove either of the first two +letters to make two, new four-letter words. The question is, what's +the word? +\end{quote} +\index{homophone} +\index{reducible word} +\index{word, reducible} + +You can use the dictionary from Exercise~\ref{wordlist2} to check +whether a string is in the word list. + +To check whether two words are homophones, you can use the CMU +Pronouncing Dictionary. You can download it from +\url{http://www.speech.cs.cmu.edu/cgi-bin/cmudict} or from +\url{http://thinkpython2.com/code/c06d} and you can also download +\url{http://thinkpython2.com/code/pronounce.py}, which provides a function +named \verb"read_dictionary" that reads the pronouncing dictionary and +returns a Python dictionary that maps from each word to a string that +describes its primary pronunciation. + +Write a program that lists all the words that solve the Puzzler. +Solution: \url{http://thinkpython2.com/code/homophone.py}. + +\end{exercise} + + + +\chapter{Tuples} +\label{tuplechap} + +This chapter presents one more built-in type, the tuple, and then +shows how lists, dictionaries, and tuples work together. +I also present a useful feature for variable-length argument lists, +the gather and scatter operators. + +One note: there is no consensus on how to pronounce ``tuple''. +Some people say ``tuh-ple'', which rhymes with ``supple''. But +in the context of programming, most people say ``too-ple'', which +rhymes with ``quadruple''. + + +\section{Tuples are immutable} +\index{tuple} +\index{type!tuple} +\index{sequence} + +A tuple is a sequence of values. The values can be any type, and +they are indexed by integers, so in that respect tuples are a lot +like lists. The important difference is that tuples are immutable. +\index{mutability} +\index{immutability} + +Syntactically, a tuple is a comma-separated list of values: + +\begin{verbatim} +>>> t = 'a', 'b', 'c', 'd', 'e' +\end{verbatim} +% +Although it is not necessary, it is common to enclose tuples in +parentheses: +\index{parentheses!tuples in} + +\begin{verbatim} +>>> t = ('a', 'b', 'c', 'd', 'e') +\end{verbatim} +% +To create a tuple with a single element, you have to include a final +comma: +\index{singleton} +\index{tuple!singleton} + +\begin{verbatim} +>>> t1 = 'a', +>>> type(t1) + +\end{verbatim} +% +A value in parentheses is not a tuple: + +\begin{verbatim} +>>> t2 = ('a') +>>> type(t2) + +\end{verbatim} +% +Another way to create a tuple is the built-in function {\tt tuple}. +With no argument, it creates an empty tuple: +\index{tuple function} +\index{function!tuple} + +\begin{verbatim} +>>> t = tuple() +>>> t +() +\end{verbatim} +% +If the argument is a sequence (string, list or tuple), the result +is a tuple with the elements of the sequence: + +\begin{verbatim} +>>> t = tuple('lupins') +>>> t +('l', 'u', 'p', 'i', 'n', 's') +\end{verbatim} +% +Because {\tt tuple} is the name of a built-in function, you should +avoid using it as a variable name. + +Most list operators also work on tuples. The bracket operator +indexes an element: +\index{bracket operator} +\index{operator!bracket} + +\begin{verbatim} +>>> t = ('a', 'b', 'c', 'd', 'e') +>>> t[0] +'a' +\end{verbatim} +% +And the slice operator selects a range of elements. +\index{slice operator} +\index{operator!slice} +\index{tuple!slice} +\index{slice!tuple} + +\begin{verbatim} +>>> t[1:3] +('b', 'c') +\end{verbatim} +% +But if you try to modify one of the elements of the tuple, you get +an error: +\index{exception!TypeError} +\index{TypeError} +\index{item assignment} +\index{assignment!item} + +\begin{verbatim} +>>> t[0] = 'A' +TypeError: object doesn't support item assignment +\end{verbatim} +% +Because tuples are immutable, you can't modify the elements. But you +can replace one tuple with another: + +\begin{verbatim} +>>> t = ('A',) + t[1:] +>>> t +('A', 'b', 'c', 'd', 'e') +\end{verbatim} +% +This statement makes a new tuple and then makes {\tt t} refer to it. + +The relational operators work with tuples and other sequences; +Python starts by comparing the first element from each +sequence. If they are equal, it goes on to the next elements, +and so on, until it finds elements that differ. Subsequent +elements are not considered (even if they are really big). +\index{comparison!tuple} +\index{tuple!comparison} + +\begin{verbatim} +>>> (0, 1, 2) < (0, 3, 4) +True +>>> (0, 1, 2000000) < (0, 3, 4) +True +\end{verbatim} + + + +\section{Tuple assignment} +\label{tuple.assignment} +\index{tuple!assignment} +\index{assignment!tuple} +\index{swap pattern} +\index{pattern!swap} + +It is often useful to swap the values of two variables. +With conventional assignments, you have to use a temporary +variable. For example, to swap {\tt a} and {\tt b}: + +\begin{verbatim} +>>> temp = a +>>> a = b +>>> b = temp +\end{verbatim} +% +This solution is cumbersome; {\bf tuple assignment} is more elegant: + +\begin{verbatim} +>>> a, b = b, a +\end{verbatim} +% +The left side is a tuple of variables; the right side is a tuple of +expressions. Each value is assigned to its respective variable. +All the expressions on the right side are evaluated before any +of the assignments. + +The number of variables on the left and the number of +values on the right have to be the same: +\index{exception!ValueError} +\index{ValueError} + +\begin{verbatim} +>>> a, b = 1, 2, 3 +ValueError: too many values to unpack +\end{verbatim} +% +More generally, the right side can be any kind of sequence +(string, list or tuple). For example, to split an email address +into a user name and a domain, you could write: +\index{split method} +\index{method!split} +\index{email address} + +\begin{verbatim} +>>> addr = 'monty@python.org' +>>> uname, domain = addr.split('@') +\end{verbatim} +% +The return value from {\tt split} is a list with two elements; +the first element is assigned to {\tt uname}, the second to +{\tt domain}. + +\begin{verbatim} +>>> uname +'monty' +>>> domain +'python.org' +\end{verbatim} +% + +\section{Tuples as return values} +\index{tuple} +\index{value!tuple} +\index{return value!tuple} +\index{function, tuple as return value} + +Strictly speaking, a function can only return one value, but +if the value is a tuple, the effect is the same as returning +multiple values. For example, if you want to divide two integers +and compute the quotient and remainder, it is inefficient to +compute {\tt x/y} and then {\tt x\%y}. It is better to compute +them both at the same time. +\index{divmod} + +The built-in function {\tt divmod} takes two arguments and +returns a tuple of two values, the quotient and remainder. +You can store the result as a tuple: + +\begin{verbatim} +>>> t = divmod(7, 3) +>>> t +(2, 1) +\end{verbatim} +% +Or use tuple assignment to store the elements separately: +\index{tuple assignment} +\index{assignment!tuple} + +\begin{verbatim} +>>> quot, rem = divmod(7, 3) +>>> quot +2 +>>> rem +1 +\end{verbatim} +% +Here is an example of a function that returns a tuple: + +\begin{verbatim} +def min_max(t): + return min(t), max(t) +\end{verbatim} +% +{\tt max} and {\tt min} are built-in functions that find +the largest and smallest elements of a sequence. \verb"min_max" +computes both and returns a tuple of two values. +\index{max function} +\index{function!max} +\index{min function} +\index{function!min} + + +\section{Variable-length argument tuples} +\label{gather} +\index{variable-length argument tuple} +\index{argument!variable-length tuple} +\index{gather} +\index{parameter!gather} +\index{argument!gather} + +Functions can take a variable number of arguments. A parameter +name that begins with {\tt *} {\bf gathers} arguments into +a tuple. For example, {\tt printall} +takes any number of arguments and prints them: + +\begin{verbatim} +def printall(*args): + print(args) +\end{verbatim} +% +The gather parameter can have any name you like, but {\tt args} is +conventional. Here's how the function works: + +\begin{verbatim} +>>> printall(1, 2.0, '3') +(1, 2.0, '3') +\end{verbatim} +% +The complement of gather is {\bf scatter}. If you have a +sequence of values and you want to pass it to a function +as multiple arguments, you can use the {\tt *} operator. +For example, {\tt divmod} takes exactly two arguments; it +doesn't work with a tuple: +\index{scatter} +\index{argument scatter} +\index{TypeError} +\index{exception!TypeError} + +\begin{verbatim} +>>> t = (7, 3) +>>> divmod(t) +TypeError: divmod expected 2 arguments, got 1 +\end{verbatim} +% +But if you scatter the tuple, it works: + +\begin{verbatim} +>>> divmod(*t) +(2, 1) +\end{verbatim} +% +Many of the built-in functions use +variable-length argument tuples. For example, {\tt max} +and {\tt min} can take any number of arguments: +\index{max function} +\index{function!max} +\index{min function} +\index{function!min} + +\begin{verbatim} +>>> max(1, 2, 3) +3 +\end{verbatim} +% +But {\tt sum} does not. +\index{sum function} +\index{function!sum} + +\begin{verbatim} +>>> sum(1, 2, 3) +TypeError: sum expected at most 2 arguments, got 3 +\end{verbatim} +% +As an exercise, write a function called {\tt sumall} that takes any number +of arguments and returns their sum. + + +\section{Lists and tuples} +\index{zip function} +\index{function!zip} + +{\tt zip} is a built-in function that takes two or more sequences and +returns a list of tuples where each tuple contains one +element from each sequence. The name of the function refers to +a zipper, which joins and interleaves two rows of teeth. + +This example zips a string and a list: + +\begin{verbatim} +>>> s = 'abc' +>>> t = [0, 1, 2] +>>> zip(s, t) + +\end{verbatim} +% +The result is a {\bf zip object} that knows how to iterate through +the pairs. The most common use of {\tt zip} is in a {\tt for} loop: + +\begin{verbatim} +>>> for pair in zip(s, t): +... print(pair) +... +('a', 0) +('b', 1) +('c', 2) +\end{verbatim} +% +A zip object is a kind of {\bf iterator}, which is any object +that iterates through a sequence. Iterators are similar to lists in some +ways, but unlike lists, you can't use an index to select an element from +an iterator. +\index{iterator} + +If you want to use list operators and methods, you can +use a zip object to make a list: + +\begin{verbatim} +>>> list(zip(s, t)) +[('a', 0), ('b', 1), ('c', 2)] +\end{verbatim} +% +The result is a list of tuples; in this example, each tuple contains +a character from the string and the corresponding element from +the list. +\index{list!of tuples} + +If the sequences are not the same length, the result has the +length of the shorter one. + +\begin{verbatim} +>>> list(zip('Anne', 'Elk')) +[('A', 'E'), ('n', 'l'), ('n', 'k')] +\end{verbatim} +% +You can use tuple assignment in a {\tt for} loop to traverse a list of +tuples: +\index{traversal} +\index{tuple assignment} +\index{assignment!tuple} + +\begin{verbatim} +t = [('a', 0), ('b', 1), ('c', 2)] +for letter, number in t: + print(number, letter) +\end{verbatim} +% +Each time through the loop, Python selects the next tuple in +the list and assigns the elements to {\tt letter} and +{\tt number}. The output of this loop is: +\index{loop} + +\begin{verbatim} +0 a +1 b +2 c +\end{verbatim} +% +If you combine {\tt zip}, {\tt for} and tuple assignment, you get a +useful idiom for traversing two (or more) sequences at the same +time. For example, \verb"has_match" takes two sequences, {\tt t1} and +{\tt t2}, and returns {\tt True} if there is an index {\tt i} +such that {\tt t1[i] == t2[i]}: +\index{for loop} + +\begin{verbatim} +def has_match(t1, t2): + for x, y in zip(t1, t2): + if x == y: + return True + return False +\end{verbatim} +% +If you need to traverse the elements of a sequence and their +indices, you can use the built-in function {\tt enumerate}: +\index{traversal} +\index{enumerate function} +\index{function!enumerate} + +\begin{verbatim} +for index, element in enumerate('abc'): + print(index, element) +\end{verbatim} +% +The result from {\tt enumerate} is an enumerate object, which +iterates a sequence of pairs; each pair contains an index (starting +from 0) and an element from the given sequence. +In this example, the output is + +\begin{verbatim} +0 a +1 b +2 c +\end{verbatim} +% +Again. +\index{iterator} +\index{object!enumerate} +\index{enumerate object} + + +\section{Dictionaries and tuples} +\label{dictuple} +\index{dictionary} +\index{items method} +\index{method!items} +\index{key-value pair} + +Dictionaries have a method called {\tt items} that returns a sequence of +tuples, where each tuple is a key-value pair. + +\begin{verbatim} +>>> d = {'a':0, 'b':1, 'c':2} +>>> t = d.items() +>>> t +dict_items([('c', 2), ('a', 0), ('b', 1)]) +\end{verbatim} +% +The result is a \verb"dict_items" object, which is an iterator that +iterates the key-value pairs. You can use it in a {\tt for} loop +like this: +\index{iterator} + +\begin{verbatim} +>>> for key, value in d.items(): +... print(key, value) +... +c 2 +a 0 +b 1 +\end{verbatim} +% +As you should expect from a dictionary, the items are in no +particular order. + +Going in the other direction, you can use a list of tuples to +initialize a new dictionary: \index{dictionary!initialize} + +\begin{verbatim} +>>> t = [('a', 0), ('c', 2), ('b', 1)] +>>> d = dict(t) +>>> d +{'a': 0, 'c': 2, 'b': 1} +\end{verbatim} + +Combining {\tt dict} with {\tt zip} yields a concise way +to create a dictionary: +\index{zip function!use with dict} + +\begin{verbatim} +>>> d = dict(zip('abc', range(3))) +>>> d +{'a': 0, 'c': 2, 'b': 1} +\end{verbatim} +% +The dictionary method {\tt update} also takes a list of tuples +and adds them, as key-value pairs, to an existing dictionary. +\index{update method} +\index{method!update} +\index{traverse!dictionary} +\index{dictionary!traversal} + +It is common to use tuples as keys in dictionaries (primarily because +you can't use lists). For example, a telephone directory might map +from last-name, first-name pairs to telephone numbers. Assuming +that we have defined {\tt last}, {\tt first} and {\tt number}, we +could write: +\index{tuple!as key in dictionary} +\index{hashable} + +\begin{verbatim} +directory[last, first] = number +\end{verbatim} +% +The expression in brackets is a tuple. We could use tuple +assignment to traverse this dictionary. +\index{tuple!in brackets} + +\begin{verbatim} +for last, first in directory: + print(first, last, directory[last,first]) +\end{verbatim} +% +This loop traverses the keys in {\tt directory}, which are tuples. It +assigns the elements of each tuple to {\tt last} and {\tt first}, then +prints the name and corresponding telephone number. + +There are two ways to represent tuples in a state diagram. The more +detailed version shows the indices and elements just as they appear in +a list. For example, the tuple \verb"('Cleese', 'John')" would appear +as in Figure~\ref{fig.tuple1}. +\index{state diagram} +\index{diagram!state} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/tuple1.pdf}} +\caption{State diagram.} +\label{fig.tuple1} +\end{figure} + +But in a larger diagram you might want to leave out the +details. For example, a diagram of the telephone directory might +appear as in Figure~\ref{fig.dict2}. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/dict2.pdf}} +\caption{State diagram.} +\label{fig.dict2} +\end{figure} + +Here the tuples are shown using Python syntax as a graphical +shorthand. The telephone number in the diagram is the complaints line +for the BBC, so please don't call it. + + +\section{Sequences of sequences} +\index{sequence} + +I have focused on lists of tuples, but almost all of the examples in +this chapter also work with lists of lists, tuples of tuples, and +tuples of lists. To avoid enumerating the possible combinations, it +is sometimes easier to talk about sequences of sequences. + +In many contexts, the different kinds of sequences (strings, lists and +tuples) can be used interchangeably. So how should you choose one +over the others? +\index{string} +\index{list} +\index{tuple} +\index{mutability} +\index{immutability} + +To start with the obvious, strings are more limited than other +sequences because the elements have to be characters. They are +also immutable. If you need the ability to change the characters +in a string (as opposed to creating a new string), you might +want to use a list of characters instead. + +Lists are more common than tuples, mostly because they are mutable. +But there are a few cases where you might prefer tuples: + +\begin{enumerate} + +\item In some contexts, like a {\tt return} statement, it is +syntactically simpler to create a tuple than a list. + +\item If you want to use a sequence as a dictionary key, you +have to use an immutable type like a tuple or string. + +\item If you are passing a sequence as an argument to a function, +using tuples reduces the potential for unexpected behavior +due to aliasing. + +\end{enumerate} + +Because tuples are immutable, they don't provide methods like {\tt + sort} and {\tt reverse}, which modify existing lists. But Python +provides the built-in function {\tt sorted}, which takes any sequence +and returns a new list with the same elements in sorted order, and +{\tt reversed}, which takes a sequence and returns an iterator that +traverses the list in reverse order. +\index{sorted function} +\index{function!sorted} \index{reversed function} +\index{function!reversed} +\index{iterator} + + +\section{Debugging} +\index{debugging} +\index{data structure} +\index{shape error} +\index{error!shape} + +Lists, dictionaries and tuples are examples of {\bf data + structures}; in this chapter we are starting to see compound data +structures, like lists of tuples, or dictionaries that contain tuples +as keys and lists as values. Compound data structures are useful, but +they are prone to what I call {\bf shape errors}; that is, errors +caused when a data structure has the wrong type, size, or structure. +For example, if you are expecting a list with one integer and I +give you a plain old integer (not in a list), it won't work. +\index{structshape module} +\index{module!structshape} + +To help debug these kinds of errors, I have written a module +called {\tt structshape} that provides a function, also called +{\tt structshape}, that takes any kind of data structure as +an argument and returns a string that summarizes its shape. +You can download it from \url{http://thinkpython2.com/code/structshape.py} + +Here's the result for a simple list: + +\begin{verbatim} +>>> from structshape import structshape +>>> t = [1, 2, 3] +>>> structshape(t) +'list of 3 int' +\end{verbatim} +% +A fancier program might write ``list of 3 int{\em s}'', but it +was easier not to deal with plurals. Here's a list of lists: + +\begin{verbatim} +>>> t2 = [[1,2], [3,4], [5,6]] +>>> structshape(t2) +'list of 3 list of 2 int' +\end{verbatim} +% +If the elements of the list are not the same type, +{\tt structshape} groups them, in order, by type: + +\begin{verbatim} +>>> t3 = [1, 2, 3, 4.0, '5', '6', [7], [8], 9] +>>> structshape(t3) +'list of (3 int, float, 2 str, 2 list of int, int)' +\end{verbatim} +% +Here's a list of tuples: + +\begin{verbatim} +>>> s = 'abc' +>>> lt = list(zip(t, s)) +>>> structshape(lt) +'list of 3 tuple of (int, str)' +\end{verbatim} +% +And here's a dictionary with 3 items that map integers to strings. + +\begin{verbatim} +>>> d = dict(lt) +>>> structshape(d) +'dict of 3 int->str' +\end{verbatim} +% +If you are having trouble keeping track of your data structures, +{\tt structshape} can help. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[tuple:] An immutable sequence of elements. +\index{tuple} + +\item[tuple assignment:] An assignment with a sequence on the +right side and a tuple of variables on the left. The right +side is evaluated and then its elements are assigned to the +variables on the left. +\index{tuple assignment} +\index{assignment!tuple} + +\item[gather:] The operation of assembling a variable-length +argument tuple. +\index{gather} + +\item[scatter:] The operation of treating a sequence as a list of +arguments. +\index{scatter} + +\item[zip object:] The result of calling a built-in function {\tt zip}; +an object that iterates through a sequence of tuples. +\index{zip object} +\index{object!zip} + +\item[iterator:] An object that can iterate through a sequence, but +which does not provide list operators and methods. +\index{iterator} + +\item[data structure:] A collection of related values, often +organized in lists, dictionaries, tuples, etc. +\index{data structure} + +\item[shape error:] An error caused because a value has the +wrong shape; that is, the wrong type or size. +\index{shape} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Write a function called \verb"most_frequent" that takes a string and +prints the letters in decreasing order of frequency. Find text +samples from several different languages and see how letter frequency +varies between languages. Compare your results with the tables at +\url{http://en.wikipedia.org/wiki/Letter_frequencies}. Solution: +\url{http://thinkpython2.com/code/most_frequent.py}. \index{letter + frequency} \index{frequency!letter} + +\end{exercise} + + +\begin{exercise} +\label{anagrams} +\index{anagram set} +\index{set!anagram} + +More anagrams! + +\begin{enumerate} + +\item Write a program +that reads a word list from a file (see Section~\ref{wordlist}) and +prints all the sets of words that are anagrams. + +Here is an example of what the output might look like: + +\begin{verbatim} +['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled'] +['retainers', 'ternaries'] +['generating', 'greatening'] +['resmelts', 'smelters', 'termless'] +\end{verbatim} +% +Hint: you might want to build a dictionary that maps from a +collection of letters to a list of words that can be spelled with those +letters. The question is, how can you represent the collection of +letters in a way that can be used as a key? + +\item Modify the previous program so that it prints the longest list +of anagrams first, followed by the second longest, and so on. +\index{Scrabble} +\index{bingo} + +\item In Scrabble a ``bingo'' is when you play all seven tiles in +your rack, along with a letter on the board, to form an eight-letter +word. What collection of 8 letters forms the most possible bingos? +Hint: there are seven. + +% (7, ['angriest', 'astringe', 'ganister', 'gantries', 'granites', +% 'ingrates', 'rangiest']) + +Solution: \url{http://thinkpython2.com/code/anagram_sets.py}. + +\end{enumerate} +\end{exercise} + +\begin{exercise} +\index{metathesis} + +Two words form a ``metathesis pair'' if you can transform one into the +other by swapping two letters; for example, ``converse'' and +``conserve''. Write a program that finds all of the metathesis pairs +in the dictionary. Hint: don't test all pairs of words, and don't +test all possible swaps. Solution: +\url{http://thinkpython2.com/code/metathesis.py}. Credit: This +exercise is inspired by an example at \url{http://puzzlers.org}. + +\end{exercise} + + +\begin{exercise} +\index{Car Talk} +\index{Puzzler} + +Here's another Car Talk Puzzler +(\url{http://www.cartalk.com/content/puzzlers}): + +\begin{quote} +What is the longest English word, that remains a valid English word, +as you remove its letters one at a time? + +Now, letters can be removed from either end, or the middle, but you +can't rearrange any of the letters. Every time you drop a letter, you +wind up with another English word. If you do that, you're eventually +going to wind up with one letter and that too is going to be an +English word---one that's found in the dictionary. I want to know +what's the longest word and how many letters does it +have? + +I'm going to give you a little modest example: Sprite. Ok? You start +off with sprite, you take a letter off, one from the interior of the +word, take the r away, and we're left with the word spite, then we +take the e off the end, we're left with spit, we take the s off, we're +left with pit, it, and I. +\end{quote} +\index{reducible word} +\index{word, reducible} + +Write a program to find all words that can be reduced in this way, +and then find the longest one. + +This exercise is a little more challenging than most, so here are +some suggestions: + +\begin{enumerate} + +\item You might want to write a function that takes a word and + computes a list of all the words that can be formed by removing one + letter. These are the ``children'' of the word. +\index{recursive definition} +\index{definition!recursive} + +\item Recursively, a word is reducible if any of its children +are reducible. As a base case, you can consider the empty +string reducible. + +\item The wordlist I provided, {\tt words.txt}, doesn't +contain single letter words. So you might want to add +``I'', ``a'', and the empty string. + +\item To improve the performance of your program, you might want +to memoize the words that are known to be reducible. + +\end{enumerate} + +Solution: \url{http://thinkpython2.com/code/reducible.py}. + +\end{exercise} + + + + +%\begin{exercise} +%\url{http://en.wikipedia.org/wiki/Word_Ladder} +%\end{exercise} + + + + +\chapter{Case study: data structure selection} + +At this point you have learned about Python's core data structures, +and you have seen some of the algorithms that use them. +If you would like to know more about algorithms, this might be a good +time to read Chapter~\ref{algorithms}. +But you don't have to read it before you go on; you can read +it whenever you are interested. + +This chapter presents a case study with exercises that let +you think about choosing data structures and practice using them. + + +\section{Word frequency analysis} +\label{analysis} + +As usual, you should at least attempt the exercises +before you read my solutions. + +\begin{exercise} + +Write a program that reads a file, breaks each line into +words, strips whitespace and punctuation from the words, and +converts them to lowercase. +\index{string module} +\index{module!string} + +Hint: The {\tt string} module provides a string named {\tt whitespace}, +which contains space, tab, newline, etc., and {\tt + punctuation} which contains the punctuation characters. Let's see +if we can make Python swear: + +\begin{verbatim} +>>> import string +>>> string.punctuation +'!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~' +\end{verbatim} +% +Also, you might consider using the string methods {\tt strip}, +{\tt replace} and {\tt translate}. +\index{strip method} +\index{method!strip} +\index{replace method} +\index{method!replace} +\index{translate method} +\index{method!translate} + +\end{exercise} + + +\begin{exercise} +\index{Project Gutenberg} + +Go to Project Gutenberg (\url{http://gutenberg.org}) and download +your favorite out-of-copyright book in plain text format. +\index{plain text} +\index{text!plain} + +Modify your program from the previous exercise to read the book +you downloaded, skip over the header information at the beginning +of the file, and process the rest of the words as before. + +Then modify the program to count the total number of words in +the book, and the number of times each word is used. +\index{word frequency} +\index{frequency!word} + +Print the number of different words used in the book. Compare +different books by different authors, written in different eras. +Which author uses the most extensive vocabulary? +\end{exercise} + + +\begin{exercise} + +Modify the program from the previous exercise to print the +20 most frequently used words in the book. + +\end{exercise} + + +\begin{exercise} + +Modify the previous program to read a word list (see +Section~\ref{wordlist}) and then print all the words in the book that +are not in the word list. How many of them are typos? How many of +them are common words that {\em should} be in the word list, and how +many of them are really obscure? + +\end{exercise} + + +\section{Random numbers} +\index{random number} +\index{number, random} +\index{deterministic} +\index{pseudorandom} + +Given the same inputs, most computer programs generate the same +outputs every time, so they are said to be {\bf deterministic}. +Determinism is usually a good thing, since we expect the same +calculation to yield the same result. For some applications, though, +we want the computer to be unpredictable. Games are an obvious +example, but there are more. + +Making a program truly nondeterministic turns out to be difficult, +but there are ways to make it at least seem nondeterministic. One of +them is to use algorithms that generate {\bf pseudorandom} numbers. +Pseudorandom numbers are not truly random because they are generated +by a deterministic computation, but just by looking at the numbers it +is all but impossible to distinguish them from random. +\index{random module} +\index{module!random} + +The {\tt random} module provides functions that generate +pseudorandom numbers (which I will simply call ``random'' from +here on). +\index{random function} +\index{function!random} + +The function {\tt random} returns a random float +between 0.0 and 1.0 (including 0.0 but not 1.0). Each time you +call {\tt random}, you get the next number in a long series. To see a +sample, run this loop: + +\begin{verbatim} +import random + +for i in range(10): + x = random.random() + print(x) +\end{verbatim} +% +The function {\tt randint} takes parameters {\tt low} and +{\tt high} and returns an integer between {\tt low} and +{\tt high} (including both). +\index{randint function} +\index{function!randint} + +\begin{verbatim} +>>> random.randint(5, 10) +5 +>>> random.randint(5, 10) +9 +\end{verbatim} +% +To choose an element from a sequence at random, you can use +{\tt choice}: +\index{choice function} +\index{function!choice} + +\begin{verbatim} +>>> t = [1, 2, 3] +>>> random.choice(t) +2 +>>> random.choice(t) +3 +\end{verbatim} +% +The {\tt random} module also provides functions to generate +random values from continuous distributions including +Gaussian, exponential, gamma, and a few more. + +\begin{exercise} +\index{histogram!random choice} + +Write a function named \verb"choose_from_hist" that takes +a histogram as defined in Section~\ref{histogram} and returns a +random value from the histogram, chosen with probability +in proportion to frequency. For example, for this histogram: + +\begin{verbatim} +>>> t = ['a', 'a', 'b'] +>>> hist = histogram(t) +>>> hist +{'a': 2, 'b': 1} +\end{verbatim} +% +your function should return \verb"'a'" with probability $2/3$ and \verb"'b'" +with probability $1/3$. +\end{exercise} + + +\section{Word histogram} + +You should attempt the previous exercises before you go on. +You can download my solution from + \url{http://thinkpython2.com/code/analyze_book1.py}. You will +also need \url{http://thinkpython2.com/code/emma.txt}. + +Here is a program that reads a file and builds a histogram of the +words in the file: +\index{histogram!word frequencies} + +\begin{verbatim} +import string + +def process_file(filename): + hist = dict() + fp = open(filename) + for line in fp: + process_line(line, hist) + return hist + +def process_line(line, hist): + line = line.replace('-', ' ') + + for word in line.split(): + word = word.strip(string.punctuation + string.whitespace) + word = word.lower() + hist[word] = hist.get(word, 0) + 1 + +hist = process_file('emma.txt') +\end{verbatim} +% +This program reads {\tt emma.txt}, which contains the text of {\em + Emma} by Jane Austen. +\index{Austin, Jane} + +\verb"process_file" loops through the lines of the file, +passing them one at a time to \verb"process_line". The histogram +{\tt hist} is being used as an accumulator. +\index{accumulator!histogram} +\index{traversal} + +\verb"process_line" uses the string method {\tt replace} to replace +hyphens with spaces before using {\tt split} to break the line into a +list of strings. It traverses the list of words and uses {\tt strip} +and {\tt lower} to remove punctuation and convert to lower case. (It +is a shorthand to say that strings are ``converted''; remember that +strings are immutable, so methods like {\tt strip} and {\tt lower} +return new strings.) + +Finally, \verb"process_line" updates the histogram by creating a new +item or incrementing an existing one. +\index{update!histogram} + +To count the total number of words in the file, we can add up +the frequencies in the histogram: + +\begin{verbatim} +def total_words(hist): + return sum(hist.values()) +\end{verbatim} +% +The number of different words is just the number of items in +the dictionary: + +\begin{verbatim} +def different_words(hist): + return len(hist) +\end{verbatim} +% +Here is some code to print the results: + +\begin{verbatim} +print('Total number of words:', total_words(hist)) +print('Number of different words:', different_words(hist)) +\end{verbatim} +% +And the results: + +\begin{verbatim} +Total number of words: 161080 +Number of different words: 7214 +\end{verbatim} +% + +\section{Most common words} + +To find the most common words, we can make a list of tuples, +where each tuple contains a word and its frequency, +and sort it. + +The following function takes a histogram and returns a list of +word-frequency tuples: + +\begin{verbatim} +def most_common(hist): + t = [] + for key, value in hist.items(): + t.append((value, key)) + + t.sort(reverse=True) + return t +\end{verbatim} + +In each tuple, the frequency appears first, so the resulting list is +sorted by frequency. Here is a loop that prints the ten most common +words: + +\begin{verbatim} +t = most_common(hist) +print('The most common words are:') +for freq, word in t[:10]: + print(word, freq, sep='\t') +\end{verbatim} +% +I use the keyword argument {\tt sep} to tell {\tt print} to use a tab +character as a ``separator'', rather than a space, so the second +column is lined up. Here are the results from {\em Emma}: + +\begin{verbatim} +The most common words are: +to 5242 +the 5205 +and 4897 +of 4295 +i 3191 +a 3130 +it 2529 +her 2483 +was 2400 +she 2364 +\end{verbatim} +% +This code can be simplified using the {\tt key} parameter of +the {\tt sort} function. If you are curious, you can read about it +at \url{https://wiki.python.org/moin/HowTo/Sorting}. + + +\section{Optional parameters} +\index{optional parameter} +\index{parameter!optional} + +We have seen built-in functions and methods that take optional +arguments. It is possible to write programmer-defined functions +with optional arguments, too. For example, here is a function that +prints the most common words in a histogram +\index{programmer-defined function} +\index{function!programmer defined} + +\begin{verbatim} +def print_most_common(hist, num=10): + t = most_common(hist) + print('The most common words are:') + for freq, word in t[:num]: + print(word, freq, sep='\t') +\end{verbatim} + +The first parameter is required; the second is optional. +The {\bf default value} of {\tt num} is 10. +\index{default value} +\index{value!default} + +If you only provide one argument: + +\begin{verbatim} +print_most_common(hist) +\end{verbatim} + +{\tt num} gets the default value. If you provide two arguments: + +\begin{verbatim} +print_most_common(hist, 20) +\end{verbatim} + +{\tt num} gets the value of the argument instead. In other +words, the optional argument {\bf overrides} the default value. +\index{override} + +If a function has both required and optional parameters, all +the required parameters have to come first, followed by the +optional ones. + + +\section{Dictionary subtraction} +\label{dictsub} +\index{dictionary!subtraction} +\index{subtraction!dictionary} + +Finding the words from the book that are not in the word list +from {\tt words.txt} is a problem you might recognize as set +subtraction; that is, we want to find all the words from one +set (the words in the book) that are not in the other (the +words in the list). + +{\tt subtract} takes dictionaries {\tt d1} and {\tt d2} and returns a +new dictionary that contains all the keys from {\tt d1} that are not +in {\tt d2}. Since we don't really care about the values, we +set them all to None. + +\begin{verbatim} +def subtract(d1, d2): + res = dict() + for key in d1: + if key not in d2: + res[key] = None + return res +\end{verbatim} +% +To find the words in the book that are not in {\tt words.txt}, +we can use \verb"process_file" to build a histogram for +{\tt words.txt}, and then subtract: + +\begin{verbatim} +words = process_file('words.txt') +diff = subtract(hist, words) + +print("Words in the book that aren't in the word list:") +for word in diff: + print(word, end=' ') +\end{verbatim} +% +Here are some of the results from {\em Emma}: + +\begin{verbatim} +Words in the book that aren't in the word list: +rencontre jane's blanche woodhouses disingenuousness +friend's venice apartment ... +\end{verbatim} +% +Some of these words are names and possessives. Others, like +``rencontre'', are no longer in common use. But a few are common +words that should really be in the list! + +\begin{exercise} +\index{set} +\index{type!set} + +Python provides a data structure called {\tt set} that provides many +common set operations. You can read about them in Section~\ref{sets}, +or read the documentation at +\url{http://docs.python.org/3/library/stdtypes.html#types-set}. + +Write a program that uses set subtraction to find words in the book +that are not in the word list. Solution: +\url{http://thinkpython2.com/code/analyze_book2.py}. + +\end{exercise} + + +\section{Random words} +\label{randomwords} +\index{histogram!random choice} + +To choose a random word from the histogram, the simplest algorithm +is to build a list with multiple copies of each word, according +to the observed frequency, and then choose from the list: + +\begin{verbatim} +def random_word(h): + t = [] + for word, freq in h.items(): + t.extend([word] * freq) + + return random.choice(t) +\end{verbatim} +% +The expression {\tt [word] * freq} creates a list with {\tt freq} +copies of the string {\tt word}. The {\tt extend} +method is similar to {\tt append} except that the argument is +a sequence. + +This algorithm works, but it is not very efficient; each time you +choose a random word, it rebuilds the list, which is as big as +the original book. An obvious improvement is to build the list +once and then make multiple selections, but the list is still big. + +An alternative is: + +\begin{enumerate} + +\item Use {\tt keys} to get a list of the words in the book. + +\item Build a list that contains the cumulative sum of the word + frequencies (see Exercise~\ref{cumulative}). The last item + in this list is the total number of words in the book, $n$. + +\item Choose a random number from 1 to $n$. Use a bisection search + (See Exercise~\ref{bisection}) to find the index where the random + number would be inserted in the cumulative sum. + +\item Use the index to find the corresponding word in the word list. + +\end{enumerate} + +\begin{exercise} +\label{randhist} +\index{algorithm} + +Write a program that uses this algorithm to choose a random word from +the book. Solution: +\url{http://thinkpython2.com/code/analyze_book3.py}. + +\end{exercise} + + + +\section{Markov analysis} +\label{markov} +\index{Markov analysis} + +If you choose words from the book at random, you can get a +sense of the vocabulary, but you probably won't get a sentence: + +\begin{verbatim} +this the small regard harriet which knightley's it most things +\end{verbatim} +% +A series of random words seldom makes sense because there +is no relationship between successive words. For example, in +a real sentence you would expect an article like ``the'' to +be followed by an adjective or a noun, and probably not a verb +or adverb. + +One way to measure these kinds of relationships is Markov +analysis, which +characterizes, for a given sequence of words, the probability of the +words that might come next. For example, the song {\em Eric, the Half a + Bee} begins: + +\begin{quote} +Half a bee, philosophically, \\ +Must, ipso facto, half not be. \\ +But half the bee has got to be \\ +Vis a vis, its entity. D'you see? \\ +\\ +But can a bee be said to be \\ +Or not to be an entire bee \\ +When half the bee is not a bee \\ +Due to some ancient injury? \\ +\end{quote} +% +In this text, +the phrase ``half the'' is always followed by the word ``bee'', +but the phrase ``the bee'' might be followed by either +``has'' or ``is''. +\index{prefix} +\index{suffix} +\index{mapping} + +The result of Markov analysis is a mapping from each prefix +(like ``half the'' and ``the bee'') to all possible suffixes +(like ``has'' and ``is''). +\index{random text} +\index{text!random} + +Given this mapping, you can generate a random text by +starting with any prefix and choosing at random from the +possible suffixes. Next, you can combine the end of the +prefix and the new suffix to form the next prefix, and repeat. + +For example, if you start with the prefix ``Half a'', then the +next word has to be ``bee'', because the prefix only appears +once in the text. The next prefix is ``a bee'', so the +next suffix might be ``philosophically'', ``be'' or ``due''. + +In this example the length of the prefix is always two, but +you can do Markov analysis with any prefix length. + +\begin{exercise} + +Markov analysis: + +\begin{enumerate} + +\item Write a program to read a text from a file and perform Markov +analysis. The result should be a dictionary that maps from +prefixes to a collection of possible suffixes. The collection +might be a list, tuple, or dictionary; it is up to you to make +an appropriate choice. You can test your program with prefix +length two, but you should write the program in a way that makes +it easy to try other lengths. + +\item Add a function to the previous program to generate random text +based on the Markov analysis. Here is an example from {\em Emma} +with prefix length 2: + +\begin{quote} +He was very clever, be it sweetness or be angry, ashamed or only +amused, at such a stroke. She had never thought of Hannah till you +were never meant for me?" "I cannot make speeches, Emma:" he soon cut +it all himself. +\end{quote} + +For this example, I left the punctuation attached to the words. +The result is almost syntactically correct, but not quite. +Semantically, it almost makes sense, but not quite. + +What happens if you increase the prefix length? Does the random +text make more sense? + +\item Once your program is working, you might want to try a mash-up: +if you combine text from two or more books, the random +text you generate will blend the vocabulary and phrases from +the sources in interesting ways. +\index{mash-up} + +\end{enumerate} + +Credit: This case study is based on an example from Kernighan and +Pike, {\em The Practice of Programming}, Addison-Wesley, 1999. + +\end{exercise} + +You should attempt this exercise before you go on; then you can can +download my solution from \url{http://thinkpython2.com/code/markov.py}. +You will also need \url{http://thinkpython2.com/code/emma.txt}. + + +\section{Data structures} +\index{data structure} + +Using Markov analysis to generate random text is fun, but there is +also a point to this exercise: data structure selection. In your +solution to the previous exercises, you had to choose: + +\begin{itemize} + +\item How to represent the prefixes. + +\item How to represent the collection of possible suffixes. + +\item How to represent the mapping from each prefix to +the collection of possible suffixes. + +\end{itemize} + +The last one is easy: a dictionary is the obvious choice +for a mapping from keys to corresponding values. + +For the prefixes, the most obvious options are string, +list of strings, or tuple of strings. + +For the suffixes, +one option is a list; another is a histogram (dictionary). +\index{implementation} + +How should you choose? The first step is to think about +the operations you will need to implement for each data structure. +For the prefixes, we need to be able to remove words from +the beginning and add to the end. For example, if the current +prefix is ``Half a'', and the next word is ``bee'', you need +to be able to form the next prefix, ``a bee''. +\index{tuple!as key in dictionary} + +Your first choice might be a list, since it is easy to add +and remove elements, but we also need to be able to use the +prefixes as keys in a dictionary, so that rules out lists. +With tuples, you can't append or remove, but you can use +the addition operator to form a new tuple: + +\begin{verbatim} +def shift(prefix, word): + return prefix[1:] + (word,) +\end{verbatim} +% +{\tt shift} takes a tuple of words, {\tt prefix}, and a string, +{\tt word}, and forms a new tuple that has all the words +in {\tt prefix} except the first, and {\tt word} added to +the end. + +For the collection of suffixes, the operations we need to +perform include adding a new suffix (or increasing the frequency +of an existing one), and choosing a random suffix. + +Adding a new suffix is equally easy for the list implementation +or the histogram. Choosing a random element from a list +is easy; choosing from a histogram is harder to do +efficiently (see Exercise~\ref{randhist}). + +So far we have been talking mostly about ease of implementation, +but there are other factors to consider in choosing data structures. +One is run time. Sometimes there is a theoretical reason to expect +one data structure to be faster than other; for example, I mentioned +that the {\tt in} operator is faster for dictionaries than for lists, +at least when the number of elements is large. + +But often you don't know ahead of time which implementation will +be faster. One option is to implement both of them and see which +is better. This approach is called {\bf benchmarking}. A practical +alternative is to choose the data structure that is +easiest to implement, and then see if it is fast enough for the +intended application. If so, there is no need to go on. If not, +there are tools, like the {\tt profile} module, that can identify +the places in a program that take the most time. +\index{benchmarking} +\index{profile module} +\index{module!profile} + +The other factor to consider is storage space. For example, using a +histogram for the collection of suffixes might take less space because +you only have to store each word once, no matter how many times it +appears in the text. In some cases, saving space can also make your +program run faster, and in the extreme, your program might not run at +all if you run out of memory. But for many applications, space is a +secondary consideration after run time. + +One final thought: in this discussion, I have implied that +we should use one data structure for both analysis and generation. But +since these are separate phases, it would also be possible to use one +structure for analysis and then convert to another structure for +generation. This would be a net win if the time saved during +generation exceeded the time spent in conversion. + + +\section{Debugging} +\index{debugging} + +When you are debugging a program, and especially if you are +working on a hard bug, there are five things to try: + +\begin{description} + +\item[Reading:] Examine your code, read it back to yourself, and +check that it says what you meant to say. + +\item[Running:] Experiment by making changes and running different +versions. Often if you display the right thing at the right place +in the program, the problem becomes obvious, but sometimes you have to +build scaffolding. + +\item[Ruminating:] Take some time to think! What kind of error +is it: syntax, runtime, or semantic? What information can you get from +the error messages, or from the output of the program? What kind of +error could cause the problem you're seeing? What did you change +last, before the problem appeared? + +\item[Rubberducking:] If you explain the problem to someone else, you + sometimes find the answer before you finish asking the question. + Often you don't need the other person; you could just talk to a rubber + duck. And that's the origin of the well-known strategy called {\bf + rubber duck debugging}. I am not making this up; see + \url{https://en.wikipedia.org/wiki/Rubber_duck_debugging}. + +\item[Retreating:] At some point, the best thing to do is back +off, undoing recent changes, until you get back to a program that +works and that you understand. Then you can start rebuilding. + +\end{description} + +Beginning programmers sometimes get stuck on one of these activities +and forget the others. Each activity comes with its own failure +mode. +\index{typographical error} + +For example, reading your code might help if the problem is a +typographical error, but not if the problem is a conceptual +misunderstanding. If you don't understand what your program does, you +can read it 100 times and never see the error, because the error is in +your head. +\index{experimental debugging} + +Running experiments can help, especially if you run small, simple +tests. But if you run experiments without thinking or reading your +code, you might fall into a pattern I call ``random walk programming'', +which is the process of making random changes until the program +does the right thing. Needless to say, random walk programming +can take a long time. +\index{random walk programming} +\index{development plan!random walk programming} + +You have to take time to think. Debugging is like an +experimental science. You should have at least one hypothesis about +what the problem is. If there are two or more possibilities, try to +think of a test that would eliminate one of them. + +But even the best debugging techniques will fail if there are too many +errors, or if the code you are trying to fix is too big and +complicated. Sometimes the best option is to retreat, simplifying the +program until you get to something that works and that you +understand. + +Beginning programmers are often reluctant to retreat because +they can't stand to delete a line of code (even if it's wrong). +If it makes you feel better, copy your program into another file +before you start stripping it down. Then you can copy the pieces +back one at a time. + +Finding a hard bug requires reading, running, ruminating, and +sometimes retreating. If you get stuck on one of these activities, +try the others. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[deterministic:] Pertaining to a program that does the same +thing each time it runs, given the same inputs. +\index{deterministic} + +\item[pseudorandom:] Pertaining to a sequence of numbers that appears +to be random, but is generated by a deterministic program. +\index{pseudorandom} + +\item[default value:] The value given to an optional parameter if no +argument is provided. +\index{default value} + +\item[override:] To replace a default value with an argument. +\index{override} + +\item[benchmarking:] The process of choosing between data structures +by implementing alternatives and testing them on a sample of the +possible inputs. +\index{benchmarking} + +\item[rubber duck debugging:] Debugging by explaining your problem +to an inanimate object such as a rubber duck. Articulating the +problem can help you solve it, even if the rubber duck doesn't know +Python. +\index{rubber duck debugging} +\index{debugging!rubber duck} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +\index{word frequency} +\index{frequency!word} +\index{Zipf's law} + +The ``rank'' of a word is its position in a list of words +sorted by frequency: the most common word has rank 1, the +second most common has rank 2, etc. + +Zipf's law describes a relationship between the ranks and frequencies +of words in natural languages +(\url{http://en.wikipedia.org/wiki/Zipf's_law}). Specifically, it +predicts that the frequency, $f$, of the word with rank $r$ is: + +\[ f = c r^{-s} \] +% +where $s$ and $c$ are parameters that depend on the language and the +text. If you take the logarithm of both sides of this equation, you +get: +\index{logarithm} + +\[ \log f = \log c - s \log r \] +% +So if you plot log $f$ versus log $r$, you should get +a straight line with slope $-s$ and intercept log $c$. + +Write a program that reads a text from a file, counts +word frequencies, and prints one line +for each word, in descending order of frequency, with +log $f$ and log $r$. Use the graphing program of your +choice to plot the results and check whether they form +a straight line. Can you estimate the value of $s$? + +Solution: \url{http://thinkpython2.com/code/zipf.py}. +To run my solution, you need the plotting module {\tt matplotlib}. +If you installed Anaconda, you already have {\tt matplotlib}; +otherwise you might have to install it. +\index{matplotlib} + +\end{exercise} + + + +\chapter{Files} + +This chapter introduces the idea of ``persistent'' programs that +keep data in permanent storage, and shows how to use different +kinds of permanent storage, like files and databases. + + +\section{Persistence} +\index{file} +\index{type!file} +\index{persistence} + +Most of the programs we have seen so far are transient in the +sense that they run for a short time and produce some output, +but when they end, their data disappears. If you run the program +again, it starts with a clean slate. + +Other programs are {\bf persistent}: they run for a long time +(or all the time); they keep at least some of their data +in permanent storage (a hard drive, for example); and +if they shut down and restart, they pick up where they left off. + +Examples of persistent programs are operating systems, which +run pretty much whenever a computer is on, and web servers, +which run all the time, waiting for requests to come in on +the network. + +One of the simplest ways for programs to maintain their data +is by reading and writing text files. We have already seen +programs that read text files; in this chapter we will see programs +that write them. + +An alternative is to store the state of the program in a database. +In this chapter I will present a simple database and a module, +{\tt pickle}, that makes it easy to store program data. +\index{pickle module} +\index{module!pickle} + + +\section{Reading and writing} +\index{file!reading and writing} + +A text file is a sequence of characters stored on a permanent +medium like a hard drive, flash memory, or CD-ROM. We saw how +to open and read a file in Section~\ref{wordlist}. +\index{open function} +\index{function!open} + +To write a file, you have to open it with mode \verb"'w'" as a second +parameter: + +\begin{verbatim} +>>> fout = open('output.txt', 'w') +\end{verbatim} +% +If the file already exists, opening it in write mode clears out +the old data and starts fresh, so be careful! +If the file doesn't exist, a new one is created. + +{\tt open} returns a file object that provides methods for working +with the file. +The {\tt write} method puts data into the file. + +\begin{verbatim} +>>> line1 = "This here's the wattle,\n" +>>> fout.write(line1) +24 +\end{verbatim} +% +The return value is the number of characters that were written. +The file object keeps track of where it is, so if +you call {\tt write} again, it adds the new data to the end of +the file. + +\begin{verbatim} +>>> line2 = "the emblem of our land.\n" +>>> fout.write(line2) +24 +\end{verbatim} +% +When you are done writing, you should close the file. + +\begin{verbatim} +>>> fout.close() +\end{verbatim} +% +\index{close method} +\index{method!close} +% +If you don't close the file, it gets closed for you when the +program ends. + + +\section{Format operator} +\index{format operator} +\index{operator!format} + +The argument of {\tt write} has to be a string, so if we want +to put other values in a file, we have to convert them to +strings. The easiest way to do that is with {\tt str}: + +\begin{verbatim} +>>> x = 52 +>>> fout.write(str(x)) +\end{verbatim} +% +An alternative is to use the {\bf format operator}, {\tt \%}. When +applied to integers, {\tt \%} is the modulus operator. But +when the first operand is a string, {\tt \%} is the format operator. +\index{format string} + +The first operand is the {\bf format string}, which contains +one or more {\bf format sequences}, which +specify how +the second operand is formatted. The result is a string. +\index{format sequence} + +For example, the format sequence \verb"'%d'" means that +the second operand should be formatted as a decimal +integer: + +\begin{verbatim} +>>> camels = 42 +>>> '%d' % camels +'42' +\end{verbatim} +% +The result is the string \verb"'42'", which is not to be confused +with the integer value {\tt 42}. + +A format sequence can appear anywhere in the string, +so you can embed a value in a sentence: + +\begin{verbatim} +>>> 'I have spotted %d camels.' % camels +'I have spotted 42 camels.' +\end{verbatim} +% +If there is more than one format sequence in the string, +the second argument has to be a tuple. Each format sequence is +matched with an element of the tuple, in order. + +The following example uses \verb"'%d'" to format an integer, +\verb"'%g'" to format a floating-point number, and +\verb"'%s'" to format a string: + +\begin{verbatim} +>>> 'In %d years I have spotted %g %s.' % (3, 0.1, 'camels') +'In 3 years I have spotted 0.1 camels.' +\end{verbatim} +% +The number of elements in the tuple has to match the number +of format sequences in the string. Also, the types of the +elements have to match the format sequences: +\index{exception!TypeError} +\index{TypeError} + +\begin{verbatim} +>>> '%d %d %d' % (1, 2) +TypeError: not enough arguments for format string +>>> '%d' % 'dollars' +TypeError: %d format: a number is required, not str +\end{verbatim} +% +In the first example, there aren't enough elements; in the +second, the element is the wrong type. + +For more information on the format operator, see +\url{https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting}. A more powerful alternative is the string +format method, which you can read about at +\url{https://docs.python.org/3/library/stdtypes.html#str.format}. + +% You can specify the number of digits as part of the format sequence. +% For example, the sequence \verb"'%8.2f'" +% formats a floating-point number to be 8 characters long, with +% 2 digits after the decimal point: + +% % \begin{verbatim} +% >>> '%8.2f' % 3.14159 +% ' 3.14' +% \end{verbatim} +% \afterverb +% % +% The result takes up eight spaces with two +% digits after the decimal point. + + +\section{Filenames and paths} +\label{paths} +\index{filename} +\index{path} +\index{directory} +\index{folder} + +Files are organized into {\bf directories} (also called ``folders''). +Every running program has a ``current directory'', which is the +default directory for most operations. +For example, when you open a file for reading, Python looks for it in the +current directory. +\index{os module} +\index{module!os} + +The {\tt os} module provides functions for working with files and +directories (``os'' stands for ``operating system''). {\tt os.getcwd} +returns the name of the current directory: +\index{getcwd function} +\index{function!getcwd} + +\begin{verbatim} +>>> import os +>>> cwd = os.getcwd() +>>> cwd +'/home/dinsdale' +\end{verbatim} +% +{\tt cwd} stands for ``current working directory''. The result in +this example is {\tt /home/dinsdale}, which is the home directory of a +user named {\tt dinsdale}. +\index{working directory} +\index{directory!working} + +A string like \verb"'/home/dinsdale'" that identifies a file or +directory is called a {\bf path}. + +A simple filename, like {\tt memo.txt} is also considered a path, +but it is a {\bf relative path} because it relates to the current +directory. If the current directory is {\tt /home/dinsdale}, the +filename {\tt memo.txt} would refer to {\tt /home/dinsdale/memo.txt}. +\index{relative path} \index{path!relative} +\index{absolute path} \index{path!absolute} + +A path that begins with {\tt /} does not depend on the current +directory; it is called an {\bf absolute path}. To find the absolute +path to a file, you can use {\tt os.path.abspath}: + +\begin{verbatim} +>>> os.path.abspath('memo.txt') +'/home/dinsdale/memo.txt' +\end{verbatim} +% +{\tt os.path} provides other functions for working with filenames +and paths. For example, +{\tt os.path.exists} checks +whether a file or directory exists: +\index{exists function} +\index{function!exists} + +\begin{verbatim} +>>> os.path.exists('memo.txt') +True +\end{verbatim} +% +If it exists, {\tt os.path.isdir} checks whether it's a directory: + +\begin{verbatim} +>>> os.path.isdir('memo.txt') +False +>>> os.path.isdir('/home/dinsdale') +True +\end{verbatim} +% +Similarly, {\tt os.path.isfile} checks whether it's a file. + +{\tt os.listdir} returns a list of the files (and other directories) +in the given directory: + +\begin{verbatim} +>>> os.listdir(cwd) +['music', 'photos', 'memo.txt'] +\end{verbatim} +% +To demonstrate these functions, the following example +``walks'' through a directory, prints +the names of all the files, and calls itself recursively on +all the directories. +\index{walk, directory} +\index{directory!walk} + +\begin{verbatim} +def walk(dirname): + for name in os.listdir(dirname): + path = os.path.join(dirname, name) + + if os.path.isfile(path): + print(path) + else: + walk(path) +\end{verbatim} +% +{\tt os.path.join} takes a directory and a file name and joins +them into a complete path. + +The {\tt os} module provides a function called {\tt walk} that is +similar to this one but more versatile. As an exercise, read the +documentation and use it to print the names of the files in a given +directory and its subdirectories. You can download my solution from +\url{http://thinkpython2.com/code/walk.py}. + + +\section{Catching exceptions} +\label{catch} + +A lot of things can go wrong when you try to read and write +files. If you try to open a file that doesn't exist, you get an +{\tt IOError}: +\index{open function} +\index{function!open} +\index{exception!IOError} +\index{IOError} + +\begin{verbatim} +>>> fin = open('bad_file') +IOError: [Errno 2] No such file or directory: 'bad_file' +\end{verbatim} +% +If you don't have permission to access a file: +\index{file!permission} +\index{permission, file} + +\begin{verbatim} +>>> fout = open('/etc/passwd', 'w') +PermissionError: [Errno 13] Permission denied: '/etc/passwd' +\end{verbatim} +% +And if you try to open a directory for reading, you get + +\begin{verbatim} +>>> fin = open('/home') +IsADirectoryError: [Errno 21] Is a directory: '/home' +\end{verbatim} +% +To avoid these errors, you could use functions like {\tt os.path.exists} +and {\tt os.path.isfile}, but it would take a lot of time and code +to check all the possibilities (if ``{\tt Errno 21}'' is any +indication, there are at least 21 things that can go wrong). +\index{exception, catching} +\index{try statement} +\index{statement!try} + +It is better to go ahead and try---and deal with problems if they +happen---which is exactly what the {\tt try} statement does. The +syntax is similar to an {\tt if...else} statement: + +\begin{verbatim} +try: + fin = open('bad_file') +except: + print('Something went wrong.') +\end{verbatim} +% +Python starts by executing the {\tt try} clause. If all goes +well, it skips the {\tt except} clause and proceeds. If an +exception occurs, it jumps out of the {\tt try} clause and +runs the {\tt except} clause. + +Handling an exception with a {\tt try} statement is called {\bf +catching} an exception. In this example, the {\tt except} clause +prints an error message that is not very helpful. In general, +catching an exception gives you a chance to fix the problem, or try +again, or at least end the program gracefully. + + +\section{Databases} +\index{database} + +A {\bf database} is a file that is organized for storing data. Many +databases are organized like a dictionary in the sense that they map +from keys to values. The biggest difference between a database and a +dictionary is that the database is on disk (or other permanent +storage), so it persists after the program ends. \index{dbm + module} \index{module!dbm} + +The module {\tt dbm} provides an interface for creating +and updating database files. +As an example, I'll create a database +that contains captions for image files. +\index{open function} +\index{function!open} + +Opening a database is similar to opening other files: + +\begin{verbatim} +>>> import dbm +>>> db = dbm.open('captions', 'c') +\end{verbatim} +% +The mode \verb"'c'" means that the database should be created if +it doesn't already exist. The result is a database object +that can be used (for most operations) like a dictionary. +\index{database object} +\index{object!database} + +When you create a new item, {\tt dbm} updates the database file. +\index{update!database} + +\begin{verbatim} +>>> db['cleese.png'] = 'Photo of John Cleese.' +\end{verbatim} +% +When you access one of the items, {\tt dbm} reads the file: + +\begin{verbatim} +>>> db['cleese.png'] +b'Photo of John Cleese.' +\end{verbatim} +% +The result is a {\bf bytes object}, which is why it begins with {\tt + b}. A bytes object is similar to a string in many ways. When you +get farther into Python, the difference becomes important, but for now +we can ignore it. +\index{bytes object} +\index{object!bytes} + +If you make another assignment to an existing key, {\tt dbm} replaces +the old value: + +\begin{verbatim} +>>> db['cleese.png'] = 'Photo of John Cleese doing a silly walk.' +>>> db['cleese.png'] +b'Photo of John Cleese doing a silly walk.' +\end{verbatim} +% + +Some dictionary methods, like {\tt keys} and {\tt items}, don't +work with database objects. But iteration with a {\tt for} +loop works: +\index{dictionary methods!dbm module} + +\begin{verbatim} +for key in db: + print(key, db[key]) +\end{verbatim} +% +As with other files, you should close the database when you are +done: + +\begin{verbatim} +>>> db.close() +\end{verbatim} +% +\index{close method} +\index{method!close} + + +\section{Pickling} +\index{pickling} + +A limitation of {\tt dbm} is that the keys and values have to be +strings or bytes. If you try to use any other type, you get an error. +\index{pickle module} \index{module!pickle} + +The {\tt pickle} module can help. It translates +almost any type of object into a string suitable for storage in a +database, and then translates strings back into objects. + +{\tt pickle.dumps} takes an object as a parameter and returns +a string representation ({\tt dumps} is short for ``dump string''): + +\begin{verbatim} +>>> import pickle +>>> t = [1, 2, 3] +>>> pickle.dumps(t) +b'\x80\x03]q\x00(K\x01K\x02K\x03e.' +\end{verbatim} +% +The format isn't obvious to human readers; it is meant to be +easy for {\tt pickle} to interpret. {\tt pickle.loads} +(``load string'') reconstitutes the object: + +\begin{verbatim} +>>> t1 = [1, 2, 3] +>>> s = pickle.dumps(t1) +>>> t2 = pickle.loads(s) +>>> t2 +[1, 2, 3] +\end{verbatim} +% +Although the new object has the same value as the old, it is +not (in general) the same object: + +\begin{verbatim} +>>> t1 == t2 +True +>>> t1 is t2 +False +\end{verbatim} +% +In other words, pickling and then unpickling has the same effect +as copying the object. + +You can use {\tt pickle} to store non-strings in a database. +In fact, this combination is so common that it has been +encapsulated in a module called {\tt shelve}. +\index{shelve module} +\index{module!shelve} + + +\section{Pipes} +\index{shell} +\index{pipe} + +Most operating systems provide a command-line interface, +also known as a {\bf shell}. Shells usually provide commands +to navigate the file system and launch applications. For +example, in Unix you can change directories with {\tt cd}, +display the contents of a directory with {\tt ls}, and launch +a web browser by typing (for example) {\tt firefox}. +\index{ls (Unix command)} +\index{Unix command!ls} + +Any program that you can launch from the shell can also be +launched from Python using a {\bf pipe object}, which +represents a running program. + +For example, the Unix command {\tt ls -l} normally displays the +contents of the current directory in long format. You can +launch {\tt ls} with {\tt os.popen}\footnote{{\tt popen} is deprecated +now, which means we are supposed to stop using it and start using +the {\tt subprocess} module. But for simple cases, I find +{\tt subprocess} more complicated than necessary. So I am going +to keep using {\tt popen} until they take it away.}: +\index{popen function} +\index{function!popen} + +\begin{verbatim} +>>> cmd = 'ls -l' +>>> fp = os.popen(cmd) +\end{verbatim} +% +The argument is a string that contains a shell command. The +return value is an object that behaves like an open +file. You can read the output from the {\tt ls} process one +line at a time with {\tt readline} or get the whole thing at +once with {\tt read}: +\index{readline method} +\index{method!readline} +\index{read method} +\index{method!read} + +\begin{verbatim} +>>> res = fp.read() +\end{verbatim} +% +When you are done, you close the pipe like a file: +\index{close method} +\index{method!close} + +\begin{verbatim} +>>> stat = fp.close() +>>> print(stat) +None +\end{verbatim} +% +The return value is the final status of the {\tt ls} process; +{\tt None} means that it ended normally (with no errors). + +For example, most Unix systems provide a command called {\tt md5sum} +that reads the contents of a file and computes a ``checksum''. +You can read about MD5 at \url{http://en.wikipedia.org/wiki/Md5}. This +command provides an efficient way to check whether two files +have the same contents. The probability that different contents +yield the same checksum is very small (that is, unlikely to happen +before the universe collapses). +\index{md5} +\index{checksum} + +You can use a pipe to run {\tt md5sum} from Python and get the result: + +\begin{verbatim} +>>> filename = 'book.tex' +>>> cmd = 'md5sum ' + filename +>>> fp = os.popen(cmd) +>>> res = fp.read() +>>> stat = fp.close() +>>> print(res) +1e0033f0ed0656636de0d75144ba32e0 book.tex +>>> print(stat) +None +\end{verbatim} + + + +\section{Writing modules} +\label{modules} +\index{module, writing} +\index{word count} + +Any file that contains Python code can be imported as a module. +For example, suppose you have a file named {\tt wc.py} with the following +code: + +\begin{verbatim} +def linecount(filename): + count = 0 + for line in open(filename): + count += 1 + return count + +print(linecount('wc.py')) +\end{verbatim} +% +If you run this program, it reads itself and prints the number +of lines in the file, which is 7. +You can also import it like this: + +\begin{verbatim} +>>> import wc +7 +\end{verbatim} +% +Now you have a module object {\tt wc}: +\index{module object} +\index{object!module} + +\begin{verbatim} +>>> wc + +\end{verbatim} +% +The module object provides \verb"linecount": + +\begin{verbatim} +>>> wc.linecount('wc.py') +7 +\end{verbatim} +% +So that's how you write modules in Python. + +The only problem with this example is that when you import +the module it runs the test code at the bottom. Normally +when you import a module, it defines new functions but it +doesn't run them. +\index{import statement} +\index{statement!import} + +Programs that will be imported as modules often +use the following idiom: + +\begin{verbatim} +if __name__ == '__main__': + print(linecount('wc.py')) +\end{verbatim} +% +\verb"__name__" is a built-in variable that is set when the +program starts. If the program is running as a script, +\verb"__name__" has the value \verb"'__main__'"; in that +case, the test code runs. Otherwise, +if the module is being imported, the test code is skipped. + +\index{name built-in variable} +\index{main} + +As an exercise, type this example into a file named {\tt wc.py} and run +it as a script. Then run the Python interpreter and +{\tt import wc}. What is the value of \verb"__name__" +when the module is being imported? + +Warning: If you import a module that has already been imported, +Python does nothing. It does not re-read the file, even if it has +changed. +\index{module!reload} +\index{reload function} +\index{function!reload} + +If you want to reload a module, you can use the built-in function +{\tt reload}, but it can be tricky, so the safest thing to do is +restart the interpreter and then import the module again. + + +\section{Debugging} +\index{debugging} +\index{whitespace} + +When you are reading and writing files, you might run into problems +with whitespace. These errors can be hard to debug because spaces, +tabs and newlines are normally invisible: + +\begin{verbatim} +>>> s = '1 2\t 3\n 4' +>>> print(s) +1 2 3 + 4 +\end{verbatim} +\index{repr function} +\index{function!repr} +\index{string representation} + +The built-in function {\tt repr} can help. It takes any object as an +argument and returns a string representation of the object. For +strings, it represents whitespace +characters with backslash sequences: + +\begin{verbatim} +>>> print(repr(s)) +'1 2\t 3\n 4' +\end{verbatim} + +This can be helpful for debugging. + +One other problem you might run into is that different systems +use different characters to indicate the end of a line. Some +systems use a newline, represented \verb"\n". Others use +a return character, represented \verb"\r". Some use both. +If you move files between different systems, these inconsistencies +can cause problems. +\index{end of line character} + +For most systems, there are applications to convert from one +format to another. You can find them (and read more about this +issue) at \url{http://en.wikipedia.org/wiki/Newline}. Or, of course, you +could write one yourself. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[persistent:] Pertaining to a program that runs indefinitely +and keeps at least some of its data in permanent storage. +\index{persistence} + +\item[format operator:] An operator, {\tt \%}, that takes a format +string and a tuple and generates a string that includes +the elements of the tuple formatted as specified by the format string. +\index{format operator} +\index{operator!format} + +\item[format string:] A string, used with the format operator, that +contains format sequences. +\index{format string} + +\item[format sequence:] A sequence of characters in a format string, +like {\tt \%d}, that specifies how a value should be formatted. +\index{format sequence} + +\item[text file:] A sequence of characters stored in permanent +storage like a hard drive. +\index{text file} + +\item[directory:] A named collection of files, also called a folder. +\index{directory} + +\item[path:] A string that identifies a file. +\index{path} + +\item[relative path:] A path that starts from the current directory. +\index{relative path} + +\item[absolute path:] A path that starts from the topmost directory +in the file system. +\index{absolute path} + +\item[catch:] To prevent an exception from terminating +a program using the {\tt try} +and {\tt except} statements. +\index{catch} + +\item[database:] A file whose contents are organized like a dictionary +with keys that correspond to values. +\index{database} + +\item[bytes object:] An object similar to a string. +\index{bytes object} +\index{object!bytes} + +\item[shell:] A program that allows users to type commands and then +executes them by starting other programs. +\index{shell} + +\item[pipe object:] An object that represents a running program, allowing +a Python program to run commands and read the results. +\index{pipe object} +\index{object!pipe} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Write a function called {\tt sed} that takes as arguments a pattern string, +a replacement string, and two filenames; it should read the first file +and write the contents into the second file (creating it if +necessary). If the pattern string appears anywhere in the file, it +should be replaced with the replacement string. + +If an error occurs while opening, reading, writing or closing files, +your program should catch the exception, print an error message, and +exit. Solution: \url{http://thinkpython2.com/code/sed.py}. + +\end{exercise} + + +\begin{exercise} +\index{anagram set} +\index{set!anagram} + +If you download my solution to Exercise~\ref{anagrams} from +\url{http://thinkpython2.com/code/anagram_sets.py}, you'll see that it creates +a dictionary that maps from a sorted string of letters to the list of +words that can be spelled with those letters. For example, +\verb"'opst'" maps to the list +\verb"['opts', 'post', 'pots', 'spot', 'stop', 'tops']". + +Write a module that imports \verb"anagram_sets" and provides +two new functions: \verb"store_anagrams" should store the +anagram dictionary in a ``shelf''; \verb"read_anagrams" should +look up a word and return a list of its anagrams. +Solution: \url{http://thinkpython2.com/code/anagram_db.py}. + +\end{exercise} + + +\begin{exercise} +\label{checksum} +\index{MP3} + +In a large collection of MP3 files, there may be more than one +copy of the same song, stored in different directories or with +different file names. The goal of this exercise is to search for +duplicates. + +\begin{enumerate} + +\item Write a program that searches a directory and all of its +subdirectories, recursively, and returns a list of complete paths +for all files with a given suffix (like {\tt .mp3}). +Hint: {\tt os.path} provides several useful functions for +manipulating file and path names. +\index{duplicate} +\index{MD5 algorithm} +\index{algorithm!MD5} +\index{checksum} + +\item To recognize duplicates, you can use {\tt md5sum} +to compute a ``checksum'' for each files. If two files have +the same checksum, they probably have the same contents. +\index{md5sum} + +\item To double-check, you can use the Unix command {\tt diff}. +\index{diff} + +\end{enumerate} + +Solution: \url{http://thinkpython2.com/code/find_duplicates.py}. + +\end{exercise} + + + +\chapter{Classes and objects} +\label{clobjects} + +At this point you know how to use +functions to organize code and +built-in types to organize data. The next step is to learn +``object-oriented programming'', which uses programmer-defined types +to organize both code and data. Object-oriented programming is +a big topic; it will take a few chapters to get there. +\index{object-oriented programming} + +Code examples from this chapter are available from +\url{http://thinkpython2.com/code/Point1.py}; solutions +to the exercises are available from +\url{http://thinkpython2.com/code/Point1_soln.py}. + + +\section{Programmer-defined types} +\label{point} +\index{programmer-defined type} +\index{type!programmer-defined} + +We have used many of Python's built-in types; now we are going +to define a new type. As an example, we will create a type +called {\tt Point} that represents a point in two-dimensional +space. +\index{point, mathematical} + +In mathematical notation, points are often written in +parentheses with a comma separating the coordinates. For example, +$(0,0)$ represents the origin, and $(x,y)$ represents the +point $x$ units to the right and $y$ units up from the origin. + +There are several ways we might represent points in Python: + +\begin{itemize} + +\item We could store the coordinates separately in two +variables, {\tt x} and {\tt y}. + +\item We could store the coordinates as elements in a list +or tuple. + +\item We could create a new type to represent points as +objects. + +\end{itemize} +\index{representation} + +Creating a new type +is more complicated than the other options, but +it has advantages that will be apparent soon. + +A programmer-defined type is also called a {\bf class}. +A class definition looks like this: +\index{class} +\index{object!class} +\index{class definition} +\index{definition!class} + +\begin{verbatim} +class Point: + """Represents a point in 2-D space.""" +\end{verbatim} +% +The header indicates that the new class is called {\tt Point}. +The body is a docstring that explains what the class is for. +You can define variables and methods inside a class definition, +but we will get back to that later. +\index{Point class} +\index{class!Point} +\index{docstring} + +Defining a class named {\tt Point} creates a {\bf class object}. + +\begin{verbatim} +>>> Point + +\end{verbatim} +% +Because {\tt Point} is defined at the top level, its ``full +name'' is \verb"__main__.Point". +\index{object!class} +\index{class object} + +The class object is like a factory for creating objects. To create a +Point, you call {\tt Point} as if it were a function. + +\begin{verbatim} +>>> blank = Point() +>>> blank +<__main__.Point object at 0xb7e9d3ac> +\end{verbatim} +% +The return value is a reference to a Point object, which we +assign to {\tt blank}. + +Creating a new object is called +{\bf instantiation}, and the object is an {\bf instance} of +the class. +\index{instance} +\index{instantiation} + +When you print an instance, Python tells you what class it +belongs to and where it is stored in memory (the prefix +{\tt 0x} means that the following number is in hexadecimal). +\index{hexadecimal} + +Every object is an instance of some class, so ``object'' and +``instance'' are interchangeable. But in this chapter I use +``instance'' to indicate that I am talking about a programmer-defined +type. + + +\section{Attributes} +\label{attributes} +\index{instance attribute} +\index{attribute!instance} +\index{dot notation} + +You can assign values to an instance using dot notation: + +\begin{verbatim} +>>> blank.x = 3.0 +>>> blank.y = 4.0 +\end{verbatim} +% +This syntax is similar to the syntax for selecting a variable from a +module, such as {\tt math.pi} or {\tt string.whitespace}. In this case, +though, we are assigning values to named elements of an object. +These elements are called {\bf attributes}. + +As a noun, ``AT-trib-ute'' is pronounced with emphasis on the first +syllable, as opposed to ``a-TRIB-ute'', which is a verb. + +The following diagram shows the result of these assignments. +A state diagram that shows an object and its attributes is +called an {\bf object diagram}; see Figure~\ref{fig.point}. +\index{state diagram} +\index{diagram!state} +\index{object diagram} +\index{diagram!object} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/point.pdf}} +\caption{Object diagram.} +\label{fig.point} +\end{figure} + +The variable {\tt blank} refers to a Point object, which +contains two attributes. Each attribute refers to a +floating-point number. + +You can read the value of an attribute using the same syntax: + +\begin{verbatim} +>>> blank.y +4.0 +>>> x = blank.x +>>> x +3.0 +\end{verbatim} +% +The expression {\tt blank.x} means, ``Go to the object {\tt blank} +refers to and get the value of {\tt x}.'' In the example, we assign that +value to a variable named {\tt x}. There is no conflict between +the variable {\tt x} and the attribute {\tt x}. + +You can use dot notation as part of any expression. For example: + +\begin{verbatim} +>>> '(%g, %g)' % (blank.x, blank.y) +'(3.0, 4.0)' +>>> distance = math.sqrt(blank.x**2 + blank.y**2) +>>> distance +5.0 +\end{verbatim} +% +You can pass an instance as an argument in the usual way. +For example: +\index{instance!as argument} + +\begin{verbatim} +def print_point(p): + print('(%g, %g)' % (p.x, p.y)) +\end{verbatim} +% +\verb"print_point" takes a point as an argument and displays it in +mathematical notation. To invoke it, you can pass {\tt blank} as +an argument: + +\begin{verbatim} +>>> print_point(blank) +(3.0, 4.0) +\end{verbatim} +% +Inside the function, {\tt p} is an alias for {\tt blank}, so if +the function modifies {\tt p}, {\tt blank} changes. +\index{aliasing} + +As an exercise, write a function called \verb"distance_between_points" +that takes two Points as arguments and returns the distance between +them. + + +\section{Rectangles} +\label{rectangles} + +Sometimes it is obvious what the attributes of an object should be, +but other times you have to make decisions. For example, imagine you +are designing a class to represent rectangles. What attributes would +you use to specify the location and size of a rectangle? You can +ignore angle; to keep things simple, assume that the rectangle is +either vertical or horizontal. +\index{representation} + +There are at least two possibilities: + +\begin{itemize} + +\item You could specify one corner of the rectangle +(or the center), the width, and the height. + +\item You could specify two opposing corners. + +\end{itemize} + +At this point it is hard to say whether either is better than +the other, so we'll implement the first one, just as an example. +\index{Rectangle class} +\index{class!Rectangle} + +Here is the class definition: + +\begin{verbatim} +class Rectangle: + """Represents a rectangle. + + attributes: width, height, corner. + """ +\end{verbatim} +% +The docstring lists the attributes: {\tt width} and +{\tt height} are numbers; {\tt corner} is a Point object that +specifies the lower-left corner. + +To represent a rectangle, you have to instantiate a Rectangle +object and assign values to the attributes: + +\begin{verbatim} +box = Rectangle() +box.width = 100.0 +box.height = 200.0 +box.corner = Point() +box.corner.x = 0.0 +box.corner.y = 0.0 +\end{verbatim} +% +The expression {\tt box.corner.x} means, +``Go to the object {\tt box} refers to and select the attribute named +{\tt corner}; then go to that object and select the attribute named +{\tt x}.'' + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/rectangle.pdf}} +\caption{Object diagram.} +\label{fig.rectangle} +\end{figure} + + +Figure~\ref{fig.rectangle} shows the state of this object. +An object that is an attribute of another object is {\bf embedded}. +\index{state diagram} +\index{diagram!state} +\index{object diagram} +\index{diagram!object} +\index{embedded object} +\index{object!embedded} + + +\section{Instances as return values} +\index{instance!as return value} +\index{return value} + +Functions can return instances. For example, \verb"find_center" +takes a {\tt Rectangle} as an argument and returns a {\tt Point} +that contains the coordinates of the center of the {\tt Rectangle}: + +\begin{verbatim} +def find_center(rect): + p = Point() + p.x = rect.corner.x + rect.width/2 + p.y = rect.corner.y + rect.height/2 + return p +\end{verbatim} +% +Here is an example that passes {\tt box} as an argument and assigns +the resulting Point to {\tt center}: + +\begin{verbatim} +>>> center = find_center(box) +>>> print_point(center) +(50, 100) +\end{verbatim} +% + +\section{Objects are mutable} +\index{object!mutable} +\index{mutability} + +You can change the state of an object by making an assignment to one of +its attributes. For example, to change the size of a rectangle +without changing its position, you can modify the values of {\tt +width} and {\tt height}: + +\begin{verbatim} +box.width = box.width + 50 +box.height = box.height + 100 +\end{verbatim} +% +You can also write functions that modify objects. For example, +\verb"grow_rectangle" takes a Rectangle object and two numbers, +{\tt dwidth} and {\tt dheight}, and adds the numbers to the +width and height of the rectangle: + +\begin{verbatim} +def grow_rectangle(rect, dwidth, dheight): + rect.width += dwidth + rect.height += dheight +\end{verbatim} +% +Here is an example that demonstrates the effect: + +\begin{verbatim} +>>> box.width, box.height +(150.0, 300.0) +>>> grow_rectangle(box, 50, 100) +>>> box.width, box.height +(200.0, 400.0) +\end{verbatim} +% +Inside the function, {\tt rect} is an +alias for {\tt box}, so when the function modifies {\tt rect}, +{\tt box} changes. + +As an exercise, write a function named \verb"move_rectangle" that takes +a Rectangle and two numbers named {\tt dx} and {\tt dy}. It +should change the location of the rectangle by adding {\tt dx} +to the {\tt x} coordinate of {\tt corner} and adding {\tt dy} +to the {\tt y} coordinate of {\tt corner}. + + +\section{Copying} +\label{copying} +\index{aliasing} + +Aliasing can make a program difficult to read because changes +in one place might have unexpected effects in another place. +It is hard to keep track of all the variables that might refer +to a given object. +\index{copying objects} +\index{object!copying} +\index{copy module} +\index{module!copy} + +Copying an object is often an alternative to aliasing. +The {\tt copy} module contains a function called {\tt copy} that +can duplicate any object: + +\begin{verbatim} +>>> p1 = Point() +>>> p1.x = 3.0 +>>> p1.y = 4.0 + +>>> import copy +>>> p2 = copy.copy(p1) +\end{verbatim} +% +{\tt p1} and {\tt p2} contain the same data, but they are +not the same Point. + +\begin{verbatim} +>>> print_point(p1) +(3, 4) +>>> print_point(p2) +(3, 4) +>>> p1 is p2 +False +>>> p1 == p2 +False +\end{verbatim} +% +The {\tt is} operator indicates that {\tt p1} and {\tt p2} are not the +same object, which is what we expected. But you might have expected +{\tt ==} to yield {\tt True} because these points contain the same +data. In that case, you will be disappointed to learn that for +instances, the default behavior of the {\tt ==} operator is the same +as the {\tt is} operator; it checks object identity, not object +equivalence. That's because for programmer-defined types, Python doesn't +know what should be considered equivalent. At least, not yet. +\index{is operator} +\index{operator!is} +\index{identity} +\index{equivalence} + +If you use {\tt copy.copy} to duplicate a Rectangle, you will find +that it copies the Rectangle object but not the embedded Point. +\index{embedded object!copying} + +\begin{verbatim} +>>> box2 = copy.copy(box) +>>> box2 is box +False +>>> box2.corner is box.corner +True +\end{verbatim} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/rectangle2.pdf}} +\caption{Object diagram.} +\label{fig.rectangle2} +\end{figure} + +Figure~\ref{fig.rectangle2} shows what the object diagram looks like. +\index{state diagram} +\index{diagram!state} +\index{object diagram} +\index{diagram!object} +This operation is called a {\bf shallow copy} because it copies the +object and any references it contains, but not the embedded objects. +\index{shallow copy} +\index{copy!shallow} + +For most applications, this is not what you want. In this example, +invoking \verb"grow_rectangle" on one of the Rectangles would not +affect the other, but invoking \verb"move_rectangle" on either would +affect both! This behavior is confusing and error-prone. +\index{deep copy} +\index{copy!deep} + +Fortunately, the {\tt copy} module provides a method named {\tt +deepcopy} that copies not only the object but also +the objects it refers to, and the objects {\em they} refer to, +and so on. +You will not be surprised to learn that this operation is +called a {\bf deep copy}. +\index{deepcopy function} +\index{function!deepcopy} + +\begin{verbatim} +>>> box3 = copy.deepcopy(box) +>>> box3 is box +False +>>> box3.corner is box.corner +False +\end{verbatim} +% +{\tt box3} and {\tt box} are completely separate objects. + +As an exercise, write a version of \verb"move_rectangle" that creates and +returns a new Rectangle instead of modifying the old one. + + +\section{Debugging} +\label{hasattr} +\index{debugging} + +When you start working with objects, you are likely to encounter +some new exceptions. If you try to access an attribute +that doesn't exist, you get an {\tt AttributeError}: +\index{exception!AttributeError} +\index{AttributeError} + +\begin{verbatim} +>>> p = Point() +>>> p.x = 3 +>>> p.y = 4 +>>> p.z +AttributeError: Point instance has no attribute 'z' +\end{verbatim} +% +If you are not sure what type an object is, you can ask: +\index{type function} +\index{function!type} + +\begin{verbatim} +>>> type(p) + +\end{verbatim} +% +You can also use {\tt isinstance} to check whether an object +is an instance of a class: +\index{isinstance function} +\index{function!isinstance} + +\begin{verbatim} +>>> isinstance(p, Point) +True +\end{verbatim} +% +If you are not sure whether an object has a particular attribute, +you can use the built-in function {\tt hasattr}: +\index{hasattr function} +\index{function!hasattr} + +\begin{verbatim} +>>> hasattr(p, 'x') +True +>>> hasattr(p, 'z') +False +\end{verbatim} +% +The first argument can be any object; the second argument is a {\em +string} that contains the name of the attribute. +\index{attribute} + +You can also use a {\tt try} statement to see if the object has the +attributes you need: +\index{try statement} +\index{statement!try} + +\begin{verbatim} +try: + x = p.x +except AttributeError: + x = 0 +\end{verbatim} + +This approach can make it easier to write functions that work with +different types; more on that topic is +coming up in Section~\ref{polymorphism}. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[class:] A programmer-defined type. A class definition creates a new +class object. +\index{class} +\index{programmer-defined type} +\index{type!programmer-defined} + +\item[class object:] An object that contains information about a +programmer-defined type. The class object can be used to create instances +of the type. +\index{class object} +\index{object!class} + +\item[instance:] An object that belongs to a class. +\index{instance} + +\item[instantiate:] To create a new object. +\index{instantiate} + +\item[attribute:] One of the named values associated with an object. +\index{attribute!instance} +\index{instance attribute} + +\item[embedded object:] An object that is stored as an attribute +of another object. +\index{embedded object} +\index{object!embedded} + +\item[shallow copy:] To copy the contents of an object, including +any references to embedded objects; +implemented by the {\tt copy} function in the {\tt copy} module. +\index{shallow copy} + +\item[deep copy:] To copy the contents of an object as well as any +embedded objects, and any objects embedded in them, and so on; +implemented by the {\tt deepcopy} function in the {\tt copy} module. +\index{deep copy} + +\item[object diagram:] A diagram that shows objects, their +attributes, and the values of the attributes. +\index{object diagram} +\index{diagram!object} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Write a definition for a class named {\tt Circle} with attributes +{\tt center} and {\tt radius}, where {\tt center} is a Point object +and radius is a number. + +Instantiate a Circle object that represents a circle with its center +at $(150, 100)$ and radius 75. + +Write a function named \verb"point_in_circle" that takes a Circle and +a Point and returns True if the Point lies in or on the boundary of +the circle. + +Write a function named \verb"rect_in_circle" that takes a Circle and a +Rectangle and returns True if the Rectangle lies entirely in or on the boundary +of the circle. + +Write a function named \verb"rect_circle_overlap" that takes a Circle +and a Rectangle and returns True if any of the corners of the Rectangle fall +inside the circle. Or as a more challenging version, return True if +any part of the Rectangle falls inside the circle. + +Solution: \url{http://thinkpython2.com/code/Circle.py}. + +\end{exercise} + + +\begin{exercise} + +Write a function called \verb"draw_rect" that takes a Turtle object +and a Rectangle and uses the Turtle to draw the Rectangle. See +Chapter~\ref{turtlechap} for examples using Turtle objects. + +Write a function called \verb"draw_circle" that takes a Turtle and +a Circle and draws the Circle. + +Solution: \url{http://thinkpython2.com/code/draw.py}. + +\end{exercise} + + + +\chapter{Classes and functions} +\label{time} + +Now that we know how to create new types, the next +step is to write functions that take programmer-defined objects +as parameters and return them as results. In this chapter I +also present ``functional programming style'' and two new +program development plans. + +Code examples from this chapter are available from +\url{http://thinkpython2.com/code/Time1.py}. +Solutions to the exercises are at +\url{http://thinkpython2.com/code/Time1_soln.py}. + + +\section{Time} +\label{isafter} + +As another example of a programmer-defined type, we'll define a class +called {\tt Time} that records the time of day. The class definition +looks like this: \index{programmer-defined type} +\index{type!programmer-defined} \index{Time class} \index{class!Time} + +\begin{verbatim} +class Time: + """Represents the time of day. + + attributes: hour, minute, second + """ +\end{verbatim} +% +We can create a new {\tt Time} object and assign +attributes for hours, minutes, and seconds: + +\begin{verbatim} +time = Time() +time.hour = 11 +time.minute = 59 +time.second = 30 +\end{verbatim} +% +The state diagram for the {\tt Time} object looks like Figure~\ref{fig.time}. +\index{state diagram} +\index{diagram!state} +\index{object diagram} +\index{diagram!object} + +As an exercise, write a function called \verb"print_time" that takes a +Time object and prints it in the form {\tt hour:minute:second}. +Hint: the format sequence \verb"'%.2d'" prints an integer using +at least two digits, including a leading zero if necessary. + +Write a boolean function called \verb"is_after" that +takes two Time objects, {\tt t1} and {\tt t2}, and +returns {\tt True} if {\tt t1} follows {\tt t2} chronologically and +{\tt False} otherwise. Challenge: don't use an {\tt if} statement. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/time.pdf}} +\caption{Object diagram.} +\label{fig.time} +\end{figure} + + +\section{Pure functions} +\index{prototype and patch} +\index{development plan!prototype and patch} + +In the next few sections, we'll write two functions that add time +values. They demonstrate two kinds of functions: pure functions and +modifiers. They also demonstrate a development plan I'll call {\bf + prototype and patch}, which is a way of tackling a complex problem +by starting with a simple prototype and incrementally dealing with the +complications. + +Here is a simple prototype of \verb"add_time": + +\begin{verbatim} +def add_time(t1, t2): + sum = Time() + sum.hour = t1.hour + t2.hour + sum.minute = t1.minute + t2.minute + sum.second = t1.second + t2.second + return sum +\end{verbatim} +% +The function creates a new {\tt Time} object, initializes its +attributes, and returns a reference to the new object. This is called +a {\bf pure function} because it does not modify any of the objects +passed to it as arguments and it has no effect, +like displaying a value or getting user input, +other than returning a value. +\index{pure function} +\index{function type!pure} + +To test this function, I'll create two Time objects: {\tt start} +contains the start time of a movie, like {\em Monty Python and the +Holy Grail}, and {\tt duration} contains the run time of the movie, +which is one hour 35 minutes. +\index{Monty Python and the Holy Grail} + +\verb"add_time" figures out when the movie will be done. + +\begin{verbatim} +>>> start = Time() +>>> start.hour = 9 +>>> start.minute = 45 +>>> start.second = 0 + +>>> duration = Time() +>>> duration.hour = 1 +>>> duration.minute = 35 +>>> duration.second = 0 + +>>> done = add_time(start, duration) +>>> print_time(done) +10:80:00 +\end{verbatim} +% +The result, {\tt 10:80:00} might not be what you were hoping +for. The problem is that this function does not deal with cases where the +number of seconds or minutes adds up to more than sixty. When that +happens, we have to ``carry'' the extra seconds into the minute column +or the extra minutes into the hour column. +\index{carrying, addition with} + +Here's an improved version: + +\begin{verbatim} +def add_time(t1, t2): + sum = Time() + sum.hour = t1.hour + t2.hour + sum.minute = t1.minute + t2.minute + sum.second = t1.second + t2.second + + if sum.second >= 60: + sum.second -= 60 + sum.minute += 1 + + if sum.minute >= 60: + sum.minute -= 60 + sum.hour += 1 + + return sum +\end{verbatim} +% +Although this function is correct, it is starting to get big. +We will see a shorter alternative later. + + +\section{Modifiers} +\label{increment} +\index{modifier} +\index{function type!modifier} + +Sometimes it is useful for a function to modify the objects it gets as +parameters. In that case, the changes are visible to the caller. +Functions that work this way are called {\bf modifiers}. +\index{increment} + +{\tt increment}, which adds a given number of seconds to a {\tt Time} +object, can be written naturally as a +modifier. Here is a rough draft: + +\begin{verbatim} +def increment(time, seconds): + time.second += seconds + + if time.second >= 60: + time.second -= 60 + time.minute += 1 + + if time.minute >= 60: + time.minute -= 60 + time.hour += 1 +\end{verbatim} +% +The first line performs the basic operation; the remainder deals +with the special cases we saw before. +\index{special case} + +Is this function correct? What happens if {\tt seconds} +is much greater than sixty? + +In that case, it is not enough to carry once; we have to keep doing it +until {\tt time.second} is less than sixty. One solution is to +replace the {\tt if} statements with {\tt while} statements. That +would make the function correct, but not very efficient. As an +exercise, write a correct version of {\tt increment} that doesn't +contain any loops. + +Anything that can be done with modifiers can also be done with pure +functions. In fact, some programming languages only allow pure +functions. There is some evidence that programs that use pure +functions are faster to develop and less error-prone than programs +that use modifiers. But modifiers are convenient at times, +and functional programs tend to be less efficient. + +In general, I recommend that you write pure functions whenever it is +reasonable and resort to modifiers only if there is a compelling +advantage. This approach might be called a {\bf functional +programming style}. +\index{functional programming style} + +As an exercise, write a ``pure'' version of {\tt increment} that +creates and returns a new Time object rather than modifying the +parameter. + + +\section{Prototyping versus planning} +\label{prototype} +\index{prototype and patch} +\index{development plan!prototype and patch} +\index{planned development} +\index{development plan!designed} + +The development plan I am demonstrating is called ``prototype and +patch''. For each function, I wrote a prototype that performed the +basic calculation and then tested it, patching errors along the +way. + +This approach can be effective, especially if you don't yet have a +deep understanding of the problem. But incremental corrections can +generate code that is unnecessarily complicated---since it deals with +many special cases---and unreliable---since it is hard to know if you +have found all the errors. + +An alternative is {\bf designed development}, in which high-level +insight into the problem can make the programming much easier. In +this case, the insight is that a Time object is really a three-digit +number in base 60 (see \url{http://en.wikipedia.org/wiki/Sexagesimal}.)! The +{\tt second} attribute is the ``ones column'', the {\tt minute} +attribute is the ``sixties column'', and the {\tt hour} attribute is +the ``thirty-six hundreds column''. +\index{sexagesimal} + +When we wrote \verb"add_time" and {\tt increment}, we were effectively +doing addition in base 60, which is why we had to carry from one +column to the next. +\index{carrying, addition with} + +This observation suggests another approach to the whole problem---we +can convert Time objects to integers and take advantage of the fact +that the computer knows how to do integer arithmetic. + +Here is a function that converts Times to integers: + +\begin{verbatim} +def time_to_int(time): + minutes = time.hour * 60 + time.minute + seconds = minutes * 60 + time.second + return seconds +\end{verbatim} +% +And here is a function that converts an integer to a Time +(recall that {\tt divmod} divides the first argument by the second +and returns the quotient and remainder as a tuple). +\index{divmod} + +\begin{verbatim} +def int_to_time(seconds): + time = Time() + minutes, time.second = divmod(seconds, 60) + time.hour, time.minute = divmod(minutes, 60) + return time +\end{verbatim} +% +You might have to think a bit, and run some tests, to convince +yourself that these functions are correct. One way to test them is to +check that \verb"time_to_int(int_to_time(x)) == x" for many values of +{\tt x}. This is an example of a consistency check. +\index{consistency check} + +Once you are convinced they are correct, you can use them to +rewrite \verb"add_time": + +\begin{verbatim} +def add_time(t1, t2): + seconds = time_to_int(t1) + time_to_int(t2) + return int_to_time(seconds) +\end{verbatim} +% +This version is shorter than the original, and easier to verify. As +an exercise, rewrite {\tt increment} using \verb"time_to_int" and +\verb"int_to_time". + +In some ways, converting from base 60 to base 10 and back is harder +than just dealing with times. Base conversion is more abstract; our +intuition for dealing with time values is better. + +But if we have the insight to treat times as base 60 numbers and make +the investment of writing the conversion functions (\verb"time_to_int" +and \verb"int_to_time"), we get a program that is shorter, easier to +read and debug, and more reliable. + +It is also easier to add features later. For example, imagine +subtracting two Times to find the duration between them. The +naive approach would be to implement subtraction with borrowing. +Using the conversion functions would be easier and more likely to be +correct. +\index{subtraction with borrowing} +\index{borrowing, subtraction with} +\index{generalization} + +Ironically, sometimes making a problem harder (or more general) makes it +easier (because there are fewer special cases and fewer opportunities +for error). + + +\section{Debugging} +\index{debugging} + +A Time object is well-formed if the values of {\tt minute} and {\tt +second} are between 0 and 60 (including 0 but not 60) and if +{\tt hour} is positive. {\tt hour} and {\tt minute} should be +integral values, but we might allow {\tt second} to have a +fraction part. +\index{invariant} + +Requirements like these are called {\bf invariants} because +they should always be true. To put it a different way, if they +are not true, something has gone wrong. + +Writing code to check invariants can help detect errors +and find their causes. For example, you might have a function +like \verb"valid_time" that takes a Time object and returns +{\tt False} if it violates an invariant: + +\begin{verbatim} +def valid_time(time): + if time.hour < 0 or time.minute < 0 or time.second < 0: + return False + if time.minute >= 60 or time.second >= 60: + return False + return True +\end{verbatim} +% +At the beginning of each function you could check the +arguments to make sure they are valid: +\index{raise statement} +\index{statement!raise} + +\begin{verbatim} +def add_time(t1, t2): + if not valid_time(t1) or not valid_time(t2): + raise ValueError('invalid Time object in add_time') + seconds = time_to_int(t1) + time_to_int(t2) + return int_to_time(seconds) +\end{verbatim} +% +Or you could use an {\bf assert statement}, which checks a given invariant +and raises an exception if it fails: +\index{assert statement} +\index{statement!assert} + +\begin{verbatim} +def add_time(t1, t2): + assert valid_time(t1) and valid_time(t2) + seconds = time_to_int(t1) + time_to_int(t2) + return int_to_time(seconds) +\end{verbatim} +% +{\tt assert} statements are useful because they distinguish +code that deals with normal conditions from code +that checks for errors. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[prototype and patch:] A development plan that involves +writing a rough draft of a program, testing, and correcting errors as +they are found. +\index{prototype and patch} + +\item[designed development:] A development plan that involves +high-level insight into the problem and more planning than incremental +development or prototype development. +\index{designed development} + +\item[pure function:] A function that does not modify any of the objects it +receives as arguments. Most pure functions are fruitful. +\index{pure function} + +\item[modifier:] A function that changes one or more of the objects it + receives as arguments. Most modifiers are void; that is, they + return {\tt None}. \index{modifier} + +\item[functional programming style:] A style of program design in which the +majority of functions are pure. +\index{functional programming style} + +\item[invariant:] A condition that should always be true during the +execution of a program. +\index{invariant} + +\item[assert statement:] A statement that check a condition and raises +an exception if it fails. +\index{assert statement} +\index{statement!assert} + +\end{description} + + +\section{연습 문제} +%Exercises + +Code examples from this chapter are available from +\url{http://thinkpython2.com/code/Time1.py}; solutions to the +exercises are available from \url{http://thinkpython2.com/code/Time1_soln.py}. + +\begin{exercise} + +Write a function called \verb"mul_time" that takes a Time object +and a number and returns a new Time object that contains +the product of the original Time and the number. + +Then use \verb"mul_time" to write a function that takes a Time +object that represents the finishing time in a race, and a number +that represents the distance, and returns a Time object that represents +the average pace (time per mile). +\index{running pace} + +\end{exercise} + + +\begin{exercise} +\index{datetime module} +\index{module!datetime} + +The {\tt datetime} module provides {\tt time} objects +that are similar to the Time objects in this chapter, but +they provide a rich set of methods and operators. Read the +documentation at \url{http://docs.python.org/3/library/datetime.html}. + +\begin{enumerate} + +\item Use the {\tt datetime} module to write a program that gets the + current date and prints the day of the week. + +\item Write a program that takes a birthday as input and prints the + user's age and the number of days, hours, minutes and seconds until + their next birthday. +\index{birthday} + +\item For two people born on different days, there is a day when one + is twice as old as the other. That's their Double Day. Write a + program that takes two birthdays and computes their Double Day. + +\item For a little more challenge, write the more general version that + computes the day when one person is $n$ times older than the other. +\index{Double Day} + +\end{enumerate} + +Solution: \url{http://thinkpython2.com/code/double.py} + +\end{exercise} + + +\chapter{Classes and methods} + +Although we are using some of Python's object-oriented features, +the programs from the last two chapters are not really +object-oriented because they don't represent the relationships +between programmer-defined types and the functions that operate +on them. The next step is to transform those functions into +methods that make the relationships explicit. + +Code examples from this chapter are available from +\url{http://thinkpython2.com/code/Time2.py}, and solutions +to the exercises are in \url{http://thinkpython2.com/code/Point2_soln.py}. + + +\section{Object-oriented features} +\index{object-oriented programming} + +Python is an {\bf object-oriented programming language}, which means +that it provides features that support object-oriented +programming, which has these defining characteristics: + +\begin{itemize} + +\item Programs include class and method definitions. + +\item Most of the computation is expressed in terms of operations on + objects. + +\item Objects often represent things +in the real world, and methods often +correspond to the ways things in the real world interact. + +\end{itemize} + +For example, the {\tt Time} class defined in Chapter~\ref{time} +corresponds to the way people record the time of day, and the +functions we defined correspond to the kinds of things people do with +times. Similarly, the {\tt Point} and {\tt Rectangle} classes +in Chapter~\ref{clobjects} +correspond to the mathematical concepts of a point and a rectangle. + +So far, we have not taken advantage of the features Python provides to +support object-oriented programming. These +features are not strictly necessary; most of them provide +alternative syntax for things we have already done. But in many cases, +the alternative is more concise and more accurately conveys the +structure of the program. + +For example, in {\tt Time1.py} there is no obvious +connection between the class definition and the function definitions +that follow. With some examination, it is apparent that every function +takes at least one {\tt Time} object as an argument. +\index{method} +\index{function} + +This observation is the motivation for {\bf methods}; a method is +a function that is associated with a particular class. +We have seen methods for strings, lists, dictionaries and tuples. +In this chapter, we will define methods for programmer-defined types. +\index{syntax} +\index{semantics} +\index{programmer-defined type} +\index{type!programmer-defined} + +Methods are semantically the same as functions, but there are +two syntactic differences: + +\begin{itemize} + +\item Methods are defined inside a class definition in order +to make the relationship between the class and the method explicit. + +\item The syntax for invoking a method is different from the +syntax for calling a function. + +\end{itemize} + +In the next few sections, we will take the functions from the previous +two chapters and transform them into methods. This transformation is +purely mechanical; you can do it by following a sequence of +steps. If you are comfortable converting from one form to another, +you will be able to choose the best form for whatever you are doing. + + +\section{Printing objects} +\index{object!printing} + +In Chapter~\ref{time}, we defined a class named +{\tt Time} and in Section~\ref{isafter}, you +wrote a function named \verb"print_time": + +\begin{verbatim} +class Time: + """Represents the time of day.""" + +def print_time(time): + print('%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)) +\end{verbatim} +% +To call this function, you have to pass a {\tt Time} object as an +argument: + +\begin{verbatim} +>>> start = Time() +>>> start.hour = 9 +>>> start.minute = 45 +>>> start.second = 00 +>>> print_time(start) +09:45:00 +\end{verbatim} +% +To make \verb"print_time" a method, all we have to do is +move the function definition inside the class definition. Notice +the change in indentation. +\index{indentation} + +\begin{verbatim} +class Time: + def print_time(time): + print('%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)) +\end{verbatim} +% +Now there are two ways to call \verb"print_time". The first +(and less common) way is to use function syntax: +\index{function syntax} +\index{dot notation} + +\begin{verbatim} +>>> Time.print_time(start) +09:45:00 +\end{verbatim} +% +In this use of dot notation, {\tt Time} is the name of the class, +and \verb"print_time" is the name of the method. {\tt start} is +passed as a parameter. + +The second (and more concise) way is to use method syntax: +\index{method syntax} + +\begin{verbatim} +>>> start.print_time() +09:45:00 +\end{verbatim} +% +In this use of dot notation, \verb"print_time" is the name of the +method (again), and {\tt start} is the object the method is +invoked on, which is called the {\bf subject}. Just as the +subject of a sentence is what the sentence is about, the subject +of a method invocation is what the method is about. +\index{subject} + +Inside the method, the subject is assigned to the first +parameter, so in this case {\tt start} is assigned +to {\tt time}. +\index{self (parameter name)} +\index{parameter!self} + +By convention, the first parameter of a method is +called {\tt self}, so it would be more common to write +\verb"print_time" like this: + +\begin{verbatim} +class Time: + def print_time(self): + print('%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)) +\end{verbatim} +% +The reason for this convention is an implicit metaphor: +\index{metaphor, method invocation} + +\begin{itemize} + +\item The syntax for a function call, \verb"print_time(start)", + suggests that the function is the active agent. It says something + like, ``Hey \verb"print_time"! Here's an object for you to print.'' + +\item In object-oriented programming, the objects are the active + agents. A method invocation like \verb"start.print_time()" says + ``Hey {\tt start}! Please print yourself.'' + +\end{itemize} + +This change in perspective might be more polite, but it is not obvious +that it is useful. In the examples we have seen so far, it may not +be. But sometimes shifting responsibility from the functions onto the +objects makes it possible to write more versatile functions (or +methods), and makes it easier to maintain and reuse code. + +As an exercise, rewrite \verb"time_to_int" (from +Section~\ref{prototype}) as a method. You might be tempted to +rewrite \verb"int_to_time" as a method, too, but that doesn't +really make sense because there would be no object to invoke +it on. + + +\section{Another example} +\index{increment} + +Here's a version of {\tt increment} (from Section~\ref{increment}) +rewritten as a method: + +\begin{verbatim} +# inside class Time: + + def increment(self, seconds): + seconds += self.time_to_int() + return int_to_time(seconds) +\end{verbatim} +% +This version assumes that \verb"time_to_int" is written +as a method. Also, note that +it is a pure function, not a modifier. + +Here's how you would invoke {\tt increment}: + +\begin{verbatim} +>>> start.print_time() +09:45:00 +>>> end = start.increment(1337) +>>> end.print_time() +10:07:17 +\end{verbatim} +% +The subject, {\tt start}, gets assigned to the first parameter, +{\tt self}. The argument, {\tt 1337}, gets assigned to the +second parameter, {\tt seconds}. + +This mechanism can be confusing, especially if you make an error. +For example, if you invoke {\tt increment} with two arguments, you +get: +\index{exception!TypeError} +\index{TypeError} + +\begin{verbatim} +>>> end = start.increment(1337, 460) +TypeError: increment() takes 2 positional arguments but 3 were given +\end{verbatim} +% +The error message is initially confusing, because there are +only two arguments in parentheses. But the subject is also +considered an argument, so all together that's three. + +By the way, a {\bf positional argument} is an argument that +doesn't have a parameter name; that is, it is not a keyword +argument. In this function call: +\index{positional argument} +\index{argument!positional} + +\begin{verbatim} +sketch(parrot, cage, dead=True) +\end{verbatim} + +{\tt parrot} and {\tt cage} are positional, and {\tt dead} is +a keyword argument. + + +\section{A more complicated example} + +Rewriting \verb"is_after" (from Section~\ref{isafter}) is slightly +more complicated because it takes two Time objects as parameters. In +this case it is conventional to name the first parameter {\tt self} +and the second parameter {\tt other}: \index{other (parameter name)} +\index{parameter!other} + +\begin{verbatim} +# inside class Time: + + def is_after(self, other): + return self.time_to_int() > other.time_to_int() +\end{verbatim} +% +To use this method, you have to invoke it on one object and pass +the other as an argument: + +\begin{verbatim} +>>> end.is_after(start) +True +\end{verbatim} +% +One nice thing about this syntax is that it almost reads +like English: ``end is after start?'' + + +\section{The init method} +\index{init method} +\index{method!init} + +The init method (short for ``initialization'') is +a special method that gets invoked when an object is instantiated. +Its full name is \verb"__init__" (two underscore characters, +followed by {\tt init}, and then two more underscores). An +init method for the {\tt Time} class might look like this: + +\begin{verbatim} +# inside class Time: + + def __init__(self, hour=0, minute=0, second=0): + self.hour = hour + self.minute = minute + self.second = second +\end{verbatim} +% +It is common for the parameters of \verb"__init__" +to have the same names as the attributes. The statement + +\begin{verbatim} + self.hour = hour +\end{verbatim} +% +stores the value of the parameter {\tt hour} as an attribute +of {\tt self}. +\index{optional parameter} +\index{parameter!optional} +\index{default value} +\index{override} + +The parameters are optional, so if you call {\tt Time} with +no arguments, you get the default values. + +\begin{verbatim} +>>> time = Time() +>>> time.print_time() +00:00:00 +\end{verbatim} +% +If you provide one argument, it overrides {\tt hour}: + +\begin{verbatim} +>>> time = Time (9) +>>> time.print_time() +09:00:00 +\end{verbatim} +% +If you provide two arguments, they override {\tt hour} and +{\tt minute}. + +\begin{verbatim} +>>> time = Time(9, 45) +>>> time.print_time() +09:45:00 +\end{verbatim} +% +And if you provide three arguments, they override all three +default values. + +As an exercise, write an init method for the {\tt Point} class that takes +{\tt x} and {\tt y} as optional parameters and assigns +them to the corresponding attributes. +\index{Point class} +\index{class!Point} + + +\section{The {\tt \_\_str\_\_} method} +\index{str method@\_\_str\_\_ method} +\index{method!\_\_str\_\_} + +\verb"__str__" is a special method, like \verb"__init__", +that is supposed to return a string representation of an object. +\index{string representation} + +For example, here is a {\tt str} method for Time objects: + +\begin{verbatim} +# inside class Time: + + def __str__(self): + return '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second) +\end{verbatim} +% +When you {\tt print} an object, Python invokes the {\tt str} method: +\index{print statement} +\index{statement!print} + +\begin{verbatim} +>>> time = Time(9, 45) +>>> print(time) +09:45:00 +\end{verbatim} +% +When I write a new class, I almost always start by writing +\verb"__init__", which makes it easier to instantiate objects, and +\verb"__str__", which is useful for debugging. + +As an exercise, write a {\tt str} method for the {\tt Point} class. +Create a Point object and print it. + + +\section{Operator overloading} +\label{operator.overloading} + +By defining other special methods, you can specify the behavior +of operators on programmer-defined types. For example, if you define +a method named \verb"__add__" for the {\tt Time} class, you can use the +{\tt +} operator on Time objects. +\index{programmer-defined type} +\index{type!programmer-defined} + +Here is what the definition might look like: +\index{add method} +\index{method!add} + +\begin{verbatim} +# inside class Time: + + def __add__(self, other): + seconds = self.time_to_int() + other.time_to_int() + return int_to_time(seconds) +\end{verbatim} +% +And here is how you could use it: + +\begin{verbatim} +>>> start = Time(9, 45) +>>> duration = Time(1, 35) +>>> print(start + duration) +11:20:00 +\end{verbatim} +% +When you apply the {\tt +} operator to Time objects, Python invokes +\verb"__add__". When you print the result, Python invokes +\verb"__str__". So there is a lot happening behind the scenes! +\index{operator overloading} + +Changing the behavior of an operator so that it works with +programmer-defined types is called {\bf operator overloading}. For every +operator in Python there is a corresponding special method, like +\verb"__add__". For more details, see +\url{http://docs.python.org/3/reference/datamodel.html#specialnames}. + +As an exercise, write an {\tt add} method for the Point class. + + +\section{Type-based dispatch} + +In the previous section we added two Time objects, but you +also might want to add an integer to a Time object. The +following is a version of \verb"__add__" +that checks the type of {\tt other} and invokes either +\verb"add_time" or {\tt increment}: + +\begin{verbatim} +# inside class Time: + + def __add__(self, other): + if isinstance(other, Time): + return self.add_time(other) + else: + return self.increment(other) + + def add_time(self, other): + seconds = self.time_to_int() + other.time_to_int() + return int_to_time(seconds) + + def increment(self, seconds): + seconds += self.time_to_int() + return int_to_time(seconds) +\end{verbatim} +% +The built-in function {\tt isinstance} takes a value and a +class object, and returns {\tt True} if the value is an instance +of the class. +\index{isinstance function} +\index{function!isinstance} + +If {\tt other} is a Time object, \verb"__add__" invokes +\verb"add_time". Otherwise it assumes that the parameter +is a number and invokes {\tt increment}. This operation is +called a {\bf type-based dispatch} because it dispatches the +computation to different methods based on the type of the +arguments. +\index{type-based dispatch} +\index{dispatch, type-based} + +Here are examples that use the {\tt +} operator with different +types: + +\begin{verbatim} +>>> start = Time(9, 45) +>>> duration = Time(1, 35) +>>> print(start + duration) +11:20:00 +>>> print(start + 1337) +10:07:17 +\end{verbatim} +% +Unfortunately, this implementation of addition is not commutative. +If the integer is the first operand, you get +\index{commutativity} + +\begin{verbatim} +>>> print(1337 + start) +TypeError: unsupported operand type(s) for +: 'int' and 'instance' +\end{verbatim} +% +The problem is, instead of asking the Time object to add an integer, +Python is asking an integer to add a Time object, and it doesn't know +how. But there is a clever solution for this problem: the +special method \verb"__radd__", which stands for ``right-side add''. +This method is invoked when a Time object appears on the right side of +the {\tt +} operator. Here's the definition: +\index{radd method} +\index{method!radd} + +\begin{verbatim} +# inside class Time: + + def __radd__(self, other): + return self.__add__(other) +\end{verbatim} +% +And here's how it's used: + +\begin{verbatim} +>>> print(1337 + start) +10:07:17 +\end{verbatim} +% + +As an exercise, write an {\tt add} method for Points that works with +either a Point object or a tuple: + +\begin{itemize} + +\item If the second operand is a Point, the method should return a new +Point whose $x$ coordinate is the sum of the $x$ coordinates of the +operands, and likewise for the $y$ coordinates. + +\item If the second operand is a tuple, the method should add the +first element of the tuple to the $x$ coordinate and the second +element to the $y$ coordinate, and return a new Point with the result. + +\end{itemize} + + + + +\section{Polymorphism} +\label{polymorphism} + +Type-based dispatch is useful when it is necessary, but (fortunately) +it is not always necessary. Often you can avoid it by writing functions +that work correctly for arguments with different types. +\index{type-based dispatch} +\index{dispatch!type-based} + +Many of the functions we wrote for strings also +work for other sequence types. +For example, in Section~\ref{histogram} +we used {\tt histogram} to count the number of times each letter +appears in a word. + +\begin{verbatim} +def histogram(s): + d = dict() + for c in s: + if c not in d: + d[c] = 1 + else: + d[c] = d[c]+1 + return d +\end{verbatim} +% +This function also works for lists, tuples, and even dictionaries, +as long as the elements of {\tt s} are hashable, so they can be used +as keys in {\tt d}. + +\begin{verbatim} +>>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam'] +>>> histogram(t) +{'bacon': 1, 'egg': 1, 'spam': 4} +\end{verbatim} +% +Functions that work with several types are called {\bf polymorphic}. +Polymorphism can facilitate code reuse. For example, the built-in +function {\tt sum}, which adds the elements of a sequence, works +as long as the elements of the sequence support addition. +\index{polymorphism} + +Since Time objects provide an {\tt add} method, they work +with {\tt sum}: + +\begin{verbatim} +>>> t1 = Time(7, 43) +>>> t2 = Time(7, 41) +>>> t3 = Time(7, 37) +>>> total = sum([t1, t2, t3]) +>>> print(total) +23:01:00 +\end{verbatim} +% +In general, if all of the operations inside a function +work with a given type, the function works with that type. + +The best kind of polymorphism is the unintentional kind, where +you discover that a function you already wrote can be +applied to a type you never planned for. + + +\section{Debugging} +\index{debugging} + +It is legal to add attributes to objects at any point in the execution +of a program, but if you have objects with the same type that don't +have the same attributes, it is easy to make mistakes. +It is considered a good idea to +initialize all of an object's attributes in the init method. +\index{init method} +\index{attribute!initializing} + +If you are not sure whether an object has a particular attribute, you +can use the built-in function {\tt hasattr} (see Section~\ref{hasattr}). +\index{hasattr function} +\index{function!hasattr} +\index{dict attribute@\_\_dict\_\_ attribute} +\index{attribute!\_\_dict\_\_} + +Another way to access attributes is the built-in function {\tt vars}, +which takes an object and returns a dictionary that maps from +attribute names (as strings) to their values: + +\begin{verbatim} +>>> p = Point(3, 4) +>>> vars(p) +{'y': 4, 'x': 3} +\end{verbatim} +% +For purposes of debugging, you might find it useful to keep this +function handy: + +\begin{verbatim} +def print_attributes(obj): + for attr in vars(obj): + print(attr, getattr(obj, attr)) +\end{verbatim} +% +\verb"print_attributes" traverses the dictionary +and prints each attribute name and its corresponding value. +\index{traversal!dictionary} +\index{dictionary!traversal} + +The built-in function {\tt getattr} takes an object and an attribute +name (as a string) and returns the attribute's value. +\index{getattr function} +\index{function!getattr} + + +\section{Interface and implementation} + +One of the goals of object-oriented design is to make software more +maintainable, which means that you can keep the program working when +other parts of the system change, and modify the program to meet new +requirements. +\index{interface} +\index{implementation} +\index{maintainable} +\index{object-oriented design} + +A design principle that helps achieve that goal is to keep +interfaces separate from implementations. For objects, that means +that the methods a class provides should not depend on how the +attributes are represented. +\index{attribute} + +For example, in this chapter we developed a class that represents +a time of day. Methods provided by this class include +\verb"time_to_int", \verb"is_after", and \verb"add_time". + +We could implement those methods in several ways. The details of the +implementation depend on how we represent time. In this chapter, the +attributes of a {\tt Time} object are {\tt hour}, {\tt minute}, and +{\tt second}. + +As an alternative, we could replace these attributes with +a single integer representing the number of seconds +since midnight. This implementation would make some methods, +like \verb"is_after", easier to write, but it makes other methods +harder. + +After you deploy a new class, you might discover a better +implementation. If other parts of the program are using your +class, it might be time-consuming and error-prone to change the +interface. + +But if you designed the interface carefully, you can +change the implementation without changing the interface, which +means that other parts of the program don't have to change. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[object-oriented language:] A language that provides features, + such as programmer-defined types and methods, that facilitate + object-oriented programming. +\index{object-oriented language} + +\item[object-oriented programming:] A style of programming in which +data and the operations that manipulate it are organized into classes +and methods. +\index{object-oriented programming} + +\item[method:] A function that is defined inside a class definition and +is invoked on instances of that class. +\index{method} + +\item[subject:] The object a method is invoked on. +\index{subject} + +\item[positional argument:] An argument that does not include +a parameter name, so it is not a keyword argument. +\index{positional argument} +\index{argument!positional} + +\item[operator overloading:] Changing the behavior of an operator like +{\tt +} so it works with a programmer-defined type. +\index{overloading} +\index{operator!overloading} + +\item[type-based dispatch:] A programming pattern that checks the type +of an operand and invokes different functions for different types. +\index{type-based dispatch} + +\item[polymorphic:] Pertaining to a function that can work with more + than one type. +\index{polymorphism} + +\item[information hiding:] The principle that the interface provided +by an object should not depend on its implementation, in particular +the representation of its attributes. +\index{information hiding} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +Download the code from this chapter from +\url{http://thinkpython2.com/code/Time2.py}. Change the attributes of + {\tt Time} to be a single integer representing seconds since + midnight. Then modify the methods (and the function + \verb"int_to_time") to work with the new implementation. You + should not have to modify the test code in {\tt main}. When you + are done, the output should be the same as before. Solution: + \url{http://thinkpython2.com/code/Time2_soln.py}. + +\end{exercise} + + +\begin{exercise} +\label{kangaroo} +\index{default value!avoiding mutable} +\index{mutable object, as default value} +\index{worst bug} +\index{bug!worst} +\index{Kangaroo class} +\index{class!Kangaroo} + +This exercise is a cautionary tale about one of the most +common, and difficult to find, errors in Python. +Write a definition for a class named {\tt Kangaroo} with the following +methods: + +\begin{enumerate} + +\item An \verb"__init__" method that initializes an attribute named +\verb"pouch_contents" to an empty list. + +\item A method named \verb"put_in_pouch" that takes an object +of any type and adds it to \verb"pouch_contents". + +\item A \verb"__str__" method that returns a string representation +of the Kangaroo object and the contents of the pouch. + +\end{enumerate} +% +Test your code +by creating two {\tt Kangaroo} objects, assigning them to variables +named {\tt kanga} and {\tt roo}, and then adding {\tt roo} to the +contents of {\tt kanga}'s pouch. + +Download \url{http://thinkpython2.com/code/BadKangaroo.py}. It contains +a solution to the previous problem with one big, nasty bug. +Find and fix the bug. + +If you get stuck, you can download +\url{http://thinkpython2.com/code/GoodKangaroo.py}, which explains the +problem and demonstrates a solution. +\index{aliasing} +\index{embedded object} +\index{object!embedded} + +\end{exercise} + + + +\chapter{Inheritance} + +The language feature most often associated with object-oriented +programming is {\bf inheritance}. Inheritance is the ability to +define a new class that is a modified version of an existing class. +In this chapter I demonstrate inheritance using classes that represent +playing cards, decks of cards, and poker hands. +\index{deck} +\index{card, playing} +\index{poker} + +If you don't play +poker, you can read about it at +\url{http://en.wikipedia.org/wiki/Poker}, but you don't have to; I'll +tell you what you need to know for the exercises. + +Code examples from +this chapter are available from +\url{http://thinkpython2.com/code/Card.py}. + + +\section{Card objects} + +There are fifty-two cards in a deck, each of which belongs to one of +four suits and one of thirteen ranks. The suits are Spades, Hearts, +Diamonds, and Clubs (in descending order in bridge). The ranks are +Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, and King. Depending on +the game that you are playing, an Ace may be higher than King +or lower than 2. +\index{rank} +\index{suit} + +If we want to define a new object to represent a playing card, it is +obvious what the attributes should be: {\tt rank} and +{\tt suit}. It is not as obvious what type the attributes +should be. One possibility is to use strings containing words like +\verb"'Spade'" for suits and \verb"'Queen'" for ranks. One problem with +this implementation is that it would not be easy to compare cards to +see which had a higher rank or suit. +\index{encode} +\index{encrypt} +\index{map to} +\index{representation} + +An alternative is to use integers to {\bf encode} the ranks and suits. +In this context, ``encode'' means that we are going to define a mapping +between numbers and suits, or between numbers and ranks. This +kind of encoding is not meant to be a secret (that +would be ``encryption''). + +\newcommand{\mymapsto}{$\mapsto$} + +For example, this table shows the suits and the corresponding integer +codes: + +\begin{tabular}{l c l} +Spades & \mymapsto & 3 \\ +Hearts & \mymapsto & 2 \\ +Diamonds & \mymapsto & 1 \\ +Clubs & \mymapsto & 0 +\end{tabular} + +This code makes it easy to compare cards; because higher suits map to +higher numbers, we can compare suits by comparing their codes. + +The mapping for ranks is fairly obvious; each of the numerical ranks +maps to the corresponding integer, and for face cards: + +\begin{tabular}{l c l} +Jack & \mymapsto & 11 \\ +Queen & \mymapsto & 12 \\ +King & \mymapsto & 13 \\ +\end{tabular} + +I am using the \mymapsto~symbol to make it clear that these mappings +are not part of the Python program. They are part of the program +design, but they don't appear explicitly in the code. +\index{Card class} +\index{class!Card} + +The class definition for {\tt Card} looks like this: + +\begin{verbatim} +class Card: + """Represents a standard playing card.""" + + def __init__(self, suit=0, rank=2): + self.suit = suit + self.rank = rank +\end{verbatim} +% +As usual, the init method takes an optional +parameter for each attribute. The default card is +the 2 of Clubs. +\index{init method} +\index{method!init} + +To create a Card, you call {\tt Card} with the +suit and rank of the card you want. + +\begin{verbatim} +queen_of_diamonds = Card(1, 12) +\end{verbatim} +% + + +\section{Class attributes} +\label{class.attribute} +\index{class attribute} +\index{attribute!class} + +In order to print Card objects in a way that people can easily +read, we need a mapping from the integer codes to the corresponding +ranks and suits. A natural way to +do that is with lists of strings. We assign these lists to {\bf class +attributes}: + +\begin{verbatim} +# inside class Card: + + suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades'] + rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7', + '8', '9', '10', 'Jack', 'Queen', 'King'] + + def __str__(self): + return '%s of %s' % (Card.rank_names[self.rank], + Card.suit_names[self.suit]) +\end{verbatim} +% +Variables like \verb"suit_names" and \verb"rank_names", which are +defined inside a class but outside of any method, are called +class attributes because they are associated with the class object +{\tt Card}. +\index{instance attribute} +\index{attribute!instance} + +This term distinguishes them from variables like {\tt suit} and {\tt + rank}, which are called {\bf instance attributes} because they are +associated with a particular instance. +\index{dot notation} + +Both kinds of attribute are accessed using dot notation. For +example, in \verb"__str__", {\tt self} is a Card object, +and {\tt self.rank} is its rank. Similarly, {\tt Card} +is a class object, and \verb"Card.rank_names" is a +list of strings associated with the class. + +Every card has its own {\tt suit} and {\tt rank}, but there +is only one copy of \verb"suit_names" and \verb"rank_names". + +Putting it all together, the expression +\verb"Card.rank_names[self.rank]" means ``use the attribute {\tt rank} +from the object {\tt self} as an index into the list \verb"rank_names" +from the class {\tt Card}, and select the appropriate string.'' + +The first element of \verb"rank_names" is {\tt None} because there +is no card with rank zero. By including {\tt None} as a place-keeper, +we get a mapping with the nice property that the index 2 maps to the +string \verb"'2'", and so on. To avoid this tweak, we could have +used a dictionary instead of a list. + +With the methods we have so far, we can create and print cards: + +\begin{verbatim} +>>> card1 = Card(2, 11) +>>> print(card1) +Jack of Hearts +\end{verbatim} + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/card1.pdf}} +\caption{Object diagram.} +\label{fig.card1} +\end{figure} + +Figure~\ref{fig.card1} is a diagram of the {\tt Card} class object and +one Card instance. {\tt Card} is a class object; its type is {\tt + type}. {\tt card1} is an instance of {\tt Card}, so its type is +{\tt Card}. To save space, I didn't draw the contents of +\verb"suit_names" and \verb"rank_names". \index{state diagram} +\index{diagram!state} \index{object diagram} \index{diagram!object} + + +\section{Comparing cards} +\label{comparecard} +\index{operator!relational} +\index{relational operator} + +For built-in types, there are relational operators +({\tt <}, {\tt >}, {\tt ==}, etc.) +that compare +values and determine when one is greater than, less than, or equal to +another. For programmer-defined types, we can override the behavior of +the built-in operators by providing a method named +\verb"__lt__", which stands for ``less than''. +\index{programmer-defined type} +\index{type!programmer-defined} + +\verb"__lt__" takes two parameters, {\tt self} and {\tt other}, +and returns {\tt True} if {\tt self} is strictly less than {\tt other}. +\index{override} +\index{operator overloading} + +The correct ordering for cards is not obvious. +For example, which +is better, the 3 of Clubs or the 2 of Diamonds? One has a higher +rank, but the other has a higher suit. In order to compare +cards, you have to decide whether rank or suit is more important. + +The answer might depend on what game you are playing, but to keep +things simple, we'll make the arbitrary choice that suit is more +important, so all of the Spades outrank all of the Diamonds, +and so on. +\index{cmp method@\_\_cmp\_\_ method} +\index{method!\_\_cmp\_\_} + +With that decided, we can write \verb"__lt__": + +\begin{verbatim} +# inside class Card: + + def __lt__(self, other): + # check the suits + if self.suit < other.suit: return True + if self.suit > other.suit: return False + + # suits are the same... check ranks + return self.rank < other.rank +\end{verbatim} +% +You can write this more concisely using tuple comparison: +\index{tuple!comparison} +\index{comparison!tuple} + +\begin{verbatim} +# inside class Card: + + def __lt__(self, other): + t1 = self.suit, self.rank + t2 = other.suit, other.rank + return t1 < t2 +\end{verbatim} +% +As an exercise, write an \verb"__lt__" method for Time objects. You +can use tuple comparison, but you also might consider +comparing integers. + + +\section{Decks} +\index{list!of objects} +\index{deck, playing cards} + +Now that we have Cards, the next step is to define Decks. Since a +deck is made up of cards, it is natural for each Deck to contain a +list of cards as an attribute. +\index{init method} +\index{method!init} + +The following is a class definition for {\tt Deck}. The +init method creates the attribute {\tt cards} and generates +the standard set of fifty-two cards: +\index{composition} +\index{loop!nested} +\index{Deck class} +\index{class!Deck} + +\begin{verbatim} +class Deck: + + def __init__(self): + self.cards = [] + for suit in range(4): + for rank in range(1, 14): + card = Card(suit, rank) + self.cards.append(card) +\end{verbatim} +% +The easiest way to populate the deck is with a nested loop. The outer +loop enumerates the suits from 0 to 3. The inner loop enumerates the +ranks from 1 to 13. Each iteration +creates a new Card with the current suit and rank, +and appends it to {\tt self.cards}. +\index{append method} +\index{method!append} + + +\section{Printing the deck} +\label{printdeck} +\index{str method@\_\_str\_\_ method} +\index{method!\_\_str\_\_} + +Here is a \verb"__str__" method for {\tt Deck}: + +\begin{verbatim} +#inside class Deck: + + def __str__(self): + res = [] + for card in self.cards: + res.append(str(card)) + return '\n'.join(res) +\end{verbatim} +% +This method demonstrates an efficient way to accumulate a large +string: building a list of strings and then using the string method +{\tt join}. The built-in function {\tt str} invokes the +\verb"__str__" method on each card and returns the string +representation. \index{accumulator!string} \index{string!accumulator} +\index{join method} \index{method!join} \index{newline} + +Since we invoke {\tt join} on a newline character, the cards +are separated by newlines. Here's what the result looks like: + +\begin{verbatim} +>>> deck = Deck() +>>> print(deck) +Ace of Clubs +2 of Clubs +3 of Clubs +... +10 of Spades +Jack of Spades +Queen of Spades +King of Spades +\end{verbatim} +% +Even though the result appears on 52 lines, it is +one long string that contains newlines. + + +\section{Add, remove, shuffle and sort} + +To deal cards, we would like a method that +removes a card from the deck and returns it. +The list method {\tt pop} provides a convenient way to do that: +\index{pop method} +\index{method!pop} + +\begin{verbatim} +#inside class Deck: + + def pop_card(self): + return self.cards.pop() +\end{verbatim} +% +Since {\tt pop} removes the {\em last} card in the list, we are +dealing from the bottom of the deck. +\index{append method} +\index{method!append} + +To add a card, we can use the list method {\tt append}: + +\begin{verbatim} +#inside class Deck: + + def add_card(self, card): + self.cards.append(card) +\end{verbatim} +% +A method like this that uses another method without doing +much work is sometimes called a {\bf veneer}. The metaphor +comes from woodworking, where a veneer is a thin +layer of good quality wood glued to the surface of a cheaper piece of +wood to improve the appearance. +\index{veneer} + +In this case \verb"add_card" is a ``thin'' method that expresses +a list operation in terms appropriate for decks. It +improves the appearance, or interface, of the +implementation. + +As another example, we can write a Deck method named {\tt shuffle} +using the function {\tt shuffle} from the {\tt random} module: +\index{random module} +\index{module!random} +\index{shuffle function} +\index{function!shuffle} + +\begin{verbatim} +# inside class Deck: + + def shuffle(self): + random.shuffle(self.cards) +\end{verbatim} +% +Don't forget to import {\tt random}. + +As an exercise, write a Deck method named {\tt sort} that uses the +list method {\tt sort} to sort the cards in a {\tt Deck}. {\tt sort} +uses the \verb"__lt__" method we defined to determine the order. +\index{sort method} \index{method!sort} + + + +\section{Inheritance} +\index{inheritance} +\index{object-oriented programming} + +Inheritance is the ability to define a new class that is a modified +version of an existing class. As an example, let's say we want a +class to represent a ``hand'', that is, the cards held by one player. +A hand is similar to a deck: both are made up of a collection of +cards, and both require operations like adding and removing cards. + +A hand is also different from a deck; there are operations we want for +hands that don't make sense for a deck. For example, in poker we +might compare two hands to see which one wins. In bridge, we might +compute a score for a hand in order to make a bid. + +This relationship between classes---similar, but different---lends +itself to inheritance. +To define a new class that inherits from an existing class, +you put the name of the existing class in parentheses: +\index{parentheses!parent class in} +\index{parent class} +\index{class!parent} +\index{Hand class} +\index{class!Hand} + +\begin{verbatim} +class Hand(Deck): + """Represents a hand of playing cards.""" +\end{verbatim} +% +This definition indicates that {\tt Hand} inherits from {\tt Deck}; +that means we can use methods like \verb"pop_card" and \verb"add_card" +for Hands as well as Decks. + +When a new class inherits from an existing one, the existing +one is called the {\bf parent} and the new class is +called the {\bf child}. +\index{parent class} +\index{child class} +\index{class!child} + +In this example, {\tt Hand} inherits \verb"__init__" from {\tt Deck}, +but it doesn't really do what we want: instead of populating the hand +with 52 new cards, the init method for Hands should initialize {\tt + cards} with an empty list. \index{override} \index{init method} +\index{method!init} + +If we provide an init method in the {\tt Hand} class, it overrides the +one in the {\tt Deck} class: + +\begin{verbatim} +# inside class Hand: + + def __init__(self, label=''): + self.cards = [] + self.label = label +\end{verbatim} +% +When you create a Hand, Python invokes this init method, not the +one in {\tt Deck}. + +\begin{verbatim} +>>> hand = Hand('new hand') +>>> hand.cards +[] +>>> hand.label +'new hand' +\end{verbatim} +% +The other methods are inherited from {\tt Deck}, so we can use +\verb"pop_card" and \verb"add_card" to deal a card: + +\begin{verbatim} +>>> deck = Deck() +>>> card = deck.pop_card() +>>> hand.add_card(card) +>>> print(hand) +King of Spades +\end{verbatim} +% +A natural next step is to encapsulate this code in a method +called \verb"move_cards": +\index{encapsulation} + +\begin{verbatim} +#inside class Deck: + + def move_cards(self, hand, num): + for i in range(num): + hand.add_card(self.pop_card()) +\end{verbatim} +% +\verb"move_cards" takes two arguments, a Hand object and the number of +cards to deal. It modifies both {\tt self} and {\tt hand}, and +returns {\tt None}. + +In some games, cards are moved from one hand to another, +or from a hand back to the deck. You can use \verb"move_cards" +for any of these operations: {\tt self} can be either a Deck +or a Hand, and {\tt hand}, despite the name, can also be a {\tt Deck}. + +Inheritance is a useful feature. Some programs that would be +repetitive without inheritance can be written more elegantly +with it. Inheritance can facilitate code reuse, since you can +customize the behavior of parent classes without having to modify +them. In some cases, the inheritance structure reflects the natural +structure of the problem, which makes the design easier to +understand. + +On the other hand, inheritance can make programs difficult to read. +When a method is invoked, it is sometimes not clear where to find its +definition. The relevant code may be spread across several modules. +Also, many of the things that can be done using inheritance can be +done as well or better without it. + + +\section{Class diagrams} +\label{class.diagram} + +So far we have seen stack diagrams, which show the state of +a program, and object diagrams, which show the attributes +of an object and their values. These diagrams represent a snapshot +in the execution of a program, so they change as the program +runs. + +They are also highly detailed; for some purposes, too +detailed. A class diagram is a more abstract representation +of the structure of a program. Instead of showing individual +objects, it shows classes and the relationships between them. + +There are several kinds of relationship between classes: + +\begin{itemize} + +\item Objects in one class might contain references to objects +in another class. For example, each Rectangle contains a reference +to a Point, and each Deck contains references to many Cards. +This kind of relationship is called {\bf HAS-A}, as in, ``a Rectangle +has a Point.'' + +\item One class might inherit from another. This relationship +is called {\bf IS-A}, as in, ``a Hand is a kind of a Deck.'' + +\item One class might depend on another in the sense that objects +in one class take objects in the second class as parameters, or +use objects in the second class as part of a computation. This +kind of relationship is called a {\bf dependency}. + +\end{itemize} +\index{IS-A relationship} +\index{HAS-A relationship} +\index{class diagram} +\index{diagram!class} + +A {\bf class diagram} is a graphical representation of these +relationships. For example, Figure~\ref{fig.class1} shows the +relationships between {\tt Card}, {\tt Deck} and {\tt Hand}. + +\begin{figure} +\centerline +{\includegraphics[scale=0.8]{figs/class1.pdf}} +\caption{Class diagram.} +\label{fig.class1} +\end{figure} + +The arrow with a hollow triangle head represents an IS-A +relationship; in this case it indicates that Hand inherits +from Deck. + +The standard arrow head represents a HAS-A +relationship; in this case a Deck has references to Card +objects. +\index{multiplicity (in class diagram)} + +The star ({\tt *}) near the arrow head is a +{\bf multiplicity}; it indicates how many Cards a Deck has. +A multiplicity can be a simple number, like {\tt 52}, a range, +like {\tt 5..7} or a star, which indicates that a Deck can +have any number of Cards. + +There are no dependencies in this diagram. They would normally +be shown with a dashed arrow. Or if there are a lot of +dependencies, they are sometimes omitted. + +A more detailed diagram might show that a Deck actually +contains a {\em list} of Cards, but built-in types +like list and dict are usually not included in class diagrams. + + +\section{Debugging} +\index{debugging} + +Inheritance can make debugging difficult because when you invoke a +method on an object, it might be hard to figure out which method will +be invoked. +\index{inheritance} + +Suppose you are writing a function that works with Hand objects. +You would like it to work with all kinds of Hands, like +PokerHands, BridgeHands, etc. If you invoke a method like +{\tt shuffle}, you might get the one defined in {\tt Deck}, +but if any of the subclasses override this method, you'll +get that version instead. This behavior is usually a good +thing, but it can be confusing. + +Any time you are unsure about the flow of execution through your +program, the simplest solution is to add print statements at the +beginning of the relevant methods. If {\tt Deck.shuffle} prints a +message that says something like {\tt Running Deck.shuffle}, then as +the program runs it traces the flow of execution. +\index{flow of execution} + +As an alternative, you could use this function, which takes an +object and a method name (as a string) and returns the class that +provides the definition of the method: + +\begin{verbatim} +def find_defining_class(obj, meth_name): + for ty in type(obj).mro(): + if meth_name in ty.__dict__: + return ty +\end{verbatim} +% +Here's an example: + +\begin{verbatim} +>>> hand = Hand() +>>> find_defining_class(hand, 'shuffle') + +\end{verbatim} +% +So the {\tt shuffle} method for this Hand is the one in {\tt Deck}. +\index{mro method} +\index{method!mro} +\index{method resolution order} + +\verb"find_defining_class" uses the {\tt mro} method to get the list +of class objects (types) that will be searched for methods. ``MRO'' +stands for ``method resolution order'', which is the sequence of +classes Python searches to ``resolve'' a method name. + +Here's a design suggestion: when you override a method, +the interface of the new method should be the same as the old. It +should take the same parameters, return the same type, and obey the +same preconditions and postconditions. If you follow this rule, you +will find that any function designed to work with an instance of a +parent class, like a Deck, will also work with instances of child +classes like a Hand and PokerHand. +\index{override} +\index{interface} +\index{precondition} +\index{postcondition} + +If you violate this rule, which is called the ``Liskov substitution +principle'', your code will collapse like (sorry) a house of cards. +\index{Liskov substitution principle} + + +\section{Data encapsulation} + +The previous chapters demonstrate a development plan we might call +``object-oriented design''. We identified objects we needed---like +{\tt Point}, {\tt Rectangle} and {\tt Time}---and defined classes to +represent them. In each case there is an obvious correspondence +between the object and some entity in the real world (or at least a +mathematical world). +\index{development plan!data encapsulation} + +But sometimes it is less obvious what objects you need +and how they should interact. In that case you need a different +development plan. In the same way that we discovered function +interfaces by encapsulation and generalization, we can discover +class interfaces by {\bf data encapsulation}. +\index{data encapsulation} + +Markov analysis, from Section~\ref{markov}, provides a good example. +If you download my code from \url{http://thinkpython2.com/code/markov.py}, +you'll see that it uses two global variables---\verb"suffix_map" and +\verb"prefix"---that are read and written from several functions. + +\begin{verbatim} +suffix_map = {} +prefix = () +\end{verbatim} + +Because these variables are global, we can only run one analysis at a +time. If we read two texts, their prefixes and suffixes would be +added to the same data structures (which makes for some interesting +generated text). + +To run multiple analyses, and keep them separate, we can encapsulate +the state of each analysis in an object. +Here's what that looks like: + +\begin{verbatim} +class Markov: + + def __init__(self): + self.suffix_map = {} + self.prefix = () +\end{verbatim} + +Next, we transform the functions into methods. For example, +here's \verb"process_word": + +\begin{verbatim} + def process_word(self, word, order=2): + if len(self.prefix) < order: + self.prefix += (word,) + return + + try: + self.suffix_map[self.prefix].append(word) + except KeyError: + # if there is no entry for this prefix, make one + self.suffix_map[self.prefix] = [word] + + self.prefix = shift(self.prefix, word) +\end{verbatim} + +Transforming a program like this---changing the design without +changing the behavior---is another example of refactoring +(see Section~\ref{refactoring}). +\index{refactoring} + +This example suggests a development plan for designing objects and +methods: + +\begin{enumerate} + +\item Start by writing functions that read and write global +variables (when necessary). + +\item Once you get the program working, look for associations +between global variables and the functions that use them. + +\item Encapsulate related variables as attributes of an object. + +\item Transform the associated functions into methods of the new +class. + +\end{enumerate} + +As an exercise, download my Markov code from +\url{http://thinkpython2.com/code/markov.py}, and follow the steps +described above to encapsulate the global variables as attributes of a +new class called {\tt Markov}. Solution: +\url{http://thinkpython2.com/code/Markov.py} (note the capital M). + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[encode:] To represent one set of values using another +set of values by constructing a mapping between them. +\index{encode} + +\item[class attribute:] An attribute associated with a class +object. Class attributes are defined inside +a class definition but outside any method. +\index{class attribute} +\index{attribute!class} + +\item[instance attribute:] An attribute associated with an +instance of a class. +\index{instance attribute} +\index{attribute!instance} + +\item[veneer:] A method or function that provides a different +interface to another function without doing much computation. +\index{veneer} + +\item[inheritance:] The ability to define a new class that is a +modified version of a previously defined class. +\index{inheritance} + +\item[parent class:] The class from which a child class inherits. +\index{parent class} + +\item[child class:] A new class created by inheriting from an +existing class; also called a ``subclass''. +\index{child class} +\index{class!child} + +\item[IS-A relationship:] A relationship between a child class +and its parent class. +\index{IS-A relationship} + +\item[HAS-A relationship:] A relationship between two classes +where instances of one class contain references to instances of +the other. +\index{HAS-A relationship} + +\item[dependency:] A relationship between two classes +where instances of one class use instances of the other class, +but do not store them as attributes. +\index{HAS-A relationship} + +\item[class diagram:] A diagram that shows the classes in a program +and the relationships between them. +\index{class diagram} +\index{diagram!class} + +\item[multiplicity:] A notation in a class diagram that shows, for +a HAS-A relationship, how many references there are to instances +of another class. +\index{multiplicity (in class diagram)} + +\item[data encapsulation:] A program development plan that +involves a prototype using global variables and a final version +that makes the global variables into instance attributes. +\index{data encapsulation} +\index{development plan!data encapsulation} + +\end{description} + + +\section{연습 문제} +%Exercises + +\begin{exercise} +For the following program, draw a UML class diagram that shows +these classes and the relationships among them. + +\begin{verbatim} +class PingPongParent: + pass + +class Ping(PingPongParent): + def __init__(self, pong): + self.pong = pong + + +class Pong(PingPongParent): + def __init__(self, pings=None): + if pings is None: + self.pings = [] + else: + self.pings = pings + + def add_ping(self, ping): + self.pings.append(ping) + +pong = Pong() +ping = Ping(pong) +pong.add_ping(ping) +\end{verbatim} + + +\end{exercise} + + + +\begin{exercise} +Write a Deck method called \verb"deal_hands" that +takes two parameters, the number of hands and the number of cards per +hand. It should create the appropriate number of Hand objects, deal +the appropriate number of cards per hand, and return a list of Hands. +\end{exercise} + + +\begin{exercise} +\label{poker} + +The following are the possible hands in poker, in increasing order +of value and decreasing order of probability: +\index{poker} + +\begin{description} + +\item[pair:] two cards with the same rank +\vspace{-0.05in} + +\item[two pair:] two pairs of cards with the same rank +\vspace{-0.05in} + +\item[three of a kind:] three cards with the same rank +\vspace{-0.05in} + +\item[straight:] five cards with ranks in sequence (aces can +be high or low, so {\tt Ace-2-3-4-5} is a straight and so is {\tt +10-Jack-Queen-King-Ace}, but {\tt Queen-King-Ace-2-3} is not.) +\vspace{-0.05in} + +\item[flush:] five cards with the same suit +\vspace{-0.05in} + +\item[full house:] three cards with one rank, two cards with another +\vspace{-0.05in} + +\item[four of a kind:] four cards with the same rank +\vspace{-0.05in} + +\item[straight flush:] five cards in sequence (as defined above) and +with the same suit +\vspace{-0.05in} + +\end{description} +% +The goal of these exercises is to estimate +the probability of drawing these various hands. + +\begin{enumerate} + +\item Download the following files from \url{http://thinkpython2.com/code}: + +\begin{description} + +\item[{\tt Card.py}]: A complete version of the {\tt Card}, +{\tt Deck} and {\tt Hand} classes in this chapter. + +\item[{\tt PokerHand.py}]: An incomplete implementation of a class +that represents a poker hand, and some code that tests it. + +\end{description} +% +\item If you run {\tt PokerHand.py}, it deals seven 7-card poker hands +and checks to see if any of them contains a flush. Read this +code carefully before you go on. + +\item Add methods to {\tt PokerHand.py} named \verb"has_pair", +\verb"has_twopair", etc. that return True or False according to +whether or not the hand meets the relevant criteria. Your code should +work correctly for ``hands'' that contain any number of cards +(although 5 and 7 are the most common sizes). + +\item Write a method named {\tt classify} that figures out +the highest-value classification for a hand and sets the +{\tt label} attribute accordingly. For example, a 7-card hand +might contain a flush and a pair; it should be labeled ``flush''. + +\item When you are convinced that your classification methods are +working, the next step is to estimate the probabilities of the various +hands. Write a function in {\tt PokerHand.py} that shuffles a deck of +cards, divides it into hands, classifies the hands, and counts the +number of times various classifications appear. + +\item Print a table of the classifications and their probabilities. +Run your program with larger and larger numbers of hands until the +output values converge to a reasonable degree of accuracy. Compare +your results to the values at \url{http://en.wikipedia.org/wiki/Hand_rankings}. + +\end{enumerate} + +Solution: \url{http://thinkpython2.com/code/PokerHandSoln.py}. +\end{exercise} + + +\chapter{The Goodies} + +One of my goals for this book has been to teach you as little Python +as possible. When there were two ways to do something, I picked +one and avoided mentioning the other. Or sometimes I put the second +one into an exercise. + +Now I want to go back for some of the good bits that got left behind. +Python provides a number of features that are not really necessary---you +can write good code without them---but with them you can sometimes +write code that's more concise, readable or efficient, and sometimes +all three. + +% TODO: add the with statement + +\section{Conditional expressions} + +We saw conditional statements in Section~\ref{conditional.execution}. +Conditional statements are often used to choose one of two values; +for example: +\index{conditional expression} +\index{expression!conditional} + +\begin{verbatim} +if x > 0: + y = math.log(x) +else: + y = float('nan') +\end{verbatim} + +This statement checks whether {\tt x} is positive. If so, it computes +{\tt math.log}. If not, {\tt math.log} would raise a ValueError. To +avoid stopping the program, we generate a ``NaN'', which is a special +floating-point value that represents ``Not a Number''. +\index{NaN} +\index{floating-point} + +We can write this statement more concisely using a {\bf conditional +expression}: + +\begin{verbatim} +y = math.log(x) if x > 0 else float('nan') +\end{verbatim} + +You can almost read this line like English: ``{\tt y} gets log-{\tt x} +if {\tt x} is greater than 0; otherwise it gets NaN''. + +Recursive functions can sometimes be rewritten using conditional +expressions. For example, here is a recursive version of {\tt factorial}: +\index{factorial} +\index{function!factorial} + +\begin{verbatim} +def factorial(n): + if n == 0: + return 1 + else: + return n * factorial(n-1) +\end{verbatim} + +We can rewrite it like this: + +\begin{verbatim} +def factorial(n): + return 1 if n == 0 else n * factorial(n-1) +\end{verbatim} + +Another use of conditional expressions is handling optional +arguments. For example, here is the init method from +{\tt GoodKangaroo} (see Exercise~\ref{kangaroo}): +\index{optional argument} +\index{argument!optional} + +\begin{verbatim} + def __init__(self, name, contents=None): + self.name = name + if contents == None: + contents = [] + self.pouch_contents = contents +\end{verbatim} + +We can rewrite this one like this: + +\begin{verbatim} + def __init__(self, name, contents=None): + self.name = name + self.pouch_contents = [] if contents == None else contents +\end{verbatim} + +In general, you can replace a conditional statement with a conditional +expression if both branches contain simple expressions that are +either returned or assigned to the same variable. +\index{conditional statement} +\index{statement!conditional} + + + +\section{List comprehensions} + +In Section~\ref{filter} we saw the map and filter patterns. For +example, this function takes a list of strings, maps the string method +{\tt capitalize} to the elements, and returns a new list of strings: + +\begin{verbatim} +def capitalize_all(t): + res = [] + for s in t: + res.append(s.capitalize()) + return res +\end{verbatim} + +We can write this more concisely using a {\bf list comprehension}: +\index{list comprehension} + +\begin{verbatim} +def capitalize_all(t): + return [s.capitalize() for s in t] +\end{verbatim} + +The bracket operators indicate that we are constructing a new +list. The expression inside the brackets specifies the elements +of the list, and the {\tt for} clause indicates what sequence +we are traversing. +\index{list} +\index{for loop} + +The syntax of a list comprehension is a little awkward because +the loop variable, {\tt s} in this example, appears in the expression +before we get to the definition. +\index{loop variable} + +List comprehensions can also be used for filtering. For example, +this function selects only the elements of {\tt t} that are +upper case, and returns a new list: +\index{filter pattern} +\index{pattern!filter} + +\begin{verbatim} +def only_upper(t): + res = [] + for s in t: + if s.isupper(): + res.append(s) + return res +\end{verbatim} + +We can rewrite it using a list comprehension + +\begin{verbatim} +def only_upper(t): + return [s for s in t if s.isupper()] +\end{verbatim} + +List comprehensions are concise and easy to read, at least for simple +expressions. And they are usually faster than the equivalent for +loops, sometimes much faster. So if you are mad at me for not +mentioning them earlier, I understand. + +But, in my defense, list comprehensions are harder to debug because +you can't put a print statement inside the loop. I suggest that you +use them only if the computation is simple enough that you are likely +to get it right the first time. And for beginners that means never. +\index{debugging} + + + +\section{Generator expressions} + +{\bf Generator expressions} are similar to list comprehensions, but +with parentheses instead of square brackets: +\index{generator expression} +\index{expression!generator} + +\begin{verbatim} +>>> g = (x**2 for x in range(5)) +>>> g + at 0x7f4c45a786c0> +\end{verbatim} +% +The result is a generator object that knows how to iterate through +a sequence of values. But unlike a list comprehension, it does not +compute the values all at once; it waits to be asked. The built-in +function {\tt next} gets the next value from the generator: +\index{generator object} +\index{object!generator} + +\begin{verbatim} +>>> next(g) +0 +>>> next(g) +1 +\end{verbatim} +% +When you get to the end of the sequence, {\tt next} raises a +StopIteration exception. You can also use a {\tt for} loop to iterate +through the values: +\index{StopIteration} +\index{exception!StopIteration} + +\begin{verbatim} +>>> for val in g: +... print(val) +4 +9 +16 +\end{verbatim} +% +The generator object keeps track of where it is in the sequence, +so the {\tt for} loop picks up where {\tt next} left off. Once the +generator is exhausted, it continues to raise {\tt StopException}: + +\begin{verbatim} +>>> next(g) +StopIteration +\end{verbatim} + +Generator expressions are often used with functions like {\tt sum}, +{\tt max}, and {\tt min}: +\index{sum} +\index{function!sum} + +\begin{verbatim} +>>> sum(x**2 for x in range(5)) +30 +\end{verbatim} + + +\section{{\tt any} and {\tt all}} + +Python provides a built-in function, {\tt any}, that takes a sequence +of boolean values and returns {\tt True} if any of the values are {\tt + True}. It works on lists: +\index{any} +\index{built-in function!any} + +\begin{verbatim} +>>> any([False, False, True]) +True +\end{verbatim} +% +But it is often used with generator expressions: +\index{generator expression} +\index{expression!generator} + +\begin{verbatim} +>>> any(letter == 't' for letter in 'monty') +True +\end{verbatim} +% +That example isn't very useful because it does the same thing +as the {\tt in} operator. But we could use {\tt any} to rewrite +some of the search functions we wrote in Section~\ref{search}. For +example, we could write {\tt avoids} like this: +\index{search pattern} +\index{pattern!search} + +\begin{verbatim} +def avoids(word, forbidden): + return not any(letter in forbidden for letter in word) +\end{verbatim} +% +The function almost reads like English, ``{\tt word} avoids +{\tt forbidden} if there are not any forbidden letters in {\tt word}.'' + +Using {\tt any} with a generator expression is efficient because +it stops immediately if it finds a {\tt True} value, +so it doesn't have to evaluate the whole sequence. + +Python provides another built-in function, {\tt all}, that returns +{\tt True} if every element of the sequence is {\tt True}. As +an exercise, use {\tt all} to re-write \verb"uses_all" from +Section~\ref{search}. +\index{all} +\index{built-in function!any} + + +\section{Sets} +\label{sets} + +In Section~\ref{dictsub} I use dictionaries to find the words +that appear in a document but not in a word list. The function +I wrote takes {\tt d1}, which contains the words from the document +as keys, and {\tt d2}, which contains the list of words. It +returns a dictionary that contains the keys from {\tt d1} that +are not in {\tt d2}. + +\begin{verbatim} +def subtract(d1, d2): + res = dict() + for key in d1: + if key not in d2: + res[key] = None + return res +\end{verbatim} +% +In all of these dictionaries, the values are {\tt None} because +we never use them. As a result, we waste some storage space. +\index{dictionary subtraction} + +Python provides another built-in type, called a {\tt set}, that +behaves like a collection of dictionary keys with no values. Adding +elements to a set is fast; so is checking membership. And sets +provide methods and operators to compute common set operations. +\index{set} +\index{object!set} + +For example, set subtraction is available as a method called +{\tt difference} or as an operator, {\tt -}. So we can rewrite +{\tt subtract} like this: +\index{set subtraction} + +\begin{verbatim} +def subtract(d1, d2): + return set(d1) - set(d2) +\end{verbatim} +% +The result is a set instead of a dictionary, but for operations like +iteration, the behavior is the same. + +Some of the exercises in this book can be done concisely and +efficiently with sets. For example, here is a solution to +\verb"has_duplicates", from +Exercise~\ref{duplicate}, that uses a dictionary: + +\begin{verbatim} +def has_duplicates(t): + d = {} + for x in t: + if x in d: + return True + d[x] = True + return False +\end{verbatim} + +When an element appears for the first time, it is added to the +dictionary. If the same element appears again, the function returns +{\tt True}. + +Using sets, we can write the same function like this: + +\begin{verbatim} +def has_duplicates(t): + return len(set(t)) < len(t) +\end{verbatim} +% +An element can only appear in a set once, so if an element in {\tt t} +appears more than once, the set will be smaller than {\tt t}. If there +are no duplicates, the set will be the same size as {\tt t}. +\index{duplicate} + +We can also use sets to do some of the exercises in +Chapter~\ref{wordplay}. For example, here's a version of +\verb"uses_only" with a loop: + +\begin{verbatim} +def uses_only(word, available): + for letter in word: + if letter not in available: + return False + return True +\end{verbatim} +% +\verb"uses_only" checks whether all letters in {\tt word} are +in {\tt available}. We can rewrite it like this: + +\begin{verbatim} +def uses_only(word, available): + return set(word) <= set(available) +\end{verbatim} +% +The \verb"<=" operator checks whether one set is a subset or another, +including the possibility that they are equal, which is true if all +the letters in {\tt word} appear in {\tt available}. +\index{subset} + +As an exercise, rewrite \verb"avoids" using sets. + + +\section{Counters} + +A Counter is like a set, except that if an element appears more +than once, the Counter keeps track of how many times it appears. +If you are familiar with the mathematical idea of a {\bf multiset}, +a Counter is a natural way to represent a multiset. +\index{Counter} +\index{object!Counter} +\index{multiset} + +Counter is defined in a standard module called {\tt collections}, +so you have to import it. You can initialize a Counter with a string, +list, or anything else that supports iteration: +\index{collections} +\index{module!collections} + +\begin{verbatim} +>>> from collections import Counter +>>> count = Counter('parrot') +>>> count +Counter({'r': 2, 't': 1, 'o': 1, 'p': 1, 'a': 1}) +\end{verbatim} + +Counters behave like dictionaries in many ways; they map from each +key to the number of times it appears. As in dictionaries, +the keys have to be hashable. + +Unlike dictionaries, Counters don't raise an exception if you access +an element that doesn't appear. Instead, they return 0: + +\begin{verbatim} +>>> count['d'] +0 +\end{verbatim} + +We can use Counters to rewrite \verb"is_anagram" from +Exercise~\ref{anagram}: + +\begin{verbatim} +def is_anagram(word1, word2): + return Counter(word1) == Counter(word2) +\end{verbatim} + +If two words are anagrams, they contain the same letters with the same +counts, so their Counters are equivalent. + +Counters provide methods and operators to perform set-like operations, +including addition, subtraction, union and intersection. And +they provide an often-useful method, \verb"most_common", which +returns a list of value-frequency pairs, sorted from most common to +least: + +\begin{verbatim} +>>> count = Counter('parrot') +>>> for val, freq in count.most_common(3): +... print(val, freq) +r 2 +p 1 +a 1 +\end{verbatim} + + +\section{defaultdict} + +The {\tt collections} module also provides {\tt defaultdict}, which is +like a dictionary except that if you access a key that doesn't exist, +it can generate a new value on the fly. +\index{defaultdict} +\index{object!defaultdict} +\index{collections} +\index{module!collections} + +When you create a defaultdict, you provide a function that's used to +create new values. A function used to create objects is sometimes +called a {\bf factory}. The built-in functions that create lists, sets, +and other types can be used as factories: +\index{factory function} + +\begin{verbatim} +>>> from collections import defaultdict +>>> d = defaultdict(list) +\end{verbatim} + +Notice that the argument is {\tt list}, which is a class object, +not {\tt list()}, which is a new list. The function you provide +doesn't get called unless you access a key that doesn't exist. + +\begin{verbatim} +>>> t = d['new key'] +>>> t +[] +\end{verbatim} + +The new list, which we're calling {\tt t}, is also added to the +dictionary. So if we modify {\tt t}, the change appears in {\tt d}: + +\begin{verbatim} +>>> t.append('new value') +>>> d +defaultdict(, {'new key': ['new value']}) +\end{verbatim} + +If you are making a dictionary of lists, you can often write simpler +code using {\tt defaultdict}. In my solution to +Exercise~\ref{anagrams}, which you can get from +\url{http://thinkpython2.com/code/anagram_sets.py}, I make a +dictionary that maps from a sorted string of letters to the list of +words that can be spelled with those letters. For example, {\tt + 'opst'} maps to the list {\tt ['opts', 'post', 'pots', 'spot', + 'stop', 'tops']}. + +Here's the original code: + +\begin{verbatim} +def all_anagrams(filename): + d = {} + for line in open(filename): + word = line.strip().lower() + t = signature(word) + if t not in d: + d[t] = [word] + else: + d[t].append(word) + return d +\end{verbatim} + +This can be simplified using {\tt setdefault}, which you might +have used in Exercise~\ref{setdefault}: +\index{setdefault} + +\begin{verbatim} +def all_anagrams(filename): + d = {} + for line in open(filename): + word = line.strip().lower() + t = signature(word) + d.setdefault(t, []).append(word) + return d +\end{verbatim} + +This solution has the drawback that it makes a new list +every time, regardless of whether it is needed. For lists, +that's no big deal, but if the factory +function is complicated, it might be. +\index{factory function} + +We can avoid this problem and +simplify the code using a {\tt defaultdict}: + +\begin{verbatim} +def all_anagrams(filename): + d = defaultdict(list) + for line in open(filename): + word = line.strip().lower() + t = signature(word) + d[t].append(word) + return d +\end{verbatim} + +My solution to Exercise~\ref{poker}, which you can download from +\url{http://thinkpython2.com/code/PokerHandSoln.py}, +uses {\tt setdefault} in the function +\verb"has_straightflush". This solution has the drawback +of creating a {\tt Hand} object every time through the loop, whether +it is needed or not. As an exercise, rewrite it using +a defaultdict. + + +\section{Named tuples} + +Many simple objects are basically collections of related values. +For example, the Point object defined in Chapter~\ref{clobjects} contains +two numbers, {\tt x} and {\tt y}. When you define a class like +this, you usually start with an init method and a str method: + +\begin{verbatim} +class Point: + + def __init__(self, x=0, y=0): + self.x = x + self.y = y + + def __str__(self): + return '(%g, %g)' % (self.x, self.y) +\end{verbatim} + +This is a lot of code to convey a small amount of information. +Python provides a more concise way to say the same thing: + +\begin{verbatim} +from collections import namedtuple +Point = namedtuple('Point', ['x', 'y']) +\end{verbatim} + +The first argument is the name of the class you want to create. +The second is a list of the attributes Point objects should have, +as strings. The return value from {\tt namedtuple} is a class object: +\index{namedtuple} +\index{object!namedtuple} +\index{collections} +\index{module!collections} + +\begin{verbatim} +>>> Point + +\end{verbatim} + +{\tt Point} automatically provides methods like \verb"__init__" and +\verb"__str__" so you don't have to write them. +\index{class object} +\index{object!class} + +To create a Point object, you use the Point class as a function: + +\begin{verbatim} +>>> p = Point(1, 2) +>>> p +Point(x=1, y=2) +\end{verbatim} + +The init method assigns the arguments to attributes using the names +you provided. The str method prints a representation of the Point +object and its attributes. + +You can access the elements of the named tuple by name: + +\begin{verbatim} +>>> p.x, p.y +(1, 2) +\end{verbatim} + +But you can also treat a named tuple as a tuple: + +\begin{verbatim} +>>> p[0], p[1] +(1, 2) + +>>> x, y = p +>>> x, y +(1, 2) +\end{verbatim} + +Named tuples provide a quick way to define simple classes. +The drawback is that simple classes don't always stay simple. +You might decide later that you want to add methods to a named tuple. +In that case, you could define a new class that inherits from +the named tuple: +\index{inheritance} + +\begin{verbatim} +class Pointier(Point): + # add more methods here +\end{verbatim} + +Or you could switch to a conventional class definition. + + +\section{Gathering keyword args} + +In Section~\ref{gather}, we saw how to write a function that +gathers its arguments into a tuple: +\index{gather} + +\begin{verbatim} +def printall(*args): + print(args) +\end{verbatim} +% +You can call this function with any number of positional arguments +(that is, arguments that don't have keywords): +\index{positional argument} +\index{argument!positional} + +\begin{verbatim} +>>> printall(1, 2.0, '3') +(1, 2.0, '3') +\end{verbatim} +% +But the {\tt *} operator doesn't gather keyword arguments: +\index{keyword argument} +\index{argument!keyword} + +\begin{verbatim} +>>> printall(1, 2.0, third='3') +TypeError: printall() got an unexpected keyword argument 'third' +\end{verbatim} +% +To gather keyword arguments, you can use the {\tt **} operator: + +\begin{verbatim} +def printall(*args, **kwargs): + print(args, kwargs) +\end{verbatim} +% +You can call the keyword gathering parameter anything you want, but +{\tt kwargs} is a common choice. The result is a dictionary that maps +keywords to values: + +\begin{verbatim} +>>> printall(1, 2.0, third='3') +(1, 2.0) {'third': '3'} +\end{verbatim} +% +If you have a dictionary of keywords and values, you can use the +scatter operator, {\tt **} to call a function: +\index{scatter} + +\begin{verbatim} +>>> d = dict(x=1, y=2) +>>> Point(**d) +Point(x=1, y=2) +\end{verbatim} +% +Without the scatter operator, the function would treat {\tt d} as +a single positional argument, so it would assign {\tt d} to +{\tt x} and complain because there's nothing to assign to {\tt y}: + +\begin{verbatim} +>>> d = dict(x=1, y=2) +>>> Point(d) +Traceback (most recent call last): + File "", line 1, in +TypeError: __new__() missing 1 required positional argument: 'y' +\end{verbatim} +% +When you are working with functions that have a large number of +parameters, it is often useful to create and pass around dictionaries +that specify frequently used options. + + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[conditional expression:] An expression that has one of two +values, depending on a condition. +\index{conditional expression} +\index{expression!conditional} + +\item[list comprehension:] An expression with a {\tt for} loop in square +brackets that yields a new list. +\index{list comprehension} + +\item[generator expression:] An expression with a {\tt for} loop in parentheses +that yields a generator object. +\index{generator expression} +\index{expression!generator} + +\item[multiset:] A mathematical entity that represents a mapping +between the elements of a set and the number of times they appear. + +\item[factory:] A function, usually passed as a parameter, used to +create objects. +\index{factory} + +\end{description} + + + + +\section{연습 문제} +%Exercises + +\begin{exercise} + +The following is a function computes the binomial +coefficient recursively. + +\begin{verbatim} +def binomial_coeff(n, k): + """Compute the binomial coefficient "n choose k". + + n: number of trials + k: number of successes + + returns: int + """ + if k == 0: + return 1 + if n == 0: + return 0 + + res = binomial_coeff(n-1, k) + binomial_coeff(n-1, k-1) + return res +\end{verbatim} + +Rewrite the body of the function using nested conditional +expressions. + +One note: this function is not very efficient because it ends up computing +the same values over and over. You could make it more efficient by +memoizing (see Section~\ref{memoize}). But you will find that it's harder to +memoize if you write it using conditional expressions. + +\end{exercise} + + + +\appendix + +\chapter{Debugging} +\index{debugging} + +When you are debugging, you should distinguish among different +kinds of errors in order to track them down more quickly: + +\begin{itemize} + +\item Syntax errors are discovered by the interpreter when it is + translating the source code into byte code. They indicate + that there is something wrong with the structure of the program. + Example: Omitting the colon at the end of a {\tt def} statement + generates the somewhat redundant message {\tt SyntaxError: invalid + syntax}. +\index{syntax error} +\index{error!syntax} + +\item Runtime errors are produced by the interpreter if something goes + wrong while the program is running. Most runtime error messages + include information about where the error occurred and what + functions were executing. Example: An infinite recursion eventually + causes the runtime error ``maximum recursion depth exceeded''. +\index{runtime error} +\index{error!runtime} +\index{exception} + +\item Semantic errors are problems with a program that runs without + producing error messages but doesn't do the right thing. Example: + An expression may not be evaluated in the order you expect, yielding + an incorrect result. +\index{semantic error} +\index{error!semantic} + +\end{itemize} + +The first step in debugging is to figure out which kind of +error you are dealing with. Although the following sections are +organized by error type, some techniques are +applicable in more than one situation. + + +\section{Syntax errors} +\index{error message} + +Syntax errors are usually easy to fix once you figure out what they +are. Unfortunately, the error messages are often not helpful. +The most common messages are {\tt SyntaxError: invalid syntax} and +{\tt SyntaxError: invalid token}, neither of which is very informative. + +On the other hand, the message does tell you where in the program the +problem occurred. Actually, it tells you where Python +noticed a problem, which is not necessarily where the error +is. Sometimes the error is prior to the location of the error +message, often on the preceding line. +\index{incremental development} +\index{development plan!incremental} + +If you are building the program incrementally, you should have +a good idea about where the error is. It will be in the last +line you added. + +If you are copying code from a book, start by comparing +your code to the book's code very carefully. Check every character. +At the same time, remember that the book might be wrong, so +if you see something that looks like a syntax error, it might be. + +Here are some ways to avoid the most common syntax errors: +\index{syntax} + +\begin{enumerate} + +\item Make sure you are not using a Python keyword for a variable name. +\index{keyword} + +\item Check that you have a colon at the end of the header of every +compound statement, including {\tt for}, {\tt while}, +{\tt if}, and {\tt def} statements. +\index{header} +\index{colon} + +\item Make sure that any strings in the code have matching +quotation marks. Make sure that all quotation marks are +``straight quotes'', not ``curly quotes''. +\index{quotation mark} + +\item If you have multiline strings with triple quotes (single or double), make +sure you have terminated the string properly. An unterminated string +may cause an {\tt invalid token} error at the end of your program, +or it may treat the following part of the program as a string until it +comes to the next string. In the second case, it might not produce an error +message at all! +\index{multiline string} +\index{string!multiline} + +\item An unclosed opening operator---\verb+(+, \verb+{+, or + \verb+[+---makes Python continue with the next line as part of the + current statement. Generally, an error occurs almost immediately in + the next line. + +\item Check for the classic {\tt =} instead of {\tt ==} inside +a conditional. +\index{conditional} + +\item Check the indentation to make sure it lines up the way it +is supposed to. Python can handle space and tabs, but if you mix +them it can cause problems. The best way to avoid this problem +is to use a text editor that knows about Python and generates +consistent indentation. +\index{indentation} +\index{whitespace} + +\item If you have non-ASCII characters in the code (including strings +and comments), that might cause a problem, although Python 3 usually +handles non-ASCII characters. Be careful if you paste in text from +a web page or other source. + +\end{enumerate} + +If nothing works, move on to the next section... + + +\subsection{I keep making changes and it makes no difference.} + +If the interpreter says there is an error and you don't see it, that +might be because you and the interpreter are not looking at the same +code. Check your programming environment to make sure that the +program you are editing is the one Python is trying to run. + +If you are not sure, try putting an obvious and deliberate syntax +error at the beginning of the program. Now run it again. If the +interpreter doesn't find the new error, you are not running the +new code. + +There are a few likely culprits: + +\begin{itemize} + +\item You edited the file and forgot to save the changes before +running it again. Some programming environments do this +for you, but some don't. + +\item You changed the name of the file, but you are still running +the old name. + +\item Something in your development environment is configured +incorrectly. + +\item If you are writing a module and using {\tt import}, +make sure you don't give your module the same name as one +of the standard Python modules. + +\item If you are using {\tt import} to read a module, remember +that you have to restart the interpreter or use {\tt reload} +to read a modified file. If you import the module again, it +doesn't do anything. +\index{module!reload} +\index{reload function} +\index{function!reload} + +\end{itemize} + +If you get stuck and you can't figure out what is going on, one +approach is to start again with a new program like ``Hello, World!'', +and make sure you can get a known program to run. Then gradually add +the pieces of the original program to the new one. + + +\section{Runtime errors} + +Once your program is syntactically correct, +Python can read it and at least start running it. What could +possibly go wrong? + + +\subsection{My program does absolutely nothing.} + +This problem is most common when your file consists of functions and +classes but does not actually invoke a function to start execution. +This may be intentional if you only plan to import this module to +supply classes and functions. + +If it is not intentional, make sure there is a function call +in the program, and make sure the flow of execution reaches +it (see ``Flow of Execution'' below). + + +\subsection{My program hangs.} +\index{infinite loop} +\index{infinite recursion} +\index{hanging} + +If a program stops and seems to be doing nothing, it is ``hanging''. +Often that means that it is caught in an infinite loop or infinite +recursion. + +\begin{itemize} + +\item If there is a particular loop that you suspect is the +problem, add a {\tt print} statement immediately before the loop that says +``entering the loop'' and another immediately after that says +``exiting the loop''. + +Run the program. If you get the first message and not the second, +you've got an infinite loop. Go to the ``Infinite Loop'' section +below. + +\item Most of the time, an infinite recursion will cause the program +to run for a while and then produce a ``RuntimeError: Maximum +recursion depth exceeded'' error. If that happens, go to the +``Infinite Recursion'' section below. + +If you are not getting this error but you suspect there is a problem +with a recursive method or function, you can still use the techniques +in the ``Infinite Recursion'' section. + +\item If neither of those steps works, start testing other +loops and other recursive functions and methods. + +\item If that doesn't work, then it is possible that +you don't understand the flow of execution in your program. +Go to the ``Flow of Execution'' section below. + +\end{itemize} + + +\subsubsection{Infinite Loop} +\index{infinite loop} +\index{loop!infinite} +\index{condition} +\index{loop!condition} + +If you think you have an infinite loop and you think you know +what loop is causing the problem, add a {\tt print} statement at +the end of the loop that prints the values of the variables in +the condition and the value of the condition. + +For example: + +\begin{verbatim} +while x > 0 and y < 0 : + # do something to x + # do something to y + + print('x: ', x) + print('y: ', y) + print("condition: ", (x > 0 and y < 0)) +\end{verbatim} +% +Now when you run the program, you will see three lines of output +for each time through the loop. The last time through the +loop, the condition should be {\tt False}. If the loop keeps +going, you will be able to see the values of {\tt x} and {\tt y}, +and you might figure out why they are not being updated correctly. + + +\subsubsection{Infinite Recursion} +\index{infinite recursion} +\index{recursion!infinite} + +Most of the time, infinite recursion causes the program to run +for a while and then produce a {\tt Maximum recursion depth exceeded} +error. + +If you suspect that a function is causing an infinite +recursion, make sure that there is a base case. +There should be some condition that causes the +function to return without making a recursive invocation. +If not, you need to rethink the algorithm and identify a base +case. + +If there is a base case but the program doesn't seem to be reaching +it, add a {\tt print} statement at the beginning of the function +that prints the parameters. Now when you run the program, you will see +a few lines of output every time the function is invoked, +and you will see the parameter values. If the parameters are not moving +toward the base case, you will get some ideas about why not. + + +\subsubsection{Flow of Execution} +\index{flow of execution} + +If you are not sure how the flow of execution is moving through +your program, add {\tt print} statements to the beginning of each +function with a message like ``entering function {\tt foo}'', where +{\tt foo} is the name of the function. + +Now when you run the program, it will print a trace of each +function as it is invoked. + + +\subsection{When I run the program I get an exception.} +\index{exception} +\index{runtime error} + +If something goes wrong during runtime, Python +prints a message that includes the name of the +exception, the line of the program where the problem occurred, +and a traceback. +\index{traceback} + +The traceback identifies the function that is currently running, and +then the function that called it, and then the function that called +{\em that}, and so on. In other words, it traces the sequence of +function calls that got you to where you are, including the line +number in your file where each call occurred. + +The first step is to examine the place in the program where +the error occurred and see if you can figure out what happened. +These are some of the most common runtime errors: + +\begin{description} + +\item[NameError:] You are trying to use a variable that doesn't +exist in the current environment. Check if the name +is spelled right, or at least consistently. +And remember that local variables are local; you +cannot refer to them from outside the function where they are defined. +\index{NameError} +\index{exception!NameError} + +\item[TypeError:] There are several possible causes: +\index{TypeError} +\index{exception!TypeError} + +\begin{itemize} + +\item You are trying to use a value improperly. Example: indexing +a string, list, or tuple with something other than an integer. +\index{index} + +\item There is a mismatch between the items in a format string and +the items passed for conversion. This can happen if either the number +of items does not match or an invalid conversion is called for. +\index{format operator} +\index{operator!format} + +\item You are passing the wrong number of arguments to a function. +For methods, look at the method definition and +check that the first parameter is {\tt self}. Then look at the +method invocation; make sure you are invoking the method on an +object with the right type and providing the other arguments +correctly. + +\end{itemize} + +\item[KeyError:] You are trying to access an element of a dictionary +using a key that the dictionary does not contain. If the keys +are strings, remember that capitalization matters. +\index{KeyError} +\index{exception!KeyError} +\index{dictionary} + +\item[AttributeError:] You are trying to access an attribute or method + that does not exist. Check the spelling! You can use the built-in + function {\tt vars} to list the attributes that do exist. +\index{dir function} +\index{function!dir} + +If an AttributeError indicates that an object has {\tt NoneType}, +that means that it is {\tt None}. So the problem is not the +attribute name, but the object. + +The reason the object is none might be that you forgot +to return a value from a function; if you get to the end of +a function without hitting a {\tt return} statement, it returns +{\tt None}. Another common cause is using the result from +a list method, like {\tt sort}, that returns {\tt None}. +\index{AttributeError} +\index{exception!AttributeError} + +\item[IndexError:] The index you are using +to access a list, string, or tuple is greater than +its length minus one. Immediately before the site of the error, +add a {\tt print} statement to display +the value of the index and the length of the array. +Is the array the right size? Is the index the right value? +\index{IndexError} +\index{exception!IndexError} + +\end{description} + +The Python debugger ({\tt pdb}) is useful for tracking down +exceptions because it allows you to examine the state of the +program immediately before the error. You can read +about {\tt pdb} at \url{https://docs.python.org/3/library/pdb.html}. +\index{debugger (pdb)} +\index{pdb (Python debugger)} + + +\subsection{I added so many {\tt print} statements I get inundated with +output.} +\index{print statement} +\index{statement!print} + +One of the problems with using {\tt print} statements for debugging +is that you can end up buried in output. There are two ways +to proceed: simplify the output or simplify the program. + +To simplify the output, you can remove or comment out {\tt print} +statements that aren't helping, or combine them, or format +the output so it is easier to understand. + +To simplify the program, there are several things you can do. First, +scale down the problem the program is working on. For example, if you +are searching a list, search a {\em small} list. If the program takes +input from the user, give it the simplest input that causes the +problem. +\index{dead code} + +Second, clean up the program. Remove dead code and reorganize the +program to make it as easy to read as possible. For example, if you +suspect that the problem is in a deeply nested part of the program, +try rewriting that part with simpler structure. If you suspect a +large function, try splitting it into smaller functions and testing them +separately. +\index{testing!minimal test case} +\index{test case, minimal} + +Often the process of finding the minimal test case leads you to the +bug. If you find that a program works in one situation but not in +another, that gives you a clue about what is going on. + +Similarly, rewriting a piece of code can help you find subtle +bugs. If you make a change that you think shouldn't affect the +program, and it does, that can tip you off. + + +\section{Semantic errors} + +In some ways, semantic errors are the hardest to debug, +because the interpreter provides no information +about what is wrong. Only you know what the program is supposed to +do. +\index{semantic error} +\index{error!semantic} + +The first step is to make a connection between the program +text and the behavior you are seeing. You need a hypothesis +about what the program is actually doing. One of the things +that makes that hard is that computers run so fast. + +You will often wish that you could slow the program down to human +speed, and with some debuggers you can. But the time it takes to +insert a few well-placed {\tt print} statements is often short compared to +setting up the debugger, inserting and removing breakpoints, and +``stepping'' the program to where the error is occurring. + + +\subsection{My program doesn't work.} + +You should ask yourself these questions: + +\begin{itemize} + +\item Is there something the program was supposed to do but +which doesn't seem to be happening? Find the section of the code +that performs that function and make sure it is executing when +you think it should. + +\item Is something happening that shouldn't? Find code in +your program that performs that function and see if it is +executing when it shouldn't. + +\item Is a section of code producing an effect that is not +what you expected? Make sure that you understand the code in +question, especially if it involves functions or methods in +other Python modules. Read the documentation for the functions you call. +Try them out by writing simple test cases and checking the results. + +\end{itemize} + +In order to program, you need a mental model of how +programs work. If you write a program that doesn't do what you expect, +often the problem is not in the program; it's in your mental +model. +\index{model, mental} +\index{mental model} + +The best way to correct your mental model is to break the program +into its components (usually the functions and methods) and test +each component independently. Once you find the discrepancy +between your model and reality, you can solve the problem. + +Of course, you should be building and testing components as you +develop the program. If you encounter a problem, +there should be only a small amount of new code +that is not known to be correct. + + +\subsection{I've got a big hairy expression and it doesn't +do what I expect.} +\index{expression!big and hairy} +\index{big, hairy expression} + +Writing complex expressions is fine as long as they are readable, +but they can be hard to debug. It is often a good idea to +break a complex expression into a series of assignments to +temporary variables. + +For example: + +\begin{verbatim} +self.hands[i].addCard(self.hands[self.findNeighbor(i)].popCard()) +\end{verbatim} +% +This can be rewritten as: + +\begin{verbatim} +neighbor = self.findNeighbor(i) +pickedCard = self.hands[neighbor].popCard() +self.hands[i].addCard(pickedCard) +\end{verbatim} +% +The explicit version is easier to read because the variable +names provide additional documentation, and it is easier to debug +because you can check the types of the intermediate variables +and display their values. +\index{temporary variable} +\index{variable!temporary} + +Another problem that can occur with big expressions is +that the order of evaluation may not be what you expect. +For example, if you are translating the expression +$\frac{x}{2 \pi}$ into Python, you might write: + +\begin{verbatim} +y = x / 2 * math.pi +\end{verbatim} +% +That is not correct because multiplication and division have +the same precedence and are evaluated from left to right. +So this expression computes $x \pi / 2$. +\index{order of operations} +\index{precedence} + +A good way to debug expressions is to add parentheses to make +the order of evaluation explicit: + +\begin{verbatim} + y = x / (2 * math.pi) +\end{verbatim} +% +Whenever you are not sure of the order of evaluation, use +parentheses. Not only will the program be correct (in the sense +of doing what you intended), it will also be more readable for +other people who haven't memorized the order of operations. + + +\subsection{I've got a function that doesn't return what I +expect.} +\index{return statement} +\index{statement!return} + +If you have a {\tt return} statement with a complex expression, +you don't have a chance to print the result before +returning. Again, you can use a temporary variable. For +example, instead of: + +\begin{verbatim} +return self.hands[i].removeMatches() +\end{verbatim} +% +you could write: + +\begin{verbatim} +count = self.hands[i].removeMatches() +return count +\end{verbatim} +% +Now you have the opportunity to display the value of +{\tt count} before returning. + + +\subsection{I'm really, really stuck and I need help.} + +First, try getting away from the computer for a few minutes. +Computers emit waves that affect the brain, causing these +symptoms: + +\begin{itemize} + +\item Frustration and rage. +\index{frustration} +\index{rage} +\index{debugging!emotional response} +\index{emotional debugging} + +\item Superstitious beliefs (``the computer hates me'') and +magical thinking (``the program only works when I wear my +hat backward''). +\index{debugging!superstition} +\index{superstitious debugging} + +\item Random walk programming (the attempt to program by writing +every possible program and choosing the one that does the right +thing). +\index{random walk programming} +\index{development plan!random walk programming} + +\end{itemize} + +If you find yourself suffering from any of these symptoms, get +up and go for a walk. When you are calm, think about the program. +What is it doing? What are some possible causes of that +behavior? When was the last time you had a working program, +and what did you do next? + +Sometimes it just takes time to find a bug. I often find bugs +when I am away from the computer and let my mind wander. Some +of the best places to find bugs are trains, showers, and in bed, +just before you fall asleep. + + +\subsection{No, I really need help.} + +It happens. Even the best programmers occasionally get stuck. +Sometimes you work on a program so long that you can't see the +error. You need a fresh pair of eyes. + +Before you bring someone else in, make sure you are prepared. +Your program should be as simple +as possible, and you should be working on the smallest input +that causes the error. You should have {\tt print} statements in the +appropriate places (and the output they produce should be +comprehensible). You should understand the problem well enough +to describe it concisely. + +When you bring someone in to help, be sure to give +them the information they need: + +\begin{itemize} + +\item If there is an error message, what is it +and what part of the program does it indicate? + +\item What was the last thing you did before this error occurred? +What were the last lines of code that you wrote, or what is +the new test case that fails? + +\item What have you tried so far, and what have you learned? + +\end{itemize} + +When you find the bug, take a second to think about what you +could have done to find it faster. Next time you see something +similar, you will be able to find the bug more quickly. + +Remember, the goal is not just to make the program +work. The goal is to learn how to make the program work. + + +\chapter{Analysis of Algorithms} +\label{algorithms} + +\begin{quote} +This appendix is an edited excerpt from {\it Think Complexity}, by +Allen B. Downey, also published by O'Reilly Media (2012). When you +are done with this book, you might want to move on to that one. +\end{quote} + +{\bf Analysis of algorithms} is a branch of computer science that +studies the performance of algorithms, especially their run time and +space requirements. See +\url{http://en.wikipedia.org/wiki/Analysis_of_algorithms}. +\index{algorithm} \index{analysis of algorithms} + +The practical goal of algorithm analysis is to predict the performance +of different algorithms in order to guide design decisions. + +During the 2008 United States Presidential Campaign, candidate +Barack Obama was asked to perform an impromptu analysis when +he visited Google. Chief executive Eric Schmidt jokingly asked him +for ``the most efficient way to sort a million 32-bit integers.'' +Obama had apparently been tipped off, because he quickly +replied, ``I think the bubble sort would be the wrong way to go.'' +See \url{http://www.youtube.com/watch?v=k4RRi_ntQc8}. +\index{Obama, Barack} +\index{Schmidt, Eric} +\index{bubble sort} + +This is true: bubble sort is conceptually simple but slow for +large datasets. The answer Schmidt was probably looking for is +``radix sort'' (\url{http://en.wikipedia.org/wiki/Radix_sort})\footnote{ +But if you get a question like this in an interview, I think +a better answer is, ``The fastest way to sort a million integers +is to use whatever sort function is provided by the language +I'm using. Its performance is good enough for the vast majority +of applications, but if it turned out that my application was too +slow, I would use a profiler to see where the time was being +spent. If it looked like a faster sort algorithm would have +a significant effect on performance, then I would look +around for a good implementation of radix sort.''}. +\index{radix sort} + +The goal of algorithm analysis is to make meaningful +comparisons between algorithms, but there are some problems: +\index{comparing algorithms} + +\begin{itemize} + +\item The relative performance of the algorithms might +depend on characteristics of the hardware, so one algorithm +might be faster on Machine A, another on Machine B. +The general solution to this problem is to specify a +{\bf machine model} and analyze the number of steps, or +operations, an algorithm requires under a given model. +\index{machine model} + +\item Relative performance might depend on the details of +the dataset. For example, some sorting +algorithms run faster if the data are already partially sorted; +other algorithms run slower in this case. +A common way to avoid this problem is to analyze the +{\bf worst case} scenario. It is sometimes useful to +analyze average case performance, but that's usually harder, +and it might not be obvious what set of cases to average over. +\index{worst case} +\index{average case} + +\item Relative performance also depends on the size of the +problem. A sorting algorithm that is fast for small lists +might be slow for long lists. +The usual solution to this problem is to express run time +(or number of operations) as a function of problem size, +and group functions into categories depending on how quickly +they grow as problem size increases. + +\end{itemize} + +The good thing about this kind of comparison is that it lends +itself to simple classification of algorithms. For example, +if I know that the run time of Algorithm A tends to be +proportional to the size of the input, $n$, and Algorithm B +tends to be proportional to $n^2$, then I +expect A to be faster than B, at least for large values of $n$. + +This kind of analysis comes with some caveats, but we'll get +to that later. + + +\section{Order of growth} + +Suppose you have analyzed two algorithms and expressed +their run times in terms of the size of the input: +Algorithm A takes $100n+1$ steps to solve a problem with +size $n$; Algorithm B takes $n^2 + n + 1$ steps. +\index{order of growth} + +The following table shows the run time of these algorithms +for different problem sizes: + +\begin{tabular}{|r|r|r|} +\hline +Input & Run time of & Run time of \\ +size & Algorithm A & Algorithm B \\ +\hline +10 & 1 001 & 111 \\ +100 & 10 001 & 10 101 \\ +1 000 & 100 001 & 1 001 001 \\ +10 000 & 1 000 001 & $> 10^{10}$ \\ +\hline +\end{tabular} + +At $n=10$, Algorithm A looks pretty bad; it takes almost 10 times +longer than Algorithm B. But for $n=100$ they are about the same, and +for larger values A is much better. + +The fundamental reason is that for large values of $n$, any function +that contains an $n^2$ term will grow faster than a function whose +leading term is $n$. The {\bf leading term} is the term with the +highest exponent. +\index{leading term} +\index{exponent} + +For Algorithm A, the leading term has a large coefficient, 100, which +is why B does better than A for small $n$. But regardless of the +coefficients, there will always be some value of $n$ where +$a n^2 > b n$, for any values of $a$ and $b$. +\index{leading coefficient} + +The same argument applies to the non-leading terms. Even if the run +time of Algorithm A were $n+1000000$, it would still be better than +Algorithm B for sufficiently large $n$. + +In general, we expect an algorithm with a smaller leading term to be a +better algorithm for large problems, but for smaller problems, there +may be a {\bf crossover point} where another algorithm is better. The +location of the crossover point depends on the details of the +algorithms, the inputs, and the hardware, so it is usually ignored for +purposes of algorithmic analysis. But that doesn't mean you can forget +about it. +\index{crossover point} + +If two algorithms have the same leading order term, it is hard to say +which is better; again, the answer depends on the details. So for +algorithmic analysis, functions with the same leading term +are considered equivalent, even if they have different coefficients. + +An {\bf order of growth} is a set of functions whose growth +behavior is considered equivalent. For example, $2n$, $100n$ and $n+1$ +belong to the same order of growth, which is written $O(n)$ in +{\bf Big-Oh notation} and often called {\bf linear} because every function +in the set grows linearly with $n$. +\index{big-oh notation} +\index{linear growth} + +All functions with the leading term $n^2$ belong to $O(n^2)$; they are +called {\bf quadratic}. +\index{quadratic growth} + +The following table shows some of the orders of growth that +appear most commonly in algorithmic analysis, +in increasing order of badness. +\index{badness} + +\begin{tabular}{|r|r|r|} +\hline +Order of & Name \\ +growth & \\ +\hline +$O(1)$ & constant \\ +$O(\log_b n)$ & logarithmic (for any $b$) \\ +$O(n)$ & linear \\ +$O(n \log_b n)$ & linearithmic \\ +$O(n^2)$ & quadratic \\ +$O(n^3)$ & cubic \\ +$O(c^n)$ & exponential (for any $c$) \\ +\hline +\end{tabular} + +For the logarithmic terms, the base of the logarithm doesn't matter; +changing bases is the equivalent of multiplying by a constant, which +doesn't change the order of growth. Similarly, all exponential +functions belong to the same order of growth regardless of the base of +the exponent. +Exponential functions grow very quickly, so exponential algorithms are +only useful for small problems. +\index{logarithmic growth} +\index{exponential growth} + + +\begin{exercise} + +Read the Wikipedia page on Big-Oh notation at +\url{http://en.wikipedia.org/wiki/Big_O_notation} and +answer the following questions: + +\begin{enumerate} +\item What is the order of growth of $n^3 + n^2$? +What about $1000000 n^3 + n^2$? +What about $n^3 + 1000000 n^2$? + +\item What is the order of growth of $(n^2 + n) \cdot (n + 1)$? Before + you start multiplying, remember that you only need the leading term. + +\item If $f$ is in $O(g)$, for some unspecified function $g$, what can + we say about $af+b$? + +\item If $f_1$ and $f_2$ are in $O(g)$, what can we say about $f_1 + f_2$? + +\item If $f_1$ is in $O(g)$ +and $f_2$ is in $O(h)$, +what can we say about $f_1 + f_2$? + +\item If $f_1$ is in $O(g)$ and $f_2$ is $O(h)$, +what can we say about $f_1 \cdot f_2$? +\end{enumerate} + +\end{exercise} + +Programmers who care about performance often find this kind of +analysis hard to swallow. They have a point: sometimes the +coefficients and the non-leading terms make a real difference. +Sometimes the details of the hardware, the programming language, and +the characteristics of the input make a big difference. And for small +problems asymptotic behavior is irrelevant. + +But if you keep those caveats in mind, algorithmic analysis is a +useful tool. At least for large problems, the ``better'' algorithm +is usually better, and sometimes it is {\em much} better. The +difference between two algorithms with the same order of growth is +usually a constant factor, but the difference between a good algorithm +and a bad algorithm is unbounded! + + +\section{Analysis of basic Python operations} + +In Python, most arithmetic operations are constant time; +multiplication usually takes longer than addition and subtraction, and +division takes even longer, but these run times don't depend on the +magnitude of the operands. Very large integers are an exception; in +that case the run time increases with the number of digits. +\index{analysis of primitives} + +Indexing operations---reading or writing elements in a sequence +or dictionary---are also constant time, regardless of the size +of the data structure. +\index{indexing} + +A {\tt for} loop that traverses a sequence or dictionary is +usually linear, as long as all of the operations in the body +of the loop are constant time. For example, adding up the +elements of a list is linear: + +\begin{verbatim} + total = 0 + for x in t: + total += x +\end{verbatim} + +The built-in function {\tt sum} is also linear because it does +the same thing, but it tends to be faster because it is a more +efficient implementation; in the language of algorithmic analysis, +it has a smaller leading coefficient. + +As a rule of thumb, if the body of a loop is in $O(n^a)$ then +the whole loop is in $O(n^{a+1})$. The exception is if you can +show that the loop exits after a constant number of iterations. +If a loop runs $k$ times regardless of $n$, then +the loop is in $O(n^a)$, even for large $k$. + +Multiplying by $k$ doesn't change the order of growth, but neither +does dividing. So if the body of a loop is in $O(n^a)$ and it runs +$n/k$ times, the loop is in $O(n^{a+1})$, even for large $k$. + +Most string and tuple operations are linear, except indexing and {\tt + len}, which are constant time. The built-in functions {\tt min} and +{\tt max} are linear. The run-time of a slice operation is +proportional to the length of the output, but independent of the size +of the input. +\index{string methods} +\index{tuple methods} + +String concatenation is linear; the run time depends on the sum +of the lengths of the operands. +\index{string concatenation} + +All string methods are linear, but if the lengths of +the strings are bounded by a constant---for example, operations on single +characters---they are considered constant time. +The string method {\tt join} is linear; the run time depends on +the total length of the strings. +\index{join@{\tt join}} + +Most list methods are linear, but there are some exceptions: +\index{list methods} + +\begin{itemize} + +\item Adding an element to the end of a list is constant time on +average; when it runs out of room it occasionally gets copied +to a bigger location, but the total time for $n$ operations +is $O(n)$, so the average time for each +operation is $O(1)$. + +\item Removing an element from the end of a list is constant time. + +\item Sorting is $O(n \log n)$. +\index{sorting} + +\end{itemize} + +Most dictionary operations and methods are constant time, but +there are some exceptions: +\index{dictionary methods} + +\begin{itemize} + +\item The run time of {\tt update} is + proportional to the size of the dictionary passed as a parameter, + not the dictionary being updated. + +\item {\tt keys}, {\tt values} and {\tt items} are constant time because + they return iterators. But + if you loop through the iterators, the loop will be linear. +\index{iterator} + +\end{itemize} + +The performance of dictionaries is one of the minor miracles of +computer science. We will see how they work in +Section~\ref{hashtable}. + + +\begin{exercise} + +Read the Wikipedia page on sorting algorithms at +\url{http://en.wikipedia.org/wiki/Sorting_algorithm} and answer +the following questions: +\index{sorting} + +\begin{enumerate} + +\item What is a ``comparison sort?'' What is the best worst-case order + of growth for a comparison sort? What is the best worst-case order + of growth for any sort algorithm? +\index{comparison sort} + +\item What is the order of growth of bubble sort, and why does Barack + Obama think it is ``the wrong way to go?'' + +\item What is the order of growth of radix sort? What preconditions + do we need to use it? + +\item What is a stable sort and why might it matter in practice? +\index{stable sort} + +\item What is the worst sorting algorithm (that has a name)? + +\item What sort algorithm does the C library use? What sort algorithm + does Python use? Are these algorithms stable? You might have to + Google around to find these answers. + +\item Many of the non-comparison sorts are linear, so why does does + Python use an $O(n \log n)$ comparison sort? + +\end{enumerate} + +\end{exercise} + + +\section{Analysis of search algorithms} + +A {\bf search} is an algorithm that takes a collection and a target +item and determines whether the target is in the collection, often +returning the index of the target. +\index{search} + +The simplest search algorithm is a ``linear search'', which traverses +the items of the collection in order, stopping if it finds the target. +In the worst case it has to traverse the entire collection, so the run +time is linear. +\index{linear search} + +The {\tt in} operator for sequences uses a linear search; so do string +methods like {\tt find} and {\tt count}. +\index{in@{\tt in} operator} + +If the elements of the sequence are in order, you can use a {\bf + bisection search}, which is $O(\log n)$. Bisection search is +similar to the algorithm you might use to look a word up in a +dictionary (a paper dictionary, not the data structure). Instead of +starting at the beginning and checking each item in order, you start +with the item in the middle and check whether the word you are looking +for comes before or after. If it comes before, then you search the +first half of the sequence. Otherwise you search the second half. +Either way, you cut the number of remaining items in half. +\index{bisection search} + +If the sequence has 1,000,000 items, it will take about 20 steps to +find the word or conclude that it's not there. So that's about 50,000 +times faster than a linear search. + +Bisection search can be much faster than linear search, but +it requires the sequence to be in order, which might require +extra work. + +There is another data structure, called a {\bf hashtable} that +is even faster---it can do a search in constant time---and it +doesn't require the items to be sorted. Python dictionaries +are implemented using hashtables, which is why most dictionary +operations, including the {\tt in} operator, are constant time. + + +\section{Hashtables} +\label{hashtable} + +To explain how hashtables work and why their performance is so +good, I start with a simple implementation of a map and +gradually improve it until it's a hashtable. +\index{hashtable} + +I use Python to demonstrate these implementations, but in real +life you wouldn't write code like this in Python; you would just use a +dictionary! So for the rest of this chapter, you have to imagine that +dictionaries don't exist and you want to implement a data structure +that maps from keys to values. The operations you have to +implement are: + +\begin{description} + +\item[{\tt add(k, v)}:] Add a new item that maps from key {\tt k} +to value {\tt v}. With a Python dictionary, {\tt d}, this operation +is written {\tt d[k] = v}. + +\item[{\tt get(k)}:] Look up and return the value that corresponds +to key {\tt k}. With a Python dictionary, {\tt d}, this operation +is written {\tt d[k]} or {\tt d.get(k)}. + +\end{description} + +For now, I assume that each key only appears once. +The simplest implementation of this interface uses a list of +tuples, where each tuple is a key-value pair. +\index{LinearMap@{\tt LinearMap}} + +\begin{verbatim} +class LinearMap: + + def __init__(self): + self.items = [] + + def add(self, k, v): + self.items.append((k, v)) + + def get(self, k): + for key, val in self.items: + if key == k: + return val + raise KeyError +\end{verbatim} + +{\tt add} appends a key-value tuple to the list of items, which +takes constant time. + +{\tt get} uses a {\tt for} loop to search the list: +if it finds the target key it returns the corresponding value; +otherwise it raises a {\tt KeyError}. +So {\tt get} is linear. +\index{KeyError@{\tt KeyError}} + +An alternative is to keep the list sorted by key. Then {\tt get} +could use a bisection search, which is $O(\log n)$. But inserting a +new item in the middle of a list is linear, so this might not be the +best option. There are other data structures that can implement {\tt + add} and {\tt get} in log time, but that's still not as good as +constant time, so let's move on. +\index{red-black tree} + +One way to improve {\tt LinearMap} is to break the list of key-value +pairs into smaller lists. Here's an implementation called +{\tt BetterMap}, which is a list of 100 LinearMaps. As we'll see +in a second, the order of growth for {\tt get} is still linear, +but {\tt BetterMap} is a step on the path toward hashtables: +\index{BetterMap@{\tt BetterMap}} + +\begin{verbatim} +class BetterMap: + + def __init__(self, n=100): + self.maps = [] + for i in range(n): + self.maps.append(LinearMap()) + + def find_map(self, k): + index = hash(k) % len(self.maps) + return self.maps[index] + + def add(self, k, v): + m = self.find_map(k) + m.add(k, v) + + def get(self, k): + m = self.find_map(k) + return m.get(k) +\end{verbatim} + +\verb"__init__" makes a list of {\tt n} {\tt LinearMap}s. + +\verb"find_map" is used by +{\tt add} and {\tt get} +to figure out which map to put the +new item in, or which map to search. + +\verb"find_map" uses the built-in function {\tt hash}, which takes +almost any Python object and returns an integer. A limitation of this +implementation is that it only works with hashable keys. Mutable +types like lists and dictionaries are unhashable. +\index{hash function} + +Hashable objects that are considered equivalent return the same hash +value, but the converse is not necessarily true: two objects with +different values can return the same hash value. + +\verb"find_map" uses the modulus operator to wrap the hash values +into the range from 0 to {\tt len(self.maps)}, so the result is a legal +index into the list. Of course, this means that many different +hash values will wrap onto the same index. But if the hash function +spreads things out pretty evenly (which is what hash functions +are designed to do), then we expect $n/100$ items per LinearMap. + +Since the run time of {\tt LinearMap.get} is proportional to the +number of items, we expect BetterMap to be about 100 times faster +than LinearMap. The order of growth is still linear, but the +leading coefficient is smaller. That's nice, but still not +as good as a hashtable. + +Here (finally) is the crucial idea that makes hashtables fast: if you +can keep the maximum length of the LinearMaps bounded, {\tt + LinearMap.get} is constant time. All you have to do is keep track +of the number of items and when the number of +items per LinearMap exceeds a threshold, resize the hashtable by +adding more LinearMaps. +\index{bounded} + +Here is an implementation of a hashtable: +\index{HashMap} + +\begin{verbatim} +class HashMap: + + def __init__(self): + self.maps = BetterMap(2) + self.num = 0 + + def get(self, k): + return self.maps.get(k) + + def add(self, k, v): + if self.num == len(self.maps.maps): + self.resize() + + self.maps.add(k, v) + self.num += 1 + + def resize(self): + new_maps = BetterMap(self.num * 2) + + for m in self.maps.maps: + for k, v in m.items: + new_maps.add(k, v) + + self.maps = new_maps +\end{verbatim} + +Each {\tt HashMap} contains a {\tt BetterMap}; \verb"__init__" starts +with just 2 LinearMaps and initializes {\tt num}, which keeps track of +the number of items. + +{\tt get} just dispatches to {\tt BetterMap}. The real work happens +in {\tt add}, which checks the number of items and the size of the +{\tt BetterMap}: if they are equal, the average number of items per +LinearMap is 1, so it calls {\tt resize}. + +{\tt resize} make a new {\tt BetterMap}, twice as big as the previous +one, and then ``rehashes'' the items from the old map to the new. + +Rehashing is necessary because changing the number of LinearMaps +changes the denominator of the modulus operator in +\verb"find_map". That means that some objects that used +to hash into the same LinearMap will get split up (which is +what we wanted, right?). +\index{rehashing} + +Rehashing is linear, so +{\tt resize} is linear, which might seem bad, since I promised +that {\tt add} would be constant time. But remember that +we don't have to resize every time, so {\tt add} is usually +constant time and only occasionally linear. The total amount +of work to run {\tt add} $n$ times is proportional to $n$, +so the average time of each {\tt add} is constant time! +\index{constant time} + +To see how this works, think about starting with an empty +HashTable and adding a sequence of items. We start with 2 LinearMaps, +so the first 2 adds are fast (no resizing required). Let's +say that they take one unit of work each. The next add +requires a resize, so we have to rehash the first two +items (let's call that 2 more units of work) and then +add the third item (one more unit). Adding the next item +costs 1 unit, so the total so far is +6 units of work for 4 items. + +The next {\tt add} costs 5 units, but the next three +are only one unit each, so the total is 14 units for the +first 8 adds. + +The next {\tt add} costs 9 units, but then we can add 7 more +before the next resize, so the total is 30 units for the +first 16 adds. + +After 32 adds, the total cost is 62 units, and I hope you are starting +to see a pattern. After $n$ adds, where $n$ is a power of two, the +total cost is $2n-2$ units, so the average work per add is +a little less than 2 units. When $n$ is a power of two, that's +the best case; for other values of $n$ the average work is a little +higher, but that's not important. The important thing is that it +is $O(1)$. +\index{average cost} + +Figure~\ref{fig.hash} shows how this works graphically. Each +block represents a unit of work. The columns show the total +work for each add in order from left to right: the first two +{\tt adds} cost 1 units, the third costs 3 units, etc. + +\begin{figure} +\centerline{\includegraphics[width=5.5in]{figs/towers.pdf}} +\caption{The cost of a hashtable add.\label{fig.hash}} +\end{figure} + +The extra work of rehashing appears as a sequence of increasingly +tall towers with increasing space between them. Now if you knock +over the towers, spreading the cost of resizing over all +adds, you can see graphically that the total cost after $n$ +adds is $2n - 2$. + +An important feature of this algorithm is that when we resize the +HashTable it grows geometrically; that is, we multiply the size by a +constant. If you increase the size +arithmetically---adding a fixed number each time---the average time +per {\tt add} is linear. +\index{geometric resizing} + +You can download my implementation of HashMap from +\url{http://thinkpython2.com/code/Map.py}, but remember that there +is no reason to use it; if you want a map, just use a Python dictionary. + +\section{용어 해설} +%Glossary + +\begin{description} + +\item[analysis of algorithms:] A way to compare algorithms in terms of +their run time and/or space requirements. +\index{analysis of algorithms} + +\item[machine model:] A simplified representation of a computer used +to describe algorithms. +\index{machine model} + +\item[worst case:] The input that makes a given algorithm run slowest (or +require the most space. +\index{worst case} + +\item[leading term:] In a polynomial, the term with the highest exponent. +\index{leading term} + +\item[crossover point:] The problem size where two algorithms require +the same run time or space. +\index{crossover point} + +\item[order of growth:] A set of functions that all grow in a way +considered equivalent for purposes of analysis of algorithms. +For example, all functions that grow linearly belong to the same +order of growth. +\index{order of growth} + +\item[Big-Oh notation:] Notation for representing an order of growth; +for example, $O(n)$ represents the set of functions that grow +linearly. +\index{Big-Oh notation} + +\item[linear:] An algorithm whose run time is proportional to +problem size, at least for large problem sizes. +\index{linear} + +\item[quadratic:] An algorithm whose run time is proportional to +$n^2$, where $n$ is a measure of problem size. +\index{quadratic} + +\item[search:] The problem of locating an element of a collection +(like a list or dictionary) or determining that it is not present. +\index{search} + +\item[hashtable:] A data structure that represents a collection of +key-value pairs and performs search in constant time. +\index{hashtable} + +\end{description} + + +\printindex + +\clearemptydoublepage +%\blankpage +%\blankpage +%\blankpage + + +\end{document} diff --git a/book_tx/figs/assign2.eps b/book_tx/figs/assign2.eps new file mode 100644 index 0000000..e0d56f6 --- /dev/null +++ b/book_tx/figs/assign2.eps @@ -0,0 +1,141 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: assign2.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5d +%%CreationDate: Mon Oct 19 10:19:36 2015 +%%BoundingBox: 0 0 60 42 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 42 moveto 0 0 lineto 60 0 lineto 60 42 lineto closepath clip newpath +-147.8 99.7 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 2475 975 m 3450 975 l 3450 1650 l 2475 1650 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2995 1451 m 3139 1500 l 3158 1443 l 3015 1394 l 3015 1394 l 3119 1462 l 2995 1451 l cp +eoclip +n 2760 1339 m + 3135 1467 l gs col0 s gr gr + +% arrowhead +n 2995 1451 m 3119 1462 l 3015 1394 l col0 s +% Polyline + [15 45] 45 sd +n 2766 1271 m + 3141 1174 l gs col0 s gr [] 0 sd +% Polyline +n 3075 1080 m + 3300 1230 l gs col0 s gr +% Polyline +n 3300 1080 m + 3075 1230 l gs col0 s gr +/Helvetica ff 183.33 scf sf +3150 1530 m +gs 1 -1 sc (7) col0 sh gr +/Helvetica ff 183.33 scf sf +3150 1230 m +gs 1 -1 sc (5) col0 sh gr +/Helvetica ff 183.33 scf sf +2730 1340 m +gs 1 -1 sc (x) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/assign2.fig b/book_tx/figs/assign2.fig new file mode 100644 index 0000000..b239db3 --- /dev/null +++ b/book_tx/figs/assign2.fig @@ -0,0 +1,23 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2760 1339 3135 1467 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 2766 1271 3141 1174 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 3075 1080 3300 1230 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 3300 1080 3075 1230 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2475 975 3450 975 3450 1650 2475 1650 2475 975 +4 0 0 50 0 16 11 0.0000 4 120 105 3150 1530 7\001 +4 0 0 50 0 16 11 0.0000 4 120 105 3150 1230 5\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2730 1340 x\001 diff --git a/book_tx/figs/assign2.fig.bak b/book_tx/figs/assign2.fig.bak new file mode 100644 index 0000000..df54f87 --- /dev/null +++ b/book_tx/figs/assign2.fig.bak @@ -0,0 +1,25 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 2325 1080 3300 1530 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2760 1339 3135 1467 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 2766 1271 3141 1174 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 3075 1080 3300 1230 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 3300 1080 3075 1230 +4 0 0 50 0 16 11 0.0000 4 120 90 3150 1530 7\001 +4 0 0 50 0 16 11 0.0000 4 120 90 3150 1230 5\001 +4 2 0 50 0 16 11 0.0000 4 120 375 2730 1340 bruce\001 +-6 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2175 975 3450 975 3450 1650 2175 1650 2175 975 diff --git a/book_tx/figs/assign2.pdf b/book_tx/figs/assign2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a57a3ac11d80b97482f95db7f58315e17c70e6cd GIT binary patch literal 3893 zcmb_f3s6+&6}I)&xe`;+sGTI{_rWYycJFK7-CYa2tRSosphz@SFL&=QS9bSq@4d+4 zb7GyTnUYeS@tql~M)R6JY-%P65f#)*1hL~|FlcEe4;yVXYN|$v_WXBuVL_+1Gh7Dv z|MQ=7{_~&job#VQqsZgc(*`4v@z;Mf>?TZzLQ>^Y!r>qbg-B4XLS~>8lU^~T3Nj+S zAx;%M0x$Ummy1wTS>VD%?A7q|C+D^NH0{HlSu3+Peb9Mz)zJkrj=t}kG4_quH&5I( zV&><=b~eNjHWs)n9bHn7(kbev;#pBAau@y#ph!e=>62Qx|l)k0*D$cJ555^>C}{=!xdv z{OpNw`!hEbeD=rbn|>^uf9p!e+%07d1uKW2^3qGkZCYKq);MNi`Qo-)^Z)kFKD}et z?vD5Lhn&$C)2A7|A7=X2-b@yD9iFMQ|N&eIzocwg6d{mA=|)}8H< z!;Pm5Rql@uoZY@`^j5>k$(?m=^Y%ZzWP|j@R-@kJ<+$===2`9k_I~KbW|7WZ$ksulSeO_7@704nkD3CtEFLF6j3@xHy*-RlL zQ$fIzEJReqVoV6KSWu)InHLm5t4Nmk51IB`P3>XsiW9yb_4h zv^D_%NjJlC5NN2uDpN$U_CyTD zCEc9Lg`{9oMZ$WYpmKg#L3EtZzqe(eg8pL==<%Rt~=jTJS$HKEfZ9c=QMYD1cjHys4B_GhE-_p&{n{mqO7Ry zDo#cwmMr8FW16AJ1)^WAQWhbT2_qi=i!tc?A^JxBwA9g%ubU_eheQN&SBwO~z({sP z5&PyPHI*ukJ`5RnI2i}{$SGhB@`yH_$AyJQyDkR;7~)sYu*k$v$U@mFa0Lk}fH_T5 zMuN;%cpT8M0(=kuyLWF+aYmu{NX7vx>ztqc#EHy;_Ez$QuYK13vgoL{PPMicmgRN4nROzwEUz#> z-}gOnOhH?Ids*~kTWeP439{sL^n5ABP}JFx>HAi1dq02gG2+O}b;k%7k^SbEdu=c0 zX0A<3OKW>--xq0V8`3J%($li)>qF)<4Qm#kYj3`@XU~cw4L857@2*|BIP2b}&wD&& z74LTE9Qx(zF{_@eJjeB1>s@h0>h8Yv!s7j_w)9TvspzfEy85)a>ABH!Bdgb_w;JzH zKmOeL`P`)f2byO6^Wc5`_-!w4*)ii#?}`am?_5HAUK+c+XZOaop4j%_+E2QJX62wRy%d&z9OVbQm9%~ z5o53!Xg$qlp@0m@TPw-ch&GsYpi=e+?8R_}#1+EKsjE`esGTHhYikX)tU;24ByF?V zNQxmDMh_f%r7og!F?~dt4*O|_h~<4^5yha{WZ>?(^xFge%7BGtSUo3Lt$LacP8=4U_V%Z4O#F5jO=hn z`fGSWcIxI76{0y+lA^{-JF*!li;hejf2gbiY#!|e05stS2k_W^P>=(49=N7m3`Lvt zG^M9)r8H%yZFVE8r;K)ra*%^K0eld3L;nT+*#97!!kHo}$)ykyu7DV1{K7I+CddlL zf;BLxh*SBh5ERT1GWp}%YdR7l4iW>F;;Nx`9vAib{=56aVI1F>&+d`_aq~u{|V9TUmHwB=xB>2i=+s&r(E|h|A$UV?<=JB*DW2w{M8dj|3#7 zwQ|rade9<=o6V+jY?Oy#nQY3!ux_v0YRS&Ad2J>yoomi@J)WZiziAYelT{5M)@Y`P KjEvm*UgAH{Q0!s= literal 0 HcmV?d00001 diff --git a/book_tx/figs/banana.eps b/book_tx/figs/banana.eps new file mode 100644 index 0000000..653aa97 --- /dev/null +++ b/book_tx/figs/banana.eps @@ -0,0 +1,194 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: banana.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Thu Jan 3 09:25:45 2008 +%%For: downey@rocky (Allen Downey,,,) +%%BoundingBox: 0 0 195 52 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 52 moveto 0 0 lineto 195 0 lineto 195 52 lineto closepath clip newpath +-93.8 99.9 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 1575 825 m 4800 825 l 4800 1350 l 1575 1350 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2338 1110 m 2490 1110 l 2490 1050 l 2338 1050 l 2338 1050 l 2458 1080 l 2338 1110 l cp +eoclip +n 2100 1080 m + 2475 1080 l gs col0 s gr gr + +% arrowhead +n 2338 1110 m 2458 1080 l 2338 1050 l col0 s +% Polyline + [15 45] 45 sd +n 2700 825 m + 2700 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 3000 825 m + 3000 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 3300 825 m + 3300 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 3600 825 m + 3600 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 3900 825 m + 3900 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 4200 825 m + 4200 1500 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 4500 825 m + 4500 1500 l gs col0 s gr [] 0 sd +/Helvetica ff 183.33 scf sf +2025 1125 m +gs 1 -1 sc (fruit) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 366.67 scf sf +2775 1200 m +gs 1 -1 sc (b) col0 sh gr +/Helvetica ff 366.67 scf sf +3075 1200 m +gs 1 -1 sc (a) col0 sh gr +/Helvetica ff 366.67 scf sf +3375 1200 m +gs 1 -1 sc (n) col0 sh gr +/Helvetica ff 366.67 scf sf +3975 1200 m +gs 1 -1 sc (n) col0 sh gr +/Helvetica ff 366.67 scf sf +3675 1200 m +gs 1 -1 sc (a) col0 sh gr +/Helvetica ff 366.67 scf sf +4275 1200 m +gs 1 -1 sc (a) col0 sh gr +/Helvetica ff 366.67 scf sf +4575 1200 m +gs 1 -1 sc (') col0 sh gr +/Helvetica ff 183.33 scf sf +2625 1650 m +gs 1 -1 sc (0) col0 sh gr +/Helvetica ff 183.33 scf sf +2925 1650 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +3225 1650 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +3525 1650 m +gs 1 -1 sc (3) col0 sh gr +/Helvetica ff 183.33 scf sf +3825 1650 m +gs 1 -1 sc (4) col0 sh gr +/Helvetica ff 183.33 scf sf +4125 1650 m +gs 1 -1 sc (5) col0 sh gr +/Helvetica ff 183.33 scf sf +4425 1650 m +gs 1 -1 sc (6) col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1650 m +gs 1 -1 sc (index) col0 sh gr +/Helvetica ff 366.67 scf sf +2550 1200 m +gs 1 -1 sc (') col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/banana.fig b/book_tx/figs/banana.fig new file mode 100644 index 0000000..f6fc430 --- /dev/null +++ b/book_tx/figs/banana.fig @@ -0,0 +1,45 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1080 2475 1080 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 2700 825 2700 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 3000 825 3000 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 3300 825 3300 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 3600 825 3600 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 3900 825 3900 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 4200 825 4200 1500 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 4500 825 4500 1500 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1575 825 4800 825 4800 1350 1575 1350 1575 825 +4 2 0 50 0 16 11 0.0000 4 135 300 2025 1125 fruit\001 +4 0 0 50 0 16 22 0.0000 4 285 210 2775 1200 b\001 +4 0 0 50 0 16 22 0.0000 4 210 195 3075 1200 a\001 +4 0 0 50 0 16 22 0.0000 4 210 210 3375 1200 n\001 +4 0 0 50 0 16 22 0.0000 4 210 210 3975 1200 n\001 +4 0 0 50 0 16 22 0.0000 4 210 195 3675 1200 a\001 +4 0 0 50 0 16 22 0.0000 4 210 195 4275 1200 a\001 +4 0 0 50 0 16 22 0.0000 4 90 90 4575 1200 '\001 +4 0 0 50 0 16 11 0.0000 4 135 105 2625 1650 0\001 +4 0 0 50 0 16 11 0.0000 4 135 105 2925 1650 1\001 +4 0 0 50 0 16 11 0.0000 4 135 105 3225 1650 2\001 +4 0 0 50 0 16 11 0.0000 4 135 105 3525 1650 3\001 +4 0 0 50 0 16 11 0.0000 4 135 105 3825 1650 4\001 +4 0 0 50 0 16 11 0.0000 4 135 105 4125 1650 5\001 +4 0 0 50 0 16 11 0.0000 4 135 105 4425 1650 6\001 +4 0 0 50 0 16 11 0.0000 4 135 450 2025 1650 index\001 +4 0 0 50 0 16 22 0.0000 4 90 90 2550 1200 '\001 diff --git a/book_tx/figs/banana.pdf b/book_tx/figs/banana.pdf new file mode 100644 index 0000000000000000000000000000000000000000..70c6225ffc083e7f039ce261281704b4465b17ea GIT binary patch literal 5443 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 KNv^(bg#Q7RC(9H7 literal 0 HcmV?d00001 diff --git a/book_tx/figs/class1.eps b/book_tx/figs/class1.eps new file mode 100644 index 0000000..0bd9600 --- /dev/null +++ b/book_tx/figs/class1.eps @@ -0,0 +1,142 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: class1.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Thu Aug 16 11:40:34 2007 +%%For: downey@rocky (Allen Downey,,,) +%%BoundingBox: 0 0 150 87 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 87 moveto 0 0 lineto 150 0 lineto 150 87 lineto closepath clip newpath +-156.8 149.2 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 2625 1050 m 3525 1050 l 3525 1500 l 2625 1500 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 2625 2025 m 3525 2025 l 3525 2475 l 2625 2475 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4200 1050 m 5100 1050 l 5100 1500 l 4200 1500 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +3150 1627 m 3150 1485 l 3000 1485 l 3000 1627 l 3000 1627 l 3075 1507 l 3150 1627 l cp +eoclip +n 3075 2025 m + 3075 1500 l gs col0 s gr gr + +% arrowhead +n 3150 1627 m 3075 1507 l 3000 1627 l 3150 1627 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +gs clippath +4071 1335 m 4215 1335 l 4215 1215 l 4071 1215 l 4071 1215 l 4191 1275 l 4071 1335 l cp +eoclip +n 3525 1275 m + 4200 1275 l gs col0 s gr gr + +% arrowhead +n 4071 1335 m 4191 1275 l 4071 1215 l col0 s +/Helvetica ff 183.33 scf sf +2850 2325 m +gs 1 -1 sc (Hand) col0 sh gr +/Helvetica ff 183.33 scf sf +2850 1350 m +gs 1 -1 sc (Deck) col0 sh gr +/Helvetica ff 233.33 scf sf +4125 1275 m +gs 1 -1 sc (*) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4800 1350 m +gs 1 -1 sc (Card) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/class1.fig b/book_tx/figs/class1.fig new file mode 100644 index 0000000..1dbd926 --- /dev/null +++ b/book_tx/figs/class1.fig @@ -0,0 +1,25 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2625 1050 3525 1050 3525 1500 2625 1500 2625 1050 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2625 2025 3525 2025 3525 2475 2625 2475 2625 2025 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 0 1.00 150.00 120.00 + 3075 2025 3075 1500 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 120.00 120.00 + 3525 1275 4200 1275 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4200 1050 5100 1050 5100 1500 4200 1500 4200 1050 +4 0 0 50 0 16 11 0.0000 4 135 450 2850 2325 Hand\001 +4 0 0 50 0 16 11 0.0000 4 135 435 2850 1350 Deck\001 +4 2 0 50 0 16 14 0.0000 4 75 90 4125 1275 *\001 +4 2 0 50 0 16 11 0.0000 4 135 405 4800 1350 Card\001 diff --git a/book_tx/figs/class1.pdf b/book_tx/figs/class1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..16091c76eecac09a1c1eb1c123a4e7f71037a746 GIT binary patch literal 4630 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/compile.eps b/book_tx/figs/compile.eps new file mode 100644 index 0000000..901f239 --- /dev/null +++ b/book_tx/figs/compile.eps @@ -0,0 +1,222 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: compile.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5a +%%CreationDate: Wed May 30 11:14:49 2012 +%%BoundingBox: 0 0 385 61 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 61 moveto 0 0 lineto 385 0 lineto 385 61 lineto closepath clip newpath +-2.7 86.0 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 63 +% Polyline +0 slj +0 slc +15.000 slw +n 3936 655 m 3840 548 l 3840 915 l + 3936 813 l gs col0 s gr +% Polyline +n 1304 647 m 1207 540 l 1207 907 l + 1304 805 l gs col0 s gr +% here ends figure; +% +% here starts figure with depth 50 +% Polyline +0 slj +0 slc +7.500 slw +gs clippath +3657 795 m 3869 795 l 3869 705 l 3657 705 l 3657 705 l 3837 750 l 3657 795 l cp +eoclip +n 3525 750 m + 3854 750 l gs col0 s gr gr + +% arrowhead +n 3657 795 m 3837 750 l 3657 705 l col0 s +% Polyline +15.000 slw +n 5002 1248 m 5100 1350 l 5100 984 l + 5002 1089 l gs col0 s gr +% Polyline +7.500 slw +gs clippath +5232 1170 m 5444 1170 l 5444 1080 l 5232 1080 l 5232 1080 l 5412 1125 l 5232 1170 l cp +eoclip +n 5100 1125 m + 5429 1125 l gs col0 s gr gr + +% arrowhead +n 5232 1170 m 5412 1125 l 5232 1080 l col0 s +% Polyline +15.000 slw +n 3936 548 m 5010 548 l 5010 1342 l 3936 1342 l + cp gs col0 s gr +% Polyline +n 2700 525 m 3525 525 l 3525 1350 l 2700 1350 l + cp gs col0 s gr +% Polyline +7.500 slw +gs clippath +1024 787 m 1236 787 l 1236 697 l 1024 697 l 1024 697 l 1204 742 l 1024 787 l cp +eoclip +n 892 742 m + 1221 742 l gs col0 s gr gr + +% arrowhead +n 1024 787 m 1204 742 l 1024 697 l col0 s +% Polyline +15.000 slw +n 67 442 m 742 442 l 892 592 l 892 1342 l 67 1342 l + 67 442 l cp gs col0 s gr +% Polyline +7.500 slw +n 742 442 m 742 592 l + 892 592 l gs col0 s gr +% Polyline +15.000 slw +n 1304 540 m 2274 540 l 2274 1327 l 1304 1327 l + cp gs col0 s gr +% Polyline +n 2274 1225 m 2371 1327 l 2371 961 l + 2274 1066 l gs col0 s gr +% Polyline +7.500 slw +gs clippath +2509 1162 m 2721 1162 l 2721 1072 l 2509 1072 l 2509 1072 l 2689 1117 l 2509 1162 l cp +eoclip +n 2377 1117 m + 2706 1117 l gs col0 s gr gr + +% arrowhead +n 2509 1162 m 2689 1117 l 2509 1072 l col0 s +% Polyline +15.000 slw +n 5694 1296 m 6151 1296 l 6151 1356 l 5694 1356 l + cp gs col0 s gr +% Polyline +n 5598 1357 m 6259 1357 l 6259 1412 l 5598 1412 l + cp gs col0 s gr +% Polyline +n 5413 463 m 6437 463 l 6437 1296 l 5413 1296 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +7.500 slw +n 5467 519 m 6381 519 l 6381 1237 l 5467 1237 l + cp gs col7 1.00 shd ef gr gs col0 s gr +/Helvetica ff 166.67 scf sf +2775 1125 m +gs 1 -1 sc (CODE) col0 sh gr +/Helvetica ff 166.67 scf sf +2775 900 m +gs 1 -1 sc (OBJECT) col0 sh gr +/Helvetica ff 166.67 scf sf +4005 975 m +gs 1 -1 sc (EXECUTOR) col0 sh gr +/Helvetica ff 166.67 scf sf +142 1117 m +gs 1 -1 sc (CODE) col0 sh gr +/Helvetica ff 166.67 scf sf +142 892 m +gs 1 -1 sc (SOURCE) col0 sh gr +/Helvetica ff 166.67 scf sf +1342 967 m +gs 1 -1 sc (COMPILER) col0 sh gr +/Helvetica ff 166.67 scf sf +5588 953 m +gs 1 -1 sc (OUTPUT) col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/compile.fig b/book_tx/figs/compile.fig new file mode 100644 index 0000000..cf882be --- /dev/null +++ b/book_tx/figs/compile.fig @@ -0,0 +1,54 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 3525 750 3854 750 +2 1 0 2 0 7 63 0 -1 0.000 0 0 -1 0 0 4 + 3936 655 3840 548 3840 915 3936 813 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 4 + 5002 1248 5100 1350 5100 984 5002 1089 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 5100 1125 5429 1125 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3936 548 5010 548 5010 1342 3936 1342 3936 548 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2700 525 3525 525 3525 1350 2700 1350 2700 525 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 892 742 1221 742 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 6 + 67 442 742 442 892 592 892 1342 67 1342 67 442 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3 + 742 442 742 592 892 592 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1304 540 2274 540 2274 1327 1304 1327 1304 540 +2 1 0 2 0 7 63 0 -1 0.000 0 0 -1 0 0 4 + 1304 647 1207 540 1207 907 1304 805 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 4 + 2274 1225 2371 1327 2371 961 2274 1066 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 2377 1117 2706 1117 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5694 1296 6151 1296 6151 1356 5694 1356 5694 1296 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5598 1357 6259 1357 6259 1412 5598 1412 5598 1357 +2 2 0 2 0 7 50 0 20 0.000 0 0 -1 0 0 5 + 5413 463 6437 463 6437 1296 5413 1296 5413 463 +2 2 0 1 0 7 50 0 20 0.000 0 0 -1 0 0 5 + 5467 519 6381 519 6381 1237 5467 1237 5467 519 +4 0 0 50 0 16 10 0.0000 4 120 465 2775 1125 CODE\001 +4 0 0 50 0 16 10 0.0000 4 120 600 2775 900 OBJECT\001 +4 0 0 50 0 16 10 0.0000 4 120 855 4005 975 EXECUTOR\001 +4 0 0 50 0 16 10 0.0000 4 120 465 142 1117 CODE\001 +4 0 0 50 0 16 10 0.0000 4 120 675 142 892 SOURCE\001 +4 0 0 50 0 16 10 0.0000 4 120 825 1342 967 COMPILER\001 +4 0 0 50 0 16 10 0.0000 4 120 615 5588 953 OUTPUT\001 diff --git a/book_tx/figs/compile.pdf b/book_tx/figs/compile.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2c888eaf30fd677b4eef531aae9aa1355e8ae0fa GIT binary patch literal 5098 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/dict1.eps b/book_tx/figs/dict1.eps new file mode 100644 index 0000000..7987e4d --- /dev/null +++ b/book_tx/figs/dict1.eps @@ -0,0 +1,321 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: dict1.fig +%%Creator: fig2dev Version 3.2 Patchlevel 4 +%%CreationDate: Tue Jul 31 12:32:19 2007 +%%For: downey@rocky.olin.edu (Allen Downey) +%%BoundingBox: 0 0 316 134 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 134 moveto 0 0 lineto 316 0 lineto 316 134 lineto closepath clip newpath +-27.0 225.7 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +7.500 slw +n 1125 1725 m 2400 1725 l 2400 3300 l 1125 3300 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4350 1725 m 5700 1725 l 5700 3000 l 4350 3000 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 3375 1725 m 4050 1725 l 4050 3750 l 3375 3750 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4350 3375 m 5700 3375 l 5700 3750 l 4350 3750 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +1965 2227 m 1965 2167 l 1813 2167 l 1933 2197 l 1813 2227 l cp +eoclip +n 1575 2197 m + 1950 2197 l gs col0 s gr gr + +% arrowhead +n 1813 2227 m 1933 2197 l 1813 2167 l col0 s +% Polyline +gs clippath +1965 1927 m 1965 1867 l 1813 1867 l 1933 1897 l 1813 1927 l cp +eoclip +n 1575 1897 m + 1950 1897 l gs col0 s gr gr + +% arrowhead +n 1813 1927 m 1933 1897 l 1813 1867 l col0 s +% Polyline +gs clippath +1140 1905 m 1140 1845 l 988 1845 l 1108 1875 l 988 1905 l cp +eoclip +n 750 1875 m + 1125 1875 l gs col0 s gr gr + +% arrowhead +n 988 1905 m 1108 1875 l 988 1845 l col0 s +% Polyline +gs clippath +1965 2827 m 1965 2767 l 1813 2767 l 1933 2797 l 1813 2827 l cp +eoclip +n 1575 2797 m + 1950 2797 l gs col0 s gr gr + +% arrowhead +n 1813 2827 m 1933 2797 l 1813 2767 l col0 s +% Polyline +gs clippath +1965 3127 m 1965 3067 l 1813 3067 l 1933 3097 l 1813 3127 l cp +eoclip +n 1575 3097 m + 1950 3097 l gs col0 s gr gr + +% arrowhead +n 1813 3127 m 1933 3097 l 1813 3067 l col0 s +% Polyline +gs clippath +1965 2527 m 1965 2467 l 1813 2467 l 1933 2497 l 1813 2527 l cp +eoclip +n 1575 2497 m + 1950 2497 l gs col0 s gr gr + +% arrowhead +n 1813 2527 m 1933 2497 l 1813 2467 l col0 s +/Helvetica ff 165.00 scf sf +1500 1950 m +gs 1 -1 sc ('a') dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 1950 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +2025 2250 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +1125 1650 m +gs 1 -1 sc (dict) col0 sh gr +/Helvetica ff 165.00 scf sf +450 1950 m +gs 1 -1 sc (hist) col0 sh gr +/Helvetica ff 165.00 scf sf +1500 2250 m +gs 1 -1 sc ('p') dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 2850 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +1500 3150 m +gs 1 -1 sc ('o') dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 3150 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +1500 2550 m +gs 1 -1 sc ('r') dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 2550 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 165.00 scf sf +1500 2850 m +gs 1 -1 sc ('t') dup sw pop neg 0 rm col0 sh gr +% Polyline +gs clippath +5190 2227 m 5190 2167 l 5038 2167 l 5158 2197 l 5038 2227 l cp +eoclip +n 4800 2197 m + 5175 2197 l gs col0 s gr gr + +% arrowhead +n 5038 2227 m 5158 2197 l 5038 2167 l col0 s +% Polyline +gs clippath +5190 1927 m 5190 1867 l 5038 1867 l 5158 1897 l 5038 1927 l cp +eoclip +n 4800 1897 m + 5175 1897 l gs col0 s gr gr + +% arrowhead +n 5038 1927 m 5158 1897 l 5038 1867 l col0 s +% Polyline +gs clippath +5190 2527 m 5190 2467 l 5038 2467 l 5158 2497 l 5038 2527 l cp +eoclip +n 4800 2497 m + 5175 2497 l gs col0 s gr gr + +% arrowhead +n 5038 2527 m 5158 2497 l 5038 2467 l col0 s +% Polyline +gs clippath +5190 2827 m 5190 2767 l 5038 2767 l 5158 2797 l 5038 2827 l cp +eoclip +n 4800 2797 m + 5175 2797 l gs col0 s gr gr + +% arrowhead +n 5038 2827 m 5158 2797 l 5038 2767 l col0 s +/Helvetica ff 165.00 scf sf +4725 1950 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +4725 2250 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +5250 1950 m +gs 1 -1 sc ('a') col0 sh gr +/Helvetica ff 165.00 scf sf +5250 2250 m +gs 1 -1 sc ('p') col0 sh gr +/Helvetica ff 165.00 scf sf +4350 1650 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 165.00 scf sf +4725 2550 m +gs 1 -1 sc (2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +5250 2550 m +gs 1 -1 sc ('t') col0 sh gr +/Helvetica ff 165.00 scf sf +5250 2850 m +gs 1 -1 sc ('o') col0 sh gr +/Helvetica ff 165.00 scf sf +4725 2850 m +gs 1 -1 sc (3) dup sw pop neg 0 rm col0 sh gr +% Polyline +gs clippath +4365 1919 m 4364 1859 l 4212 1861 l 4333 1890 l 4213 1921 l cp +eoclip +n 3825 1897 m + 4350 1890 l gs col0 s gr gr + +% arrowhead +n 4213 1921 m 4333 1890 l 4212 1861 l col0 s +% Polyline +gs clippath +3390 1905 m 3390 1845 l 3238 1845 l 3358 1875 l 3238 1905 l cp +eoclip +n 3000 1875 m + 3375 1875 l gs col0 s gr gr + +% arrowhead +n 3238 1905 m 3358 1875 l 3238 1845 l col0 s +% Polyline +gs clippath +4365 3551 m 4364 3491 l 4212 3493 l 4333 3522 l 4213 3553 l cp +eoclip +n 3825 3529 m + 4350 3522 l gs col0 s gr gr + +% arrowhead +n 4213 3553 m 4333 3522 l 4212 3493 l col0 s +% Polyline +gs clippath +5190 3577 m 5190 3517 l 5038 3517 l 5158 3547 l 5038 3577 l cp +eoclip +n 4800 3547 m + 5175 3547 l gs col0 s gr gr + +% arrowhead +n 5038 3577 m 5158 3547 l 5038 3517 l col0 s +/Helvetica ff 165.00 scf sf +3750 1950 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3375 1650 m +gs 1 -1 sc (dict) col0 sh gr +/Helvetica ff 165.00 scf sf +2700 1950 m +gs 1 -1 sc (inv) col0 sh gr +/Helvetica ff 165.00 scf sf +3750 3600 m +gs 1 -1 sc (2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +4725 3600 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +4350 3300 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 165.00 scf sf +5250 3600 m +gs 1 -1 sc ('r') col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage diff --git a/book_tx/figs/dict1.fig b/book_tx/figs/dict1.fig new file mode 100644 index 0000000..f1cf02e --- /dev/null +++ b/book_tx/figs/dict1.fig @@ -0,0 +1,91 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 450 1500 2400 3300 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1575 2197 1950 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1575 1897 1950 1897 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 750 1875 1125 1875 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1575 2797 1950 2797 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1575 3097 1950 3097 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1575 2497 1950 2497 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1125 1725 2400 1725 2400 3300 1125 3300 1125 1725 +4 2 0 50 0 16 11 0.0000 4 120 135 1500 1950 'a'\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2025 1950 1\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2025 2250 1\001 +4 0 0 50 0 16 11 0.0000 4 120 255 1125 1650 dict\001 +4 0 0 50 0 16 11 0.0000 4 120 255 450 1950 hist\001 +4 2 0 50 0 16 11 0.0000 4 150 150 1500 2250 'p'\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2025 2850 1\001 +4 2 0 50 0 16 11 0.0000 4 120 150 1500 3150 'o'\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2025 3150 1\001 +4 2 0 50 0 16 11 0.0000 4 120 120 1500 2550 'r'\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2025 2550 2\001 +4 2 0 50 0 16 11 0.0000 4 120 120 1500 2850 't'\001 +-6 +6 4350 1500 5700 3000 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 2197 5175 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 1897 5175 1897 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 2497 5175 2497 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 2797 5175 2797 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4350 1725 5700 1725 5700 3000 4350 3000 4350 1725 +4 2 0 50 0 16 11 0.0000 4 120 90 4725 1950 0\001 +4 2 0 50 0 16 11 0.0000 4 120 90 4725 2250 1\001 +4 0 0 50 0 16 11 0.0000 4 120 135 5250 1950 'a'\001 +4 0 0 50 0 16 11 0.0000 4 150 150 5250 2250 'p'\001 +4 0 0 50 0 16 11 0.0000 4 120 195 4350 1650 list\001 +4 2 0 50 0 16 11 0.0000 4 120 90 4725 2550 2\001 +4 0 0 50 0 16 11 0.0000 4 120 120 5250 2550 't'\001 +4 0 0 50 0 16 11 0.0000 4 120 150 5250 2850 'o'\001 +4 2 0 50 0 16 11 0.0000 4 120 90 4725 2850 3\001 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3825 1897 4350 1890 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3000 1875 3375 1875 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 3375 1725 4050 1725 4050 3750 3375 3750 3375 1725 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3825 3529 4350 3522 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 3547 5175 3547 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4350 3375 5700 3375 5700 3750 4350 3750 4350 3375 +4 2 0 50 0 16 11 0.0000 4 120 90 3750 1950 1\001 +4 0 0 50 0 16 11 0.0000 4 120 255 3375 1650 dict\001 +4 0 0 50 0 16 11 0.0000 4 120 210 2700 1950 inv\001 +4 2 0 50 0 16 11 0.0000 4 120 90 3750 3600 2\001 +4 2 0 50 0 16 11 0.0000 4 120 90 4725 3600 0\001 +4 0 0 50 0 16 11 0.0000 4 120 195 4350 3300 list\001 +4 0 0 50 0 16 11 0.0000 4 120 120 5250 3600 'r'\001 diff --git a/book_tx/figs/dict1.pdf b/book_tx/figs/dict1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..db7af312ddf9627f06ac79f9d91e02b35cf9c8aa GIT binary patch literal 5915 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 bjNy;J@hC8^98(#MZp5GxbakyatR?&p!#}$$ literal 0 HcmV?d00001 diff --git a/book_tx/figs/dict2.eps b/book_tx/figs/dict2.eps new file mode 100644 index 0000000..b1023b7 --- /dev/null +++ b/book_tx/figs/dict2.eps @@ -0,0 +1,195 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: dict2.fig +%%Creator: fig2dev Version 3.2 Patchlevel 4 +%%CreationDate: Tue Jul 31 12:39:25 2007 +%%For: downey@rocky.olin.edu (Allen Downey) +%%BoundingBox: 0 0 231 125 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 125 moveto 0 0 lineto 231 0 lineto 231 125 lineto closepath clip newpath +-75.8 194.2 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +7.500 slw +n 1275 1350 m 5100 1350 l 5100 3225 l 1275 3225 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +3690 1852 m 3690 1792 l 3538 1792 l 3658 1822 l 3538 1852 l cp +eoclip +n 3300 1822 m + 3675 1822 l gs col0 s gr gr + +% arrowhead +n 3538 1852 m 3658 1822 l 3538 1792 l col0 s +% Polyline +gs clippath +3690 1552 m 3690 1492 l 3538 1492 l 3658 1522 l 3538 1552 l cp +eoclip +n 3300 1522 m + 3675 1522 l gs col0 s gr gr + +% arrowhead +n 3538 1552 m 3658 1522 l 3538 1492 l col0 s +% Polyline +gs clippath +3690 2452 m 3690 2392 l 3538 2392 l 3658 2422 l 3538 2452 l cp +eoclip +n 3300 2422 m + 3675 2422 l gs col0 s gr gr + +% arrowhead +n 3538 2452 m 3658 2422 l 3538 2392 l col0 s +% Polyline +gs clippath +3690 2752 m 3690 2692 l 3538 2692 l 3658 2722 l 3538 2752 l cp +eoclip +n 3300 2722 m + 3675 2722 l gs col0 s gr gr + +% arrowhead +n 3538 2752 m 3658 2722 l 3538 2692 l col0 s +% Polyline +gs clippath +3690 2152 m 3690 2092 l 3538 2092 l 3658 2122 l 3538 2152 l cp +eoclip +n 3300 2122 m + 3675 2122 l gs col0 s gr gr + +% arrowhead +n 3538 2152 m 3658 2122 l 3538 2092 l col0 s +% Polyline +gs clippath +3690 3030 m 3690 2970 l 3538 2970 l 3658 3000 l 3538 3030 l cp +eoclip +n 3300 3000 m + 3675 3000 l gs col0 s gr gr + +% arrowhead +n 3538 3030 m 3658 3000 l 3538 2970 l col0 s +/Helvetica ff 165.00 scf sf +3225 1575 m +gs 1 -1 sc (\('Cleese', 'John'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3750 1575 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +3750 1875 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +3750 2175 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +3750 2475 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +3750 2775 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +3225 1875 m +gs 1 -1 sc (\('Chapman', 'Graham'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3225 2175 m +gs 1 -1 sc (\('Idle', 'Eric'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3225 2775 m +gs 1 -1 sc (\('Jones', 'Terry'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3225 2475 m +gs 1 -1 sc (\('Gilliam', 'Terry'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3225 3075 m +gs 1 -1 sc (\('Palin', 'Michael'\)) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3750 3075 m +gs 1 -1 sc ('08700 100 222') col0 sh gr +/Helvetica ff 165.00 scf sf +1275 1275 m +gs 1 -1 sc (dict) col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage diff --git a/book_tx/figs/dict2.fig b/book_tx/figs/dict2.fig new file mode 100644 index 0000000..d376f55 --- /dev/null +++ b/book_tx/figs/dict2.fig @@ -0,0 +1,42 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 1822 3675 1822 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 1522 3675 1522 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 2422 3675 2422 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 2722 3675 2722 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 2122 3675 2122 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 3000 3675 3000 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1275 1350 5100 1350 5100 3225 1275 3225 1275 1350 +4 2 0 50 0 16 11 0.0000 4 150 1125 3225 1575 ('Cleese', 'John')\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 1575 '08700 100 222'\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 1875 '08700 100 222'\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 2175 '08700 100 222'\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 2475 '08700 100 222'\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 2775 '08700 100 222'\001 +4 2 0 50 0 16 11 0.0000 4 150 1530 3225 1875 ('Chapman', 'Graham')\001 +4 2 0 50 0 16 11 0.0000 4 150 840 3225 2175 ('Idle', 'Eric')\001 +4 2 0 50 0 16 11 0.0000 4 150 1080 3225 2775 ('Jones', 'Terry')\001 +4 2 0 50 0 16 11 0.0000 4 150 1110 3225 2475 ('Gilliam', 'Terry')\001 +4 2 0 50 0 16 11 0.0000 4 150 1170 3225 3075 ('Palin', 'Michael')\001 +4 0 0 50 0 16 11 0.0000 4 120 1140 3750 3075 '08700 100 222'\001 +4 0 0 50 0 16 11 0.0000 4 120 255 1275 1275 dict\001 diff --git a/book_tx/figs/dict2.pdf b/book_tx/figs/dict2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..114a87a715acbfb6335ea937c3ca5f139eb1af29 GIT binary patch literal 6487 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ℜ9AyaY}4&q74pM$=X; z{&FTe<4&HMM)v7vRn6h}ij;xv=N3&NxwQ#DLJvtEK?NVyUCkuKrCzgM6)EW;@?Sk+ zpEWMdO#P%PKX0I*Ub(a)!mFQz=VagUzCa6*hEM(D(;U4Vy}@W7y)#c&7QZq%ZJ(~F zZs`^J`bPK3co*Thr0%3xGp9?siYvu`WefW+wV)w822dToEC=>-OMJ^e|C+P^r+MoRE-MyDVMH zftWu)jNcLzE%%^luF7Exo8=ww;AOjzNkOVfOLoSI#wn*gt{C4RkrOt#clE~hZnu}G z+^x{@@;zHiT9^5@;-Bkm#1}|1MD4AHGbM3RIT!a9R=wBCG^%h)GTS_Fj9 zP4=B#b~kn2*hISBJfh*(yMmi#c43hFCUiVLt917HWTjx!Ji3F0m{UbevNQht*Ex#az;i76dl-FClvRVb=nyySp}fsN;DeINR*oYGCIqPLDY?mujfIe_~sOzl~y5er`-GVFrWQBj7AXcB# zqrZMx@zmxHM~1pdiWVd7?N?Q0g+sTk%;~1On%-0=c;M6LW4k&_U2UAY%2zckXeVY-kd7VH$eGdgFm3wXGgF%?CQrSxKszsh zY~+_jnwi`(@l5QP8yjeFQeyE+V^#dkQo1yG;9Dy!(73q2|NwL#gz^ zy6XEih84@tl$WZCa=d2ED!dhH)p+O2mj>e-?9K7>UmZRXq0MLV%o??05~Q9Nj7y53 zcCN>qqQRGso~1B)6?A*|=-N7kTFkgiU-NgAMvKV|&Z_9ax6O4yT6vFDHzw@I?U*JH zb%{3PwN3IjUb3p=UYT(B`L!$0jmovUY?}yi?3v=#%BtGOA4JX6CU4E#s5iCy`i#Q- zx>oahux;$K2S(HQ^rDuwMkAFIH_pxr(05#M?AZ#neNk^t@j|-IG&TgyQj1j(Z*S7r z(p=-2`RY)BIpJXG3B?^(lp8;^SSG8_JsRm5v2NS736C9a7&u=w zM|Iy(dwaq*&f=8kdtArFebl?V0->gsPdb=jR3GJcFi(F;#FSH?u}4bpg<@!3$q}|Sj@l}1H%MJMuG-d5ZFu? z2o;G00elo98<`rB3`rCN$X5bR{GlRA07NpP6M#qw&)19vuFOLM!OVi-kD_8T7!C~$ zH43E|i6nk7$<)*oCX!(?*$_||O2dUHC(KYN)du=xhVa?n*o0CenN3FEkPh?NFv*Ar zk0=_seegv>2vf{iBML?>2oySrNaB#VhCD9a#E?WnxQ0aV7}Duv6AF(+Ci`;eBbvmc zEc`(gKmc77-~uo*1ML7_Fc*`h#853LweZy@)GlD@TlE{Wcnjx9&PNJKUNoGW2Ln76TNHm9kq68ratk$4G2O4(& z1M4WtQLG|~J4ghEFW-;MLqZ@AL?Xo^KrtdiE*zBWF8~)I0Yu{rsh7zZW-*7cFpcuk zf9N-kn92PAJr@{=B{W87W+UPT2ZC#*qs{-AF8^VKdE9Siii0HrSw--;Fd{%Oi=-gP zBw#0xYvwDG1ad$=bHrkB>E)on$uLMp0>d02Q9dd_7_xe^5}-o^0UxU$GXY2FXF&)v zC@c3MmYy{#p`_L&f40FW@=|kw4+nOkn!&nK3MBkigF~VENFBh O1^kXO&vvOD?*9Nb3b-Et literal 0 HcmV?d00001 diff --git a/book_tx/figs/fibonacci.eps b/book_tx/figs/fibonacci.eps new file mode 100644 index 0000000..ed1a8e3 --- /dev/null +++ b/book_tx/figs/fibonacci.eps @@ -0,0 +1,356 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: fibonacci.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Fri Dec 7 17:25:43 2001 +%%For: downey@rocky.wellesley.edu (Allen B. Downey) +%%BoundingBox: 0 0 308 218 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 218 moveto 0 0 lineto 308 0 lineto 308 218 lineto closepath clip newpath +-62.0 244.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 3450 450 m 4350 450 l 4350 1125 l 3450 1125 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 2250 1425 m 3150 1425 l 3150 2100 l 2250 2100 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4650 1425 m 5550 1425 l 5550 2100 l 4650 2100 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 5250 2400 m 6150 2400 l 6150 3075 l 5250 3075 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4050 2400 m 4950 2400 l 4950 3075 l 4050 3075 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 2850 2400 m 3750 2400 l 3750 3075 l 2850 3075 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1650 2400 m 2550 2400 l 2550 3075 l 1650 3075 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 2250 3375 m 3150 3375 l 3150 4050 l 2250 4050 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1050 3375 m 1950 3375 l 1950 4050 l 1050 4050 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +4095 929 m 4095 869 l 3943 869 l 4063 899 l 3943 929 l cp +eoclip +n 3705 899 m + 4080 899 l gs col0 s gr gr + +% arrowhead +n 3943 929 m 4063 899 l 3943 869 l col0 s +/Helvetica ff 165.00 scf sf +3555 705 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +3630 952 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +4155 952 m +gs 1 -1 sc (4) col0 sh gr +% Polyline +gs clippath +3118 1414 m 3160 1456 l 3268 1349 l 3162 1413 l 3225 1306 l cp +eoclip +n 3450 1125 m + 3150 1425 l gs col0 s gr gr + +% arrowhead +n 3225 1306 m 3162 1413 l 3268 1349 l col0 s +% Polyline +gs clippath +2068 2389 m 2110 2431 l 2218 2324 l 2112 2388 l 2175 2281 l cp +eoclip +n 2400 2100 m + 2100 2400 l gs col0 s gr gr + +% arrowhead +n 2175 2281 m 2112 2388 l 2218 2324 l col0 s +% Polyline +gs clippath +1468 3364 m 1510 3406 l 1618 3299 l 1512 3363 l 1575 3256 l cp +eoclip +n 1800 3075 m + 1500 3375 l gs col0 s gr gr + +% arrowhead +n 1575 3256 m 1512 3363 l 1618 3299 l col0 s +% Polyline +gs clippath +4468 2389 m 4510 2431 l 4618 2324 l 4512 2388 l 4575 2281 l cp +eoclip +n 4800 2100 m + 4500 2400 l gs col0 s gr gr + +% arrowhead +n 4575 2281 m 4512 2388 l 4618 2324 l col0 s +% Polyline +gs clippath +4639 1456 m 4681 1414 l 4574 1306 l 4638 1413 l 4531 1349 l cp +eoclip +n 4350 1125 m + 4650 1425 l gs col0 s gr gr + +% arrowhead +n 4531 1349 m 4638 1413 l 4574 1306 l col0 s +% Polyline +gs clippath +3289 2431 m 3331 2389 l 3224 2281 l 3288 2388 l 3181 2324 l cp +eoclip +n 3000 2100 m + 3300 2400 l gs col0 s gr gr + +% arrowhead +n 3181 2324 m 3288 2388 l 3224 2281 l col0 s +% Polyline +gs clippath +2689 3406 m 2731 3364 l 2624 3256 l 2688 3363 l 2581 3299 l cp +eoclip +n 2400 3075 m + 2700 3375 l gs col0 s gr gr + +% arrowhead +n 2581 3299 m 2688 3363 l 2624 3256 l col0 s +% Polyline +gs clippath +5689 2431 m 5731 2389 l 5624 2281 l 5688 2388 l 5581 2324 l cp +eoclip +n 5400 2100 m + 5700 2400 l gs col0 s gr gr + +% arrowhead +n 5581 2324 m 5688 2388 l 5624 2281 l col0 s +% Polyline +gs clippath +2895 1904 m 2895 1844 l 2743 1844 l 2863 1874 l 2743 1904 l cp +eoclip +n 2505 1874 m + 2880 1874 l gs col0 s gr gr + +% arrowhead +n 2743 1904 m 2863 1874 l 2743 1844 l col0 s +% Polyline +gs clippath +5295 1904 m 5295 1844 l 5143 1844 l 5263 1874 l 5143 1904 l cp +eoclip +n 4905 1874 m + 5280 1874 l gs col0 s gr gr + +% arrowhead +n 5143 1904 m 5263 1874 l 5143 1844 l col0 s +% Polyline +gs clippath +5895 2879 m 5895 2819 l 5743 2819 l 5863 2849 l 5743 2879 l cp +eoclip +n 5505 2849 m + 5880 2849 l gs col0 s gr gr + +% arrowhead +n 5743 2879 m 5863 2849 l 5743 2819 l col0 s +% Polyline +gs clippath +4695 2879 m 4695 2819 l 4543 2819 l 4663 2849 l 4543 2879 l cp +eoclip +n 4305 2849 m + 4680 2849 l gs col0 s gr gr + +% arrowhead +n 4543 2879 m 4663 2849 l 4543 2819 l col0 s +% Polyline +gs clippath +3495 2879 m 3495 2819 l 3343 2819 l 3463 2849 l 3343 2879 l cp +eoclip +n 3105 2849 m + 3480 2849 l gs col0 s gr gr + +% arrowhead +n 3343 2879 m 3463 2849 l 3343 2819 l col0 s +% Polyline +gs clippath +2295 2879 m 2295 2819 l 2143 2819 l 2263 2849 l 2143 2879 l cp +eoclip +n 1905 2849 m + 2280 2849 l gs col0 s gr gr + +% arrowhead +n 2143 2879 m 2263 2849 l 2143 2819 l col0 s +% Polyline +gs clippath +2895 3854 m 2895 3794 l 2743 3794 l 2863 3824 l 2743 3854 l cp +eoclip +n 2505 3824 m + 2880 3824 l gs col0 s gr gr + +% arrowhead +n 2743 3854 m 2863 3824 l 2743 3794 l col0 s +% Polyline +gs clippath +1695 3854 m 1695 3794 l 1543 3794 l 1663 3824 l 1543 3854 l cp +eoclip +n 1305 3824 m + 1680 3824 l gs col0 s gr gr + +% arrowhead +n 1543 3854 m 1663 3824 l 1543 3794 l col0 s +/Helvetica ff 165.00 scf sf +2355 1680 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +2430 1927 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2955 1927 m +gs 1 -1 sc (3) col0 sh gr +/Helvetica ff 165.00 scf sf +4755 1680 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +4830 1927 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +5355 1927 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 165.00 scf sf +5355 2655 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +5430 2902 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +5955 2902 m +gs 1 -1 sc (0) col0 sh gr +/Helvetica ff 165.00 scf sf +4155 2655 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +4230 2902 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +4755 2902 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +2955 2655 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +3030 2902 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3555 2902 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +1755 2655 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +1830 2902 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2355 2902 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 165.00 scf sf +2355 3630 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +2430 3877 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2955 3877 m +gs 1 -1 sc (0) col0 sh gr +/Helvetica ff 165.00 scf sf +1155 3630 m +gs 1 -1 sc (fibonacci) col0 sh gr +/Helvetica ff 165.00 scf sf +1230 3877 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +1755 3877 m +gs 1 -1 sc (1) col0 sh gr +$F2psEnd +rs diff --git a/book_tx/figs/fibonacci.fig b/book_tx/figs/fibonacci.fig new file mode 100644 index 0000000..244cee1 --- /dev/null +++ b/book_tx/figs/fibonacci.fig @@ -0,0 +1,107 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 3450 450 4350 1125 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 3450 450 4350 450 4350 1125 3450 1125 3450 450 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3705 899 4080 899 +4 0 0 50 0 16 11 0.0000 4 120 615 3555 705 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 3630 952 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 4155 952 4\001 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3450 1125 3150 1425 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2400 2100 2100 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1800 3075 1500 3375 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4800 2100 4500 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4350 1125 4650 1425 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3000 2100 3300 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2400 3075 2700 3375 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5400 2100 5700 2400 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2250 1425 3150 1425 3150 2100 2250 2100 2250 1425 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2505 1874 2880 1874 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4650 1425 5550 1425 5550 2100 4650 2100 4650 1425 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4905 1874 5280 1874 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 5250 2400 6150 2400 6150 3075 5250 3075 5250 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5505 2849 5880 2849 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4050 2400 4950 2400 4950 3075 4050 3075 4050 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4305 2849 4680 2849 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2850 2400 3750 2400 3750 3075 2850 3075 2850 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3105 2849 3480 2849 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 2400 2550 2400 2550 3075 1650 3075 1650 2400 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1905 2849 2280 2849 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2250 3375 3150 3375 3150 4050 2250 4050 2250 3375 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2505 3824 2880 3824 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1050 3375 1950 3375 1950 4050 1050 4050 1050 3375 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1305 3824 1680 3824 +4 0 0 50 0 16 11 0.0000 4 120 615 2355 1680 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2430 1927 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2955 1927 3\001 +4 0 0 50 0 16 11 0.0000 4 120 615 4755 1680 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 4830 1927 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 5355 1927 2\001 +4 0 0 50 0 16 11 0.0000 4 120 615 5355 2655 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 5430 2902 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 5955 2902 0\001 +4 0 0 50 0 16 11 0.0000 4 120 615 4155 2655 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 4230 2902 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 4755 2902 1\001 +4 0 0 50 0 16 11 0.0000 4 120 615 2955 2655 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 3030 2902 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 3555 2902 1\001 +4 0 0 50 0 16 11 0.0000 4 120 615 1755 2655 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 1830 2902 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2355 2902 2\001 +4 0 0 50 0 16 11 0.0000 4 120 615 2355 3630 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2430 3877 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2955 3877 0\001 +4 0 0 50 0 16 11 0.0000 4 120 615 1155 3630 fibonacci\001 +4 2 0 50 0 16 11 0.0000 4 90 90 1230 3877 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 1755 3877 1\001 diff --git a/book_tx/figs/fibonacci.pdf b/book_tx/figs/fibonacci.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ed4dc0dbf1662dc16f3b1b9e969e28b056c71369 GIT binary patch literal 5525 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 PL19q|=H@PQTnYaJ!zvf@ literal 0 HcmV?d00001 diff --git a/book_tx/figs/flower.test.pdf b/book_tx/figs/flower.test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d48dd6112ba9d60af8ce2b2dc5135779e29b5415 GIT binary patch literal 17297 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/interpret.eps b/book_tx/figs/interpret.eps new file mode 100644 index 0000000..8274779 --- /dev/null +++ b/book_tx/figs/interpret.eps @@ -0,0 +1,173 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: interpret.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5a +%%CreationDate: Wed May 30 11:13:36 2012 +%%BoundingBox: 0 0 263 61 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 61 moveto 0 0 lineto 263 0 lineto 263 61 lineto closepath clip newpath +-138.2 86.0 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Polyline +0 slj +0 slc +7.500 slw +gs clippath +3403 795 m 3615 795 l 3615 705 l 3403 705 l 3403 705 l 3583 750 l 3403 795 l cp +eoclip +n 3225 750 m + 3600 750 l gs col0 s gr gr + +% arrowhead +n 3403 795 m 3583 750 l 3403 705 l col0 s +% Polyline +15.000 slw +n 2325 1350 m 2325 450 l 3000 450 l 3150 600 l 3150 1350 l + 2325 1350 l cp gs col0 s gr +% Polyline +7.500 slw +n 3000 450 m 3000 600 l + 3150 600 l gs col0 s gr +% Polyline +15.000 slw +n 3748 640 m 3652 533 l 3652 900 l + 3748 798 l gs col0 s gr +% Polyline +7.500 slw +gs clippath +5375 1162 m 5587 1162 l 5587 1072 l 5375 1072 l 5375 1072 l 5555 1117 l 5375 1162 l cp +eoclip +n 5197 1117 m + 5572 1117 l gs col0 s gr gr + +% arrowhead +n 5375 1162 m 5555 1117 l 5375 1072 l col0 s +% Polyline +15.000 slw +n 5039 1173 m 5137 1275 l 5137 909 l + 5039 1014 l gs col0 s gr +% Polyline +n 3750 525 m 5047 525 l 5047 1290 l 3750 1290 l + cp gs col0 s gr +% Polyline +n 5919 1296 m 6376 1296 l 6376 1356 l 5919 1356 l + cp gs col0 s gr +% Polyline +n 5823 1357 m 6484 1357 l 6484 1412 l 5823 1412 l + cp gs col0 s gr +% Polyline +n 5638 463 m 6662 463 l 6662 1296 l 5638 1296 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +7.500 slw +n 5692 519 m 6606 519 l 6606 1237 l 5692 1237 l + cp gs col7 1.00 shd ef gr gs col0 s gr +/Helvetica ff 166.67 scf sf +2400 900 m +gs 1 -1 sc (SOURCE) col0 sh gr +/Helvetica ff 166.67 scf sf +2400 1125 m +gs 1 -1 sc (CODE) col0 sh gr +/Helvetica ff 166.67 scf sf +3825 975 m +gs 1 -1 sc (INTERPRETER) col0 sh gr +/Helvetica ff 166.67 scf sf +5813 953 m +gs 1 -1 sc (OUTPUT) col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/interpret.fig b/book_tx/figs/interpret.fig new file mode 100644 index 0000000..f887cfe --- /dev/null +++ b/book_tx/figs/interpret.fig @@ -0,0 +1,37 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 3225 750 3600 750 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 6 + 2325 1350 2325 450 3000 450 3150 600 3150 1350 2325 1350 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3 + 3000 450 3000 600 3150 600 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 4 + 3748 640 3652 533 3652 900 3748 798 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 90.00 180.00 + 5197 1117 5572 1117 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 4 + 5039 1173 5137 1275 5137 909 5039 1014 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3750 525 5047 525 5047 1290 3750 1290 3750 525 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5919 1296 6376 1296 6376 1356 5919 1356 5919 1296 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5823 1357 6484 1357 6484 1412 5823 1412 5823 1357 +2 2 0 2 0 7 50 0 20 0.000 0 0 -1 0 0 5 + 5638 463 6662 463 6662 1296 5638 1296 5638 463 +2 2 0 1 0 7 50 0 20 0.000 0 0 -1 0 0 5 + 5692 519 6606 519 6606 1237 5692 1237 5692 519 +4 0 0 50 0 16 10 0.0000 4 120 675 2400 900 SOURCE\001 +4 0 0 50 0 16 10 0.0000 4 120 465 2400 1125 CODE\001 +4 0 0 50 0 16 10 0.0000 4 120 1050 3825 975 INTERPRETER\001 +4 0 0 50 0 16 10 0.0000 4 120 615 5813 953 OUTPUT\001 diff --git a/book_tx/figs/interpret.pdf b/book_tx/figs/interpret.pdf new file mode 100644 index 0000000000000000000000000000000000000000..19dbb7618ef565dc63715b381eea737d53212c3b GIT binary patch literal 4565 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 Y;=7I)C{FMPjnu;28y!9M$z;j@06({@Z~y=R literal 0 HcmV?d00001 diff --git a/book_tx/figs/list2.eps b/book_tx/figs/list2.eps new file mode 100644 index 0000000..ebe15aa --- /dev/null +++ b/book_tx/figs/list2.eps @@ -0,0 +1,128 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: list2.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Thu Dec 6 09:32:48 2001 +%%For: downey@rocky.wellesley.edu (Allen B. Downey) +%%BoundingBox: 0 0 97 43 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 43 moveto 0 0 lineto 97 0 lineto 97 43 lineto closepath clip newpath +-107.0 100.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 1800 975 m 3375 975 l 3375 1650 l 1800 1650 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2490 1477 m 2490 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +2490 1177 m 2490 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +/Helvetica ff 165.00 scf sf +2025 1200 m +gs 1 -1 sc (a) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 1500 m +gs 1 -1 sc (b) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1200 m +gs 1 -1 sc ([ 1, 2, 3 ]) col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1500 m +gs 1 -1 sc ([ 1, 2, 3 ]) col0 sh gr +$F2psEnd +rs diff --git a/book_tx/figs/list2.fig b/book_tx/figs/list2.fig new file mode 100644 index 0000000..73d6dd0 --- /dev/null +++ b/book_tx/figs/list2.fig @@ -0,0 +1,21 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 975 3375 975 3375 1650 1800 1650 1800 975 +4 2 0 50 0 16 11 0.0000 4 90 75 2025 1200 a\001 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1500 b\001 +4 0 0 50 0 16 11 0.0000 4 150 630 2550 1200 [ 1, 2, 3 ]\001 +4 0 0 50 0 16 11 0.0000 4 150 630 2550 1500 [ 1, 2, 3 ]\001 diff --git a/book_tx/figs/list2.pdf b/book_tx/figs/list2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0d3d7e1c090c1e4e6f74fb393e07a7856629f2ed GIT binary patch literal 4373 zcmb^#d0Z1$y2`rhsK06vx>buKE(EB_%w%$xgd-3@h$2wIM%WI?Bn%{(bY=npTaTi< z+X@OOTC1Y1M?DLo#e*WdMQbg)*4Cp^#TI|qsz9;z?22{YgoH!w@rTI|c<;O4cfIcs zlpLcIVj>9?bgXmvdyo`HVLCe(3J*t;NV|p0fn@-ag6JqKM=~&?vl1K`LmFulsnI|z z$B={#a;>XO(I+-Vj{m6fZ`l5=TXxYA6|D`>rK3y#`^NAeH=fxVAGkT7=brtrao@0! z?OjP`0e(HVrtI7Au6}>`y`Af0e@vJbzV~+dFHVJ@iD=V9O`$Vr?p)cp(8Jqqef&dy z=%?G4eN&R1wtMSeH|Y1aC8{cBXDL>dRh*wwKFc@kMN@4+>9tWML<{zrP`at3JV16A zzSqpOgODAqk=x zRdDt-sO(Pt*wtHtTh`y(Q|);EQq{ru5#0@1Me_ay&&;U7zmA?mj0>Ay^;MhN9CKh( zJJ}Fuiw!oB;vRgpoAT#R2kI7Z;bxfq20fF9opZXuytP?hObZq6K>(k%jrNr$7MYF^X5w zn+8A{unKmY#llD;Wny6i#2cLgWx_y$lNULFm6z_xpk7Wb!4X#4;uYbsUQcp_31DEX z7tpU;K3G8iF(71SvL41X8jq3gQ+ZUS$RVCDrC*Hum|m;`QVhoOTMsgtU`gIF$eg&O zgcR)y@uW4M$D-}pOW#V#J z10@3x{PjzN< zd>Znx1FrTa1b_AcQGLiY?(Gc1Mn2w$(IAsSA`8Ws7?$EvST0s(@}0!Og6LxyDuIwF z*2t$ez<{hI9PuP&$?G0G;`iH!z)CLw9Q5!w4Fp)2Vo=;E{7q(?*cm1 zeMHa&NgM{J7@TSR-s7C!J~^;W0viXqRO{`lN=&TL^fl0zlAlhRNREH-!IF+rKZhC# zX)Ri9C8m*c7FnS%>&~IMS0}B7mnoZz>MA=XpHG<$FP%8+2))oy7v=ANPN*2F+y3Vm z!QP-2bPgId;@v6R4S8dNmx`?4)&Fqb-{30^Mv(6N7rPsJ<}ZJW5=V}W(fJ{FUDaLN zLeEe^(kZr;32WQO8n*0NtbW}W9o_TJ$Vz5glJDg99VZWtxnh##77qP%HV3t!~UJW za_@-wtIss8`H%VHx|erKN51BpPWW0yt4|%f+_C@FSXE}*ZPVA(zLtq=)fa}WXli=y zz=VrmPJ8>p1D_#JbtIL>9=-7H8%;}|>Ks-SSu7Ybq-yw@jia|k>b{JC7mWz;4GxUH zuxiWky5_9PmM=n*nk(M8`15N2pw`;lz_lOPq8`vm}(`sj)sS3Eg__R+=mTt~fCF z+MD91zbdy>FE5R&zCW($+MSah#{OlAJRIM;Ff_Sf59I&xj^G;_`Ga4|MQXpP^FF8w zxaxcKIQ{qHvX|HF4vo0}!<6DBt+W1dV?$y64xf&yRe$=4{yBbbbXRlOo2BVT*efsH z41nlv-{&tpT0d>8(8u>gjtf#B3_166QgQd6DjaBW8 z*jjrsM_l8aGA<*zwIqCLiSlOV=@mVbWSWb`C8G?_ERu?2TP8#vQNMKa7ei`-?qge%%g3>{4yLMr#42*Zcm9X0*>`Zm7n z4ZgVDx75G}=)J%C%R57#ECbb}4sz>z> zEtx~b7cpdN(Tp@>QJzt05=3aA@CX7-45ZLSID}^R@WsNQ5vl{VDM`9Op1`GY*&H@- zjlwRQ)y}G1YJrA7U&?mzjODwPN-M#N$vpb)Z!c8+if?d(*b z&us{m(Z^_;35Ju18!vT#-4=!JGVGNkfG-4DJ3sI?1jHh7|l@wJ;6+%>^LeX&K zAxaQ(z^Vl!HyFYH0P6tC0jxBW1`aGZr z5h1N4ZxIWEi~&1MMwOXnYy`+>!r=e|3&8;=BOnPppd?Hp@HBh^m%fE z`g1r*x%P;oJ&8BE`p1mZhc?+2Di`BB&mdtp)~cnI+y*zSel zaw&M24Thmo96Y`rg5ios=}_!Z7%l@3(1&EFjr>gPWRrC0m@Xc zG<+gxDq(JFCYktHO3mC&%q{$xCcXkJcC}PMEb-AQvgZynymYHSocRIgeDCwU&UXk- ziPcLmX*d*otaatzAQ_CpO!izTA_7UI>^ZyzmIFvCqNlAq#lnc*O7c`JWn@g0Rts@F zOOZCnRk1u(lROw3-qbny^HZ~CR=?NoKWumPNqu(I@O>wP>UDF++`Xr~`a;L|zVGo5 zju(Er^v=|`R$n{U;2d(UWJv=8uUTq6+p(BCA5**JLOy@#mm5!Q9HactFM(qNq}NXb zuB|?|!SBmYZneU1M;dOv=o*qcX;0l-+*z&Yi~MnMRV#EQ#fuVZH|#E5wI(osMeX^< zAiwREFCP7P+)Cp9lhZep)h{Sp;+t#!5T9@&ZjR4`(oRm?Hu_i_f0-SToKcYAJibFW z$Kp>pil6I5e-e-FSaR#o+Chck6m!YLSw+_7Sijvon!kSS$TP*4$A?s1^*?X%xwl|U-Q>i|RX>ZleRt>F zvzNT{m&R*dL%OaP{gtwtJkA3v!Qq0Ng}(%F zWTK7H_8cn(+=8U>lx-HQ1gj*PdfZbrtj%}7XmkG8V9X8a%9YBV=sO;<=w`v!GoS?Nn9Rxv~lyIBa5GC z^(}}h5)B$uIb{9&!?#E2zl($y4ju0o5){+8cI($Qby?*XPKguiN*7)HZCyZc)1J9O z@BDX?s-rCY_6yveD!=(dL*pA3lL4LYXY8!_Dslhj3)VBPIil7~XZ^RA)^A+68r`xs zq~ex!ug@!Qv>|yvE}Qpe&gs`aFjy9pk9y~S|=1awqnfTU#CR|wj4ZPxOLM@^wSf@l@2G<<=Y`i+lu$w zKTz#M%BqQ#tR(y9VE4}8X_Ux4(9EZ&2Q%igYeq5u zXsMd!JbG_-iu{`|zIe{K=2J3#Lq^D!($D5xTZ)f7w>oFn%H{F9I-f1LcIV{ZXr37LnCiopIEfGX~x?( zH{~DPF}S62?UTPUzfGMJ(^eO@bouOB?#j%L@euLz*T1A)&D*xJHB6mxP}ksawhgX% zw{@rL&WWhgqswoeeQ{Mx{^7V8_D1!g+~Te6Cq}#}?@W_^6P8&!_w)VteLwD;>NhDl z>2{X(P5MUNF67&&u={PzO}FMB+`s%*#WU)v$ZdO0TJUP;#Ah>7nwCYBEK_x4)~~rg zPOiOJwCriaa|>m7+=a1GwVIh74-9Du`i}8?^Uv;D;D5|8_JBAG>-w$U77*&+bunmF zSkUO*<AqFHEa%pFQ+l3wVgb{=8KK;^-_nL*S*Z<;n-%@=Wp!fdjE$@t^L~m_l1R?7w z?ubYi=p~@tz}Zv|ZP$p}4;~i5v`HhHElWa^96HKEPc2}nw1VmB#)4d<$|Q=^LJ^T9 zm>4LDi*!iL?y-!6K_k=z=~5H*K>~qG?Xo#+;2MQpHmjXeyEGy@S6-*G_0>Mrrvhch^jUah> zdD1*W%CI>Irc$X86i0Ae0w^S0zMUss5<52u=yMxFXY{byIjP$wDQK(+oq=Fd6!9wZ z-mElZhXuuCHsjK2T5K1{AR~XGQ48y&e9DOY8rwSl| zE&{j!tkhsSGC7SDs}aSgB*O6)hU2?0byz7?U?RkG^2cBhh{&VQ4#Ma;d<39TCxOe? zoF5BjGcAr{xCE6+a6BE8tFdr3K}gVWHHt-->I!FYq zna;sY)I4|=#d1Of2q_Myki5}irRGsqSVnfMcgygwL?A+#`grLv`i*oXCH=nVY&IdG z1v+&sV|3cUNRSZwC)4FIM%ZNRG1K8>t?r6284=1#2^Mi6$QZEGWK^3O)<%MSCLIni zu#h}(G6IrOq>TVbo(98*)?IJWR=#^-rG@%YTSaC?Q3V|e zrahrZfX9V05yz^98bf6`j>)lbcX^3WR0POC8U6u9x)3OFPYArC8CLv<1r*xzP;s%8 z8BE_;I3#qk?hh=N38SzX_QK>Cn6ZTqZ1=(lg%Z4``omC}9J~Yuz`}*c&HxySfk)i{ z7@-0_8~~Fm!DDU!Ord;;7ekc~*@r6dhv-m+>>(IND8M7HzYd&`_mRi5Bp9t(@DB+X zNuvwEi!~fZQW*w3ErnSdMiT6126oTg;0X{58zL0)I4n9A_)ss4!=tenWlVI8N~I@o hLM79yVleF=Q)CLSR*olG-W?!9C6`0N!EwoY=zn97*vtR` literal 0 HcmV?d00001 diff --git a/book_tx/figs/liststate.eps b/book_tx/figs/liststate.eps new file mode 100644 index 0000000..56544ee --- /dev/null +++ b/book_tx/figs/liststate.eps @@ -0,0 +1,255 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: liststate.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5d +%%CreationDate: Mon Oct 19 10:23:07 2015 +%%BoundingBox: 0 0 218 204 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 204 moveto 0 0 lineto 218 0 lineto 218 204 lineto closepath clip newpath +-12.8 243.7 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 1650 3675 m 1950 3675 l 1950 3975 l 1650 3975 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1650 975 m 3675 975 l 3675 1950 l 1650 1950 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1650 2325 m 3225 2325 l 3225 3300 l 1650 3300 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2338 2527 m 2490 2527 l 2490 2467 l 2338 2467 l 2338 2467 l 2458 2497 l 2338 2527 l cp +eoclip +n 2100 2497 m + 2475 2497 l gs col0 s gr gr + +% arrowhead +n 2338 2527 m 2458 2497 l 2338 2467 l col0 s +% Polyline +gs clippath +1438 2505 m 1590 2505 l 1590 2445 l 1438 2445 l 1438 2445 l 1558 2475 l 1438 2505 l cp +eoclip +n 1200 2475 m + 1575 2475 l gs col0 s gr gr + +% arrowhead +n 1438 2505 m 1558 2475 l 1438 2445 l col0 s +% Polyline +gs clippath +2342 3029 m 2472 3108 l 2503 3056 l 2373 2978 l 2373 2978 l 2461 3066 l 2342 3029 l cp +eoclip +n 2100 2850 m + 2475 3075 l gs col0 s gr gr + +% arrowhead +n 2342 3029 m 2461 3066 l 2373 2978 l col0 s +% Polyline + [15 60] 60 sd +n 2100 2797 m + 2475 2797 l gs col0 s gr [] 0 sd +% Polyline +n 2550 2700 m + 2850 2850 l gs col0 s gr +% Polyline +n 2850 2700 m + 2550 2850 l gs col0 s gr +% Polyline +gs clippath +1438 3855 m 1590 3855 l 1590 3795 l 1438 3795 l 1438 3795 l 1558 3825 l 1438 3855 l cp +eoclip +n 1200 3825 m + 1575 3825 l gs col0 s gr gr + +% arrowhead +n 1438 3855 m 1558 3825 l 1438 3795 l col0 s +% Polyline +gs clippath +2338 1477 m 2490 1477 l 2490 1417 l 2338 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +2338 1777 m 2490 1777 l 2490 1717 l 2338 1717 l 2338 1717 l 2458 1747 l 2338 1777 l cp +eoclip +n 2100 1747 m + 2475 1747 l gs col0 s gr gr + +% arrowhead +n 2338 1777 m 2458 1747 l 2338 1717 l col0 s +% Polyline +gs clippath +2338 1177 m 2490 1177 l 2490 1117 l 2338 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +% Polyline +gs clippath +1438 1155 m 1590 1155 l 1590 1095 l 1438 1095 l 1438 1095 l 1558 1125 l 1438 1155 l cp +eoclip +n 1200 1125 m + 1575 1125 l gs col0 s gr gr + +% arrowhead +n 1438 1155 m 1558 1125 l 1438 1095 l col0 s +% Polyline +n 225 675 m 3825 675 l 3825 4050 l 225 4050 l + cp gs col7 s gr +/Helvetica ff 183.33 scf sf +2025 2550 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 2850 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 2250 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 183.33 scf sf +1125 2550 m +gs 1 -1 sc (numbers) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 2850 m +gs 1 -1 sc (123) col0 sh gr +/Helvetica ff 183.33 scf sf +2550 3150 m +gs 1 -1 sc (5) col0 sh gr +/Helvetica ff 183.33 scf sf +1650 3600 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 183.33 scf sf +1125 3900 m +gs 1 -1 sc (empty) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1200 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1500 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1800 m +gs 1 -1 sc (2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1200 m +gs 1 -1 sc ('Cheddar') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1500 m +gs 1 -1 sc ('Edam') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1800 m +gs 1 -1 sc ('Gouda') col0 sh gr +/Helvetica ff 183.33 scf sf +1650 900 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 183.33 scf sf +1125 1200 m +gs 1 -1 sc (cheeses) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 2550 m +gs 1 -1 sc (42) col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/liststate.fig b/book_tx/figs/liststate.fig new file mode 100644 index 0000000..79bb4cb --- /dev/null +++ b/book_tx/figs/liststate.fig @@ -0,0 +1,64 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2497 2475 2497 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 2475 1575 2475 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2850 2475 3075 +2 1 2 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2100 2797 2475 2797 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2550 2700 2850 2850 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2850 2700 2550 2850 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 3825 1575 3825 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 3675 1950 3675 1950 3975 1650 3975 1650 3675 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 975 3675 975 3675 1950 1650 1950 1650 975 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1747 2475 1747 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 1125 1575 1125 +2 2 0 1 7 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 225 675 3825 675 3825 4050 225 4050 225 675 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 2325 3225 2325 3225 3300 1650 3300 1650 2325 +4 2 0 50 0 16 11 0.0000 4 120 105 2025 2550 0\001 +4 2 0 50 0 16 11 0.0000 4 120 105 2025 2850 1\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 2250 list\001 +4 2 0 50 0 16 11 0.0000 4 135 720 1125 2550 numbers\001 +4 0 0 50 0 16 11 0.0000 4 120 315 2550 2850 123\001 +4 0 0 50 0 16 11 0.0000 4 120 105 2550 3150 5\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 3600 list\001 +4 2 0 50 0 16 11 0.0000 4 165 495 1125 3900 empty\001 +4 2 0 50 0 16 11 0.0000 4 120 105 2025 1200 0\001 +4 2 0 50 0 16 11 0.0000 4 120 105 2025 1500 1\001 +4 2 0 50 0 16 11 0.0000 4 120 105 2025 1800 2\001 +4 0 0 50 0 16 11 0.0000 4 135 780 2550 1200 'Cheddar'\001 +4 0 0 50 0 16 11 0.0000 4 135 540 2550 1500 'Edam'\001 +4 0 0 50 0 16 11 0.0000 4 135 615 2550 1800 'Gouda'\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 900 list\001 +4 2 0 50 0 16 11 0.0000 4 135 690 1125 1200 cheeses\001 +4 0 0 50 0 16 11 0.0000 4 120 210 2550 2550 42\001 diff --git a/book_tx/figs/liststate.fig.bak b/book_tx/figs/liststate.fig.bak new file mode 100644 index 0000000..55fcf23 --- /dev/null +++ b/book_tx/figs/liststate.fig.bak @@ -0,0 +1,64 @@ +#FIG 3.2 Produced by xfig version 3.2.5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2497 2475 2497 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 2475 1575 2475 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2850 2475 3075 +2 1 2 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2100 2797 2475 2797 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2550 2700 2850 2850 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2850 2700 2550 2850 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 2325 3225 2325 3225 3300 1650 3300 1650 2325 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 3825 1575 3825 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 3675 1950 3675 1950 3975 1650 3975 1650 3675 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 975 3675 975 3675 1950 1650 1950 1650 975 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1747 2475 1747 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 1125 1575 1125 +2 2 0 1 7 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 225 675 3825 675 3825 4050 225 4050 225 675 +4 2 0 50 0 16 11 0.0000 4 135 105 2025 2550 0\001 +4 2 0 50 0 16 11 0.0000 4 135 105 2025 2850 1\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 2250 list\001 +4 2 0 50 0 16 11 0.0000 4 135 705 1125 2550 numbers\001 +4 0 0 50 0 16 11 0.0000 4 135 210 2550 2550 17\001 +4 0 0 50 0 16 11 0.0000 4 135 315 2550 2850 123\001 +4 0 0 50 0 16 11 0.0000 4 135 105 2550 3150 5\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 3600 list\001 +4 2 0 50 0 16 11 0.0000 4 180 495 1125 3900 empty\001 +4 2 0 50 0 16 11 0.0000 4 135 105 2025 1200 0\001 +4 2 0 50 0 16 11 0.0000 4 135 105 2025 1500 1\001 +4 2 0 50 0 16 11 0.0000 4 135 105 2025 1800 2\001 +4 0 0 50 0 16 11 0.0000 4 135 810 2550 1200 'Cheddar'\001 +4 0 0 50 0 16 11 0.0000 4 135 555 2550 1500 'Edam'\001 +4 0 0 50 0 16 11 0.0000 4 135 645 2550 1800 'Gouda'\001 +4 0 0 50 0 16 11 0.0000 4 135 225 1650 900 list\001 +4 2 0 50 0 16 11 0.0000 4 135 705 1125 1200 cheeses\001 diff --git a/book_tx/figs/liststate.pdf b/book_tx/figs/liststate.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0c4d6f534041eec858b3a38f7f3289dd46247876 GIT binary patch literal 6467 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/listsum1.eps b/book_tx/figs/listsum1.eps new file mode 100644 index 0000000..27870ec --- /dev/null +++ b/book_tx/figs/listsum1.eps @@ -0,0 +1,1740 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: listsum1.eps +%%Creator: matplotlib version 0.99.1.1, http://matplotlib.sourceforge.net/ +%%CreationDate: Fri Aug 5 16:02:46 2011 +%%Orientation: portrait +%%BoundingBox: 18 180 594 612 +%%EndComments +%%BeginProlog +/mpldict 8 dict def +mpldict begin +/m { moveto } bind def +/l { lineto } bind def +/r { rlineto } bind def +/c { curveto } bind def +/cl { closepath } bind def +/box { +m +1 index 0 r +0 exch r +neg 0 r +cl +} bind def +/clipbox { +box +clip +newpath +} bind def +%!PS-Adobe-3.0 Resource-Font +%%Title: DejaVu Sans +%%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain +%%Creator: Converted from TrueType by PPR +25 dict begin +/_d{bind def}bind def +/_m{moveto}_d +/_l{lineto}_d +/_cl{closepath eofill}_d +/_c{curveto}_d +/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d +/_e{exec}_d +/FontName /DejaVuSans def +/PaintType 0 def +/FontMatrix[.001 0 0 .001 0 0]def +/FontBBox[-1020 -349 1681 1167]def +/FontType 3 def +/Encoding StandardEncoding def +/FontInfo 10 dict dup begin +/FamilyName (DejaVu Sans) def +/FullName (DejaVu Sans) def +/Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain ) def +/Weight (Book) def +/Version (Version 2.30) def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -130 def +/UnderlineThickness 90 def +end readonly def +/CharStrings 23 dict dup begin +/space{318 0 0 0 0 0 _sc +}_d +/parenleft{390 0 86 -131 310 759 _sc +310 759 _m +266 683 234 609 213 536 _c +191 463 181 389 181 314 _c +181 238 191 164 213 91 _c +234 17 266 -56 310 -131 _c +232 -131 _l +183 -54 146 20 122 94 _c +98 168 86 241 86 314 _c +86 386 98 459 122 533 _c +146 607 182 682 232 759 _c +310 759 _l +_cl}_d +/parenright{390 0 80 -131 304 759 _sc +80 759 _m +158 759 _l +206 682 243 607 267 533 _c +291 459 304 386 304 314 _c +304 241 291 168 267 94 _c +243 20 206 -54 158 -131 _c +80 -131 _l +123 -56 155 17 177 91 _c +198 164 209 238 209 314 _c +209 389 198 463 177 536 _c +155 609 123 683 80 759 _c +_cl}_d +/hyphen{361 0 49 234 312 314 _sc +49 314 _m +312 314 _l +312 234 _l +49 234 _l +49 314 _l +_cl}_d +/zero{636 0 66 -13 570 742 _sc +318 664 _m +267 664 229 639 203 589 _c +177 539 165 464 165 364 _c +165 264 177 189 203 139 _c +229 89 267 64 318 64 _c +369 64 407 89 433 139 _c +458 189 471 264 471 364 _c +471 464 458 539 433 589 _c +407 639 369 664 318 664 _c +318 742 _m +399 742 461 709 505 645 _c +548 580 570 486 570 364 _c +570 241 548 147 505 83 _c +461 19 399 -13 318 -13 _c +236 -13 173 19 130 83 _c +87 147 66 241 66 364 _c +66 486 87 580 130 645 _c +173 709 236 742 318 742 _c +_cl}_d +/one{636 0 110 0 544 729 _sc +124 83 _m +285 83 _l +285 639 _l +110 604 _l +110 694 _l +284 729 _l +383 729 _l +383 83 _l +544 83 _l +544 0 _l +124 0 _l +124 83 _l +_cl}_d +/two{{636 0 73 0 536 742 _sc +192 83 _m +536 83 _l +536 0 _l +73 0 _l +73 83 _l +110 121 161 173 226 239 _c +290 304 331 346 348 365 _c +380 400 402 430 414 455 _c +426 479 433 504 433 528 _c +433 566 419 598 392 622 _c +365 646 330 659 286 659 _c +255 659 222 653 188 643 _c +154 632 117 616 78 594 _c +78 694 _l +118 710 155 722 189 730 _c +223 738 255 742 284 742 _c +359 742 419 723 464 685 _c +509 647 532 597 532 534 _c +532 504 526 475 515 449 _c +504 422 484 390 454 354 _c +446 344 420 317 376 272 _c +332 227 271 164 192 83 _c +_cl}_e}_d +/five{{636 0 77 -13 549 729 _sc +108 729 _m +495 729 _l +495 646 _l +198 646 _l +198 467 _l +212 472 227 476 241 478 _c +255 480 270 482 284 482 _c +365 482 429 459 477 415 _c +525 370 549 310 549 234 _c +549 155 524 94 475 51 _c +426 8 357 -13 269 -13 _c +238 -13 207 -10 175 -6 _c +143 -1 111 6 77 17 _c +77 116 _l +106 100 136 88 168 80 _c +199 72 232 69 267 69 _c +323 69 368 83 401 113 _c +433 143 450 183 450 234 _c +450 284 433 324 401 354 _c +368 384 323 399 267 399 _c +241 399 214 396 188 390 _c +162 384 135 375 108 363 _c +108 729 _l +_cl}_e}_d +/six{{636 0 70 -13 573 742 _sc +330 404 _m +286 404 251 388 225 358 _c +199 328 186 286 186 234 _c +186 181 199 139 225 109 _c +251 79 286 64 330 64 _c +374 64 409 79 435 109 _c +461 139 474 181 474 234 _c +474 286 461 328 435 358 _c +409 388 374 404 330 404 _c +526 713 _m +526 623 _l +501 635 476 644 451 650 _c +425 656 400 659 376 659 _c +310 659 260 637 226 593 _c +192 549 172 482 168 394 _c +187 422 211 444 240 459 _c +269 474 301 482 336 482 _c +409 482 467 459 509 415 _c +551 371 573 310 573 234 _c +573 159 550 99 506 54 _c +462 9 403 -13 330 -13 _c +246 -13 181 19 137 83 _c +92 147 70 241 70 364 _c +70 479 97 571 152 639 _c +206 707 280 742 372 742 _c +}_e{396 742 421 739 447 735 _c +472 730 498 723 526 713 _c +_cl}_e}_d +/seven{636 0 82 0 551 729 _sc +82 729 _m +551 729 _l +551 687 _l +286 0 _l +183 0 _l +432 646 _l +82 646 _l +82 729 _l +_cl}_d +/underscore{500 0 -9 -235 510 -165 _sc +510 -165 _m +510 -235 _l +-9 -235 _l +-9 -165 _l +510 -165 _l +_cl}_d +/d{{635 0 55 -13 544 760 _sc +454 464 _m +454 760 _l +544 760 _l +544 0 _l +454 0 _l +454 82 _l +435 49 411 25 382 10 _c +353 -5 319 -13 279 -13 _c +213 -13 159 13 117 65 _c +75 117 55 187 55 273 _c +55 359 75 428 117 481 _c +159 533 213 560 279 560 _c +319 560 353 552 382 536 _c +411 520 435 496 454 464 _c +148 273 _m +148 207 161 155 188 117 _c +215 79 253 61 301 61 _c +348 61 385 79 413 117 _c +440 155 454 207 454 273 _c +454 339 440 390 413 428 _c +385 466 348 485 301 485 _c +253 485 215 466 188 428 _c +161 390 148 339 148 273 _c +_cl}_e}_d +/e{{615 0 55 -13 562 560 _sc +562 296 _m +562 252 _l +149 252 _l +153 190 171 142 205 110 _c +238 78 284 62 344 62 _c +378 62 412 66 444 74 _c +476 82 509 95 541 113 _c +541 28 _l +509 14 476 3 442 -3 _c +408 -9 373 -13 339 -13 _c +251 -13 182 12 131 62 _c +80 112 55 181 55 268 _c +55 357 79 428 127 481 _c +175 533 241 560 323 560 _c +397 560 455 536 498 489 _c +540 441 562 377 562 296 _c +472 322 _m +471 371 457 410 431 440 _c +404 469 368 484 324 484 _c +274 484 234 469 204 441 _c +174 413 156 373 152 322 _c +472 322 _l +_cl}_e}_d +/i{278 0 94 0 184 760 _sc +94 547 _m +184 547 _l +184 0 _l +94 0 _l +94 547 _l +94 760 _m +184 760 _l +184 646 _l +94 646 _l +94 760 _l +_cl}_d +/l{278 0 94 0 184 760 _sc +94 760 _m +184 760 _l +184 0 _l +94 0 _l +94 760 _l +_cl}_d +/m{{974 0 91 0 889 560 _sc +520 442 _m +542 482 569 511 600 531 _c +631 550 668 560 711 560 _c +767 560 811 540 842 500 _c +873 460 889 403 889 330 _c +889 0 _l +799 0 _l +799 327 _l +799 379 789 418 771 444 _c +752 469 724 482 686 482 _c +639 482 602 466 575 435 _c +548 404 535 362 535 309 _c +535 0 _l +445 0 _l +445 327 _l +445 379 435 418 417 444 _c +398 469 369 482 331 482 _c +285 482 248 466 221 435 _c +194 404 181 362 181 309 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +201 495 226 520 255 536 _c +283 552 317 560 357 560 _c +397 560 430 550 458 530 _c +486 510 506 480 520 442 _c +}_e{_cl}_e}_d +/n{634 0 91 0 549 560 _sc +549 330 _m +549 0 _l +459 0 _l +459 327 _l +459 379 448 417 428 443 _c +408 469 378 482 338 482 _c +289 482 251 466 223 435 _c +195 404 181 362 181 309 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +202 494 227 519 257 535 _c +286 551 320 560 358 560 _c +420 560 468 540 500 501 _c +532 462 549 405 549 330 _c +_cl}_d +/p{{635 0 91 -207 580 560 _sc +181 82 _m +181 -207 _l +91 -207 _l +91 547 _l +181 547 _l +181 464 _l +199 496 223 520 252 536 _c +281 552 316 560 356 560 _c +422 560 476 533 518 481 _c +559 428 580 359 580 273 _c +580 187 559 117 518 65 _c +476 13 422 -13 356 -13 _c +316 -13 281 -5 252 10 _c +223 25 199 49 181 82 _c +487 273 _m +487 339 473 390 446 428 _c +418 466 381 485 334 485 _c +286 485 249 466 222 428 _c +194 390 181 339 181 273 _c +181 207 194 155 222 117 _c +249 79 286 61 334 61 _c +381 61 418 79 446 117 _c +473 155 487 207 487 273 _c +_cl}_e}_d +/r{411 0 91 0 411 560 _sc +411 463 _m +401 469 390 473 378 476 _c +366 478 353 480 339 480 _c +288 480 249 463 222 430 _c +194 397 181 350 181 288 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +199 495 224 520 254 536 _c +284 552 321 560 365 560 _c +371 560 378 559 386 559 _c +393 558 401 557 411 555 _c +411 463 _l +_cl}_d +/s{{521 0 54 -13 472 560 _sc +443 531 _m +443 446 _l +417 458 391 468 364 475 _c +336 481 308 485 279 485 _c +234 485 200 478 178 464 _c +156 450 145 430 145 403 _c +145 382 153 366 169 354 _c +185 342 217 330 265 320 _c +296 313 _l +360 299 405 279 432 255 _c +458 230 472 195 472 151 _c +472 100 452 60 412 31 _c +372 1 316 -13 246 -13 _c +216 -13 186 -10 154 -5 _c +122 0 89 8 54 20 _c +54 113 _l +87 95 120 82 152 74 _c +184 65 216 61 248 61 _c +290 61 323 68 346 82 _c +368 96 380 117 380 144 _c +380 168 371 187 355 200 _c +339 213 303 226 247 238 _c +216 245 _l +160 257 119 275 95 299 _c +70 323 58 356 58 399 _c +58 450 76 490 112 518 _c +148 546 200 560 268 560 _c +}_e{301 560 332 557 362 552 _c +391 547 418 540 443 531 _c +_cl}_e}_d +/t{392 0 27 0 368 702 _sc +183 702 _m +183 547 _l +368 547 _l +368 477 _l +183 477 _l +183 180 _l +183 135 189 106 201 94 _c +213 81 238 75 276 75 _c +368 75 _l +368 0 _l +276 0 _l +206 0 158 13 132 39 _c +106 65 93 112 93 180 _c +93 477 _l +27 477 _l +27 547 _l +93 547 _l +93 702 _l +183 702 _l +_cl}_d +/u{634 0 85 -13 543 560 _sc +85 216 _m +85 547 _l +175 547 _l +175 219 _l +175 167 185 129 205 103 _c +225 77 255 64 296 64 _c +344 64 383 79 411 110 _c +439 141 453 183 453 237 _c +453 547 _l +543 547 _l +543 0 _l +453 0 _l +453 84 _l +431 50 405 26 377 10 _c +348 -5 315 -13 277 -13 _c +214 -13 166 6 134 45 _c +101 83 85 140 85 216 _c +_cl}_d +/x{592 0 29 0 559 547 _sc +549 547 _m +351 281 _l +559 0 _l +453 0 _l +294 215 _l +135 0 _l +29 0 _l +241 286 _l +47 547 _l +153 547 _l +298 352 _l +443 547 _l +549 547 _l +_cl}_d +end readonly def + +/BuildGlyph + {exch begin + CharStrings exch + 2 copy known not{pop /.notdef}if + true 3 1 roll get exec + end}_d + +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +}_d + +FontName currentdict end definefont pop +end +%%EndProlog +mpldict begin +18 180 translate +576 432 0 0 clipbox +1.000 setlinewidth +1 setlinejoin +2 setlinecap +[] 0 setdash +1.000 setgray +gsave +0 0 m +576 0 l +576 432 l +0 432 l +0 0 l +gsave +fill +grestore +stroke +grestore +gsave +72 43.2 m +518.4 43.2 l +518.4 388.8 l +72 388.8 l +72 43.2 l +fill +grestore +2.000 setlinewidth +0.700 setgray +gsave +446.4 345.6 72 43.2 clipbox +139.19 187.425 m +178.493 217.853 l +206.38 239.442 l +228.01 256.189 l +245.683 269.871 l +260.626 281.439 l +273.57 291.46 l +284.987 300.3 l +295.2 308.207 l +304.439 315.359 l +312.873 321.889 l +320.632 327.896 l +327.816 333.457 l +334.504 338.635 l +340.76 343.478 l +346.636 348.028 l +352.177 352.318 l +357.418 356.375 l +362.39 360.225 l +367.119 363.886 l +371.629 367.377 l +375.938 370.713 l +380.063 373.907 l +stroke +grestore +3.000 setlinewidth +0.000 0.000 1.000 setrgbcolor +gsave +446.4 345.6 72 43.2 clipbox +139.19 177.665 m +178.493 223.153 l +206.38 235.689 l +228.01 255.822 l +245.683 268.018 l +260.626 275.171 l +273.57 284.764 l +284.987 293.269 l +295.2 300.907 l +304.439 310.015 l +312.873 320.036 l +320.632 321.889 l +327.816 327.189 l +334.504 336.782 l +340.76 338.268 l +346.636 342.558 l +352.177 350.465 l +357.418 349.203 l +362.39 356.471 l +367.119 367.211 l +371.629 364.147 l +375.938 363.097 l +380.063 373.907 l +stroke +grestore +2.000 setlinewidth +0.700 setgray +gsave +446.4 345.6 72 43.2 clipbox +139.19 153.243 m +178.493 183.671 l +206.38 205.261 l +228.01 222.007 l +245.683 235.689 l +260.626 247.258 l +273.57 257.279 l +284.987 266.118 l +295.2 274.025 l +304.439 281.178 l +312.873 287.707 l +320.632 293.714 l +327.816 299.276 l +334.504 304.453 l +340.76 309.297 l +346.636 313.846 l +352.177 318.136 l +357.418 322.193 l +362.39 326.043 l +367.119 329.704 l +371.629 333.196 l +375.938 336.531 l +380.063 339.725 l +stroke +grestore +3.000 setlinewidth +0.000 0.502 0.000 setrgbcolor +gsave +446.4 345.6 72 43.2 clipbox +139.19 147.236 m +178.493 177.665 l +206.38 216 l +228.01 216 l +245.683 235.689 l +260.626 241.251 l +273.57 251.272 l +284.987 271.679 l +295.2 281.701 l +304.439 287.707 l +312.873 290.54 l +320.632 293.269 l +327.816 303.29 l +334.504 303.29 l +340.76 310.015 l +346.636 312.129 l +352.177 316.187 l +357.418 328.875 l +362.39 327.189 l +367.119 330.525 l +371.629 333.718 l +375.938 336.782 l +380.063 339.725 l +stroke +grestore +0.500 setlinewidth +0 setlinecap +0.000 setgray +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +72 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +72 388.8 o +grestore +gsave +61.000000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/five glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +295.2 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +295.2 388.8 o +grestore +gsave +284.200000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/six glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +518.4 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +518.4 388.8 o +grestore +gsave +507.400000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/seven glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +139.19 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +139.19 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +178.493 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +178.493 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +206.38 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +206.38 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +228.01 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +228.01 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +245.683 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +245.683 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +260.626 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +260.626 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +273.57 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +273.57 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +284.987 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +284.987 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +362.39 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +362.39 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +401.693 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +401.693 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +429.58 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +429.58 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +451.21 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +451.21 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +468.883 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +468.883 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +483.826 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +483.826 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +496.77 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +496.77 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +508.187 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +508.187 388.8 o +grestore +/DejaVuSans findfont +12.000 scalefont +setfont +292.45 12.481 m +(n) show +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 43.2 o +grestore +gsave +43.000000 35.700000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/hyphen glyphshow + +18.300586 8.765625 moveto +/two glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 216 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 216 o +grestore +gsave +43.000000 208.500000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/hyphen glyphshow + +18.300586 8.875000 moveto +/one glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 388.8 o +grestore +gsave +46.000000 381.300000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/zero glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 95.218 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 95.218 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 125.647 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 125.647 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 147.236 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 147.236 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 163.982 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 163.982 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 177.665 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 177.665 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 189.233 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 189.233 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 199.254 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 199.254 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 208.093 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 208.093 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 268.018 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 268.018 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 298.447 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 298.447 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 320.036 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 320.036 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 336.782 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 336.782 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 350.465 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 350.465 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 362.033 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 362.033 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 372.054 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 372.054 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 380.893 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 380.893 o +grestore +38 181.258 m +gsave +90 rotate +0 1.578 rmoveto +(run time \(s\)) show +grestore +1.000 setlinewidth +2 setlinecap +gsave +72 388.8 m +518.4 388.8 l +stroke +grestore +gsave +518.4 43.2 m +518.4 388.8 l +stroke +grestore +gsave +72 43.2 m +518.4 43.2 l +stroke +grestore +gsave +72 43.2 m +72 388.8 l +stroke +grestore +gsave +373.844 50.4 m +511.2 50.4 l +511.2 96.995 l +373.844 96.995 l +373.844 50.4 l +cl +gsave +1.000 setgray +fill +grestore +stroke +grestore +3.000 setlinewidth +0.000 0.000 1.000 setrgbcolor +gsave +383.924 85.6344 m +404.084 85.6344 l +stroke +grestore +0.000 setgray +/DejaVuSans findfont +14.400 scalefont +setfont +419.924 77.297 m +0 3.297 rmoveto +(sum_extend) show +0.000 0.502 0.000 setrgbcolor +gsave +383.924 64.4969 m +404.084 64.4969 l +stroke +grestore +0.000 setgray +419.924 56.16 m +0 3.297 rmoveto +(sum_plus) show + +end +showpage diff --git a/book_tx/figs/listsum1.pdf b/book_tx/figs/listsum1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..103db1934cb24ebf0d1140f668abc81f5e401ff7 GIT binary patch literal 11055 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 ZZswlw$W%JxB!M$PA|Rxsv`usn{|BxdVgvvH literal 0 HcmV?d00001 diff --git a/book_tx/figs/listsum2.eps b/book_tx/figs/listsum2.eps new file mode 100644 index 0000000..f771ec9 --- /dev/null +++ b/book_tx/figs/listsum2.eps @@ -0,0 +1,2086 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: listsum2.eps +%%Creator: matplotlib version 0.99.1.1, http://matplotlib.sourceforge.net/ +%%CreationDate: Wed Aug 3 16:20:28 2011 +%%Orientation: portrait +%%BoundingBox: 18 180 594 612 +%%EndComments +%%BeginProlog +/mpldict 8 dict def +mpldict begin +/m { moveto } bind def +/l { lineto } bind def +/r { rlineto } bind def +/c { curveto } bind def +/cl { closepath } bind def +/box { +m +1 index 0 r +0 exch r +neg 0 r +cl +} bind def +/clipbox { +box +clip +newpath +} bind def +%!PS-Adobe-3.0 Resource-Font +%%Title: DejaVu Sans +%%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain +%%Creator: Converted from TrueType by PPR +25 dict begin +/_d{bind def}bind def +/_m{moveto}_d +/_l{lineto}_d +/_cl{closepath eofill}_d +/_c{curveto}_d +/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d +/_e{exec}_d +/FontName /DejaVuSans def +/PaintType 0 def +/FontMatrix[.001 0 0 .001 0 0]def +/FontBBox[-1020 -349 1681 1167]def +/FontType 3 def +/Encoding StandardEncoding def +/FontInfo 10 dict dup begin +/FamilyName (DejaVu Sans) def +/FullName (DejaVu Sans) def +/Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain ) def +/Weight (Book) def +/Version (Version 2.30) def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -130 def +/UnderlineThickness 90 def +end readonly def +/CharStrings 19 dict dup begin +/space{318 0 0 0 0 0 _sc +}_d +/parenleft{390 0 86 -131 310 759 _sc +310 759 _m +266 683 234 609 213 536 _c +191 463 181 389 181 314 _c +181 238 191 164 213 91 _c +234 17 266 -56 310 -131 _c +232 -131 _l +183 -54 146 20 122 94 _c +98 168 86 241 86 314 _c +86 386 98 459 122 533 _c +146 607 182 682 232 759 _c +310 759 _l +_cl}_d +/parenright{390 0 80 -131 304 759 _sc +80 759 _m +158 759 _l +206 682 243 607 267 533 _c +291 459 304 386 304 314 _c +304 241 291 168 267 94 _c +243 20 206 -54 158 -131 _c +80 -131 _l +123 -56 155 17 177 91 _c +198 164 209 238 209 314 _c +209 389 198 463 177 536 _c +155 609 123 683 80 759 _c +_cl}_d +/hyphen{361 0 49 234 312 314 _sc +49 314 _m +312 314 _l +312 234 _l +49 234 _l +49 314 _l +_cl}_d +/zero{636 0 66 -13 570 742 _sc +318 664 _m +267 664 229 639 203 589 _c +177 539 165 464 165 364 _c +165 264 177 189 203 139 _c +229 89 267 64 318 64 _c +369 64 407 89 433 139 _c +458 189 471 264 471 364 _c +471 464 458 539 433 589 _c +407 639 369 664 318 664 _c +318 742 _m +399 742 461 709 505 645 _c +548 580 570 486 570 364 _c +570 241 548 147 505 83 _c +461 19 399 -13 318 -13 _c +236 -13 173 19 130 83 _c +87 147 66 241 66 364 _c +66 486 87 580 130 645 _c +173 709 236 742 318 742 _c +_cl}_d +/one{636 0 110 0 544 729 _sc +124 83 _m +285 83 _l +285 639 _l +110 604 _l +110 694 _l +284 729 _l +383 729 _l +383 83 _l +544 83 _l +544 0 _l +124 0 _l +124 83 _l +_cl}_d +/two{{636 0 73 0 536 742 _sc +192 83 _m +536 83 _l +536 0 _l +73 0 _l +73 83 _l +110 121 161 173 226 239 _c +290 304 331 346 348 365 _c +380 400 402 430 414 455 _c +426 479 433 504 433 528 _c +433 566 419 598 392 622 _c +365 646 330 659 286 659 _c +255 659 222 653 188 643 _c +154 632 117 616 78 594 _c +78 694 _l +118 710 155 722 189 730 _c +223 738 255 742 284 742 _c +359 742 419 723 464 685 _c +509 647 532 597 532 534 _c +532 504 526 475 515 449 _c +504 422 484 390 454 354 _c +446 344 420 317 376 272 _c +332 227 271 164 192 83 _c +_cl}_e}_d +/three{{636 0 76 -13 556 742 _sc +406 393 _m +453 383 490 362 516 330 _c +542 298 556 258 556 212 _c +556 140 531 84 482 45 _c +432 6 362 -13 271 -13 _c +240 -13 208 -10 176 -4 _c +144 1 110 10 76 22 _c +76 117 _l +103 101 133 89 166 81 _c +198 73 232 69 268 69 _c +330 69 377 81 409 105 _c +441 129 458 165 458 212 _c +458 254 443 288 413 312 _c +383 336 341 349 287 349 _c +202 349 _l +202 430 _l +291 430 _l +339 430 376 439 402 459 _c +428 478 441 506 441 543 _c +441 580 427 609 401 629 _c +374 649 336 659 287 659 _c +260 659 231 656 200 650 _c +169 644 135 635 98 623 _c +98 711 _l +135 721 170 729 203 734 _c +235 739 266 742 296 742 _c +}_e{370 742 429 725 473 691 _c +517 657 539 611 539 553 _c +539 513 527 479 504 451 _c +481 423 448 403 406 393 _c +_cl}_e}_d +/four{636 0 49 0 580 729 _sc +378 643 _m +129 254 _l +378 254 _l +378 643 _l +352 729 _m +476 729 _l +476 254 _l +580 254 _l +580 172 _l +476 172 _l +476 0 _l +378 0 _l +378 172 _l +49 172 _l +49 267 _l +352 729 _l +_cl}_d +/five{{636 0 77 -13 549 729 _sc +108 729 _m +495 729 _l +495 646 _l +198 646 _l +198 467 _l +212 472 227 476 241 478 _c +255 480 270 482 284 482 _c +365 482 429 459 477 415 _c +525 370 549 310 549 234 _c +549 155 524 94 475 51 _c +426 8 357 -13 269 -13 _c +238 -13 207 -10 175 -6 _c +143 -1 111 6 77 17 _c +77 116 _l +106 100 136 88 168 80 _c +199 72 232 69 267 69 _c +323 69 368 83 401 113 _c +433 143 450 183 450 234 _c +450 284 433 324 401 354 _c +368 384 323 399 267 399 _c +241 399 214 396 188 390 _c +162 384 135 375 108 363 _c +108 729 _l +_cl}_e}_d +/underscore{500 0 -9 -235 510 -165 _sc +510 -165 _m +510 -235 _l +-9 -235 _l +-9 -165 _l +510 -165 _l +_cl}_d +/e{{615 0 55 -13 562 560 _sc +562 296 _m +562 252 _l +149 252 _l +153 190 171 142 205 110 _c +238 78 284 62 344 62 _c +378 62 412 66 444 74 _c +476 82 509 95 541 113 _c +541 28 _l +509 14 476 3 442 -3 _c +408 -9 373 -13 339 -13 _c +251 -13 182 12 131 62 _c +80 112 55 181 55 268 _c +55 357 79 428 127 481 _c +175 533 241 560 323 560 _c +397 560 455 536 498 489 _c +540 441 562 377 562 296 _c +472 322 _m +471 371 457 410 431 440 _c +404 469 368 484 324 484 _c +274 484 234 469 204 441 _c +174 413 156 373 152 322 _c +472 322 _l +_cl}_e}_d +/i{278 0 94 0 184 760 _sc +94 547 _m +184 547 _l +184 0 _l +94 0 _l +94 547 _l +94 760 _m +184 760 _l +184 646 _l +94 646 _l +94 760 _l +_cl}_d +/m{{974 0 91 0 889 560 _sc +520 442 _m +542 482 569 511 600 531 _c +631 550 668 560 711 560 _c +767 560 811 540 842 500 _c +873 460 889 403 889 330 _c +889 0 _l +799 0 _l +799 327 _l +799 379 789 418 771 444 _c +752 469 724 482 686 482 _c +639 482 602 466 575 435 _c +548 404 535 362 535 309 _c +535 0 _l +445 0 _l +445 327 _l +445 379 435 418 417 444 _c +398 469 369 482 331 482 _c +285 482 248 466 221 435 _c +194 404 181 362 181 309 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +201 495 226 520 255 536 _c +283 552 317 560 357 560 _c +397 560 430 550 458 530 _c +486 510 506 480 520 442 _c +}_e{_cl}_e}_d +/n{634 0 91 0 549 560 _sc +549 330 _m +549 0 _l +459 0 _l +459 327 _l +459 379 448 417 428 443 _c +408 469 378 482 338 482 _c +289 482 251 466 223 435 _c +195 404 181 362 181 309 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +202 494 227 519 257 535 _c +286 551 320 560 358 560 _c +420 560 468 540 500 501 _c +532 462 549 405 549 330 _c +_cl}_d +/r{411 0 91 0 411 560 _sc +411 463 _m +401 469 390 473 378 476 _c +366 478 353 480 339 480 _c +288 480 249 463 222 430 _c +194 397 181 350 181 288 _c +181 0 _l +91 0 _l +91 547 _l +181 547 _l +181 462 _l +199 495 224 520 254 536 _c +284 552 321 560 365 560 _c +371 560 378 559 386 559 _c +393 558 401 557 411 555 _c +411 463 _l +_cl}_d +/s{{521 0 54 -13 472 560 _sc +443 531 _m +443 446 _l +417 458 391 468 364 475 _c +336 481 308 485 279 485 _c +234 485 200 478 178 464 _c +156 450 145 430 145 403 _c +145 382 153 366 169 354 _c +185 342 217 330 265 320 _c +296 313 _l +360 299 405 279 432 255 _c +458 230 472 195 472 151 _c +472 100 452 60 412 31 _c +372 1 316 -13 246 -13 _c +216 -13 186 -10 154 -5 _c +122 0 89 8 54 20 _c +54 113 _l +87 95 120 82 152 74 _c +184 65 216 61 248 61 _c +290 61 323 68 346 82 _c +368 96 380 117 380 144 _c +380 168 371 187 355 200 _c +339 213 303 226 247 238 _c +216 245 _l +160 257 119 275 95 299 _c +70 323 58 356 58 399 _c +58 450 76 490 112 518 _c +148 546 200 560 268 560 _c +}_e{301 560 332 557 362 552 _c +391 547 418 540 443 531 _c +_cl}_e}_d +/t{392 0 27 0 368 702 _sc +183 702 _m +183 547 _l +368 547 _l +368 477 _l +183 477 _l +183 180 _l +183 135 189 106 201 94 _c +213 81 238 75 276 75 _c +368 75 _l +368 0 _l +276 0 _l +206 0 158 13 132 39 _c +106 65 93 112 93 180 _c +93 477 _l +27 477 _l +27 547 _l +93 547 _l +93 702 _l +183 702 _l +_cl}_d +/u{634 0 85 -13 543 560 _sc +85 216 _m +85 547 _l +175 547 _l +175 219 _l +175 167 185 129 205 103 _c +225 77 255 64 296 64 _c +344 64 383 79 411 110 _c +439 141 453 183 453 237 _c +453 547 _l +543 547 _l +543 0 _l +453 0 _l +453 84 _l +431 50 405 26 377 10 _c +348 -5 315 -13 277 -13 _c +214 -13 166 6 134 45 _c +101 83 85 140 85 216 _c +_cl}_d +end readonly def + +/BuildGlyph + {exch begin + CharStrings exch + 2 copy known not{pop /.notdef}if + true 3 1 roll get exec + end}_d + +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +}_d + +FontName currentdict end definefont pop +end +%%EndProlog +mpldict begin +18 180 translate +576 432 0 0 clipbox +1.000 setlinewidth +1 setlinejoin +2 setlinecap +[] 0 setdash +1.000 setgray +gsave +0 0 m +576 0 l +576 432 l +0 432 l +0 0 l +gsave +fill +grestore +stroke +grestore +gsave +72 43.2 m +518.4 43.2 l +518.4 388.8 l +72 388.8 l +72 43.2 l +fill +grestore +2.000 setlinewidth +0.700 setgray +gsave +446.4 345.6 72 43.2 clipbox +139.19 144.289 m +178.493 174.718 l +206.38 196.307 l +228.01 213.054 l +245.683 226.736 l +260.626 238.304 l +273.57 248.325 l +284.987 257.165 l +295.2 265.071 l +304.439 272.224 l +312.873 278.754 l +320.632 284.761 l +327.816 290.322 l +334.504 295.5 l +340.76 300.343 l +346.636 304.893 l +352.177 309.183 l +357.418 313.24 l +362.39 317.089 l +367.119 320.751 l +371.629 324.242 l +375.938 327.578 l +380.063 330.772 l +stroke +grestore +3.000 setlinewidth +0.000 0.000 1.000 setrgbcolor +gsave +446.4 345.6 72 43.2 clipbox +139.19 129.6 m +178.493 181.618 l +206.38 189.991 l +228.01 212.047 l +245.683 225.845 l +260.626 235.911 l +273.57 248.85 l +284.987 257.223 l +295.2 264.065 l +304.439 271.594 l +312.873 279.279 l +320.632 285.654 l +327.816 291.102 l +334.504 295.408 l +340.76 299.677 l +346.636 306.316 l +352.177 310.472 l +357.418 313.661 l +362.39 317.111 l +367.119 320.502 l +371.629 324.036 l +375.938 328.221 l +380.063 330.772 l +stroke +grestore +0.500 setlinewidth +0 setlinecap +0.000 setgray +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +72 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +72 388.8 o +grestore +gsave +61.000000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/three glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +295.2 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +295.2 388.8 o +grestore +gsave +284.200000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/four glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 4 l +stroke +grestore +} bind def +518.4 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -4 l +stroke +grestore +} bind def +518.4 388.8 o +grestore +gsave +507.400000 24.200000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/five glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +139.19 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +139.19 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +178.493 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +178.493 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +206.38 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +206.38 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +228.01 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +228.01 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +245.683 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +245.683 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +260.626 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +260.626 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +273.57 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +273.57 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +284.987 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +284.987 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +362.39 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +362.39 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +401.693 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +401.693 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +429.58 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +429.58 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +451.21 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +451.21 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +468.883 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +468.883 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +483.826 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +483.826 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +496.77 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +496.77 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 2 l +stroke +grestore +} bind def +508.187 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +0 -2 l +stroke +grestore +} bind def +508.187 388.8 o +grestore +/DejaVuSans findfont +12.000 scalefont +setfont +292.45 12.481 m +(n) show +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 43.2 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 43.2 o +grestore +gsave +43.000000 35.700000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/hyphen glyphshow + +18.300586 8.765625 moveto +/three glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 129.6 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 129.6 o +grestore +gsave +43.000000 122.100000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/hyphen glyphshow + +18.300586 8.765625 moveto +/two glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 216 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 216 o +grestore +gsave +43.000000 208.500000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/hyphen glyphshow + +18.300586 8.875000 moveto +/one glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 302.4 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 302.4 o +grestore +gsave +46.000000 294.900000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.828125 moveto +/one glyphshow + +7.634766 1.828125 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.765625 moveto +/zero glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +4 0 l +stroke +grestore +} bind def +72 388.8 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-4 0 l +stroke +grestore +} bind def +518.4 388.8 o +grestore +gsave +46.000000 381.300000 translate +0.000000 rotate +/DejaVuSans findfont +12.0 scalefont +setfont +0.000000 1.937500 moveto +/one glyphshow + +7.634766 1.937500 moveto +/zero glyphshow + +/DejaVuSans findfont +8.4 scalefont +setfont +15.269531 8.875000 moveto +/one glyphshow + + +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 69.209 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 69.209 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 84.4233 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 84.4233 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 95.218 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 95.218 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 103.591 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 103.591 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 110.432 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 110.432 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 116.216 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 116.216 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 121.227 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 121.227 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 125.647 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 125.647 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 155.609 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 155.609 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 170.823 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 170.823 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 181.618 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 181.618 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 189.991 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 189.991 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 196.832 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 196.832 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 202.616 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 202.616 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 207.627 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 207.627 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 212.047 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 212.047 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 242.009 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 242.009 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 257.223 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 257.223 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 268.018 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 268.018 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 276.391 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 276.391 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 283.232 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 283.232 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 289.016 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 289.016 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 294.027 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 294.027 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 298.447 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 298.447 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 328.409 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 328.409 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 343.623 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 343.623 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 354.418 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 354.418 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 362.791 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 362.791 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 369.632 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 369.632 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 375.416 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 375.416 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 380.427 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 380.427 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +2 0 l +stroke +grestore +} bind def +72 384.847 o +grestore +gsave +/o { +gsave +newpath +translate +0 0 m +-2 0 l +stroke +grestore +} bind def +518.4 384.847 o +grestore +38 181.258 m +gsave +90 rotate +0 1.578 rmoveto +(run time \(s\)) show +grestore +1.000 setlinewidth +2 setlinecap +gsave +72 388.8 m +518.4 388.8 l +stroke +grestore +gsave +518.4 43.2 m +518.4 388.8 l +stroke +grestore +gsave +72 43.2 m +518.4 43.2 l +stroke +grestore +gsave +72 43.2 m +72 388.8 l +stroke +grestore +gsave +392.985 50.4 m +511.2 50.4 l +511.2 75.8575 l +392.985 75.8575 l +392.985 50.4 l +cl +gsave +1.000 setgray +fill +grestore +stroke +grestore +3.000 setlinewidth +0.000 0.000 1.000 setrgbcolor +gsave +403.065 64.4969 m +423.225 64.4969 l +stroke +grestore +0.000 setgray +/DejaVuSans findfont +14.400 scalefont +setfont +439.065 56.16 m +0 3.297 rmoveto +(sum_sum) show + +end +showpage diff --git a/book_tx/figs/listsum2.pdf b/book_tx/figs/listsum2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1b5e77de019c9a0c01bd103267e277a0cf1019ca GIT binary patch literal 9928 zcmb_C2{cvR_X))#M5a(Tk_No_Jx_+rndhNU9-eu8o_VSyUwwpx2xTl384?ne$ec7N z4GNJ&p+Y6Ua~}$|zSa7#|Fe#B@4ox&v!}DqzGq)?166e?v@{MOe(5<>SdBnKD9F>+ z1tBK~Ax#3kC=gPGOe4E_IzmVTvLnR@!U6;%NI?NX@vw&xF-r!hP$^`Zv!{nDnMQ%O ztIA?fXf#R&g+&uED2$903MYX=N$fx%4XB>>zIGHUwB4Od^K$c~xjEZHUiJ=YJ+KwfR$t+>afJ~!Ns2&i3&OFjW z-`0g}H)h%`UVylP>MLP#TukEbuy4(JwU*$7rN72wWm8iCZM z*gKPzJp%v-Fhx9(0O7EhWmCaK7iUs;b_1e9NOdC^z3mbzRK~O3Y?}){ z=O%5mhAk~rp+Ju4BLZ9Q_wSAowJq3z{ zuISFkf#3U6spx?S=IucTLp7;4aD_*?3U{GzWw>!PGwU-%RVt9qZckEPpPFfK(~;x2 z_I7G02O%$2i-vz4)EIc8&8k_Ws`kodanqeIb6vJOjPOVdo$whAiAmznx?laiO8uP6 zq3B=>^=nj)%7{#zq<`dl(q&o$^(*YF5;Qn7c^d|sI9`}@w+1SgF{Z|CKYuQVmsGVg z)TC$F?cZ3^(3#bnO+@yu3u_nHM%w(uc8|dsvHXoO(Rx7wL*fjF(Lp7ReR7FZrl=9Y z3n%V9OpV>5zh!1WEALeot##6gR?7Vvr3x368TvnX-#EJJMzqqGm{#=69d znMB>6x?HVFXzLWdLtO(fau&uGbZU*f5(~m<4vzehcglkWQKdW11 zLVoUZu+uiS)2=C<$) zbt@xpqnv#{;d{r%*JtaBKOB0_lPPAXFD*7z$(Aif>Jv)l_6T;Xnj)BSyzF07^Jddf zq1qR=s@vkNpJk^mVve=oHL|3pog%Nj%~9o0iZ7m2`6w9L5->P@g?aN3dcUA)o^W>b zEMG|UDUHq9w{WHep(o06Xr;4#NGY`FGZ zsQCtC*@kjr3z&sD;@E{_r!7s!+U>?f9E6_J&MFQVdtmFM?DPbRho0ZU`0w#|Px{(F zJ@c{h>*Wx|Q^biExVaGdmp5*{a#uRPJvBL8Bz&f)|C#N9FqxOr#ci$n8tV738)KjJ z1IonCdv*MDh%(>_~c8$z12$pWO|M!rTTdFns+NCJOjHI$!G5h z2zUoDI};Ty2uMlbyK92c-8kh$Nk37G(eX1MdP7d7+_G_y8H#+?CmQ2Ev{rs-{P|Ud zdoIFPw$`hEVnd={5;j+4SbS8o-^zKjVxp;=Zxtndb8&TJe%Y0g_dXO0{{3^|yJ9wJ ziS@E2aGLMC5W}vrl6qnN-X{#UlLt$V|LeZhLepHn=Y&X4-j{WV zZH~1Sg)!Ay{HB)r@5a`cenE6^t2Hzq&T<*ieDPwU#>?V@Rq)&~)1Fb*tagd%TS)t- z8Md>Bbi-L{6U;}|9}nuioQ+8{(Cm9})P`&N*H2>CB;@(y%cncv_3|C0Nil@tp4q^H zw)C2BLV~VOM?|zFkUi;_+9GOZB84*xxOOd&Q10M}J%w-5x*mVED#5=luA68ivF}E1 zbyLst=IeFw$^QG&YifI|;}Zkph;?x#w|B_iEA$g{^^y1xmh$9dfd0;VTGw^`dqPfa z{vH!Ol+{w!HD*uQG|=9=t^ZB>D^0Txte(c@82^beevFD~pjl7MrFOtlWKFGxT=TmZ zeQI<$l=VtE4@_Pv7ut7rcil~1HN!r#37$>J`9+mfTBCJf$!&Z)ED2o+;bP{2!F2=s zoc&8NoD+lm)RPzO+snE!?Q8;ULYu3Yn>r90tX9R?{; z)O+TQ_@$X~mP9wH`>Nej7ETj^A4@jdT+wP9HIE&8!CUoe+UZAV&F-Y$0f9m?d#UC> z;qJTl1n!E=>$Kjzd-BGxNKe?fKzhs2$w(FV^A=Kf{o-k_i|gusFwSZ8ip(*W9yU7% zXI=~Y_d*Uv-`C*;08Jud7ZWoyob3EnR)8bHY0J-)03WN(!MKH8Wr`GuL>Yx0_1aWW zlsDB&An#{oWqXFa#TOADt*vA8{*2vgaTEQ^3R}fut2Ien`36KLeJ34utXr4(#}-;I zCd0BO&FtL~y}bj&mk1lPq8$#@-#6|+oc+=Ie5(sZJ%tf7VseeAwA6-qkol_I6n5;Q z)!U;{=`B~@>Y=lqJE(6An|t=@$Le4V%I*&$!@1kvNQcGBESJuRRPi9KFG#2`Y1O;>js`|*L||r>r-RC z%jGdB_N}KDSzHsgg+tO^UWxsMN&?GO`5&Bz;PilSL zyUSIl$3I)sxlJ^oC|S*u=ou?88b{46%JlEE4NdlR44 z$!n>5MQ+)zcxpfQnSX9-vzMIq?9)(Jl4q;qkL<(VxyK)=)NwRtPugceu9SddJ?b8B z{k%GA>ao$J)%*?nz49KUe6e~mkhWHWtHb^Dc(ii0rU|dN$vJPG@q*HOG2MrAuey~z zh=0E&=BT!&__pLQHJX0@j_|9F+MH2+@qJ1q=l?1#$5(~kUO zsf<%PeZ+z**I}Cjm!=G(X!4p>&E>pr{=m!9*UbOo1&>)FB-R9FfGROTVF-pO0&cY} zPb84|Jj*|ct;{^F3}t%?sFmkid~871wQ87k-OWGDz4VRszvjl^SGZ@q_9;e)MRh9U zh}fa;19B;;rqsDn+!-B$U-HG-qgrBl+>%2Z0#UO~6YcgD!&ik1(_>bj5Z%x=u=A6} z;YaB^`r59lUj1Bxp*|lLiRfE5RFq~?T4~rQTOi9TlQ-1zwP5UfrDRL3SQLiY?JT^~pU~uGO&SxUmd0aYb_|UDqoL_a6EFa!$5BeW-`s{G|W*ZXMU_{YZ54 ziK;_tV;de$%JW|yVHf$(oMK0P5UMg{b*1%%Qr^Aqn@6TN4Nf@x^9Mb`CjoyGfid7s zc-j79(7H|q&2rrl!FO@P>cjRKW;cB2T-`f&lh@BFTQr?!3CwTq*fFfFAgjY!AzfD@ z%68dT{C!I*l(FkWW=d(v{U?1kUK_U^IK)S^dFvdr5l?%4Bu_d~`EY~y$CMD?;J3B< zf&ngqR6nNmD$O>mF4cUx7Ugp1;`A8$=ECa7qy{oiO}1nR%?PE9e%xK=@mj*gPxL;O z7xSy_>4s3c!3`Kg1(HyI6L=Wsc^u9=yq}_Eg_nc?V z-6_sJtBlM4pc?ov;crxfCZLz8MlDX8yB-2tZh@#N~MO$!EB zFs)1PfA`ciB~tww>DDgs5Q1M2b>c?qKF;R+y?c2dR3r4Vn>J`aNt#YQk=pgJ^48rU|@K5Y$N7 zA?9uCfp|Y9xXPi{yt1*M`2_fK=VYSoBqUVVC`=o&pcVLbk;<`Uw4CK5pO%T zY1E8ZDq9A*1&H(XHLg-+ddeTyZj&8dk{H)O-E7eAs3a^ls+>VQ!85$!9t-{uBOh7>7pZu_LO+h0@c#>YIK^$wiOMk(p>iL&yx zq1X1zoullU{?>eNa+ZyEyVcG==o5O(mKQ&r0nzHLrH7=)Z8$l zg(2dY3M4D#ZP2LCm9*>SM3ZUx>klacxBPEq_O|#6@sYTA_jU=G=w7t0*>q#ApRmK~ z$sD|7gy0CHq8)-5(4h z>mO4Da?U0;MjsW^-D0#i^WC<5tWq3PcA;T*jBrEPaI084*;LGh{hO8cvu+=rj*Yn8 ze1&qPTn+QI*5(GbU2A7++Hb0vY%G-H;`XY0rZSuMet`J0tE#Nw)ARwK(i#-6#rWV= zp*Y>E(?n$7w0!@_%y-6%xt4stD-ip)Dc{O83lEYkgU+iaop=nv6oqFhUDvL|Ys6ml z>b(^U&(?GG%*L$b!#O@&JAFW!Ws=M(@`t(qHpN2|u*>4EZk#s9YBbmbF$ zQ7$%mPE1{yyDU4%W9$3`29G2_xgpn>WnYsYwN(_f7ag^>^RM2l>D*l#6cDj~%f}O$ ztc9ztU!OT_d2@Q7ajWO$)1P$PTGl?6l55H1;>}8)2u)LHAZ_xLb(N9+gRFm>Qpzmf z1=XUjue*t2Q4P+sVG7&kaBh2IS-23S_1sIpI=E7n8)N*Ed@PD7gI)5N@%WmQY#V%~ zx=~E}`|K+o2Yn9@1{oKAo?5$8-_OrmzP(lO(;xWy+Y}9rTONSq^{dt~&cBJt+zgVm zoV1F2R~jzVqHe?@x@SC|qHz~tWxG1zB#9g8tT^qw@vy}jyvC=aC&(7BJWj3VjF8ka z&yYI69^a#Ey?6RC*UQT~_E~bp>vwxe@Mo`8FcI3fDQM4bRo;C?n)Mcs%&c9~udEg> z?YQkL-&Vl%=DvjMj?D%p$~S0p=Yo5_v90n%j{HHkzs|9+D{`#Z)^$wac;kb~Ywig_ zh5V>T8Bcx`kDyYOl&6(McaNi3E=^7lIvYOT&#EW>AUrCxOO)JP9b{z2IUE;NGr?=% zj553vxlcz#h1_wbr6~z>P3U!nZp09U3sJy#Q zF;4rk{|(dHaAjju^6#>sm&pQ3MXD4ZJF2r64HUr8^947g9@!lfa#SfUWHVo5vWE`> z374&O$uz1ny)-0^LcuEz{QbPLhLFl+9}2y^wPYlOG={_oaqz7OR2O+^2A3y^PfH|En%KhXQB!fsD@`9`jFN2E* zZc7&yY%I85CxyWhK-~>kXHNKwgg^+15{MVUccyQg0ii%osx&68wH+AX`V?EhJM($D92*pvV;gI)c;3A z{9ox{(K5gb&=8J*f@Hv%9RW)~knkvo2x2CNh=;J?4FYa>z$g41#>ax!Cwh-1!ubEy z5R1>T02gjBjm3rsAp(tp6(EBH4G<#9Ktv+A2Of$ClM~?vHc1Q#j{prK;0X{Oq^2@p z?;--XB+38=P~aNw;pbS;z^N<|jE8BGWJsW&hrvBv7%UM1_b?N%P;euF)eeuv1HtEM z09-IH{Thn{ijbi=z&?FKvrHvDm{(0d_~wd-!@uquYA^IgInO z!G1yaJJ4Ih`xE?1PY?c!@AgX~GQF^1L=UP9A1utraP-2r4bBk#s1acJKp6TL7l_3O z4y;c9!oeNF(D$B&_zj^KzQpi=Fbm&d&;vT~2|7AG=mSTg?^aac`SW0UxW_E;0PhAM zw$bsIgnxPp3|R36o;Cjv-aCNm>9l@rIoO457JPOw&jE=33wl_#IRi&q`FzO{$ge?5 zP91&$m%R1<0xsQ3R6KpbMglf0ZD)IUgQR~$Vg$bRSlAWjKf(DmHh@ZTK!7!eM}X+H z@B_gK4?=+h^b-af4E{kLzhDHw^>P>q1yi$Uk61o01`qq?3K$UwEWR9u zMT4{9l`tIfH#x9)!f*7jMAYvv8F-;Ap96=+|28iU2X?NNcmxp0R>EXpe_l=xj{(7F zB@71+`&YteDQ!d0IqxE^p=VNQI-e$KWH%OvvSk-K7A~vkaHV)yq zq2NG(vTPH}DJr+^jkhcH2WL&J`g_~@$G@1md(W~XnWI&ck5uj48Jl;Z`#5`k;?^$r zy4j`IUh7!9!uNfzwBX{dPcL83@RPSIeb1e16=HwwaL=l|x{Cj@Zc}va7HK?<51-km zEHcjZu9?>L-ObY7|yHf&pF!xcWtU!n9+bp~X!HmjBYX)wyE)jSZgOJ%8T1_4Lwc$%2hdA5C#*|6P6X*OsJN zvboZj{%UPyZ?{yk|KYvbmG1JsISrX7_tl@fRc$@m(6y;Y?4+j8jfjUPlyqO{T<%`- zp7n(3`~986a}SHY@z0$7A$H=@`AIV@>*(C-w=NpT-Dk_j`4Y(oYSzrW_VVSHvr`W( zJ@)L0=+-Orq!~-bdHXh;O`ZA2yI0#%aehT@$$I=$*H5SFKa_uby=#5L_O&}+xqbT- zv*eNP~PtKe;P#aZ!*(+Zd;!I(oV_S!0~e4tuM1>ggNAN{wS@?Yq7;Y<84!2P{s!=Yb>6Vo9(|HpK)<4$;9g zyt5o7OgV+KhM7dX!%c%rQ%OkCP`Ka_{`u*4+fGX?o6Tk&S*OD=+gM%{MV1p-L0~|G zu{v~H&M~?*2jb-uQJV(Lbjy*?$q_eFtlGr#4vsAb3PCxhnzmI#MAoY(Ok0909B(Ag+>$W7AJBs;fbZ z+6~L@4~@JI4^Oj&%EurfKxFjV0mee{KG2aOhN31qLeM+`f#U^+b1_b?p64ZjlQ@y# zDkP5cu_H7Aaxe|TyoLFDAErYzhnN~>JrE&KpF}}fUnN_pQB~To-5)J)Qqb_R1eGC& zGKR+_rz4U7Kd4lS@R#UGAtRni!BnXZ-6uQ75KtvPkY+k#YWW6G;w;uM$;bjsdB{_V zO9{hF$v|H@oz~R2OjykV_vnBRHf`0`a3J4am73kZ&{Wbck|yhIemch}I3Z^=n+`Op zFvhdU!SDjldqtP40+>LM(9}TxBJYA7bPKCEA%$V~dye6i#Sno?O~X108Ce~7jBt}z zBW?zaM*%!9f{_5&vjYPsK%p`E#?H~;l!a;Tr?X^+!fN={C=3qq;!G$TZ6wTtn~a<& zfJhpxEChYY3!KZz@$i#xP@3atP=iLkhen~L%0@OE7*}TOcEcVLu}MA;3+`vVZ>JJ2?G)Q;89W? zLd`yp(yc3Gkk4=M~V55%O0+E~ok9pNCs=(+&3@SpS!UpX7x>`bMTpC$BTV}Lt{?e9eN{nesFOU zwsHEpQ;+gX9@d>dnYMkkd)|rXan!`V8JpHM)|%OrK94AR`t6jQpQm5g9{)HuyV>-k zO^nT}@zohWxrJ%Jbv@>Oa6-_E@a}LWvE!-tZ`^wyOJ;p{-d=z9%<_4Ye>BIY^G`l3 z8L7`(9TCN|HN7Z`KR9K~RIl7AY^mcx?#0;pt#552;FH~-m}bAcX5BkO+T1%cwk9^y z{EhkLjd;P~ZY8q*X}e$ED75fd)c4vx_0l^(K6x`XV`_vw^Z-4cW+K>m=?Sitw;CC& zXvfg*pno}B0izYf?eJOnEFBJqVDUIC#pNo@n=nApY;cUAT!_buVSqCd*HRFNb}9o7 z#q~rYDZ}-^-613)3&W{s7z6|ahvNncp!*r9v0)T&IfT$`0Es^V$PvW20TBTEfIZ-- zhv>)&WdKmCRiryNDH7tw%}6+9oJyM6GEgAB9XKzX}ndds89ierVH(0W4vbDsgNQ3 z^pxJV9(rSXoHh(Bm4-`$eMbi1>Li>}$uOh2d~v;uROu*!ghVt8qdANxz?>>lPx&Y@ z65{gVAgpzbpa?ukC8w17Xb2SmK@1*`c03z6k#GFc>nMu)>FToVb200*f`uLqYgI)!!#1CDCt!sF0Pfd@hI zxWFMW2FJk)kX5h>PJq?07A9aFPO1nwOu>|r#BtaF&w^8Ml5jO%3RG5{0}>QmzjNr( z`&M(b)ZWge7iiYmh(2w#8bL)oiKM+MM}(yXg-se-R#;HDB<|XEL3r^TpM@g^_fNB* zpW8b-e_PbyzL`P!-Rv|Cs3S6>{G;OH)T#cKwTCK=V+VaN5;>`9KWzTW`ZY$Ci4vd~#CM%ue%|=Y@ zwr5OomU`PN!8h1v#czIo~duM zHCvnN&c$x{Zs39p`$1N-r+a_n_=C+^?AM3mp52l<&F#}my(DJX{-k+>9Dl5JAQ5hK z%B_NCr|A_;;VN0vH^DOpMOJQeIqqWr>QoQuj49^jx790|Hn?X+UfwW|$O~Dd=yiI-EWvT_OzTaZT`z6oqRU2|;DwnmT1TO0DX z#_dvOc_cR9aTYi{OBflje2CfF<8|Ew$2Jvrzy9lojP;k^Q_d3|SraMZ-QGJ5Pv1{; z*4)^jc4=hnk1U-THPm7F$GWKzvLyi* zhvAKl65Id0(9KKlA#{!Mk28yuneFb$7*O|0wIN-TK5@WfZ_^%i=BI{=3eJ_?y}YM( zOL1W7`#RGHrOc2iwe_5k<)&Myw0oYRDT%KK?>Z>xEuYr!WJ<{Xxr^{uFV}_^)n9d- z-%q{Ee{ObFQPXcLo@T9#{=?p+o3`1qTI7FIcz?ad;ihQA`L`R*dTu)F)?=xodX4VU zSi6g^uGO-~b5E~`n6lS*W<_abV*Q(oemlP}{iv>dcl&*jCgkzJEB*gi#YuXrHQCcE zYnMZlJjc@Q?b>c5XDwD09!qVwz4Eo)MbG}DvXUP7p|w2KQ2SfZ=-sAEnilDkgK`wf zj?GO9_u0SC2`SEdI;^fTG&iJX{+#^ZtUp{gwOmTnW(=~OIXmBy(7)gAY>{zb;fEiF z^Y2HV>N6nCBy9}pXr>&n{@~=3m*kBndf3j~Y`gouNdnWt=PxlMS0cQ>>;U=FA0DEA z+po69`p}!BvHM>C$y<7dS6%s2dD^S*Q=KLkNH&J8zPIe=azRxV^k{9b$Fp9GZ*b2S zTsdZYq9K)SdHPzJus574uv%!h(qj49!pIn57;!B1MTLd`qhHQtjW4n}G`>D_;cxY> zXOH$1iVD4lA98c=^=D=3(_T)QD=W98zGJVsyL{B?IRj^S9qqS&^o|2-dvHEfoL4HU z%&rKBA6XLCXGm^&es2RtuS)N>s;_SN zUURu$`L25_>#3c5ZJh7Hx!diqsn1Y!Rpx?Sf0@}_rE+pFoU!Vau=&uWdg$(dhe?w+ zH#Mh)zZl(pYnsVoBGZ+A&wScS8QX@=ubj4qqNBVxA#iHD^Ghs#nDWFk3pw1nX?8UsBX&N5&+mcrOj z>ml&^@f_h38stBMMlgsC8l498HIPB0*6PIuPo|MX4AwLlW0-@ zCgt&SwIaq+B5m1ub0*L$LE?Dk(}QhT-JoWcOr_J3+?7 zh)5)Y*(i*nEP%n%&(czufu+?u0C`45R8j3@TD`kbCwCd4fmKm3;?9QK1hus~Dnbj< zg0VOvk@93JcmkeWB;&B;a+JeD5M0J$gNG%Pab+BZfXzctPMaiMCk;Ol1rC5L4ln^& zi9x$6Pn6-LCv$8_5Hwav=&6=23lh2u5GLGu^RJ)~@W_|%4&2y!c@KaimV$OiG0PV; z%Mz50pe#0zg>u3Xu9(Xcv$-rbSIlO6z@K3PmjhBCFh+r~>R*s{!t6v!kl`Q@BnnkL zD#w$cNSxHu9^km6PzXlJlxjQ)S3^9kMZA$mD~Sh8yQ!0vzM|bQomBewmeXkHfTr=p zzJx4M0~)bF-+vh{U(v&IS-YCLL{e?c2)PW#)i|w@9yl2Rddg*D1wm>s5YL!S2iio8 z0!D^GFft_`;E+;LYFuK>H!n5SvQVq&{1K}$ZM-Mbz>?z%EKyA{B|1W-rQCtPTI{b@ zNm>?0Lb!w37rbKxfrJK*g4@f5gaLh}=j$=*sF9%ZdNPyg3fQFvcWQInGTP-!3GE7c zY&uDR#pyJ0@fFiK#^#|Mgv;d_(~HSwGXWY%!+*dCryb?e?t(Vf1nKgR3FO*7IT}b@ z0p=fs%b+V+%LDOwJPr?1Ky5HSAIw_x18Lh}ToeV<>ZdR^pAAOd&tP0$R~Q=sQ}*Y0 z9ALxGU;?x&o)85S`7KpmQ5H6<+Eh?lZ<~A7=iGk6E1b-z#aF{9u z{Dr`U;8219vpzlRKyaW|K|sd22Mk`mP_%~+Pvq|-@Dp)-IbJ-J$3X=mp|6m~;quvR gROBm={4+)j{WpT1!br;KATF0JWH>qbP4H*@AIBY@EdT%j literal 0 HcmV?d00001 diff --git a/book_tx/figs/rectangle.eps b/book_tx/figs/rectangle.eps new file mode 100644 index 0000000..26ad4a9 --- /dev/null +++ b/book_tx/figs/rectangle.eps @@ -0,0 +1,206 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: rectangle.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5a +%%CreationDate: Wed May 30 11:35:27 2012 +%%BoundingBox: 0 0 219 74 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 74 moveto 0 0 lineto 219 0 lineto 219 74 lineto closepath clip newpath +-39.1 117.7 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 3300 1350 m 4275 1350 l 4275 1950 l 3300 1950 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1425 975 m 3075 975 l 3075 1950 l 1425 1950 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +3763 1852 m 3915 1852 l 3915 1792 l 3763 1792 l 3763 1792 l 3883 1822 l 3763 1852 l cp +eoclip +n 3525 1822 m + 3900 1822 l gs col0 s gr gr + +% arrowhead +n 3763 1852 m 3883 1822 l 3763 1792 l col0 s +% Polyline +gs clippath +3763 1552 m 3915 1552 l 3915 1492 l 3763 1492 l 3763 1492 l 3883 1522 l 3763 1552 l cp +eoclip +n 3525 1522 m + 3900 1522 l gs col0 s gr gr + +% arrowhead +n 3763 1552 m 3883 1522 l 3763 1492 l col0 s +% Polyline +gs clippath +2338 1477 m 2490 1477 l 2490 1417 l 2338 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +3158 1775 m 3310 1774 l 3309 1714 l 3157 1715 l 3157 1715 l 3278 1745 l 3158 1775 l cp +eoclip +n 2100 1747 m + 3295 1745 l gs col0 s gr gr + +% arrowhead +n 3158 1775 m 3278 1745 l 3157 1715 l col0 s +% Polyline +gs clippath +2338 1177 m 2490 1177 l 2490 1117 l 2338 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +% Polyline +gs clippath +1276 1170 m 1428 1170 l 1428 1110 l 1276 1110 l 1276 1110 l 1396 1140 l 1276 1170 l cp +eoclip +n 1028 1140 m + 1413 1140 l gs col0 s gr gr + +% arrowhead +n 1276 1170 m 1396 1140 l 1276 1110 l col0 s +/Helvetica ff 183.33 scf sf +3450 1875 m +gs 1 -1 sc (y) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +3975 1575 m +gs 1 -1 sc (0.0) col0 sh gr +/Helvetica ff 183.33 scf sf +3450 1575 m +gs 1 -1 sc (x) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +3975 1875 m +gs 1 -1 sc (0.0) col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1200 m +gs 1 -1 sc (width) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1200 m +gs 1 -1 sc (100.0) col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1800 m +gs 1 -1 sc (corner) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1500 m +gs 1 -1 sc (200.0) col0 sh gr +/Helvetica ff 183.33 scf sf +3300 1275 m +gs 1 -1 sc (Point) col0 sh gr +/Helvetica ff 183.33 scf sf +1500 900 m +gs 1 -1 sc (Rectangle) col0 sh gr +/Helvetica ff 183.33 scf sf +975 1200 m +gs 1 -1 sc (box) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1500 m +gs 1 -1 sc (height) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/rectangle.fig b/book_tx/figs/rectangle.fig new file mode 100644 index 0000000..6ce860c --- /dev/null +++ b/book_tx/figs/rectangle.fig @@ -0,0 +1,45 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 3300 1350 4275 1950 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3525 1822 3900 1822 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3525 1522 3900 1522 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 3300 1350 4275 1350 4275 1950 3300 1950 3300 1350 +4 2 0 50 0 16 11 0.0000 4 150 105 3450 1875 y\001 +4 0 0 50 0 16 11 0.0000 4 135 255 3975 1575 0.0\001 +4 2 0 50 0 16 11 0.0000 4 105 90 3450 1575 x\001 +4 0 0 50 0 16 11 0.0000 4 135 255 3975 1875 0.0\001 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1747 3295 1745 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1028 1140 1413 1140 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1425 975 3075 975 3075 1950 1425 1950 1425 975 +4 2 0 50 0 16 11 0.0000 4 135 435 2025 1200 width\001 +4 0 0 50 0 16 11 0.0000 4 135 465 2550 1200 100.0\001 +4 2 0 50 0 16 11 0.0000 4 105 540 2025 1800 corner\001 +4 0 0 50 0 16 11 0.0000 4 135 465 2550 1500 200.0\001 +4 0 0 50 0 16 11 0.0000 4 135 420 3300 1275 Point\001 +4 0 0 50 0 16 11 0.0000 4 180 840 1500 900 Rectangle\001 +4 2 0 50 0 16 11 0.0000 4 135 300 975 1200 box\001 +4 2 0 50 0 16 11 0.0000 4 180 510 2025 1500 height\001 diff --git a/book_tx/figs/rectangle.pdf b/book_tx/figs/rectangle.pdf new file mode 100644 index 0000000000000000000000000000000000000000..79bc9216743079303fe10114966613bed3fc253c GIT binary patch literal 5697 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 TWth@IG?E3GU}WUz$szn7ozd@3 literal 0 HcmV?d00001 diff --git a/book_tx/figs/stack.eps b/book_tx/figs/stack.eps new file mode 100644 index 0000000..c377a9b --- /dev/null +++ b/book_tx/figs/stack.eps @@ -0,0 +1,219 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: stack.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5e +%%CreationDate: Mon Jul 27 11:38:05 2015 +%%BoundingBox: 0 0 284 141 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 141 moveto 0 0 lineto 284 0 lineto 284 141 lineto closepath clip newpath +-14.6 198.7 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 1424 2925 m 4950 2925 l 4950 3300 l 1424 3300 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1425 1800 m 4950 1800 l 4950 2775 l 1425 2775 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1425 975 m 4950 975 l 4950 1650 l 1425 1650 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2338 2302 m 2490 2302 l 2490 2242 l 2338 2242 l 2338 2242 l 2458 2272 l 2338 2302 l cp +eoclip +n 2100 2272 m + 2475 2272 l gs col0 s gr gr + +% arrowhead +n 2338 2302 m 2458 2272 l 2338 2242 l col0 s +% Polyline +gs clippath +2338 2602 m 2490 2602 l 2490 2542 l 2338 2542 l 2338 2542 l 2458 2572 l 2338 2602 l cp +eoclip +n 2100 2572 m + 2475 2572 l gs col0 s gr gr + +% arrowhead +n 2338 2602 m 2458 2572 l 2338 2542 l col0 s +% Polyline +gs clippath +2338 2002 m 2490 2002 l 2490 1942 l 2338 1942 l 2338 1942 l 2458 1972 l 2338 2002 l cp +eoclip +n 2100 1972 m + 2475 1972 l gs col0 s gr gr + +% arrowhead +n 2338 2002 m 2458 1972 l 2338 1942 l col0 s +% Polyline +gs clippath +2338 1477 m 2490 1477 l 2490 1417 l 2338 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +2338 1177 m 2490 1177 l 2490 1117 l 2338 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +% Polyline +gs clippath +2330 3127 m 2482 3127 l 2482 3067 l 2330 3067 l 2330 3067 l 2450 3097 l 2330 3127 l cp +eoclip +n 2092 3097 m + 2467 3097 l gs col0 s gr gr + +% arrowhead +n 2330 3127 m 2450 3097 l 2330 3067 l col0 s +/Helvetica ff 183.33 scf sf +2025 1200 m +gs 1 -1 sc (line1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 1500 m +gs 1 -1 sc (line2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1500 m +gs 1 -1 sc ('tiddle bang.') col0 sh gr +/Helvetica ff 183.33 scf sf +2025 2025 m +gs 1 -1 sc (part1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 2325 m +gs 1 -1 sc (part2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2025 2625 m +gs 1 -1 sc (cat) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2017 3150 m +gs 1 -1 sc (bruce) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2550 1200 m +gs 1 -1 sc ('Bing tiddle ') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 2025 m +gs 1 -1 sc ('Bing tiddle ') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 2325 m +gs 1 -1 sc ('tiddle bang.') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 2625 m +gs 1 -1 sc ('Bing tiddle tiddle bang.') col0 sh gr +/Helvetica ff 183.33 scf sf +2550 3150 m +gs 1 -1 sc ('Bing tiddle tiddle bang.') col0 sh gr +/Helvetica ff 183.33 scf sf +1275 2325 m +gs 1 -1 sc (cat_twice) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1275 3150 m +gs 1 -1 sc (print_twice) dup sw pop neg 0 rm col0 sh gr +% __main__ +/Helvetica ff 183.33 scf sf +1275 1350 m +gs 1 -1 sc (__main__) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/stack.fig b/book_tx/figs/stack.fig new file mode 100644 index 0000000..a8e4b9e --- /dev/null +++ b/book_tx/figs/stack.fig @@ -0,0 +1,51 @@ +#FIG 3.2 Produced by xfig version 3.2.5c +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 2100 1897 2475 2647 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2272 2475 2272 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2572 2475 2572 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1972 2475 1972 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2092 3097 2467 3097 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1424 2925 4950 2925 4950 3300 1424 3300 1424 2925 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1425 1800 4950 1800 4950 2775 1425 2775 1425 1800 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1425 975 4950 975 4950 1650 1425 1650 1425 975 +4 2 0 50 0 16 11 0.0000 4 135 450 2025 1200 line1\001 +4 2 0 50 0 16 11 0.0000 4 135 450 2025 1500 line2\001 +4 0 0 50 0 16 11 0.0000 4 165 1260 2550 1500 'tiddle bang.'\001 +4 2 0 50 0 16 11 0.0000 4 165 450 2025 2025 part1\001 +4 2 0 50 0 16 11 0.0000 4 165 450 2025 2325 part2\001 +4 2 0 50 0 16 11 0.0000 4 120 270 2025 2625 cat\001 +4 2 0 50 0 16 11 0.0000 4 135 450 2017 3150 bruce\001 +4 0 0 50 0 16 11 0.0000 4 165 1260 2550 1200 'Bing tiddle '\001 +4 0 0 50 0 16 11 0.0000 4 165 1260 2550 2025 'Bing tiddle '\001 +4 0 0 50 0 16 11 0.0000 4 165 1260 2550 2325 'tiddle bang.'\001 +4 0 0 50 0 16 11 0.0000 4 165 2340 2550 2625 'Bing tiddle tiddle bang.'\001 +4 0 0 50 0 16 11 0.0000 4 165 2340 2550 3150 'Bing tiddle tiddle bang.'\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1275 2325 cat_twice\001 +4 2 0 50 0 16 11 0.0000 4 150 990 1275 3150 print_twice\001 +# __main__ +4 2 0 50 0 16 11 0.0000 4 135 720 1275 1350 __main__\001 diff --git a/book_tx/figs/stack.pdf b/book_tx/figs/stack.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f402410f8c7bb2713d431f1323111e58bdcc145d GIT binary patch literal 5805 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/stack2.eps b/book_tx/figs/stack2.eps new file mode 100644 index 0000000..0e82547 --- /dev/null +++ b/book_tx/figs/stack2.eps @@ -0,0 +1,200 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: stack2.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5d +%%CreationDate: Mon Oct 19 10:20:09 2015 +%%BoundingBox: 0 0 139 150 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 150 moveto 0 0 lineto 139 0 lineto 139 150 lineto closepath clip newpath +-42.7 176.2 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 1800 450 m 3000 450 l 3000 825 l 1800 825 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 975 m 3000 975 l 3000 1350 l 1800 1350 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 1500 m 3000 1500 l 3000 1875 l 1800 1875 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 2025 m 3000 2025 l 3000 2400 l 1800 2400 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 2550 m 3000 2550 l 3000 2925 l 1800 2925 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2413 1177 m 2565 1177 l 2565 1117 l 2413 1117 l 2413 1117 l 2533 1147 l 2413 1177 l cp +eoclip +n 2175 1147 m + 2550 1147 l gs col0 s gr gr + +% arrowhead +n 2413 1177 m 2533 1147 l 2413 1117 l col0 s +% Polyline +gs clippath +2413 1702 m 2565 1702 l 2565 1642 l 2413 1642 l 2413 1642 l 2533 1672 l 2413 1702 l cp +eoclip +n 2175 1672 m + 2550 1672 l gs col0 s gr gr + +% arrowhead +n 2413 1702 m 2533 1672 l 2413 1642 l col0 s +% Polyline +gs clippath +2413 2227 m 2565 2227 l 2565 2167 l 2413 2167 l 2413 2167 l 2533 2197 l 2413 2227 l cp +eoclip +n 2175 2197 m + 2550 2197 l gs col0 s gr gr + +% arrowhead +n 2413 2227 m 2533 2197 l 2413 2167 l col0 s +% Polyline +gs clippath +2413 2752 m 2565 2752 l 2565 2692 l 2413 2692 l 2413 2692 l 2533 2722 l 2413 2752 l cp +eoclip +n 2175 2722 m + 2550 2722 l gs col0 s gr gr + +% arrowhead +n 2413 2752 m 2533 2722 l 2413 2692 l col0 s +/Helvetica ff 183.33 scf sf +1650 675 m +gs 1 -1 sc (__main__) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 1200 m +gs 1 -1 sc (countdown) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 1725 m +gs 1 -1 sc (countdown) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 2250 m +gs 1 -1 sc (countdown) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 2775 m +gs 1 -1 sc (countdown) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2100 1200 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 1200 m +gs 1 -1 sc (3) col0 sh gr +/Helvetica ff 183.33 scf sf +2100 1725 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 1725 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +2100 2250 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 2250 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +2100 2775 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 2775 m +gs 1 -1 sc (0) col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/stack2.fig b/book_tx/figs/stack2.fig new file mode 100644 index 0000000..4826deb --- /dev/null +++ b/book_tx/figs/stack2.fig @@ -0,0 +1,44 @@ +#FIG 3.2 Produced by xfig version 3.2.5c +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 450 3000 450 3000 825 1800 825 1800 450 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 975 3000 975 3000 1350 1800 1350 1800 975 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 1500 3000 1500 3000 1875 1800 1875 1800 1500 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 2025 3000 2025 3000 2400 1800 2400 1800 2025 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 2550 3000 2550 3000 2925 1800 2925 1800 2550 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 1147 2550 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 1672 2550 1672 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 2197 2550 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 2722 2550 2722 +4 2 0 50 0 16 11 0.0000 4 135 720 1650 675 __main__\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 1200 countdown\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 1725 countdown\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 2250 countdown\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 2775 countdown\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 1200 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 1200 3\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 1725 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 1725 2\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 2250 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 2250 1\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 2775 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 2775 0\001 diff --git a/book_tx/figs/stack2.pdf b/book_tx/figs/stack2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8625e86426397f75fcb3f5b1ffe4259b2f44c7f1 GIT binary patch literal 5056 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 literal 0 HcmV?d00001 diff --git a/book_tx/figs/stack3.eps b/book_tx/figs/stack3.eps new file mode 100644 index 0000000..b894ef6 --- /dev/null +++ b/book_tx/figs/stack3.eps @@ -0,0 +1,342 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: stack3.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5e +%%CreationDate: Mon Jul 27 11:39:42 2015 +%%BoundingBox: 0 0 319 150 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 150 moveto 0 0 lineto 319 0 lineto 319 150 lineto closepath clip newpath +-48.2 176.2 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 1800 975 m 5700 975 l 5700 1350 l 1800 1350 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 1500 m 5700 1500 l 5700 1875 l 1800 1875 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 2025 m 5700 2025 l 5700 2400 l 1800 2400 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 2550 m 5700 2550 l 5700 2925 l 1800 2925 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 450 m 5700 450 l 5700 825 l 1800 825 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2413 1177 m 2565 1177 l 2565 1117 l 2413 1117 l 2413 1117 l 2533 1147 l 2413 1177 l cp +eoclip +n 2175 1147 m + 2550 1147 l gs col0 s gr gr + +% arrowhead +n 2413 1177 m 2533 1147 l 2413 1117 l col0 s +% Polyline +gs clippath +3913 1177 m 4065 1177 l 4065 1117 l 3913 1117 l 3913 1117 l 4033 1147 l 3913 1177 l cp +eoclip +n 3675 1147 m + 4050 1147 l gs col0 s gr gr + +% arrowhead +n 3913 1177 m 4033 1147 l 3913 1117 l col0 s +% Polyline +gs clippath +3913 1702 m 4065 1702 l 4065 1642 l 3913 1642 l 3913 1642 l 4033 1672 l 3913 1702 l cp +eoclip +n 3675 1672 m + 4050 1672 l gs col0 s gr gr + +% arrowhead +n 3913 1702 m 4033 1672 l 3913 1642 l col0 s +% Polyline +gs clippath +3913 2227 m 4065 2227 l 4065 2167 l 3913 2167 l 3913 2167 l 4033 2197 l 3913 2227 l cp +eoclip +n 3675 2197 m + 4050 2197 l gs col0 s gr gr + +% arrowhead +n 3913 2227 m 4033 2197 l 3913 2167 l col0 s +% Arc +gs clippath +5839 2262 m 5694 2216 l 5676 2274 l 5821 2319 l 5821 2319 l 5716 2255 l 5839 2262 l cp +eoclip +n 5700.0 2475.0 225.0 90.0000 -90.0000 arcn +gs col0 s gr + gr + +% arrowhead +n 5839 2262 m 5716 2255 l 5821 2319 l col0 s +% Arc +gs clippath +5839 1737 m 5694 1691 l 5676 1749 l 5821 1794 l 5821 1794 l 5716 1730 l 5839 1737 l cp +eoclip +n 5700.0 1950.0 225.0 90.0000 -90.0000 arcn +gs col0 s gr + gr + +% arrowhead +n 5839 1737 m 5716 1730 l 5821 1794 l col0 s +% Arc +gs clippath +5839 687 m 5694 641 l 5676 699 l 5821 744 l 5821 744 l 5716 680 l 5839 687 l cp +eoclip +n 5700.0 900.0 225.0 90.0000 -90.0000 arcn +gs col0 s gr + gr + +% arrowhead +n 5839 687 m 5716 680 l 5821 744 l col0 s +% Arc +gs clippath +5839 1212 m 5694 1166 l 5676 1224 l 5821 1269 l 5821 1269 l 5716 1205 l 5839 1212 l cp +eoclip +n 5700.0 1425.0 225.0 90.0000 -90.0000 arcn +gs col0 s gr + gr + +% arrowhead +n 5839 1212 m 5716 1205 l 5821 1269 l col0 s +% Polyline +gs clippath +2413 1702 m 2565 1702 l 2565 1642 l 2413 1642 l 2413 1642 l 2533 1672 l 2413 1702 l cp +eoclip +n 2175 1672 m + 2550 1672 l gs col0 s gr gr + +% arrowhead +n 2413 1702 m 2533 1672 l 2413 1642 l col0 s +% Polyline +gs clippath +2413 2227 m 2565 2227 l 2565 2167 l 2413 2167 l 2413 2167 l 2533 2197 l 2413 2227 l cp +eoclip +n 2175 2197 m + 2550 2197 l gs col0 s gr gr + +% arrowhead +n 2413 2227 m 2533 2197 l 2413 2167 l col0 s +% Polyline +gs clippath +2413 2752 m 2565 2752 l 2565 2692 l 2413 2692 l 2413 2692 l 2533 2722 l 2413 2752 l cp +eoclip +n 2175 2722 m + 2550 2722 l gs col0 s gr gr + +% arrowhead +n 2413 2752 m 2533 2722 l 2413 2692 l col0 s +% Polyline +gs clippath +5263 2227 m 5415 2227 l 5415 2167 l 5263 2167 l 5263 2167 l 5383 2197 l 5263 2227 l cp +eoclip +n 5025 2197 m + 5400 2197 l gs col0 s gr gr + +% arrowhead +n 5263 2227 m 5383 2197 l 5263 2167 l col0 s +% Polyline +gs clippath +5263 1702 m 5415 1702 l 5415 1642 l 5263 1642 l 5263 1642 l 5383 1672 l 5263 1702 l cp +eoclip +n 5025 1672 m + 5400 1672 l gs col0 s gr gr + +% arrowhead +n 5263 1702 m 5383 1672 l 5263 1642 l col0 s +% Polyline +gs clippath +5263 1177 m 5415 1177 l 5415 1117 l 5263 1117 l 5263 1117 l 5383 1147 l 5263 1177 l cp +eoclip +n 5025 1147 m + 5400 1147 l gs col0 s gr gr + +% arrowhead +n 5263 1177 m 5383 1147 l 5263 1117 l col0 s +/Helvetica ff 183.33 scf sf +2100 1200 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 1200 m +gs 1 -1 sc (3) col0 sh gr +/Helvetica ff 183.33 scf sf +3600 1200 m +gs 1 -1 sc (recurse) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4125 1200 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +3600 1725 m +gs 1 -1 sc (recurse) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4125 1725 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +3600 2250 m +gs 1 -1 sc (recurse) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4125 2250 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +1650 675 m +gs 1 -1 sc (__main__) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 1200 m +gs 1 -1 sc (factorial) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2100 1725 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 1725 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +2100 2250 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 2250 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +2100 2775 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2625 2775 m +gs 1 -1 sc (0) col0 sh gr +/Helvetica ff 183.33 scf sf +1650 1725 m +gs 1 -1 sc (factorial) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 2250 m +gs 1 -1 sc (factorial) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +1650 2775 m +gs 1 -1 sc (factorial) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +6000 2550 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +6000 2025 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +6000 1500 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +6000 975 m +gs 1 -1 sc (6) col0 sh gr +/Helvetica ff 183.33 scf sf +5475 2250 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 183.33 scf sf +4950 2250 m +gs 1 -1 sc (result) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +5475 1725 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 183.33 scf sf +5475 1200 m +gs 1 -1 sc (6) col0 sh gr +/Helvetica ff 183.33 scf sf +4950 1200 m +gs 1 -1 sc (result) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4950 1725 m +gs 1 -1 sc (result) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/stack3.fig b/book_tx/figs/stack3.fig new file mode 100644 index 0000000..623fa28 --- /dev/null +++ b/book_tx/figs/stack3.fig @@ -0,0 +1,96 @@ +#FIG 3.2 Produced by xfig version 3.2.5c +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 0 -1 0.000 0 1 1 0 5700.000 2475.000 5700 2700 5925 2475 5700 2250 + 0 0 1.00 60.00 120.00 +5 1 0 1 0 7 50 0 -1 0.000 0 1 1 0 5700.000 1950.000 5700 2175 5925 1950 5700 1725 + 0 0 1.00 60.00 120.00 +5 1 0 1 0 7 50 0 -1 0.000 0 1 1 0 5700.000 900.000 5700 1125 5925 900 5700 675 + 0 0 1.00 60.00 120.00 +5 1 0 1 0 7 50 0 -1 0.000 0 1 1 0 5700.000 1425.000 5700 1650 5925 1425 5700 1200 + 0 0 1.00 60.00 120.00 +6 1950 1050 2775 1200 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 1147 2550 1147 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 1200 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 1200 3\001 +-6 +6 3075 1050 4275 2250 +6 3075 1050 4275 1200 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3675 1147 4050 1147 +4 2 0 50 0 16 11 0.0000 4 90 630 3600 1200 recurse\001 +4 0 0 50 0 16 11 0.0000 4 135 90 4125 1200 2\001 +-6 +6 3075 1575 4275 1725 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3675 1672 4050 1672 +4 2 0 50 0 16 11 0.0000 4 90 630 3600 1725 recurse\001 +4 0 0 50 0 16 11 0.0000 4 135 90 4125 1725 1\001 +-6 +6 3075 2100 4275 2250 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3675 2197 4050 2197 +4 2 0 50 0 16 11 0.0000 4 90 630 3600 2250 recurse\001 +4 0 0 50 0 16 11 0.0000 4 135 90 4125 2250 1\001 +-6 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 1672 2550 1672 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 2197 2550 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 2722 2550 2722 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 975 5700 975 5700 1350 1800 1350 1800 975 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 1500 5700 1500 5700 1875 1800 1875 1800 1500 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 2025 5700 2025 5700 2400 1800 2400 1800 2025 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 2550 5700 2550 5700 2925 1800 2925 1800 2550 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 450 5700 450 5700 825 1800 825 1800 450 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5025 2197 5400 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5025 1672 5400 1672 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5025 1147 5400 1147 +4 2 0 50 0 16 11 0.0000 4 135 720 1650 675 __main__\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 1200 factorial\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 1725 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 1725 2\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 2250 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 2250 1\001 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 2775 n\001 +4 0 0 50 0 16 11 0.0000 4 135 90 2625 2775 0\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 1725 factorial\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 2250 factorial\001 +4 2 0 50 0 16 11 0.0000 4 135 810 1650 2775 factorial\001 +4 0 0 50 0 16 11 0.0000 4 135 90 6000 2550 1\001 +4 0 0 50 0 16 11 0.0000 4 135 90 6000 2025 1\001 +4 0 0 50 0 16 11 0.0000 4 135 90 6000 1500 2\001 +4 0 0 50 0 16 11 0.0000 4 135 90 6000 975 6\001 +4 0 0 50 0 16 11 0.0000 4 135 90 5475 2250 1\001 +4 2 0 50 0 16 11 0.0000 4 135 540 4950 2250 result\001 +4 0 0 50 0 16 11 0.0000 4 135 90 5475 1725 2\001 +4 0 0 50 0 16 11 0.0000 4 135 90 5475 1200 6\001 +4 2 0 50 0 16 11 0.0000 4 135 540 4950 1200 result\001 +4 2 0 50 0 16 11 0.0000 4 135 540 4950 1725 result\001 diff --git a/book_tx/figs/stack3.pdf b/book_tx/figs/stack3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..456bd930e6e203cedacec06c4382563b987cb6a9 GIT binary patch literal 5999 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 Wz_udEsDZ#`0u`sJxzceJ?tcI|1ph4n literal 0 HcmV?d00001 diff --git a/book_tx/figs/stack4.eps b/book_tx/figs/stack4.eps new file mode 100644 index 0000000..430a3d4 --- /dev/null +++ b/book_tx/figs/stack4.eps @@ -0,0 +1,173 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: stack4.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Fri Dec 14 14:02:13 2001 +%%For: downey@rocky.wellesley.edu (Allen B. Downey) +%%BoundingBox: 0 0 222 101 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 101 moveto 0 0 lineto 222 0 lineto 222 101 lineto closepath clip newpath +-40.0 145.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 1800 1725 m 4350 1725 l 4350 2400 l 1800 2400 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 1800 750 m 4350 750 l 4350 1575 l 1800 1575 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline + [15 45] 45 sd +n 2175 1125 m + 2550 1125 l gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 2175 1125 m + 2550 900 l gs col0 s gr [] 0 sd +% Polyline +gs clippath +2547 1383 m 2578 1331 l 2448 1253 l 2536 1341 l 2417 1304 l cp +eoclip +n 2175 1125 m + 2550 1350 l gs col0 s gr gr + +% arrowhead +n 2417 1304 m 2536 1341 l 2448 1253 l col0 s +/Helvetica ff 165.00 scf sf +2100 1200 m +gs 1 -1 sc (i) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2625 1200 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 165.00 scf sf +2625 975 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +2625 1425 m +gs 1 -1 sc (3) col0 sh gr +% Polyline +gs clippath +2565 2130 m 2565 2070 l 2413 2070 l 2533 2100 l 2413 2130 l cp +eoclip +n 2175 2100 m + 2550 2100 l gs col0 s gr gr + +% arrowhead +n 2413 2130 m 2533 2100 l 2413 2070 l col0 s +% Polyline + [15 45] 45 sd +n 3300 2100 m + 3675 1875 l gs col0 s gr [] 0 sd +% Polyline +gs clippath +3690 2130 m 3690 2070 l 3538 2070 l 3658 2100 l 3538 2130 l cp +eoclip +n 3300 2100 m + 3675 2100 l gs col0 s gr gr + +% arrowhead +n 3538 2130 m 3658 2100 l 3538 2070 l col0 s +/Helvetica ff 165.00 scf sf +2100 2175 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2625 2175 m +gs 1 -1 sc (3) col0 sh gr +/Helvetica ff 165.00 scf sf +3225 2175 m +gs 1 -1 sc (i) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +3750 2175 m +gs 1 -1 sc (2) col0 sh gr +/Helvetica ff 165.00 scf sf +3750 1950 m +gs 1 -1 sc (1) col0 sh gr +/Helvetica ff 165.00 scf sf +675 975 m +gs 1 -1 sc (printMultTable) col0 sh gr +/Helvetica ff 165.00 scf sf +750 1950 m +gs 1 -1 sc (printMultiples) col0 sh gr +$F2psEnd +rs diff --git a/book_tx/figs/stack4.fig b/book_tx/figs/stack4.fig new file mode 100644 index 0000000..d79f4c7 --- /dev/null +++ b/book_tx/figs/stack4.fig @@ -0,0 +1,41 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 2025 825 2775 1425 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 2175 1125 2550 1125 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 2175 1125 2550 900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 1125 2550 1350 +4 2 0 50 0 16 11 0.0000 4 120 30 2100 1200 i\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2625 1200 2\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2625 975 1\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2625 1425 3\001 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2175 2100 2550 2100 +2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 + 3300 2100 3675 1875 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3300 2100 3675 2100 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 1725 4350 1725 4350 2400 1800 2400 1800 1725 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1800 750 4350 750 4350 1575 1800 1575 1800 750 +4 2 0 50 0 16 11 0.0000 4 90 90 2100 2175 n\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2625 2175 3\001 +4 2 0 50 0 16 11 0.0000 4 120 30 3225 2175 i\001 +4 0 0 50 0 16 11 0.0000 4 120 90 3750 2175 2\001 +4 0 0 50 0 16 11 0.0000 4 120 90 3750 1950 1\001 +4 0 0 50 0 16 11 0.0000 4 150 975 675 975 printMultTable\001 +4 0 0 50 0 16 11 0.0000 4 150 930 750 1950 printMultiples\001 diff --git a/book_tx/figs/stack4.pdf b/book_tx/figs/stack4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0797d083519d7bfbaa3f9844e75804e6d2dc0e54 GIT binary patch literal 5098 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 CuQbH~ literal 0 HcmV?d00001 diff --git a/book_tx/figs/stack5.eps b/book_tx/figs/stack5.eps new file mode 100644 index 0000000..92a8a36 --- /dev/null +++ b/book_tx/figs/stack5.eps @@ -0,0 +1,197 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Title: stack5.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5e +%%CreationDate: Mon Jul 27 11:40:36 2015 +%%BoundingBox: 0 0 238 74 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 74 moveto 0 0 lineto 238 0 lineto 238 74 lineto closepath clip newpath +-96.1 162.7 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +0 slj +0 slc +7.500 slw +n 2700 1500 m 3675 1500 l 3675 1950 l 2700 1950 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 2700 2100 m 3675 2100 l 3675 2550 l 2700 2550 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +n 4125 1725 m 5550 1725 l 5550 2700 l 4125 2700 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +4813 2227 m 4965 2227 l 4965 2167 l 4813 2167 l 4813 2167 l 4933 2197 l 4813 2227 l cp +eoclip +n 4575 2197 m + 4950 2197 l gs col0 s gr gr + +% arrowhead +n 4813 2227 m 4933 2197 l 4813 2167 l col0 s +% Polyline +gs clippath +4813 2527 m 4965 2527 l 4965 2467 l 4813 2467 l 4813 2467 l 4933 2497 l 4813 2527 l cp +eoclip +n 4575 2497 m + 4950 2497 l gs col0 s gr gr + +% arrowhead +n 4813 2527 m 4933 2497 l 4813 2467 l col0 s +% Polyline +gs clippath +4813 1927 m 4965 1927 l 4965 1867 l 4813 1867 l 4813 1867 l 4933 1897 l 4813 1927 l cp +eoclip +n 4575 1897 m + 4950 1897 l gs col0 s gr gr + +% arrowhead +n 4813 1927 m 4933 1897 l 4813 1867 l col0 s +% Polyline +gs clippath +3953 2051 m 4079 1966 l 4045 1916 l 3919 2001 l 3919 2001 l 4036 1959 l 3953 2051 l cp +eoclip +n 3507 2318 m + 4050 1950 l gs col0 s gr gr + +% arrowhead +n 3953 2051 m 4036 1959 l 3919 2001 l col0 s +% Polyline +gs clippath +3910 1867 m 4056 1907 l 4072 1850 l 3926 1809 l 3926 1809 l 4034 1871 l 3910 1867 l cp +eoclip +n 3510 1725 m + 4050 1875 l gs col0 s gr gr + +% arrowhead +n 3910 1867 m 4034 1871 l 3926 1809 l col0 s +/Helvetica ff 183.33 scf sf +4500 1950 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4500 2250 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +4500 2550 m +gs 1 -1 sc (2) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +5025 1950 m +gs 1 -1 sc ('a') col0 sh gr +/Helvetica ff 183.33 scf sf +5025 2250 m +gs 1 -1 sc ('b') col0 sh gr +/Helvetica ff 183.33 scf sf +5025 2550 m +gs 1 -1 sc ('c') col0 sh gr +/Helvetica ff 183.33 scf sf +4125 1650 m +gs 1 -1 sc (list) col0 sh gr +/Helvetica ff 183.33 scf sf +3450 2377 m +gs 1 -1 sc (t) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +3465 1770 m +gs 1 -1 sc (letters) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2632 2377 m +gs 1 -1 sc (delete_head) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 183.33 scf sf +2617 1770 m +gs 1 -1 sc (__main__) dup sw pop neg 0 rm col0 sh gr +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/stack5.fig b/book_tx/figs/stack5.fig new file mode 100644 index 0000000..6db872a --- /dev/null +++ b/book_tx/figs/stack5.fig @@ -0,0 +1,41 @@ +#FIG 3.2 Produced by xfig version 3.2.5c +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4575 2197 4950 2197 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4575 2497 4950 2497 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4575 1897 4950 1897 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2700 1500 3675 1500 3675 1950 2700 1950 2700 1500 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 2700 2100 3675 2100 3675 2550 2700 2550 2700 2100 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3507 2318 4050 1950 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3510 1725 4050 1875 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 4125 1725 5550 1725 5550 2700 4125 2700 4125 1725 +4 2 0 50 0 16 11 0.0000 4 135 90 4500 1950 0\001 +4 2 0 50 0 16 11 0.0000 4 135 90 4500 2250 1\001 +4 2 0 50 0 16 11 0.0000 4 135 90 4500 2550 2\001 +4 0 0 50 0 16 11 0.0000 4 135 270 5025 1950 'a'\001 +4 0 0 50 0 16 11 0.0000 4 135 270 5025 2250 'b'\001 +4 0 0 50 0 16 11 0.0000 4 135 270 5025 2550 'c'\001 +4 0 0 50 0 16 11 0.0000 4 135 360 4125 1650 list\001 +4 2 0 50 0 16 11 0.0000 4 120 90 3450 2377 t\001 +4 2 0 50 0 16 11 0.0000 4 135 630 3465 1770 letters\001 +4 2 0 50 0 16 11 0.0000 4 150 990 2632 2377 delete_head\001 +4 2 0 50 0 16 11 0.0000 4 135 720 2617 1770 __main__\001 diff --git a/book_tx/figs/stack5.pdf b/book_tx/figs/stack5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b2b781b5db201cbb896fa08b5cab28e29345110b GIT binary patch literal 5449 zcmb_A3p|wB+oe!bsZA+cO)pj>%)Il?eI_$U&tf1$~}>^;;{o~UF0PjW7k)<#BuQp2RaPum|9)_ zw7J8YOdES)NLGWHkbgaEQs6(mZu1b?n~DX2*7C##--A@*8+? zd+t8_o1s&fYg4i&v{Od78A*@JMqMI*T6{K6B&ZoeZrKu(AJyO2UtL@{^MmjCz!&zh z&ac89rp#D4=3;d!agM|0@)~~L`q02(;bYY7qE}1LANy<|Ng2PdY=|_PwIO%(C2`ZP z>T{GFlY;fdA+`HHu9n;@+!mQ>J}L1B$8NuI;NyYRF;5RjoXtV2>oexy|79}Rgf0-HC-wpsYEW1tjzD1{DwT^})$vdW6`*N!4#Z}J5&%w%sxXL-2PXmc zLv?DsR)Xq4*ow4ji9d>kz#y<8H~@{u0J%pzHq9Rcp$j3n7{KDG2J8r8n1D!z-M}13 z)IoR#_z?i8ODlYd&Wr%kfLf42FC7HWluLC`2m#mHj}Qt033^;)FIHT7S2A^Sx`{Ed zLLJd9qDy-riixEF10kKVde&z570|N{0_-aiLWn@nrKDk3T}%0~2{@l$j~K%?yRjSs zr!N+tb|GEGIuthy?B+5QaS;Y{7%;$`a;*+? zixg`iIv4g9ca0H*1qaEcSfnllqS0`3^!Xz&nJlRLzYnH29pQh(bW;5b9>@n2-K#LE zJ!4!h4yVy*21)oYhfX)Zs0OKYd#8DX;^Hj4(aY1~l!NRQBgJt0&!ivYXmBzR&049E$wW;%*% z&^g5y!f`k|0rmo+ESI>bA`~b@CBXg|stg1P#UQ{!xlRYnWNCS+twMY49M-}*7=y7mHLO=jQLRp*)}n9%s#Q-m>=oQf zC>=s@_w^2UeBNcH&U>r(wFOk|?KijXdk$eTr~<*48*O&LV3B#y*ax;&rL)&;R+>z( zT{~^oD2FIZ_jPksk^TCwTE5K0+-md6L0+7JCg+A^?55E~*&|)dZX66YEi*1W(Bf+E z=a*_TYNll^?Zg8a(dVOUbVx*O?0e^v9UbpG>OV|h9_{wi4_xx}UubsNWhE`=_siF< z?v}7}&8Kbp zL7G!GnRXt1?suod$-#-wxAnTKwjSy1kw}|k6LWr|$trtcPGBS!HgbM?p5NqRug$aX z)}{_!>rDx|n3o^9V@9(5U{QAJTxFWek(xUmN2;zV&(S_n-l~ zn_KMXw1xOAhX$toIrL{o`ObOCnE?my2jQI;)V{z=7lX zZ>um5wmM~9Wk!4MO4{nW7zeh99dUEyw!5#(1|BZdYz;(-^y`*{IhMR&7{L4&vuA@J$rPHSw!}^{kchH zQ3FI*lh)sRm~!9%M>*p6pw~Hd_3nosO>lYt^LLelD>c=p_YA(db*pj2*|01l=bPy! z!lQ?a8L@(r-FJf>AC-HCvP<{+znNUOzU-~9&uKsJ+Y>1BHd?e9FX2yq=rLd9oSkhi zmM^WA(B;2*l_C1u2QQyf2?1VX`w6#%^Uk5 z%X5I*`XTRN*e>hKm9GQGoU0sAR<(M}IPYbz-k0;p z1-d3J5twzf$AsuVhJL5BZ3|X8HG^X5yz_Zz-`SZc|PnPXpeJCbm^bOO9)0Pu{EPu3=eQV8~ z6as0bscLk3g<|?iE9INtrlb{*k4YZ>2Qm3{Yvsdx#J^NKYF2D}S}?oO^x5y@7BzT3 zt5GG~)^jgqd4FP6%%v+{bv!GvNh!Ao&%Cs6Y* zFt+)wTOJmZm5+UTy`ulrQ;SDD3mdr3Z1kL+{cOg)9eOCoy0onzj1%gwd)+b3L9bt= z&2eXP(dP@Mv=_?~_Z8QFw43!ICVkMZbIZLhEJtLnKTc|mUp8P{ga7e_s+x+U2TF+V zOyfCb8!S%QA2Bx#jgfD<6V+7Y)R8g0sQN;(Wk%KWAvrZ+e)V-H>sxO>T?c)a(0;yb zsS8oToI`rCT9`-qOe;_1B)>??oirjxQ#bL4Chyd$imdCg>}Xmt*(P7Ua==S+!I=dk z4&5bg8c=(zIi$HX^WteIyQ-xVJ4A);jfrj0)J3`rhsYkuc2?pYS3bUV zJ`*|iN2Nj$<-Ij{6wFbVuT`vz{V*cUfa*3AgZ8t;P1cjbWQx#y`xrl|6hi zrR?#9r)gJ8-vxa(vUq9n8o$r`)~ts5toQZXUAgt#DZxVTFBb}(1*(EB2~N)O8nGlA#h`FB zLaySInoCcSAi0!J3StVWLX8_5DW9I8Mg0?e0wf9160VfwEFd^Ji$SrBlHY|@+Gq%&ut-3pRx0E9f!euKAeiw)MXpvs z_`>3FwI1V>^m@6J#}uP0c`V#?-iZIDkHkrl_KoA~-%A;|}R0fYqb%Os!37ijD-9QHpI`aPmYcI-PtZHol z2nm5q9zm0$u}~l=vT$F}DKtnV#w3vnG!|7rOtf=(gN!Z~Cm45FFH?PMlGLYoG;*5 zVN!tqI{l%L3pxh|PPj+fKX}Uk0;vuh2Y)$81O(_Cecw({&*=%yWIiblKO4U~oqJXN z-Dz(3Pgy=0v>3Cc-4(=Ue9ov6xIc6OuvQFb)g!tM~`0x?v0s-uL%~Q8`r5Xa5bx zVtx$+d;Xe^4vhFWUM}q`I)q9C&o_PP5C#*xUi5`gxva0~s9f$>FoewjFBW}y5jyBk z{|2Me*}Y(xRt(xdEqJPgV1Ic6c-mn?u%B8D-eB;45Q4o_GBt!p1$gf9a)&~kSX8E) z2i=3tado4zT-hv71VP+b3^tv{LO5(DP4Mp&q4@I-@V6E-IE?{zL$I~=@bx787Yl8& AOaK4? literal 0 HcmV?d00001 diff --git a/book_tx/figs/state.eps b/book_tx/figs/state.eps new file mode 100644 index 0000000..eec6614 --- /dev/null +++ b/book_tx/figs/state.eps @@ -0,0 +1,143 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: state.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Thu Dec 6 11:03:45 2001 +%%For: downey@rocky.wellesley.edu (Allen B. Downey) +%%BoundingBox: 0 0 173 61 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 61 moveto 0 0 lineto 173 0 lineto 173 61 lineto closepath clip newpath +-71.0 118.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 1200 975 m 4050 975 l 4050 1950 l 1200 1950 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2490 1477 m 2490 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +2490 1777 m 2490 1717 l 2338 1717 l 2458 1747 l 2338 1777 l cp +eoclip +n 2100 1747 m + 2475 1747 l gs col0 s gr gr + +% arrowhead +n 2338 1777 m 2458 1747 l 2338 1717 l col0 s +% Polyline +gs clippath +2490 1177 m 2490 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +/Helvetica ff 165.00 scf sf +2025 1200 m +gs 1 -1 sc (message) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 1500 m +gs 1 -1 sc (n) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 1800 m +gs 1 -1 sc (pi) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1200 m +gs 1 -1 sc ("What's up, Doc?") col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1500 m +gs 1 -1 sc (17) col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1800 m +gs 1 -1 sc (3.14159) col0 sh gr +$F2psEnd +rs diff --git a/book_tx/figs/state.fig b/book_tx/figs/state.fig new file mode 100644 index 0000000..512fe95 --- /dev/null +++ b/book_tx/figs/state.fig @@ -0,0 +1,60 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 525 750 3675 1950 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 975 3675 975 3675 1950 1650 1950 1650 975 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1747 2475 1747 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 1125 1575 1125 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1200 0\001 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1500 1\001 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1800 2\001 +4 0 0 50 0 16 11 0.0000 4 120 615 2550 1200 'cheddar'\001 +4 0 0 50 0 16 11 0.0000 4 120 420 2550 1500 'edam'\001 +4 0 0 50 0 16 11 0.0000 4 150 480 2550 1800 'gouda'\001 +4 0 0 50 0 16 11 0.0000 4 120 195 1650 900 list\001 +4 2 0 50 0 16 11 0.0000 4 120 540 1125 1200 cheeses\001 +-6 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 2325 3675 2325 3675 3300 1650 3300 1650 2325 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2497 2475 2497 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 2475 1575 2475 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 3675 3675 3675 3675 4650 1650 4650 1650 3675 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1200 3825 1575 3825 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 2850 2475 3075 +2 1 2 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2100 2797 2475 2797 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 2550 0\001 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 2850 1\001 +4 0 0 50 0 16 11 0.0000 4 120 195 1650 2250 list\001 +4 0 0 50 0 16 11 0.0000 4 120 195 1650 3600 list\001 +4 2 0 50 0 16 11 0.0000 4 120 585 1125 2550 numbers\001 +4 2 0 50 0 16 11 0.0000 4 150 420 1125 3900 empty\001 +4 0 0 50 0 16 11 0.0000 4 120 180 2550 2550 17\001 +4 0 0 50 0 16 11 0.0000 4 120 270 2550 2850 123\001 +4 0 0 50 0 16 11 0.0000 4 120 90 2550 3150 5\001 diff --git a/book_tx/figs/state.pdf b/book_tx/figs/state.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d820979438e324b45bca50b69f659a8198433af8 GIT binary patch literal 6236 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ЭEPe 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 bXN&;+l?T{chAE9kH)Md-oC@^km3p>!6- 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 V8Uj-jdIPcSc}$9xm4~k<<-addbN&DT literal 0 HcmV?d00001 diff --git a/book_tx/figs/towers.eps b/book_tx/figs/towers.eps new file mode 100644 index 0000000..f1fcd2a --- /dev/null +++ b/book_tx/figs/towers.eps @@ -0,0 +1,317 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: towers.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5a +%%CreationDate: Wed May 23 14:46:36 2012 +%%BoundingBox: 0 0 657 158 +%Magnification: 1.0000 +%%EndComments +%%BeginProlog +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +/pageheader { +save +newpath 0 158 moveto 0 0 lineto 657 0 lineto 657 158 lineto closepath clip newpath +-64.4 176.5 translate +1 -1 scale +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +} bind def +/pagefooter { +$F2psEnd +restore +} bind def +%%EndProlog +pageheader +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Polyline +0 slj +0 slc +7.500 slw +n 1035 2520 m 1305 2520 l 1305 2790 l 1035 2790 l + cp gs col0 s gr +% Polyline +n 1305 2520 m 1575 2520 l 1575 2790 l 1305 2790 l + cp gs col0 s gr +% Polyline +n 1620 2520 m 1890 2520 l 1890 2790 l 1620 2790 l + cp gs col0 s gr +% Polyline +n 1890 2520 m 2160 2520 l 2160 2790 l 1890 2790 l + cp gs col0 s gr +% Polyline +n 2205 2520 m 2475 2520 l 2475 2790 l 2205 2790 l + cp gs col0 s gr +% Polyline +n 2475 2520 m 2745 2520 l 2745 2790 l 2475 2790 l + cp gs col0 s gr +% Polyline +n 2745 2520 m 3015 2520 l 3015 2790 l 2745 2790 l + cp gs col0 s gr +% Polyline +n 3015 2520 m 3285 2520 l 3285 2790 l 3015 2790 l + cp gs col0 s gr +% Polyline +n 3330 2520 m 3600 2520 l 3600 2790 l 3330 2790 l + cp gs col0 s gr +% Polyline +n 3600 2520 m 3870 2520 l 3870 2790 l 3600 2790 l + cp gs col0 s gr +% Polyline +n 3870 2520 m 4140 2520 l 4140 2790 l 3870 2790 l + cp gs col0 s gr +% Polyline +n 4140 2520 m 4410 2520 l 4410 2790 l 4140 2790 l + cp gs col0 s gr +% Polyline +n 4410 2520 m 4680 2520 l 4680 2790 l 4410 2790 l + cp gs col0 s gr +% Polyline +n 4680 2520 m 4950 2520 l 4950 2790 l 4680 2790 l + cp gs col0 s gr +% Polyline +n 4950 2520 m 5220 2520 l 5220 2790 l 4950 2790 l + cp gs col0 s gr +% Polyline +n 5220 2520 m 5490 2520 l 5490 2790 l 5220 2790 l + cp gs col0 s gr +% Polyline +n 6975 2520 m 7245 2520 l 7245 2790 l 6975 2790 l + cp gs col0 s gr +% Polyline +n 7245 2520 m 7515 2520 l 7515 2790 l 7245 2790 l + cp gs col0 s gr +% Polyline +n 7560 2520 m 7830 2520 l 7830 2790 l 7560 2790 l + cp gs col0 s gr +% Polyline +n 7830 2520 m 8100 2520 l 8100 2790 l 7830 2790 l + cp gs col0 s gr +% Polyline +n 8145 2520 m 8415 2520 l 8415 2790 l 8145 2790 l + cp gs col0 s gr +% Polyline +n 8415 2520 m 8685 2520 l 8685 2790 l 8415 2790 l + cp gs col0 s gr +% Polyline +n 8685 2520 m 8955 2520 l 8955 2790 l 8685 2790 l + cp gs col0 s gr +% Polyline +n 8955 2520 m 9225 2520 l 9225 2790 l 8955 2790 l + cp gs col0 s gr +% Polyline +n 9270 2520 m 9540 2520 l 9540 2790 l 9270 2790 l + cp gs col0 s gr +% Polyline +n 9540 2520 m 9810 2520 l 9810 2790 l 9540 2790 l + cp gs col0 s gr +% Polyline +n 9810 2520 m 10080 2520 l 10080 2790 l 9810 2790 l + cp gs col0 s gr +% Polyline +n 10080 2520 m 10350 2520 l 10350 2790 l 10080 2790 l + cp gs col0 s gr +% Polyline +n 10350 2520 m 10620 2520 l 10620 2790 l 10350 2790 l + cp gs col0 s gr +% Polyline +n 10620 2520 m 10890 2520 l 10890 2790 l 10620 2790 l + cp gs col0 s gr +% Polyline +n 10890 2520 m 11160 2520 l 11160 2790 l 10890 2790 l + cp gs col0 s gr +% Polyline +n 11160 2520 m 11430 2520 l 11430 2790 l 11160 2790 l + cp gs col0 s gr +% Polyline +n 1620 2205 m 1890 2205 l 1890 2475 l 1620 2475 l + cp gs col0 s gr +% Polyline +n 1620 1935 m 1890 1935 l 1890 2205 l 1620 2205 l + cp gs col0 s gr +% Polyline +n 2205 2205 m 2475 2205 l 2475 2475 l 2205 2475 l + cp gs col0 s gr +% Polyline +n 2205 1935 m 2475 1935 l 2475 2205 l 2205 2205 l + cp gs col0 s gr +% Polyline +n 2205 1665 m 2475 1665 l 2475 1935 l 2205 1935 l + cp gs col0 s gr +% Polyline +n 2205 1395 m 2475 1395 l 2475 1665 l 2205 1665 l + cp gs col0 s gr +% Polyline +n 3330 2205 m 3600 2205 l 3600 2475 l 3330 2475 l + cp gs col0 s gr +% Polyline +n 3330 1935 m 3600 1935 l 3600 2205 l 3330 2205 l + cp gs col0 s gr +% Polyline +n 3330 1665 m 3600 1665 l 3600 1935 l 3330 1935 l + cp gs col0 s gr +% Polyline +n 3330 1395 m 3600 1395 l 3600 1665 l 3330 1665 l + cp gs col0 s gr +% Polyline +n 3330 1125 m 3600 1125 l 3600 1395 l 3330 1395 l + cp gs col0 s gr +% Polyline +n 3330 855 m 3600 855 l 3600 1125 l 3330 1125 l + cp gs col0 s gr +% Polyline +n 3330 585 m 3600 585 l 3600 855 l 3330 855 l + cp gs col0 s gr +% Polyline +n 3330 315 m 3600 315 l 3600 585 l 3330 585 l + cp gs col0 s gr +% Polyline +n 9540 2205 m 9540 2475 l 9270 2475 l 9270 2205 l + cp gs col0 s gr +% Polyline +n 9810 2205 m 9810 2475 l 9540 2475 l 9540 2205 l + cp gs col0 s gr +% Polyline +n 10080 2205 m 10080 2475 l 9810 2475 l 9810 2205 l + cp gs col0 s gr +% Polyline +n 10350 2205 m 10350 2475 l 10080 2475 l 10080 2205 l + cp gs col0 s gr +% Polyline +n 10620 2205 m 10620 2475 l 10350 2475 l 10350 2205 l + cp gs col0 s gr +% Polyline +n 10890 2205 m 10890 2475 l 10620 2475 l 10620 2205 l + cp gs col0 s gr +% Polyline +n 11160 2205 m 11160 2475 l 10890 2475 l 10890 2205 l + cp gs col0 s gr +% Polyline +n 11430 2205 m 11430 2475 l 11160 2475 l 11160 2205 l + cp gs col0 s gr +% Polyline +n 8415 2205 m 8415 2475 l 8145 2475 l 8145 2205 l + cp gs col0 s gr +% Polyline +n 8685 2205 m 8685 2475 l 8415 2475 l 8415 2205 l + cp gs col0 s gr +% Polyline +n 8955 2205 m 8955 2475 l 8685 2475 l 8685 2205 l + cp gs col0 s gr +% Polyline +n 9225 2205 m 9225 2475 l 8955 2475 l 8955 2205 l + cp gs col0 s gr +% Polyline +n 7830 2205 m 7830 2475 l 7560 2475 l 7560 2205 l + cp gs col0 s gr +% Polyline +n 8100 2205 m 8100 2475 l 7830 2475 l 7830 2205 l + cp gs col0 s gr +% Polyline +gs clippath +1933 2100 m 2085 2100 l 2085 2040 l 1933 2040 l 1933 2040 l 2053 2070 l 1933 2100 l cp +eoclip +n 1800 2070 m + 2070 2070 l gs col0 s gr gr + +% arrowhead +n 1933 2100 m 2053 2070 l 1933 2040 l col0 s +% Polyline +gs clippath +3643 480 m 3795 480 l 3795 420 l 3643 420 l 3643 420 l 3763 450 l 3643 480 l cp +eoclip +n 3510 450 m + 3780 450 l gs col0 s gr gr + +% arrowhead +n 3643 480 m 3763 450 l 3643 420 l col0 s +% Polyline +gs clippath +2518 1560 m 2670 1560 l 2670 1500 l 2518 1500 l 2518 1500 l 2638 1530 l 2518 1560 l cp +eoclip +n 2385 1530 m + 2655 1530 l gs col0 s gr gr + +% arrowhead +n 2518 1560 m 2638 1530 l 2518 1500 l col0 s +% here ends figure; +pagefooter +showpage +%%Trailer +%EOF diff --git a/book_tx/figs/towers.fig b/book_tx/figs/towers.fig new file mode 100644 index 0000000..8760390 --- /dev/null +++ b/book_tx/figs/towers.fig @@ -0,0 +1,178 @@ +#FIG 3.2 Produced by xfig version 3.2.5 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +6 1035 2520 5490 2790 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1035 2520 1305 2520 1305 2790 1035 2790 1035 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1305 2520 1575 2520 1575 2790 1305 2790 1305 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1620 2520 1890 2520 1890 2790 1620 2790 1620 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1890 2520 2160 2520 2160 2790 1890 2790 1890 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2205 2520 2475 2520 2475 2790 2205 2790 2205 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2475 2520 2745 2520 2745 2790 2475 2790 2475 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2745 2520 3015 2520 3015 2790 2745 2790 2745 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3015 2520 3285 2520 3285 2790 3015 2790 3015 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 2520 3600 2520 3600 2790 3330 2790 3330 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3600 2520 3870 2520 3870 2790 3600 2790 3600 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3870 2520 4140 2520 4140 2790 3870 2790 3870 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4140 2520 4410 2520 4410 2790 4140 2790 4140 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4410 2520 4680 2520 4680 2790 4410 2790 4410 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4680 2520 4950 2520 4950 2790 4680 2790 4680 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 2520 5220 2520 5220 2790 4950 2790 4950 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 5220 2520 5490 2520 5490 2790 5220 2790 5220 2520 +-6 +6 6975 2520 11430 2790 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6975 2520 7245 2520 7245 2790 6975 2790 6975 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7245 2520 7515 2520 7515 2790 7245 2790 7245 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7560 2520 7830 2520 7830 2790 7560 2790 7560 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7830 2520 8100 2520 8100 2790 7830 2790 7830 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8145 2520 8415 2520 8415 2790 8145 2790 8145 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8415 2520 8685 2520 8685 2790 8415 2790 8415 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8685 2520 8955 2520 8955 2790 8685 2790 8685 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8955 2520 9225 2520 9225 2790 8955 2790 8955 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9270 2520 9540 2520 9540 2790 9270 2790 9270 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9540 2520 9810 2520 9810 2790 9540 2790 9540 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9810 2520 10080 2520 10080 2790 9810 2790 9810 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10080 2520 10350 2520 10350 2790 10080 2790 10080 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10350 2520 10620 2520 10620 2790 10350 2790 10350 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10620 2520 10890 2520 10890 2790 10620 2790 10620 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10890 2520 11160 2520 11160 2790 10890 2790 10890 2520 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 11160 2520 11430 2520 11430 2790 11160 2790 11160 2520 +-6 +6 1620 1935 1890 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1620 2205 1890 2205 1890 2475 1620 2475 1620 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1620 1935 1890 1935 1890 2205 1620 2205 1620 1935 +-6 +6 2205 1395 2475 2475 +6 2205 1935 2475 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2205 2205 2475 2205 2475 2475 2205 2475 2205 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2205 1935 2475 1935 2475 2205 2205 2205 2205 1935 +-6 +6 2205 1395 2475 1935 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2205 1665 2475 1665 2475 1935 2205 1935 2205 1665 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2205 1395 2475 1395 2475 1665 2205 1665 2205 1395 +-6 +-6 +6 3330 315 3600 2475 +6 3330 1935 3600 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 2205 3600 2205 3600 2475 3330 2475 3330 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 1935 3600 1935 3600 2205 3330 2205 3330 1935 +-6 +6 3330 1395 3600 1935 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 1665 3600 1665 3600 1935 3330 1935 3330 1665 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 1395 3600 1395 3600 1665 3330 1665 3330 1395 +-6 +6 3330 855 3600 1395 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 1125 3600 1125 3600 1395 3330 1395 3330 1125 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 855 3600 855 3600 1125 3330 1125 3330 855 +-6 +6 3330 315 3600 855 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 585 3600 585 3600 855 3330 855 3330 585 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3330 315 3600 315 3600 585 3330 585 3330 315 +-6 +-6 +6 9270 2205 11430 2475 +6 9270 2205 9810 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9540 2205 9540 2475 9270 2475 9270 2205 9540 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9810 2205 9810 2475 9540 2475 9540 2205 9810 2205 +-6 +6 9810 2205 10350 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10080 2205 10080 2475 9810 2475 9810 2205 10080 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10350 2205 10350 2475 10080 2475 10080 2205 10350 2205 +-6 +6 10350 2205 10890 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10620 2205 10620 2475 10350 2475 10350 2205 10620 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10890 2205 10890 2475 10620 2475 10620 2205 10890 2205 +-6 +6 10890 2205 11430 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 11160 2205 11160 2475 10890 2475 10890 2205 11160 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 11430 2205 11430 2475 11160 2475 11160 2205 11430 2205 +-6 +-6 +6 8145 2205 9225 2475 +6 8145 2205 8685 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8415 2205 8415 2475 8145 2475 8145 2205 8415 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8685 2205 8685 2475 8415 2475 8415 2205 8685 2205 +-6 +6 8685 2205 9225 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8955 2205 8955 2475 8685 2475 8685 2205 8955 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 9225 2205 9225 2475 8955 2475 8955 2205 9225 2205 +-6 +-6 +6 7560 2205 8100 2475 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7830 2205 7830 2475 7560 2475 7560 2205 7830 2205 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8100 2205 8100 2475 7830 2475 7830 2205 8100 2205 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1800 2070 2070 2070 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3510 450 3780 450 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2385 1530 2655 1530 diff --git a/book_tx/figs/towers.pdf b/book_tx/figs/towers.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8e49809e5116d5f35b3125d433eaf6972205c988 GIT binary patch literal 2998 zcmb_edvH|M8J|EDat9M_&_NhFhlJ#AguC~#cc1QV9=ll*n}wZCngk-!yZ4^WUUGNu zdhgln62XB%lqi8#tYhUdLM=$g>9hz<9Y&$8sRPzJqR0r2rH+Ur&P0J!nlQBIZg%sM zDgKf3&z}9x_d4hI{l4#3g!}=DHSS1pQD{CFu1MI?|vJCo;SHp8tb(o|*Gx+Oy@0VpHu5aJ_KPf|3mzA2#3r+^4@; zI6Pdi`e`k;;2KO856`|iTvT(TeddMvU#%J0@c5cHt1k`>4c7gtKd zUnSl7d69JA$5)FMvzxX(`@7vsi>}1JJ296%aJ{$eK;Z+WrY$Ib@kD5EY*cEqVFSU*D z^I=KTwxO2F-teI{1;>34@BDZ1xBEU?=)C->vq)f%hY^tNU!{ z*1ytcTXEWZ?uI{}7zyn&F4&!mq$-SGOS3w8{g+13#mOq|~0P6XJUn>SqL>xSv_7v=;#hljQXj+O6R^)jW+ zn8%zAyuZ=b^JUHUBk#_JNBevCyh`lfVm{kio|yf{YXkc}lLl|D?W!&yqAQoegp?~f zyfX^bD9`LK>m+g_e!PZT)+Hew5;`Frgpw@OsTt70;A5NB4p^&WHGvN`m_Wc{R5?M1 zp{}Mh5$d@9Lz*f!L)1ZIhG50|3|iKVaPP%7)yC4D)*eNGGHg2AQ~$&|Mi1nKg0Yy&@>3!Ygr1Snh=L+RqFz**+ycQniO?~{ehfA{Le$i5K6jeI-O3N(-yO;b<(WU z>7*Hs<~Ry#Q2M$A5;9amFURq+iOB6^W(nP#&B-jPaawMtSu;cD1NrfFG&zZ6H35vk zLPSj=4{2fS4o2d6N|HF9Vp%9s3|^Go4kd>TN)anB1lKESao_zCdNg$q|o ziBR*9%R)_HSxnW@XlURt+gXy%-FzAn!ie1Z?ij}0<=t4v6;vfTy3UWucbNTPn;iMIze-Ssj9W$LhwfAPELZ|pcQJmfq=!# zfsla2m;$?@0<6Ml_^gkdiJLZHn(#`~_-;Zn82tY)7mphSZRolDs+fx7Hq+?;f#oud z2utEvn#q)=WEmleG*qCGk&Z!Tah{UsimF;%!1XL7lZq?~Mw!#N7)h@iA0ink(3|C3 zt%623ifr)5r3i^m51FAP7!^_qBE3jWV~orguu%XM**m()TGHd*ZUIkLgc*&IqR0A$ zmjKhWrq9uMlf=!~L#B-uh=HX1DkQl@bX^1fBgbXy8ljg6L!2BQQ6ScWiq+33PE*J`nXD9Fp4EFNXX z0*SngT5a9>gVhH i9MAf>S|{VZy~b+evp`3JhO!UJ*?22aQBl7lK>QDd*2Zf9 literal 0 HcmV?d00001 diff --git a/book_tx/figs/tuple1.eps b/book_tx/figs/tuple1.eps new file mode 100644 index 0000000..7949bda --- /dev/null +++ b/book_tx/figs/tuple1.eps @@ -0,0 +1,135 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: tuple1.fig +%%Creator: fig2dev Version 3.2 Patchlevel 4 +%%CreationDate: Tue Jul 31 12:27:49 2007 +%%For: downey@rocky.olin.edu (Allen Downey) +%%BoundingBox: 0 0 123 53 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 53 moveto 0 0 lineto 123 0 lineto 123 53 lineto closepath clip newpath +-98.3 99.7 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 51 +% Polyline +7.500 slw +n 1650 975 m 3675 975 l 3675 1650 l 1650 1650 l + cp gs col7 0.90 shd ef gr gs col0 s gr +% Polyline +gs clippath +2490 1477 m 2490 1417 l 2338 1417 l 2458 1447 l 2338 1477 l cp +eoclip +n 2100 1447 m + 2475 1447 l gs col0 s gr gr + +% arrowhead +n 2338 1477 m 2458 1447 l 2338 1417 l col0 s +% Polyline +gs clippath +2490 1177 m 2490 1117 l 2338 1117 l 2458 1147 l 2338 1177 l cp +eoclip +n 2100 1147 m + 2475 1147 l gs col0 s gr gr + +% arrowhead +n 2338 1177 m 2458 1147 l 2338 1117 l col0 s +/Helvetica ff 165.00 scf sf +2025 1200 m +gs 1 -1 sc (0) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2025 1500 m +gs 1 -1 sc (1) dup sw pop neg 0 rm col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1200 m +gs 1 -1 sc ('Cleese') col0 sh gr +/Helvetica ff 165.00 scf sf +2550 1500 m +gs 1 -1 sc ('John') col0 sh gr +/Helvetica ff 165.00 scf sf +1650 900 m +gs 1 -1 sc (tuple) col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage diff --git a/book_tx/figs/tuple1.fig b/book_tx/figs/tuple1.fig new file mode 100644 index 0000000..fad2c3d --- /dev/null +++ b/book_tx/figs/tuple1.fig @@ -0,0 +1,22 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1447 2475 1447 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2100 1147 2475 1147 +2 2 0 1 0 7 51 0 18 0.000 0 0 -1 0 0 5 + 1650 975 3675 975 3675 1650 1650 1650 1650 975 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1200 0\001 +4 2 0 50 0 16 11 0.0000 4 120 90 2025 1500 1\001 +4 0 0 50 0 16 11 0.0000 4 120 510 2550 1200 'Cleese'\001 +4 0 0 50 0 16 11 0.0000 4 120 405 2550 1500 'John'\001 +4 0 0 50 0 16 11 0.0000 4 150 330 1650 900 tuple\001 diff --git a/book_tx/figs/tuple1.pdf b/book_tx/figs/tuple1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..df15839af51289cb574d63f59917acdd002e7451 GIT binary patch literal 4825 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 +Buy this book at Amazon.com + + + + + +

+

Are you using one of our books in a class?

We'd like to know +about it. Please consider filling out this short survey. + +

+
+ +

+Think DSP + +

+ + +

+Think Java + +

+ + +

+Think Bayes + +

+ + +

+Think Python 2e + + +

+ + +

+Think Stats 2e + +

+ + +

+Think Complexity + +

+ + + + + + diff --git a/book_tx/header.html b/book_tx/header.html new file mode 100644 index 0000000..85e9e99 --- /dev/null +++ b/book_tx/header.html @@ -0,0 +1,12 @@ + + + + + + +
+ + +

+Buy this book at Amazon.com + diff --git a/book_tx/hevea.sty b/book_tx/hevea.sty new file mode 100644 index 0000000..17b4e54 --- /dev/null +++ b/book_tx/hevea.sty @@ -0,0 +1,90 @@ +% hevea : hevea.sty +% This is a very basic style file for latex document to be processed +% with hevea. It contains definitions of LaTeX environment which are +% processed in a special way by the translator. +% Mostly : +% - latexonly, not processed by hevea, processed by latex. +% - htmlonly , the reverse. +% - rawhtml, to include raw HTML in hevea output. +% - toimage, to send text to the image file. +% The package also provides hevea logos, html related commands (ahref +% etc.), void cutting and image commands. +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{hevea}[2002/01/11] +\RequirePackage{comment} +\newif\ifhevea\heveafalse +\@ifundefined{ifimagen}{\newif\ifimagen\imagenfalse} +\makeatletter% +\newcommand{\heveasmup}[2]{% +\raise #1\hbox{$\m@th$% + \csname S@\f@size\endcsname + \fontsize\sf@size 0% + \math@fontsfalse\selectfont +#2% +}}% +\DeclareRobustCommand{\hevea}{H\kern-.15em\heveasmup{.2ex}{E}\kern-.15emV\kern-.15em\heveasmup{.2ex}{E}\kern-.15emA}% +\DeclareRobustCommand{\hacha}{H\kern-.15em\heveasmup{.2ex}{A}\kern-.15emC\kern-.1em\heveasmup{.2ex}{H}\kern-.15emA}% +\DeclareRobustCommand{\html}{\protect\heveasmup{0.ex}{HTML}} +%%%%%%%%% Hyperlinks hevea style +\newcommand{\ahref}[2]{{#2}} +\newcommand{\ahrefloc}[2]{{#2}} +\newcommand{\aname}[2]{{#2}} +\newcommand{\ahrefurl}[1]{\texttt{#1}} +\newcommand{\footahref}[2]{#2\footnote{\texttt{#1}}} +\newcommand{\mailto}[1]{\texttt{#1}} +\newcommand{\imgsrc}[2][]{} +\newcommand{\home}[1]{\protect\raisebox{-.75ex}{\char126}#1} +\AtBeginDocument +{\@ifundefined{url} +{%url package is not loaded +\let\url\ahref\let\oneurl\ahrefurl\let\footurl\footahref} +{}} +%% Void cutting instructions +\newcounter{cuttingdepth} +\newcommand{\tocnumber}{} +\newcommand{\notocnumber}{} +\newcommand{\cuttingunit}{} +\newcommand{\cutdef}[2][]{} +\newcommand{\cuthere}[2]{} +\newcommand{\cutend}{} +\newcommand{\htmlhead}[1]{} +\newcommand{\htmlfoot}[1]{} +\newcommand{\htmlprefix}[1]{} +\newenvironment{cutflow}[1]{}{} +\newcommand{\cutname}[1]{} +\newcommand{\toplinks}[3]{} +\newcommand{\setlinkstext}[3]{} +\newcommand{\flushdef}[1]{} +\newcommand{\footnoteflush}[1]{} +%%%% Html only +\excludecomment{rawhtml} +\newcommand{\rawhtmlinput}[1]{} +\excludecomment{htmlonly} +%%%% Latex only +\newenvironment{latexonly}{}{} +\newenvironment{verblatex}{}{} +%%%% Image file stuff +\def\toimage{\endgroup} +\def\endtoimage{\begingroup\def\@currenvir{toimage}} +\def\verbimage{\endgroup} +\def\endverbimage{\begingroup\def\@currenvir{verbimage}} +\newcommand{\imageflush}[1][]{} +%%% Bgcolor definition +\newsavebox{\@bgcolorbin} +\newenvironment{bgcolor}[2][] + {\newcommand{\@mycolor}{#2}\begin{lrbox}{\@bgcolorbin}\vbox\bgroup} + {\egroup\end{lrbox}% + \begin{flushleft}% + \colorbox{\@mycolor}{\usebox{\@bgcolorbin}}% + \end{flushleft}} +%%% Style sheets macros, defined as no-ops +\newcommand{\newstyle}[2]{} +\newcommand{\addstyle}[1]{} +\newcommand{\setenvclass}[2]{} +\newcommand{\getenvclass}[1]{} +\newcommand{\loadcssfile}[1]{} +\newenvironment{divstyle}[1]{}{} +\newenvironment{cellstyle}[2]{}{} +\newif\ifexternalcss +%%% Postlude +\makeatother diff --git a/book_tx/htmlonly b/book_tx/htmlonly new file mode 100644 index 0000000..1731866 --- /dev/null +++ b/book_tx/htmlonly @@ -0,0 +1,28 @@ +% put commands here that should be used for the HTML +% version of the book but not Postscript or PDF + +\newcommand{\beforefig}{} +\newcommand{\afterfig}{} + +\newcommand{\beforeverb}{\blue \large} +\newcommand{\afterverb}{\black \normalsize} + +\newcommand{\adjustpage}[1]{} + +\newcommand{\clearemptydoublepage}{} +\newcommand{\blankpage}{} + +\newcommand{\spacing}{} +\newcommand{\endspacing}{} + +\newcommand{\frontmatter}{} +\newcommand{\mainmatter}{} + +\newcommand{\theoremstyle}[1]{} +\newcommand{\newtheoremstyle}[1]{} + +\newcommand{\vfill}{} + +\htmlhead{\rawhtmlinput{header.html}} + +\htmlfoot{\rawhtmlinput{footer.html}} \ No newline at end of file diff --git a/book_tx/latexonly b/book_tx/latexonly new file mode 100644 index 0000000..9f6786f --- /dev/null +++ b/book_tx/latexonly @@ -0,0 +1,102 @@ +\sloppy +%\setlength{\topmargin}{-0.375in} +%\setlength{\oddsidemargin}{0.0in} +%\setlength{\evensidemargin}{0.0in} + +% Uncomment these to center on 8.5 x 11 +%\setlength{\topmargin}{0.625in} +%\setlength{\oddsidemargin}{0.875in} +%\setlength{\evensidemargin}{0.875in} + +%\setlength{\textheight}{7.2in} + +\setlength{\headsep}{3ex} +\setlength{\parindent}{0.0in} +\setlength{\parskip}{1.7ex plus 0.5ex minus 0.5ex} +\renewcommand{\baselinestretch}{1.02} + +% see LaTeX Companion page 62 +\setlength{\topsep}{-0.0\parskip} +\setlength{\partopsep}{-0.5\parskip} +\setlength{\itemindent}{0.0in} +\setlength{\listparindent}{0.0in} + +% see LaTeX Companion page 26 +% these are copied from /usr/local/teTeX/share/texmf/tex/latex/base/book.cls +% all I changed is afterskip + +\makeatletter + +\renewcommand{\section}{\@startsection + {section} {1} {0mm}% + {-3.5ex \@plus -1ex \@minus -.2ex}% + {0.7ex \@plus.2ex}% + {\normalfont\Large\bfseries}} +\renewcommand\subsection{\@startsection {subsection}{2}{0mm}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {0.3ex \@plus .2ex}% + {\normalfont\large\bfseries}} +\renewcommand\subsubsection{\@startsection {subsubsection}{3}{0mm}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {0.3ex \@plus .2ex}% + {\normalfont\normalsize\bfseries}} + +% The following line adds a little extra space to the column +% in which the Section numbers appear in the table of contents +\renewcommand{\l@section}{\@dottedtocline{1}{1.5em}{3.0em}} +\setcounter{tocdepth}{1} + +\makeatother + +\newcommand{\beforefig}{\vspace{1.3\parskip}} +\newcommand{\afterfig}{\vspace{-0.2\parskip}} + +\newcommand{\beforeverb}{\vspace{0.6\parskip}} +\newcommand{\afterverb}{\vspace{0.6\parskip}} + +\newcommand{\adjustpage}[1]{\enlargethispage{#1\baselineskip}} + + +% Note: the following command seems to cause problems for Acroreader +% on Windows, so for now I am overriding it. +%\newcommand{\clearemptydoublepage}{ +% \newpage{\pagestyle{empty}\cleardoublepage}} +\newcommand{\clearemptydoublepage}{\cleardoublepage} + +%\newcommand{\blankpage}{\pagestyle{empty}\vspace*{1in}\newpage} +\newcommand{\blankpage}{\vspace*{1in}\newpage} + +% HEADERS + +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}{}} + +\lhead[\fancyplain{}{\bfseries\thepage}]% + {\fancyplain{}{\bfseries\rightmark}} +\rhead[\fancyplain{}{\bfseries\leftmark}]% + {\fancyplain{}{\bfseries\thepage}} +\cfoot{} + +\pagestyle{fancyplain} + + +% turn off the rule under the header +%\setlength{\headrulewidth}{0pt} + +% the following is a brute-force way to prevent the headers +% from getting transformed into all-caps +\renewcommand\MakeUppercase{} + +% Exercise environment +\newtheoremstyle{myex}% name + {9pt}% Space above + {9pt}% Space below + {}% Body font + {}% Indent amount (empty = no indent, \parindent = para indent) + {\bfseries}% Thm head font + {}% Punctuation after thm head + {0.5em}% Space after thm head: " " = normal interword space; + % \newline = linebreak + {}% Thm head spec (can be left empty, meaning `normal') + +\theoremstyle{myex} diff --git a/book_tx/localdef.py b/book_tx/localdef.py new file mode 100644 index 0000000..14f7a5b --- /dev/null +++ b/book_tx/localdef.py @@ -0,0 +1,81 @@ +import plasTeX.Base as Base + +def idgen(): + """ Generate a unique ID """ + i = 1 + while 1: + yield 'a%.10d' % i + i += 1 + +idgen = idgen() + +class Eqn(Base.Command): + args = 'self' + +class Anchor(Base.Command): + args = 'label:str' + def invoke(self, tex): + Base.Command.invoke(self, tex) + self.ownerDocument.context.label(self.attributes['label'], self) + +class exercise(Base.Environment): + counter = 'exercise' + +class index(Base.Command): + args = 'termstring' + + def setEntry(self, s, seetype=0): + # TYPE_NORMAL = 0 + # TYPE_SEE = 1 + # TYPE_SEEALSO = 2 + if type(s) != type(''): + s = s.textContent + if s.count('!'): + priterm, secterm = s.split('!') + if priterm.count('@'): + prisort, primary = priterm.split('@') + else: + prisort, primary = None, priterm + if secterm.count('@'): + secsort, secondary = secterm.split('@') + else: + secsort, secondary = None, secterm + elif s.count('@'): + prisort, primary = s.split('@') + secsort, secondary = None, None + else: + prisort, primary = None, s + secsort, secondary = None, None + +# if secondary: +# self.ownerDocument.userdata.setdefault('index', []).append(\ +# Base.IndexEntry([primary, secondary], self, [prisort, secsort], None, type=seetype)) +# else: +# self.ownerDocument.userdata.setdefault('index', []).append(\ +# Base.IndexEntry([primary], self, [prisort], None, type=seetype)) + return prisort, primary, secsort, secondary + + def invoke(self, tex): + Base.Command.invoke(self, tex) + self.ownerDocument.context.label(idgen.next(), self) + p0,p1,s0,s1 = self.setEntry(self.attributes['termstring']) + if p0: + self.prisort = '%s' % p0 + if p1: + self.primary = '%s' % p1 + if s0: + self.secsort = '%s' % s0 + if s1: + self.secondary = '%s' % s1 + +class scriptN(Base.Command): + unicode = u'\U0001D4A9' + +class uxbar(Base.Command): pass +class uybar(Base.Command): pass +class unhat(Base.Command): pass +class ule(Base.Command): pass +class minus(Base.Command): pass +class lowast(Base.Command): pass +class Erdos(Base.Command): pass + diff --git a/book_tx/next.png b/book_tx/next.png new file mode 100644 index 0000000000000000000000000000000000000000..e89db2714db22dd89072b4798f40db7c6d9e12d3 GIT binary patch literal 4479 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 R>q-Cs002ovPDHLkV1mnxqsjmP literal 0 HcmV?d00001 diff --git a/book_tx/up.png b/book_tx/up.png new file mode 100644 index 0000000000000000000000000000000000000000..4e86da1aa2442e2b5eba5ea81221db539b5a9c84 GIT binary patch literal 4426 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 QbN~PV07*qoM6N<$g3PCUP5=M^ literal 0 HcmV?d00001 From 3b2c0bde9f5545e0b81a126a3629ce9a5fa68294 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Wed, 28 Jun 2017 11:38:04 +0900 Subject: [PATCH 02/13] readme added --- book_tx/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 book_tx/README.md diff --git a/book_tx/README.md b/book_tx/README.md new file mode 100644 index 0000000..7204b02 --- /dev/null +++ b/book_tx/README.md @@ -0,0 +1,6 @@ +ThinkPython Korean Translation +=========== + +LaTeX source, code examples, and exercise solutions for Think Python, 2nd edition, by Allen Downey. + +Translated by Seongjin Lee From ba1557914427b521a37990c73d94dcc6701678f4 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Wed, 28 Jun 2017 23:04:08 +0900 Subject: [PATCH 03/13] renamed the directory --- {book_tx => book_kr}/Makefile | 0 {book_tx => book_kr}/README.md | 0 {book_tx => book_kr}/back.png | Bin {book_tx => book_kr}/book.tex | 0 {book_tx => book_kr}/figs/assign2.eps | 0 {book_tx => book_kr}/figs/assign2.fig | 0 {book_tx => book_kr}/figs/assign2.fig.bak | 0 {book_tx => book_kr}/figs/assign2.pdf | Bin {book_tx => book_kr}/figs/banana.eps | 0 {book_tx => book_kr}/figs/banana.fig | 0 {book_tx => book_kr}/figs/banana.pdf | Bin {book_tx => book_kr}/figs/card1.eps | 0 {book_tx => book_kr}/figs/card1.fig | 0 {book_tx => book_kr}/figs/card1.pdf | Bin {book_tx => book_kr}/figs/class1.eps | 0 {book_tx => book_kr}/figs/class1.fig | 0 {book_tx => book_kr}/figs/class1.pdf | Bin {book_tx => book_kr}/figs/compile.eps | 0 {book_tx => book_kr}/figs/compile.fig | 0 {book_tx => book_kr}/figs/compile.pdf | Bin {book_tx => book_kr}/figs/dict1.eps | 0 {book_tx => book_kr}/figs/dict1.fig | 0 {book_tx => book_kr}/figs/dict1.pdf | Bin {book_tx => book_kr}/figs/dict2.eps | 0 {book_tx => book_kr}/figs/dict2.fig | 0 {book_tx => book_kr}/figs/dict2.pdf | Bin {book_tx => book_kr}/figs/fibonacci.eps | 0 {book_tx => book_kr}/figs/fibonacci.fig | 0 {book_tx => book_kr}/figs/fibonacci.pdf | Bin {book_tx => book_kr}/figs/flower.test.pdf | Bin {book_tx => book_kr}/figs/flowers.eps | 0 {book_tx => book_kr}/figs/flowers.pdf | Bin {book_tx => book_kr}/figs/interpret.eps | 0 {book_tx => book_kr}/figs/interpret.fig | 0 {book_tx => book_kr}/figs/interpret.pdf | Bin {book_tx => book_kr}/figs/koch.eps | 0 {book_tx => book_kr}/figs/koch.pdf | Bin {book_tx => book_kr}/figs/list1.eps | 0 {book_tx => book_kr}/figs/list1.fig | 0 {book_tx => book_kr}/figs/list1.pdf | Bin {book_tx => book_kr}/figs/list2.eps | 0 {book_tx => book_kr}/figs/list2.fig | 0 {book_tx => book_kr}/figs/list2.pdf | Bin {book_tx => book_kr}/figs/list3.eps | 0 {book_tx => book_kr}/figs/list3.fig | 0 {book_tx => book_kr}/figs/list3.pdf | Bin {book_tx => book_kr}/figs/liststate.eps | 0 {book_tx => book_kr}/figs/liststate.fig | 0 {book_tx => book_kr}/figs/liststate.fig.bak | 0 {book_tx => book_kr}/figs/liststate.pdf | Bin {book_tx => book_kr}/figs/listsum1.eps | 0 {book_tx => book_kr}/figs/listsum1.pdf | Bin {book_tx => book_kr}/figs/listsum2.eps | 0 {book_tx => book_kr}/figs/listsum2.pdf | Bin {book_tx => book_kr}/figs/loop.py | 0 {book_tx => book_kr}/figs/loop.py~ | 0 {book_tx => book_kr}/figs/pies.eps | 0 {book_tx => book_kr}/figs/pies.pdf | Bin {book_tx => book_kr}/figs/point.eps | 0 {book_tx => book_kr}/figs/point.fig | 0 {book_tx => book_kr}/figs/point.pdf | Bin {book_tx => book_kr}/figs/rectangle.eps | 0 {book_tx => book_kr}/figs/rectangle.fig | 0 {book_tx => book_kr}/figs/rectangle.pdf | Bin {book_tx => book_kr}/figs/rectangle2.eps | 0 {book_tx => book_kr}/figs/rectangle2.fig | 0 {book_tx => book_kr}/figs/rectangle2.pdf | Bin {book_tx => book_kr}/figs/stack.eps | 0 {book_tx => book_kr}/figs/stack.fig | 0 {book_tx => book_kr}/figs/stack.pdf | Bin {book_tx => book_kr}/figs/stack2.eps | 0 {book_tx => book_kr}/figs/stack2.fig | 0 {book_tx => book_kr}/figs/stack2.pdf | Bin {book_tx => book_kr}/figs/stack3.eps | 0 {book_tx => book_kr}/figs/stack3.fig | 0 {book_tx => book_kr}/figs/stack3.pdf | Bin {book_tx => book_kr}/figs/stack4.eps | 0 {book_tx => book_kr}/figs/stack4.fig | 0 {book_tx => book_kr}/figs/stack4.pdf | Bin {book_tx => book_kr}/figs/stack5.eps | 0 {book_tx => book_kr}/figs/stack5.fig | 0 {book_tx => book_kr}/figs/stack5.pdf | Bin {book_tx => book_kr}/figs/state.eps | 0 {book_tx => book_kr}/figs/state.fig | 0 {book_tx => book_kr}/figs/state.pdf | Bin {book_tx => book_kr}/figs/state2.eps | 0 {book_tx => book_kr}/figs/state2.fig | 0 {book_tx => book_kr}/figs/state2.pdf | Bin {book_tx => book_kr}/figs/state3.eps | 0 {book_tx => book_kr}/figs/state3.fig | 0 {book_tx => book_kr}/figs/state3.pdf | Bin {book_tx => book_kr}/figs/state4.eps | 0 {book_tx => book_kr}/figs/state4.fig | 0 {book_tx => book_kr}/figs/state4.pdf | Bin {book_tx => book_kr}/figs/state5.eps | 0 {book_tx => book_kr}/figs/state5.fig | 0 {book_tx => book_kr}/figs/state5.pdf | Bin {book_tx => book_kr}/figs/time.eps | 0 {book_tx => book_kr}/figs/time.fig | 0 {book_tx => book_kr}/figs/time.pdf | Bin {book_tx => book_kr}/figs/towers.eps | 0 {book_tx => book_kr}/figs/towers.fig | 0 {book_tx => book_kr}/figs/towers.pdf | Bin {book_tx => book_kr}/figs/tuple1.eps | 0 {book_tx => book_kr}/figs/tuple1.fig | 0 {book_tx => book_kr}/figs/tuple1.pdf | Bin {book_tx => book_kr}/footer.html | 0 {book_tx => book_kr}/header.html | 0 {book_tx => book_kr}/hevea.sty | 0 {book_tx => book_kr}/htmlonly | 0 {book_tx => book_kr}/latexonly | 0 {book_tx => book_kr}/localdef.py | 0 {book_tx => book_kr}/next.png | Bin {book_tx => book_kr}/up.png | Bin 114 files changed, 0 insertions(+), 0 deletions(-) rename {book_tx => book_kr}/Makefile (100%) rename {book_tx => book_kr}/README.md (100%) rename {book_tx => book_kr}/back.png (100%) rename {book_tx => book_kr}/book.tex (100%) rename {book_tx => book_kr}/figs/assign2.eps (100%) rename {book_tx => book_kr}/figs/assign2.fig (100%) rename {book_tx => book_kr}/figs/assign2.fig.bak (100%) rename {book_tx => book_kr}/figs/assign2.pdf (100%) rename {book_tx => book_kr}/figs/banana.eps (100%) rename {book_tx => book_kr}/figs/banana.fig (100%) rename {book_tx => book_kr}/figs/banana.pdf (100%) rename {book_tx => book_kr}/figs/card1.eps (100%) rename {book_tx => book_kr}/figs/card1.fig (100%) rename {book_tx => book_kr}/figs/card1.pdf (100%) rename {book_tx => book_kr}/figs/class1.eps (100%) rename {book_tx => book_kr}/figs/class1.fig (100%) rename {book_tx => book_kr}/figs/class1.pdf (100%) rename {book_tx => book_kr}/figs/compile.eps (100%) rename {book_tx => book_kr}/figs/compile.fig (100%) rename {book_tx => book_kr}/figs/compile.pdf (100%) rename {book_tx => book_kr}/figs/dict1.eps (100%) rename {book_tx => book_kr}/figs/dict1.fig (100%) rename {book_tx => book_kr}/figs/dict1.pdf (100%) rename {book_tx => book_kr}/figs/dict2.eps (100%) rename {book_tx => book_kr}/figs/dict2.fig (100%) rename {book_tx => book_kr}/figs/dict2.pdf (100%) rename {book_tx => book_kr}/figs/fibonacci.eps (100%) rename {book_tx => book_kr}/figs/fibonacci.fig (100%) rename {book_tx => book_kr}/figs/fibonacci.pdf (100%) rename {book_tx => book_kr}/figs/flower.test.pdf (100%) rename {book_tx => book_kr}/figs/flowers.eps (100%) rename {book_tx => book_kr}/figs/flowers.pdf (100%) rename {book_tx => book_kr}/figs/interpret.eps (100%) rename {book_tx => book_kr}/figs/interpret.fig (100%) rename {book_tx => book_kr}/figs/interpret.pdf (100%) rename {book_tx => book_kr}/figs/koch.eps (100%) rename {book_tx => book_kr}/figs/koch.pdf (100%) rename {book_tx => book_kr}/figs/list1.eps (100%) rename {book_tx => book_kr}/figs/list1.fig (100%) rename {book_tx => book_kr}/figs/list1.pdf (100%) rename {book_tx => book_kr}/figs/list2.eps (100%) rename {book_tx => book_kr}/figs/list2.fig (100%) rename {book_tx => book_kr}/figs/list2.pdf (100%) rename {book_tx => book_kr}/figs/list3.eps (100%) rename {book_tx => book_kr}/figs/list3.fig (100%) rename {book_tx => book_kr}/figs/list3.pdf (100%) rename {book_tx => book_kr}/figs/liststate.eps (100%) rename {book_tx => book_kr}/figs/liststate.fig (100%) rename {book_tx => book_kr}/figs/liststate.fig.bak (100%) rename {book_tx => book_kr}/figs/liststate.pdf (100%) rename {book_tx => book_kr}/figs/listsum1.eps (100%) rename {book_tx => book_kr}/figs/listsum1.pdf (100%) rename {book_tx => book_kr}/figs/listsum2.eps (100%) rename {book_tx => book_kr}/figs/listsum2.pdf (100%) rename {book_tx => book_kr}/figs/loop.py (100%) rename {book_tx => book_kr}/figs/loop.py~ (100%) rename {book_tx => book_kr}/figs/pies.eps (100%) rename {book_tx => book_kr}/figs/pies.pdf (100%) rename {book_tx => book_kr}/figs/point.eps (100%) rename {book_tx => book_kr}/figs/point.fig (100%) rename {book_tx => book_kr}/figs/point.pdf (100%) rename {book_tx => book_kr}/figs/rectangle.eps (100%) rename {book_tx => book_kr}/figs/rectangle.fig (100%) rename {book_tx => book_kr}/figs/rectangle.pdf (100%) rename {book_tx => book_kr}/figs/rectangle2.eps (100%) rename {book_tx => book_kr}/figs/rectangle2.fig (100%) rename {book_tx => book_kr}/figs/rectangle2.pdf (100%) rename {book_tx => book_kr}/figs/stack.eps (100%) rename {book_tx => book_kr}/figs/stack.fig (100%) rename {book_tx => book_kr}/figs/stack.pdf (100%) rename {book_tx => book_kr}/figs/stack2.eps (100%) rename {book_tx => book_kr}/figs/stack2.fig (100%) rename {book_tx => book_kr}/figs/stack2.pdf (100%) rename {book_tx => book_kr}/figs/stack3.eps (100%) rename {book_tx => book_kr}/figs/stack3.fig (100%) rename {book_tx => book_kr}/figs/stack3.pdf (100%) rename {book_tx => book_kr}/figs/stack4.eps (100%) rename {book_tx => book_kr}/figs/stack4.fig (100%) rename {book_tx => book_kr}/figs/stack4.pdf (100%) rename {book_tx => book_kr}/figs/stack5.eps (100%) rename {book_tx => book_kr}/figs/stack5.fig (100%) rename {book_tx => book_kr}/figs/stack5.pdf (100%) rename {book_tx => book_kr}/figs/state.eps (100%) rename {book_tx => book_kr}/figs/state.fig (100%) rename {book_tx => book_kr}/figs/state.pdf (100%) rename {book_tx => book_kr}/figs/state2.eps (100%) rename {book_tx => book_kr}/figs/state2.fig (100%) rename {book_tx => book_kr}/figs/state2.pdf (100%) rename {book_tx => book_kr}/figs/state3.eps (100%) rename {book_tx => book_kr}/figs/state3.fig (100%) rename {book_tx => book_kr}/figs/state3.pdf (100%) rename {book_tx => book_kr}/figs/state4.eps (100%) rename {book_tx => book_kr}/figs/state4.fig (100%) rename {book_tx => book_kr}/figs/state4.pdf (100%) rename {book_tx => book_kr}/figs/state5.eps (100%) rename {book_tx => book_kr}/figs/state5.fig (100%) rename {book_tx => book_kr}/figs/state5.pdf (100%) rename {book_tx => book_kr}/figs/time.eps (100%) rename {book_tx => book_kr}/figs/time.fig (100%) rename {book_tx => book_kr}/figs/time.pdf (100%) rename {book_tx => book_kr}/figs/towers.eps (100%) rename {book_tx => book_kr}/figs/towers.fig (100%) rename {book_tx => book_kr}/figs/towers.pdf (100%) rename {book_tx => book_kr}/figs/tuple1.eps (100%) rename {book_tx => book_kr}/figs/tuple1.fig (100%) rename {book_tx => book_kr}/figs/tuple1.pdf (100%) rename {book_tx => book_kr}/footer.html (100%) rename {book_tx => book_kr}/header.html (100%) rename {book_tx => book_kr}/hevea.sty (100%) rename {book_tx => book_kr}/htmlonly (100%) rename {book_tx => book_kr}/latexonly (100%) rename {book_tx => book_kr}/localdef.py (100%) rename {book_tx => book_kr}/next.png (100%) rename {book_tx => book_kr}/up.png (100%) diff --git a/book_tx/Makefile b/book_kr/Makefile similarity index 100% rename from book_tx/Makefile rename to book_kr/Makefile diff --git a/book_tx/README.md b/book_kr/README.md similarity index 100% rename from book_tx/README.md rename to book_kr/README.md diff --git a/book_tx/back.png b/book_kr/back.png similarity index 100% rename from book_tx/back.png rename to book_kr/back.png diff --git a/book_tx/book.tex b/book_kr/book.tex similarity index 100% rename from book_tx/book.tex rename to book_kr/book.tex diff --git a/book_tx/figs/assign2.eps b/book_kr/figs/assign2.eps similarity index 100% rename from book_tx/figs/assign2.eps rename to book_kr/figs/assign2.eps diff --git a/book_tx/figs/assign2.fig b/book_kr/figs/assign2.fig similarity index 100% rename from book_tx/figs/assign2.fig rename to book_kr/figs/assign2.fig diff --git a/book_tx/figs/assign2.fig.bak b/book_kr/figs/assign2.fig.bak similarity index 100% rename from book_tx/figs/assign2.fig.bak rename to book_kr/figs/assign2.fig.bak diff --git a/book_tx/figs/assign2.pdf b/book_kr/figs/assign2.pdf similarity index 100% rename from book_tx/figs/assign2.pdf rename to book_kr/figs/assign2.pdf diff --git a/book_tx/figs/banana.eps b/book_kr/figs/banana.eps similarity index 100% rename from book_tx/figs/banana.eps rename to book_kr/figs/banana.eps diff --git a/book_tx/figs/banana.fig b/book_kr/figs/banana.fig similarity index 100% rename from book_tx/figs/banana.fig rename to book_kr/figs/banana.fig diff --git a/book_tx/figs/banana.pdf b/book_kr/figs/banana.pdf similarity index 100% rename from book_tx/figs/banana.pdf rename to book_kr/figs/banana.pdf diff --git a/book_tx/figs/card1.eps b/book_kr/figs/card1.eps similarity index 100% rename from book_tx/figs/card1.eps rename to book_kr/figs/card1.eps diff --git a/book_tx/figs/card1.fig b/book_kr/figs/card1.fig similarity index 100% rename from book_tx/figs/card1.fig rename to book_kr/figs/card1.fig diff --git a/book_tx/figs/card1.pdf b/book_kr/figs/card1.pdf similarity index 100% rename from book_tx/figs/card1.pdf rename to book_kr/figs/card1.pdf diff --git a/book_tx/figs/class1.eps b/book_kr/figs/class1.eps similarity index 100% rename from book_tx/figs/class1.eps rename to book_kr/figs/class1.eps diff --git a/book_tx/figs/class1.fig b/book_kr/figs/class1.fig similarity index 100% rename from book_tx/figs/class1.fig rename to book_kr/figs/class1.fig diff --git a/book_tx/figs/class1.pdf b/book_kr/figs/class1.pdf similarity index 100% rename from book_tx/figs/class1.pdf rename to book_kr/figs/class1.pdf diff --git a/book_tx/figs/compile.eps b/book_kr/figs/compile.eps similarity index 100% rename from book_tx/figs/compile.eps rename to book_kr/figs/compile.eps diff --git a/book_tx/figs/compile.fig b/book_kr/figs/compile.fig similarity index 100% rename from book_tx/figs/compile.fig rename to book_kr/figs/compile.fig diff --git a/book_tx/figs/compile.pdf b/book_kr/figs/compile.pdf similarity index 100% rename from book_tx/figs/compile.pdf rename to book_kr/figs/compile.pdf diff --git a/book_tx/figs/dict1.eps b/book_kr/figs/dict1.eps similarity index 100% rename from book_tx/figs/dict1.eps rename to book_kr/figs/dict1.eps diff --git a/book_tx/figs/dict1.fig b/book_kr/figs/dict1.fig similarity index 100% rename from book_tx/figs/dict1.fig rename to book_kr/figs/dict1.fig diff --git a/book_tx/figs/dict1.pdf b/book_kr/figs/dict1.pdf similarity index 100% rename from book_tx/figs/dict1.pdf rename to book_kr/figs/dict1.pdf diff --git a/book_tx/figs/dict2.eps b/book_kr/figs/dict2.eps similarity index 100% rename from book_tx/figs/dict2.eps rename to book_kr/figs/dict2.eps diff --git a/book_tx/figs/dict2.fig b/book_kr/figs/dict2.fig similarity index 100% rename from book_tx/figs/dict2.fig rename to book_kr/figs/dict2.fig diff --git a/book_tx/figs/dict2.pdf b/book_kr/figs/dict2.pdf similarity index 100% rename from book_tx/figs/dict2.pdf rename to book_kr/figs/dict2.pdf diff --git a/book_tx/figs/fibonacci.eps b/book_kr/figs/fibonacci.eps similarity index 100% rename from book_tx/figs/fibonacci.eps rename to book_kr/figs/fibonacci.eps diff --git a/book_tx/figs/fibonacci.fig b/book_kr/figs/fibonacci.fig similarity index 100% rename from book_tx/figs/fibonacci.fig rename to book_kr/figs/fibonacci.fig diff --git a/book_tx/figs/fibonacci.pdf b/book_kr/figs/fibonacci.pdf similarity index 100% rename from book_tx/figs/fibonacci.pdf rename to book_kr/figs/fibonacci.pdf diff --git a/book_tx/figs/flower.test.pdf b/book_kr/figs/flower.test.pdf similarity index 100% rename from book_tx/figs/flower.test.pdf rename to book_kr/figs/flower.test.pdf diff --git a/book_tx/figs/flowers.eps b/book_kr/figs/flowers.eps similarity index 100% rename from book_tx/figs/flowers.eps rename to book_kr/figs/flowers.eps diff --git a/book_tx/figs/flowers.pdf b/book_kr/figs/flowers.pdf similarity index 100% rename from book_tx/figs/flowers.pdf rename to book_kr/figs/flowers.pdf diff --git a/book_tx/figs/interpret.eps b/book_kr/figs/interpret.eps similarity index 100% rename from book_tx/figs/interpret.eps rename to book_kr/figs/interpret.eps diff --git a/book_tx/figs/interpret.fig b/book_kr/figs/interpret.fig similarity index 100% rename from book_tx/figs/interpret.fig rename to book_kr/figs/interpret.fig diff --git a/book_tx/figs/interpret.pdf b/book_kr/figs/interpret.pdf similarity index 100% rename from book_tx/figs/interpret.pdf rename to book_kr/figs/interpret.pdf diff --git a/book_tx/figs/koch.eps b/book_kr/figs/koch.eps similarity index 100% rename from book_tx/figs/koch.eps rename to book_kr/figs/koch.eps diff --git a/book_tx/figs/koch.pdf b/book_kr/figs/koch.pdf similarity index 100% rename from book_tx/figs/koch.pdf rename to book_kr/figs/koch.pdf diff --git a/book_tx/figs/list1.eps b/book_kr/figs/list1.eps similarity index 100% rename from book_tx/figs/list1.eps rename to book_kr/figs/list1.eps diff --git a/book_tx/figs/list1.fig b/book_kr/figs/list1.fig similarity index 100% rename from book_tx/figs/list1.fig rename to book_kr/figs/list1.fig diff --git a/book_tx/figs/list1.pdf b/book_kr/figs/list1.pdf similarity index 100% rename from book_tx/figs/list1.pdf rename to book_kr/figs/list1.pdf diff --git a/book_tx/figs/list2.eps b/book_kr/figs/list2.eps similarity index 100% rename from book_tx/figs/list2.eps rename to book_kr/figs/list2.eps diff --git a/book_tx/figs/list2.fig b/book_kr/figs/list2.fig similarity index 100% rename from book_tx/figs/list2.fig rename to book_kr/figs/list2.fig diff --git a/book_tx/figs/list2.pdf b/book_kr/figs/list2.pdf similarity index 100% rename from book_tx/figs/list2.pdf rename to book_kr/figs/list2.pdf diff --git a/book_tx/figs/list3.eps b/book_kr/figs/list3.eps similarity index 100% rename from book_tx/figs/list3.eps rename to book_kr/figs/list3.eps diff --git a/book_tx/figs/list3.fig b/book_kr/figs/list3.fig similarity index 100% rename from book_tx/figs/list3.fig rename to book_kr/figs/list3.fig diff --git a/book_tx/figs/list3.pdf b/book_kr/figs/list3.pdf similarity index 100% rename from book_tx/figs/list3.pdf rename to book_kr/figs/list3.pdf diff --git a/book_tx/figs/liststate.eps b/book_kr/figs/liststate.eps similarity index 100% rename from book_tx/figs/liststate.eps rename to book_kr/figs/liststate.eps diff --git a/book_tx/figs/liststate.fig b/book_kr/figs/liststate.fig similarity index 100% rename from book_tx/figs/liststate.fig rename to book_kr/figs/liststate.fig diff --git a/book_tx/figs/liststate.fig.bak b/book_kr/figs/liststate.fig.bak similarity index 100% rename from book_tx/figs/liststate.fig.bak rename to book_kr/figs/liststate.fig.bak diff --git a/book_tx/figs/liststate.pdf b/book_kr/figs/liststate.pdf similarity index 100% rename from book_tx/figs/liststate.pdf rename to book_kr/figs/liststate.pdf diff --git a/book_tx/figs/listsum1.eps b/book_kr/figs/listsum1.eps similarity index 100% rename from book_tx/figs/listsum1.eps rename to book_kr/figs/listsum1.eps diff --git a/book_tx/figs/listsum1.pdf b/book_kr/figs/listsum1.pdf similarity index 100% rename from book_tx/figs/listsum1.pdf rename to book_kr/figs/listsum1.pdf diff --git a/book_tx/figs/listsum2.eps b/book_kr/figs/listsum2.eps similarity index 100% rename from book_tx/figs/listsum2.eps rename to book_kr/figs/listsum2.eps diff --git a/book_tx/figs/listsum2.pdf b/book_kr/figs/listsum2.pdf similarity index 100% rename from book_tx/figs/listsum2.pdf rename to book_kr/figs/listsum2.pdf diff --git a/book_tx/figs/loop.py b/book_kr/figs/loop.py similarity index 100% rename from book_tx/figs/loop.py rename to book_kr/figs/loop.py diff --git a/book_tx/figs/loop.py~ b/book_kr/figs/loop.py~ similarity index 100% rename from book_tx/figs/loop.py~ rename to book_kr/figs/loop.py~ diff --git a/book_tx/figs/pies.eps b/book_kr/figs/pies.eps similarity index 100% rename from book_tx/figs/pies.eps rename to book_kr/figs/pies.eps diff --git a/book_tx/figs/pies.pdf b/book_kr/figs/pies.pdf similarity index 100% rename from book_tx/figs/pies.pdf rename to book_kr/figs/pies.pdf diff --git a/book_tx/figs/point.eps b/book_kr/figs/point.eps similarity index 100% rename from book_tx/figs/point.eps rename to book_kr/figs/point.eps diff --git a/book_tx/figs/point.fig b/book_kr/figs/point.fig similarity index 100% rename from book_tx/figs/point.fig rename to book_kr/figs/point.fig diff --git a/book_tx/figs/point.pdf b/book_kr/figs/point.pdf similarity index 100% rename from book_tx/figs/point.pdf rename to book_kr/figs/point.pdf diff --git a/book_tx/figs/rectangle.eps b/book_kr/figs/rectangle.eps similarity index 100% rename from book_tx/figs/rectangle.eps rename to book_kr/figs/rectangle.eps diff --git a/book_tx/figs/rectangle.fig b/book_kr/figs/rectangle.fig similarity index 100% rename from book_tx/figs/rectangle.fig rename to book_kr/figs/rectangle.fig diff --git a/book_tx/figs/rectangle.pdf b/book_kr/figs/rectangle.pdf similarity index 100% rename from book_tx/figs/rectangle.pdf rename to book_kr/figs/rectangle.pdf diff --git a/book_tx/figs/rectangle2.eps b/book_kr/figs/rectangle2.eps similarity index 100% rename from book_tx/figs/rectangle2.eps rename to book_kr/figs/rectangle2.eps diff --git a/book_tx/figs/rectangle2.fig b/book_kr/figs/rectangle2.fig similarity index 100% rename from book_tx/figs/rectangle2.fig rename to book_kr/figs/rectangle2.fig diff --git a/book_tx/figs/rectangle2.pdf b/book_kr/figs/rectangle2.pdf similarity index 100% rename from book_tx/figs/rectangle2.pdf rename to book_kr/figs/rectangle2.pdf diff --git a/book_tx/figs/stack.eps b/book_kr/figs/stack.eps similarity index 100% rename from book_tx/figs/stack.eps rename to book_kr/figs/stack.eps diff --git a/book_tx/figs/stack.fig b/book_kr/figs/stack.fig similarity index 100% rename from book_tx/figs/stack.fig rename to book_kr/figs/stack.fig diff --git a/book_tx/figs/stack.pdf b/book_kr/figs/stack.pdf similarity index 100% rename from book_tx/figs/stack.pdf rename to book_kr/figs/stack.pdf diff --git a/book_tx/figs/stack2.eps b/book_kr/figs/stack2.eps similarity index 100% rename from book_tx/figs/stack2.eps rename to book_kr/figs/stack2.eps diff --git a/book_tx/figs/stack2.fig b/book_kr/figs/stack2.fig similarity index 100% rename from book_tx/figs/stack2.fig rename to book_kr/figs/stack2.fig diff --git a/book_tx/figs/stack2.pdf b/book_kr/figs/stack2.pdf similarity index 100% rename from book_tx/figs/stack2.pdf rename to book_kr/figs/stack2.pdf diff --git a/book_tx/figs/stack3.eps b/book_kr/figs/stack3.eps similarity index 100% rename from book_tx/figs/stack3.eps rename to book_kr/figs/stack3.eps diff --git a/book_tx/figs/stack3.fig b/book_kr/figs/stack3.fig similarity index 100% rename from book_tx/figs/stack3.fig rename to book_kr/figs/stack3.fig diff --git a/book_tx/figs/stack3.pdf b/book_kr/figs/stack3.pdf similarity index 100% rename from book_tx/figs/stack3.pdf rename to book_kr/figs/stack3.pdf diff --git a/book_tx/figs/stack4.eps b/book_kr/figs/stack4.eps similarity index 100% rename from book_tx/figs/stack4.eps rename to book_kr/figs/stack4.eps diff --git a/book_tx/figs/stack4.fig b/book_kr/figs/stack4.fig similarity index 100% rename from book_tx/figs/stack4.fig rename to book_kr/figs/stack4.fig diff --git a/book_tx/figs/stack4.pdf b/book_kr/figs/stack4.pdf similarity index 100% rename from book_tx/figs/stack4.pdf rename to book_kr/figs/stack4.pdf diff --git a/book_tx/figs/stack5.eps b/book_kr/figs/stack5.eps similarity index 100% rename from book_tx/figs/stack5.eps rename to book_kr/figs/stack5.eps diff --git a/book_tx/figs/stack5.fig b/book_kr/figs/stack5.fig similarity index 100% rename from book_tx/figs/stack5.fig rename to book_kr/figs/stack5.fig diff --git a/book_tx/figs/stack5.pdf b/book_kr/figs/stack5.pdf similarity index 100% rename from book_tx/figs/stack5.pdf rename to book_kr/figs/stack5.pdf diff --git a/book_tx/figs/state.eps b/book_kr/figs/state.eps similarity index 100% rename from book_tx/figs/state.eps rename to book_kr/figs/state.eps diff --git a/book_tx/figs/state.fig b/book_kr/figs/state.fig similarity index 100% rename from book_tx/figs/state.fig rename to book_kr/figs/state.fig diff --git a/book_tx/figs/state.pdf b/book_kr/figs/state.pdf similarity index 100% rename from book_tx/figs/state.pdf rename to book_kr/figs/state.pdf diff --git a/book_tx/figs/state2.eps b/book_kr/figs/state2.eps similarity index 100% rename from book_tx/figs/state2.eps rename to book_kr/figs/state2.eps diff --git a/book_tx/figs/state2.fig b/book_kr/figs/state2.fig similarity index 100% rename from book_tx/figs/state2.fig rename to book_kr/figs/state2.fig diff --git a/book_tx/figs/state2.pdf b/book_kr/figs/state2.pdf similarity index 100% rename from book_tx/figs/state2.pdf rename to book_kr/figs/state2.pdf diff --git a/book_tx/figs/state3.eps b/book_kr/figs/state3.eps similarity index 100% rename from book_tx/figs/state3.eps rename to book_kr/figs/state3.eps diff --git a/book_tx/figs/state3.fig b/book_kr/figs/state3.fig similarity index 100% rename from book_tx/figs/state3.fig rename to book_kr/figs/state3.fig diff --git a/book_tx/figs/state3.pdf b/book_kr/figs/state3.pdf similarity index 100% rename from book_tx/figs/state3.pdf rename to book_kr/figs/state3.pdf diff --git a/book_tx/figs/state4.eps b/book_kr/figs/state4.eps similarity index 100% rename from book_tx/figs/state4.eps rename to book_kr/figs/state4.eps diff --git a/book_tx/figs/state4.fig b/book_kr/figs/state4.fig similarity index 100% rename from book_tx/figs/state4.fig rename to book_kr/figs/state4.fig diff --git a/book_tx/figs/state4.pdf b/book_kr/figs/state4.pdf similarity index 100% rename from book_tx/figs/state4.pdf rename to book_kr/figs/state4.pdf diff --git a/book_tx/figs/state5.eps b/book_kr/figs/state5.eps similarity index 100% rename from book_tx/figs/state5.eps rename to book_kr/figs/state5.eps diff --git a/book_tx/figs/state5.fig b/book_kr/figs/state5.fig similarity index 100% rename from book_tx/figs/state5.fig rename to book_kr/figs/state5.fig diff --git a/book_tx/figs/state5.pdf b/book_kr/figs/state5.pdf similarity index 100% rename from book_tx/figs/state5.pdf rename to book_kr/figs/state5.pdf diff --git a/book_tx/figs/time.eps b/book_kr/figs/time.eps similarity index 100% rename from book_tx/figs/time.eps rename to book_kr/figs/time.eps diff --git a/book_tx/figs/time.fig b/book_kr/figs/time.fig similarity index 100% rename from book_tx/figs/time.fig rename to book_kr/figs/time.fig diff --git a/book_tx/figs/time.pdf b/book_kr/figs/time.pdf similarity index 100% rename from book_tx/figs/time.pdf rename to book_kr/figs/time.pdf diff --git a/book_tx/figs/towers.eps b/book_kr/figs/towers.eps similarity index 100% rename from book_tx/figs/towers.eps rename to book_kr/figs/towers.eps diff --git a/book_tx/figs/towers.fig b/book_kr/figs/towers.fig similarity index 100% rename from book_tx/figs/towers.fig rename to book_kr/figs/towers.fig diff --git a/book_tx/figs/towers.pdf b/book_kr/figs/towers.pdf similarity index 100% rename from book_tx/figs/towers.pdf rename to book_kr/figs/towers.pdf diff --git a/book_tx/figs/tuple1.eps b/book_kr/figs/tuple1.eps similarity index 100% rename from book_tx/figs/tuple1.eps rename to book_kr/figs/tuple1.eps diff --git a/book_tx/figs/tuple1.fig b/book_kr/figs/tuple1.fig similarity index 100% rename from book_tx/figs/tuple1.fig rename to book_kr/figs/tuple1.fig diff --git a/book_tx/figs/tuple1.pdf b/book_kr/figs/tuple1.pdf similarity index 100% rename from book_tx/figs/tuple1.pdf rename to book_kr/figs/tuple1.pdf diff --git a/book_tx/footer.html b/book_kr/footer.html similarity index 100% rename from book_tx/footer.html rename to book_kr/footer.html diff --git a/book_tx/header.html b/book_kr/header.html similarity index 100% rename from book_tx/header.html rename to book_kr/header.html diff --git a/book_tx/hevea.sty b/book_kr/hevea.sty similarity index 100% rename from book_tx/hevea.sty rename to book_kr/hevea.sty diff --git a/book_tx/htmlonly b/book_kr/htmlonly similarity index 100% rename from book_tx/htmlonly rename to book_kr/htmlonly diff --git a/book_tx/latexonly b/book_kr/latexonly similarity index 100% rename from book_tx/latexonly rename to book_kr/latexonly diff --git a/book_tx/localdef.py b/book_kr/localdef.py similarity index 100% rename from book_tx/localdef.py rename to book_kr/localdef.py diff --git a/book_tx/next.png b/book_kr/next.png similarity index 100% rename from book_tx/next.png rename to book_kr/next.png diff --git a/book_tx/up.png b/book_kr/up.png similarity index 100% rename from book_tx/up.png rename to book_kr/up.png From a06ec8efdf16f37f2c7957287ab236611ae6961e Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Fri, 30 Jun 2017 00:53:15 +0900 Subject: [PATCH 04/13] case study --- book_kr/auto/book.el | 1216 ++++++++++++++++++++++++++++++++++++++++++ book_kr/book.tex | 201 ++++--- 2 files changed, 1312 insertions(+), 105 deletions(-) create mode 100644 book_kr/auto/book.el diff --git a/book_kr/auto/book.el b/book_kr/auto/book.el new file mode 100644 index 0000000..d634b5d --- /dev/null +++ b/book_kr/auto/book.el @@ -0,0 +1,1216 @@ +(TeX-add-style-hook "book" + (lambda () + (LaTeX-add-index-entries + "GNU Free Documentation License" + "Free Documentation License, GNU" + "Elkner, Jeff" + "Olin College" + "Meyers, Chris" + "Creative Commons" + "contributors" + "problem solving" + "program" + "running Python" + "Python!running" + "Python in a browser" + "PythonAnywhere" + "Python 2" + "interpreter" + "prompt" + "Hello, World" + "quotation mark" + "print statement" + "statement!print" + "function" + "print function" + "operator!arithmetic" + "arithmetic operator" + "bitwise operator" + "operator!bitwise" + "value" + "type" + "string" + "integer" + "floating-point" + "class" + "string type" + "type!str" + "int type" + "type!int" + "float type" + "type!float" + "sequence" + "formal language" + "natural language" + "language!formal" + "language!natural" + "syntax" + "token" + "structure" + "parse" + "ambiguity" + "redundancy" + "literalness" + "poetry" + "prose" + "debugging" + "bug" + "debugging!emotional response" + "emotional debugging" + "high-level language" + "low-level language" + "portability" + "interpret" + "operator" + "error message" + "calculator" + "running pace" + "variable" + "assignment statement" + "statement!assignment" + "state diagram" + "diagram!state" + "underscore character" + "keyword" + "expression" + "evaluate" + "statement" + "execute" + "interactive mode" + "script" + "script mode" + "order of operations" + "PEMDAS" + "string!operation" + "operator!string" + "concatenation" + "commutativity" + "comment" + "syntax error" + "error!syntax" + "runtime error" + "error!runtime" + "exception" + "safe language" + "language!safe" + "semantic error" + "error!semantic" + "assignment" + "operand" + "semantics" + "function call" + "parentheses!argument in" + "argument" + "return value" + "conversion!type" + "type conversion" + "int function" + "function!int" + "float function" + "function!float" + "str function" + "function!str" + "math function" + "function, math" + "module" + "module object" + "dot notation" + "log function" + "function!log" + "sine function" + "radian" + "trigonometric function" + "function, trigonometric" + "pi" + "sqrt function" + "function!sqrt" + "composition" + "SyntaxError" + "exception!SyntaxError" + "function definition" + "definition!function" + "def keyword" + "keyword!def" + "parentheses!empty" + "header" + "body" + "indentation" + "colon" + "ellipses" + "function type" + "type!function" + "use before def" + "flow of execution" + "parameter" + "function parameter" + "function argument" + "parentheses!parameters in" + "programmer-defined function" + "function!programmer defined" + "local variable" + "variable!local" + "NameError" + "exception!NameError" + "stack diagram" + "function frame" + "frame" + "diagram!stack" + "main" + "traceback" + "fruitful function" + "void function" + "function, fruitful" + "function, void" + "None special value" + "special value!None" + "NoneType type" + "type!NoneType" + "function, reasons for" + "experimental debugging" + "debugging!experimental" + "Holmes, Sherlock" + "Doyle, Arthur Conan" + "Linux" + "import statement" + "statement!import" + "len function" + "function!len" + "function object" + "object!function" + "grid" + "repetition" + "for loop" + "loop!for" + "statement!for" + "loop" + "polygon function" + "function!polygon" + "circle function" + "function!circle" + "arc function" + "function!arc" + "encapsulation" + "generalization" + "keyword argument" + "argument!keyword" + "interface" + "refactoring" + "development plan!encapsulation and generalization" + "docstring" + "triple-quoted string" + "string!triple-quoted" + "multiline string" + "string!multiline" + "precondition" + "postcondition" + "method" + "development plan" + "flower" + "pie" + "alphabet" + "turtle typewriter" + "typewriter, turtle" + "spiral" + "Archimedian spiral" + "floor division" + "floating-point division" + "division!floor" + "division!floating-point" + "modulus operator" + "operator!modulus" + "divisibility" + "boolean expression" + "expression!boolean" + "logical operator" + "operator!logical" + "True special value" + "False special value" + "special value!True" + "special value!False" + "bool type" + "type!bool" + "relational operator" + "operator!relational" + "and operator" + "or operator" + "not operator" + "operator!and" + "operator!or" + "operator!not" + "conditional statement" + "statement!conditional" + "if statement" + "statement!if" + "conditional execution" + "condition" + "compound statement" + "statement!compound" + "pass statement" + "statement!pass" + "alternative execution" + "else keyword" + "keyword!else" + "branch" + "chained conditional" + "conditional!chained" + "elif keyword" + "keyword!elif" + "nested conditional" + "conditional!nested" + "recursion" + "function!recursive" + "return statement" + "statement!return" + "base case" + "recursion!base case" + "infinite recursion" + "recursion!infinite" + "exception!RuntimeError" + "RuntimeError" + "keyboard input" + "input function" + "function!input" + "newline" + "ValueError" + "exception!ValueError" + "whitespace" + "exception!OverflowError" + "OverflowError" + "Fermat's Last Theorem" + "triangle" + "TurtleWorld" + "Koch curve" + "temporary variable" + "variable!temporary" + "dead code" + "abs function" + "function!abs" + "compare function" + "function!compare" + "development plan!incremental" + "testing!incremental development" + "Pythagorean theorem" + "testing!knowing the answer" + "sqrt" + "scaffolding" + "hypotenuse" + "function composition" + "boolean function" + "Turing complete language" + "language!Turing complete" + "Turing, Alan" + "Turing Thesis" + "vorpal" + "circular definition" + "definition!circular" + "factorial function" + "function!factorial" + "recursive definition" + "leap of faith" + "testing!leap of faith" + "fibonacci function" + "function!fibonacci" + "type checking" + "error checking" + "gamma function" + "isinstance function" + "function!isinstance" + "guardian pattern" + "pattern!guardian" + "incremental development" + "Ackermann function" + "function!ack" + "palindrome" + "greatest common divisor (GCD)" + "GCD (greatest common divisor)" + "reassignment" + "equality and assignment" + "update" + "variable!updating" + "initialization (before update)" + "increment" + "decrement" + "statement!while" + "while loop" + "loop!while" + "iteration" + "infinite loop" + "loop!infinite" + "Collatz conjecture" + "break statement" + "statement!break" + "square root" + "Newton's method" + "epsilon" + "algorithm" + "addition with carrying" + "carrying, addition with" + "subtraction!with borrowing" + "borrowing, subtraction with" + "debugging!by bisection" + "bisection, debugging by" + "initialization!variable" + "algorithm!square root" + "eval function" + "function!eval" + "Ramanujan, Srinivasa" + "character" + "bracket operator" + "operator!bracket" + "index" + "index!starting at zero" + "zero, index + starting at" + "exception!TypeError" + "TypeError" + "exception!IndexError" + "IndexError" + "index!negative" + "negative index" + "traversal" + "loop!traversal" + "abecedarian" + "McCloskey, Robert" + "slice operator" + "operator!slice" + "index!slice" + "string!slice" + "slice!string" + "copy!slice" + "slice!copy" + "mutability" + "immutability" + "string!immutable" + "object" + "item" + "item assignment" + "assignment!item" + "find function" + "function!find" + "search pattern" + "pattern!search" + "counter" + "counting and looping" + "looping and counting" + "looping!with strings" + "string!method" + "invocation" + "optional argument" + "argument!optional" + "in operator" + "operator!in" + "boolean operator" + "operator!boolean" + "string!comparison" + "comparison!string" + "slice" + "empty string" + "string method" + "method!string" + "count method" + "method!count" + "step size" + "letter rotation" + "rotation, letter" + "Moby Project" + "crosswords" + "open function" + "function!open" + "plain text" + "text!plain" + "object!file" + "file object" + "readline method" + "method!readline" + "strip method" + "method!strip" + "lipogram" + "reduction to a + previously solved problem" + "development plan!reduction" + "looping!with indices" + "index!looping with" + "reduction to a previously solved problem" + "testing!is hard" + "program testing" + "special case" + "testing!and absence of bugs" + "Dijkstra, Edsger" + "Car Talk" + "Puzzler" + "double letters" + "odometer" + "list" + "type!list" + "element" + "nested list" + "list!nested" + "empty list" + "list!empty" + "list!element" + "access" + "zero, index starting at" + "list!index" + "list!membership" + "membership!list" + "list!traversal" + "traversal!list" + "item update" + "update!item" + "list!operation" + "concatenation!list" + "list!concatenation" + "repetition!list" + "list!repetition" + "list!slice" + "slice!list" + "list!copy" + "slice!update" + "update!slice" + "list!method" + "method, list" + "append method" + "method!append" + "extend method" + "method!extend" + "sort method" + "method!sort" + "void method" + "method!void" + "update operator" + "operator!update" + "assignment!augmented" + "augmented assignment" + "accumulator!sum" + "reduce pattern" + "pattern!reduce" + "accumulator!list" + "map pattern" + "pattern!map" + "filter pattern" + "pattern!filter" + "element deletion" + "deletion, element of list" + "pop method" + "method!pop" + "del operator" + "operator!del" + "remove method" + "method!remove" + "list!function" + "function!list" + "split method" + "method!split" + "delimiter" + "join method" + "method!join" + "string!empty" + "aliasing" + "is operator" + "operator!is" + "equivalence" + "identity" + "reference!aliasing" + "reference" + "list!as argument" + "argument!list" + "aliasing!copying to avoid" + "copy!to avoid aliasing" + "sorted!function" + "function!sorted" + "accumulator" + "equivalent" + "identical" + "cumulative sum" + "anagram" + "duplicate" + "uniqueness" + "birthday paradox" + "random module" + "module!random" + "randint function" + "function!randint" + "method append" + "time module" + "module!time" + "membership!bisection search" + "bisection search" + "search, bisection" + "membership!binary search" + "binary search" + "search, binary" + "bisect module" + "module!bisect" + "reverse word pair" + "interlocking words" + "dictionary" + "type!dict" + "key" + "key-value pair" + "dict function" + "function!dict" + "squiggly bracket" + "bracket!squiggly" + "exception!KeyError" + "KeyError" + "membership!dictionary" + "values method" + "method!values" + "implementation" + "histogram" + "frequency" + "get method" + "method!get" + "dictionary!looping with" + "looping!with dictionaries" + "dictionary!lookup" + "dictionary!reverse lookup" + "lookup, dictionary" + "reverse lookup, dictionary" + "search" + "raise statement" + "statement!raise" + "exception!LookupError" + "LookupError" + "invert dictionary" + "dictionary!invert" + "singleton" + "hash function" + "hashable" + "call graph" + "memo" + "global variable" + "variable!global" + "flag" + "global statement" + "statement!global" + "declaration" + "update!global variable" + "global variable!update" + "UnboundLocalError" + "exception!UnboundLocalError" + "sanity check" + "consistency check" + "pretty print" + "pprint module" + "module!pprint" + "mapping" + "item!dictionary" + "hashtable" + "lookup" + "reverse lookup" + "diagram!call graph" + "set membership" + "membership!set" + "setdefault method" + "method!setdefault" + "rotation!letters" + "homophone" + "reducible word" + "word, reducible" + "tuple" + "type!tuple" + "parentheses!tuples in" + "tuple!singleton" + "tuple function" + "function!tuple" + "tuple!slice" + "slice!tuple" + "comparison!tuple" + "tuple!comparison" + "tuple!assignment" + "assignment!tuple" + "swap pattern" + "pattern!swap" + "email address" + "value!tuple" + "return value!tuple" + "function, tuple as return value" + "divmod" + "tuple assignment" + "max function" + "function!max" + "min function" + "function!min" + "variable-length argument tuple" + "argument!variable-length tuple" + "gather" + "parameter!gather" + "argument!gather" + "scatter" + "argument scatter" + "sum function" + "function!sum" + "zip function" + "function!zip" + "iterator" + "list!of tuples" + "enumerate function" + "function!enumerate" + "object!enumerate" + "enumerate object" + "items method" + "method!items" + "dictionary!initialize" + "zip function!use with dict" + "update method" + "method!update" + "traverse!dictionary" + "dictionary!traversal" + "tuple!as key in dictionary" + "tuple!in brackets" + "sorted function" + "reversed function" + "function!reversed" + "data structure" + "shape error" + "error!shape" + "structshape module" + "module!structshape" + "zip object" + "object!zip" + "shape" + "letter + frequency" + "frequency!letter" + "anagram set" + "set!anagram" + "Scrabble" + "bingo" + "metathesis" + "definition!recursive" + "string module" + "module!string" + "replace method" + "method!replace" + "translate method" + "method!translate" + "Project Gutenberg" + "word frequency" + "frequency!word" + "random number" + "number, random" + "deterministic" + "pseudorandom" + "random function" + "function!random" + "choice function" + "function!choice" + "histogram!random choice" + "histogram!word frequencies" + "Austin, Jane" + "accumulator!histogram" + "update!histogram" + "optional parameter" + "parameter!optional" + "default value" + "value!default" + "override" + "dictionary!subtraction" + "subtraction!dictionary" + "set" + "type!set" + "Markov analysis" + "prefix" + "suffix" + "random text" + "text!random" + "mash-up" + "benchmarking" + "profile module" + "module!profile" + "typographical error" + "random walk programming" + "development plan!random walk programming" + "rubber duck debugging" + "debugging!rubber duck" + "Zipf's law" + "logarithm" + "matplotlib" + "file" + "type!file" + "persistence" + "pickle module" + "module!pickle" + "file!reading and writing" + "close method" + "method!close" + "format operator" + "operator!format" + "format string" + "format sequence" + "filename" + "path" + "directory" + "folder" + "os module" + "module!os" + "getcwd function" + "function!getcwd" + "working directory" + "directory!working" + "relative path" + "path!relative" + "absolute path" + "path!absolute" + "exists function" + "function!exists" + "walk, directory" + "directory!walk" + "exception!IOError" + "IOError" + "file!permission" + "permission, file" + "exception, catching" + "try statement" + "statement!try" + "database" + "dbm + module" + "module!dbm" + "database object" + "object!database" + "update!database" + "bytes object" + "object!bytes" + "dictionary methods!dbm module" + "pickling" + "shelve module" + "module!shelve" + "shell" + "pipe" + "ls (Unix command)" + "Unix command!ls" + "popen function" + "function!popen" + "read method" + "method!read" + "md5" + "checksum" + "module, writing" + "word count" + "object!module" + "name built-in variable" + "module!reload" + "reload function" + "function!reload" + "repr function" + "function!repr" + "string representation" + "end of line character" + "text file" + "catch" + "pipe object" + "object!pipe" + "MP3" + "MD5 algorithm" + "algorithm!MD5" + "md5sum" + "diff" + "object-oriented programming" + "programmer-defined type" + "type!programmer-defined" + "point, mathematical" + "representation" + "object!class" + "class definition" + "definition!class" + "Point class" + "class!Point" + "class object" + "instance" + "instantiation" + "hexadecimal" + "instance attribute" + "attribute!instance" + "object diagram" + "diagram!object" + "instance!as argument" + "Rectangle class" + "class!Rectangle" + "embedded object" + "object!embedded" + "instance!as return value" + "object!mutable" + "copying objects" + "object!copying" + "copy module" + "module!copy" + "embedded object!copying" + "shallow copy" + "copy!shallow" + "deep copy" + "copy!deep" + "deepcopy function" + "function!deepcopy" + "exception!AttributeError" + "AttributeError" + "type function" + "function!type" + "hasattr function" + "function!hasattr" + "attribute" + "instantiate" + "Time class" + "class!Time" + "prototype and patch" + "development plan!prototype and patch" + "pure function" + "function type!pure" + "Monty Python and the Holy Grail" + "modifier" + "function type!modifier" + "functional programming style" + "planned development" + "development plan!designed" + "sexagesimal" + "subtraction with borrowing" + "invariant" + "assert statement" + "statement!assert" + "designed development" + "datetime module" + "module!datetime" + "birthday" + "Double Day" + "object!printing" + "function syntax" + "method syntax" + "subject" + "self (parameter name)" + "parameter!self" + "metaphor, method invocation" + "positional argument" + "argument!positional" + "other (parameter name)" + "parameter!other" + "init method" + "method!init" + "str method@\\_\\_str\\_\\_ method" + "method!\\_\\_str\\_\\_" + "add method" + "method!add" + "operator overloading" + "type-based dispatch" + "dispatch, type-based" + "radd method" + "method!radd" + "dispatch!type-based" + "polymorphism" + "attribute!initializing" + "dict attribute@\\_\\_dict\\_\\_ attribute" + "attribute!\\_\\_dict\\_\\_" + "traversal!dictionary" + "getattr function" + "function!getattr" + "maintainable" + "object-oriented design" + "object-oriented language" + "overloading" + "operator!overloading" + "information hiding" + "default value!avoiding mutable" + "mutable object, as default value" + "worst bug" + "bug!worst" + "Kangaroo class" + "class!Kangaroo" + "deck" + "card, playing" + "poker" + "rank" + "suit" + "encode" + "encrypt" + "map to" + "Card class" + "class!Card" + "class attribute" + "attribute!class" + "cmp method@\\_\\_cmp\\_\\_ method" + "method!\\_\\_cmp\\_\\_" + "list!of objects" + "deck, playing cards" + "loop!nested" + "Deck class" + "class!Deck" + "accumulator!string" + "string!accumulator" + "veneer" + "shuffle function" + "function!shuffle" + "inheritance" + "parentheses!parent class in" + "parent class" + "class!parent" + "Hand class" + "class!Hand" + "child class" + "class!child" + "IS-A relationship" + "HAS-A relationship" + "class diagram" + "diagram!class" + "multiplicity (in class diagram)" + "mro method" + "method!mro" + "method resolution order" + "Liskov substitution principle" + "development plan!data encapsulation" + "data encapsulation" + "conditional expression" + "expression!conditional" + "NaN" + "factorial" + "list comprehension" + "loop variable" + "generator expression" + "expression!generator" + "generator object" + "object!generator" + "StopIteration" + "exception!StopIteration" + "sum" + "any" + "built-in function!any" + "all" + "dictionary subtraction" + "object!set" + "set subtraction" + "subset" + "Counter" + "object!Counter" + "multiset" + "collections" + "module!collections" + "defaultdict" + "object!defaultdict" + "factory function" + "setdefault" + "namedtuple" + "object!namedtuple" + "factory" + "conditional" + "hanging" + "loop!condition" + "dir function" + "function!dir" + "debugger (pdb)" + "pdb (Python debugger)" + "testing!minimal test case" + "test case, minimal" + "model, mental" + "mental model" + "expression!big and hairy" + "big, hairy expression" + "precedence" + "frustration" + "rage" + "debugging!superstition" + "superstitious debugging" + "analysis of algorithms" + "Obama, Barack" + "Schmidt, Eric" + "bubble sort" + "radix sort" + "comparing algorithms" + "machine model" + "worst case" + "average case" + "order of growth" + "leading term" + "exponent" + "leading coefficient" + "crossover point" + "big-oh notation" + "linear growth" + "quadratic growth" + "badness" + "logarithmic growth" + "exponential growth" + "analysis of primitives" + "indexing" + "string methods" + "tuple methods" + "string concatenation" + "join@{\\tt join}" + "list methods" + "sorting" + "dictionary methods" + "comparison sort" + "stable sort" + "linear search" + "in@{\\tt in} operator" + "LinearMap@{\\tt LinearMap}" + "KeyError@{\\tt KeyError}" + "red-black tree" + "BetterMap@{\\tt BetterMap}" + "bounded" + "HashMap" + "rehashing" + "constant time" + "average cost" + "geometric resizing" + "Big-Oh notation" + "linear" + "quadratic") + (LaTeX-add-environments + "exercise") + (LaTeX-add-labels + "#1" + "hello" + "variables" + "fig.state2" + "funcchap" + "functionchap" + "parameters" + "stackdiagram" + "fig.stack" + "turtlechap" + "turtle" + "repetition" + "refactoring" + "docstring" + "fig.flowers" + "fig.pies" + "conditional.execution" + "alternative.execution" + "recursion" + "recursive.stack" + "fig.stack2" + "whitespace" + "fig.koch" + "fruitchap" + "incremental.development" + "boolean" + "more.recursion" + "fig.stack3" + "one.more.example" + "guardian" + "factdebug" + "ackermann" + "palindrome" + "fig.assign2" + "update" + "squareroot" + "bisectbug" + "strings" + "for" + "slice" + "fig.banana" + "find" + "counter" + "optional" + "inboth" + "fig.state4" + "isreverse" + "exrotate" + "wordplay" + "wordlist" + "search" + "sequence" + "mutable" + "fig.liststate" + "filter" + "equivalence" + "fig.list1" + "fig.list2" + "fig.list3" + "list.arguments" + "fig.stack5" + "cumulative" + "anagram" + "duplicate" + "wordlist1" + "bisection" + "histogram" + "raise" + "invert" + "fig.dict1" + "memoize" + "fig.fibonacci" + "wordlist2" + "setdefault" + "exrotatepairs" + "tuplechap" + "tuple.assignment" + "gather" + "dictuple" + "fig.tuple1" + "fig.dict2" + "anagrams" + "analysis" + "dictsub" + "randomwords" + "randhist" + "markov" + "paths" + "catch" + "modules" + "checksum" + "clobjects" + "point" + "attributes" + "fig.point" + "rectangles" + "fig.rectangle" + "copying" + "fig.rectangle2" + "hasattr" + "time" + "isafter" + "fig.time" + "increment" + "prototype" + "operator.overloading" + "polymorphism" + "kangaroo" + "class.attribute" + "fig.card1" + "comparecard" + "printdeck" + "class.diagram" + "fig.class1" + "poker" + "sets" + "algorithms" + "hashtable" + "fig.hash") + (TeX-add-symbols + '("Anchor" 1) + "thetitle" + "theversion" + "thedate" + "anchorcnt" + "mymapsto") + (TeX-run-style-hooks + "localdef" + "kotex" + "hyperref" + "bookmarks" + "appendix" + "upquote" + "hevea" + "setspace" + "makeidx" + "exercise" + "amsthm" + "amsmath" + "graphicx" + "fancyhdr" + "url" + "mathpazo" + "textcomp" + "" + "fontenc" + "T1" + "geometry" + "vmarginratio=1:1" + "hmarginratio=3:2" + "height=8.5in" + "width=5.5in" + "latex2e" + "bk10" + "10pt" + "latexonly"))) + diff --git a/book_kr/book.tex b/book_kr/book.tex index 407b9b4..7a8eee0 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -867,7 +867,7 @@ \section{최초의 프로그램} >>> print('Hello, World!') \end{verbatim} % -이것은 {\bf print 문장}의 예제이다. 실제 종이 인쇄하는 것이 아니고 +이것은 {\bf print 문}의 예제이다. 실제 종이 인쇄하는 것이 아니고 화면에 결과를 표시한다. 이 경우에는 결과는 다음의 단어들이다. \begin{verbatim} @@ -884,7 +884,7 @@ \section{최초의 프로그램} \ref{funcchap} 장에서 다룰 것이다. \index{function} \index{print function} -Python 2에서는 \texttt{print} 문장은 함수가 아니라서 괄호를 사용하지 +Python 2에서는 \texttt{print} 문은 함수가 아니라서 괄호를 사용하지 않는다는 것이 약간 다르다. \index{Python 2} @@ -1191,7 +1191,7 @@ \section{용어 해설} \item[프로그램(program):] 연산을 지정해놓은 명령어들의 집합. \index{program} -\item[print 문장(print statment):] Python 인터프리터가 화면에 어떤 값을 +\item[print 문(print statment):] Python 인터프리터가 화면에 어떤 값을 표시하도록 하는 명령어. \index{print statement} \index{statement!print} @@ -1264,7 +1264,7 @@ \section{연습 문제} \begin{enumerate} -\item \texttt{print} 문장에서 괄호 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? +\item \texttt{print} 문에서 괄호 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? \item 문자열을 출력한다고 했을 때 따옴표 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? @@ -1315,13 +1315,13 @@ \chapter{변수와 수식 그리고 문장} \index{variable} -\section{할당 문장} +\section{할당문} %Assignment statements \label{variables} \index{assignment statement} \index{statement!assignment} -{\bf 할당 문장(assignment statement)}은 새로운 변수를 생성하고 값을 부여한다. +{\bf 할당문(assignment statement)}은 새로운 변수를 생성하고 값을 부여한다. \begin{verbatim} >>> message = 'And now for something completely different' @@ -1437,8 +1437,8 @@ \section{수식과 문장} >>> print(n) \end{verbatim} % -첫 줄은 할당 문장으로 {\tt n}에 값을 부여하고 있고 두 번째 줄은 {\tt - n}에 할당된 값을 출력하는 \texttt{print} 문장이다. +첫 줄은 할당문으로 {\tt n}에 값을 부여하고 있고 두 번째 줄은 {\tt + n}에 할당된 값을 출력하는 \texttt{print} 문이다. 문장을 입력하면, 인터프리터는 {\bf 실행(excute)}한다. 실행한다는 의미는 그 문장이 뜻하는 데로 동작한다는 것이다. 일반적으로 문장에는 값이 할당되지 않는다. @@ -1513,7 +1513,7 @@ \section{스크립트 모드} 2 \end{verbatim} % -할당 문장은 결과를 표시하지 않는다. +할당문은 결과를 표시하지 않는다. 이해를 했는지 확인해보기 위해 다음의 문장들을 Python 인터프리터에 입력하여 어떻게 동작하는지 살펴보라. @@ -1524,7 +1524,7 @@ \section{스크립트 모드} \end{verbatim} 그리고 이 문장들을 스크립트로 저장하여 실행해보자. 결과가 어떻게 -되는가? 스크립트의 각 수식을 \texttt{print} 문장으로 변환하여 다시 +되는가? 스크립트의 각 수식을 \texttt{print} 문으로 변환하여 다시 실행해보자. @@ -1741,7 +1741,7 @@ \section{용어 해설} \item[계산(evaluate):] 하나의 값을 얻기 위해 연산하여 수식을 간단화하는 것 \item[문장(statement):] 명령이나 어떤 동작을 뜻하는 코드의 일부분. - 지금까지는 봐왔던 문장은 할당하는 것과 \texttt{print} 문장이 있다. + 지금까지는 봐왔던 문장은 할당하는 것과 \texttt{print} 문이 있다. \index{statement} \item[실행(execute):] 문장에 적힌 그대로를 수행 @@ -1931,7 +1931,7 @@ \section{수학 함수} \index{module} \index{module object} -모듈에 포함된 함수를 사용하기 전에 {\bf import 문장}으로 읽어들여야 한다. +모듈에 포함된 함수를 사용하기 전에 {\bf import 문}으로 읽어들여야 한다. \begin{verbatim} >>> import math @@ -2023,7 +2023,7 @@ \section{구성} \end{verbatim} % 거의 모든 곳에 값을 넣을 수 있으며 임의의 수식을 쓸 수 있다. 단, 한 -가지 예외가 있다. 할당 문장의 왼쪽에는 변수의 이름이 있어야 한다. +가지 예외가 있다. 할당문의 왼쪽에는 변수의 이름이 있어야 한다. 왼쪽에 다른 어떤 수식이라도 오면 문법 오류가 발생한다 (이것에 대한 예외 상황을 이후에 살펴 보자). @@ -2081,7 +2081,7 @@ \section{새로운 함수의 추가} %body 내용 -\texttt{print} 문장에 문자열은 큰따옴표로 싸여있다. 작은 따옴표나 +\texttt{print} 문에 문자열은 큰따옴표로 싸여있다. 작은 따옴표나 큰따옴표나 동일하다. 대부분의 사람들은 작은 따옴표를 사용하지만, 예외적으로 작은 따옴표(아포스트로피 또는 생략 기호)가 문자열 중에 포함된 경우에만 큰따옴표를 사용한다. @@ -2594,7 +2594,7 @@ \section{용어 해설} \index{import statement} \index{statement!import} -\item[모듈 객체(module object):] {\tt import} 문장으로 생성되는 값으로 +\item[모듈 객체(module object):] {\tt import} 문으로 생성되는 값으로 모듈에서 정의한 값들을 사용할 수 있도록 함 \index{module} @@ -2738,7 +2738,7 @@ \section{연습 문제} % 이 문장들의 결과는 \verb"'+ -'"이다. -{\tt print} 문장에 인자가 없다면 현재 출력 중이던 줄을 종료하고 다음 +{\tt print} 문에 인자가 없다면 현재 출력 중이던 줄을 종료하고 다음 줄로 넘어간다. \item 네 개의 행과 열이 있는 격자 무늬를 그리는 함수를 작성하여라. @@ -2874,7 +2874,7 @@ \section{간단한 반복} bob.fd(100) \end{verbatim} % -{\tt for} 문장을 쓰면 훨씬 간결하게 똑같은 일을 해 낼 수 있다. 다음의 +{\tt for} 문을 쓰면 훨씬 간결하게 똑같은 일을 해 낼 수 있다. 다음의 예제를 {\tt mypolygon.py}에 추가하고 다시 실행시켜보자. \index{for loop} \index{loop!for} @@ -2894,11 +2894,11 @@ \section{간단한 반복} Hello! \end{verbatim} % -이 예제가 {\tt for} 문장을 쓰는 가장 간단한 형태이다. 나중에 좀 더 +이 예제가 {\tt for} 문을 쓰는 가장 간단한 형태이다. 나중에 좀 더 살펴보자. 지금의 예제만으로도 정사각형을 그리는 프로그램을 더 단순하게 다시 작성할 수 있을 것이다. 성공할 때까지 시도해보자. -여기에 {\tt for} 문장을 써서 정사각형을 그리는 코드가 있다. +여기에 {\tt for} 문을 써서 정사각형을 그리는 코드가 있다. \begin{verbatim} @@ -2907,11 +2907,11 @@ \section{간단한 반복} bob.lt(90) \end{verbatim} % -{\tt for} 문장의 문법은 함수 정의와 유사하다. 콜론으로 끝이 나는 +{\tt for} 문의 문법은 함수 정의와 유사하다. 콜론으로 끝이 나는 헤더와 들여쓰기된 내용으로 구성된다. 내용에는 문장이 몇 개라도 포함될 수 있다. -{\tt for} 문장은 {\bf 반복문(루프, loop)}이라고도 불린다. 실행의 +{\tt for} 문은 {\bf 반복문(루프, loop)}이라고도 불린다. 실행의 흐름이 내용을 한 번 다 실행하고 다시 처음으로 돌아가서 실행하기 때문이다. 이 경우에는 내용을 4번 반복한다. \index{loop} @@ -3236,13 +3236,14 @@ \section{개발 계획} 이 과정에는 몇 가지 단점이 있다. 그 대안들은 이후에 살펴볼 것이다. 그래도 이 방법은 프로그램을 함수로 나누는 어떻게 나눌지 개발 전에 미리 알 수 없는 경우라면 충분히 의미있다. 개발하면서 설계도 같이 할 수 있기 때문이다. -\section{docstring} +\section{참고 문자열} +%docstring \label{docstring} \index{docstring} -A {\bf docstring} is a string at the beginning of a function that -explains the interface (``doc'' is short for ``documentation''). Here -is an example: +함수의 시작 부분에 인터페이스를 설명하는 글을 {\bf 참고 + 문자열(docstring)}이라 한다(doc은 documentation의 약어이다. 예를 +살펴보자. \begin{verbatim} def polyline(t, n, length, angle): @@ -3254,57 +3255,54 @@ \section{docstring} t.lt(angle) \end{verbatim} % -By convention, all docstrings are triple-quoted strings, also known -as multiline strings because the triple quotes allow the string -to span more than one line. +관례상 모든 참고 문자열은 멀티라인 문자열이라고도 불리는 세 개의 +큰따옴표로 싸여있다. 세 개의 큰따옴표는 여러 줄에 걸친 문자열을 +표현하는데 사용된다. \index{quotation mark} \index{triple-quoted string} \index{string!triple-quoted} \index{multiline string} \index{string!multiline} -It is terse, but it contains the essential information -someone would need to use this function. It explains concisely what -the function does (without getting into the details of how it does -it). It explains what effect each parameter has on the behavior of -the function and what type each parameter should be (if it is not -obvious). +이 함수를 사용하는데 간결하기는 하지만 꼭 필요한 정보를 포함하고 있다. +참고 문자열은 함수가 어떤 일을 하는지 요약한다(상세 동작 설명은 +제외한다). 매개 변수가 함수의 동작에 미치는 영향과 각 매개 변수는 어떤 +데이터 형을 갖는지를 설명한다(당연한 경우는 제외한다). -Writing this kind of documentation is an important part of interface -design. A well-designed interface should be simple to explain; -if you have a hard time explaining one of your functions, -maybe the interface could be improved. +이런 문서를 남기는 것은 인터페이스 설계에 있어 중요한 부분이다. 잘 +설계된 인터페이스라면 간단히 설명할 수 있어야 한다. 어떤 함수를 +설명하는데 애를 먹는다면 인터페이스에 개선의 여지가 있다는 말이다. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} \index{interface} -An interface is like a contract between a function and a caller. -The caller agrees to provide certain parameters and the function -agrees to do certain work. - -For example, {\tt polyline} requires four arguments: {\tt t} has to be -a Turtle; {\tt n} has to be an -integer; {\tt length} should be a positive number; and {\tt - angle} has to be a number, which is understood to be in degrees. - -These requirements are called {\bf preconditions} because they -are supposed to be true before the function starts executing. -Conversely, conditions at the end of the function are -{\bf postconditions}. Postconditions include the intended -effect of the function (like drawing line segments) and any -side effects (like moving the Turtle or making other changes). +인터페이스는 함수와 그 함수를 호출한 함수간의 계약과 같다. 호출한 +함수는 특정 매개 변수를 전달할 것을 그리고 함수는 그에 맞는 작업을 +한다는 것을 약속한다. + +예를 들면, {\tt polyline}은 거북이 객체 {\tt t}, 정수 {\tt n}, 양수 +{\tt length}, 각도를 나타나는 숫자 {\tt angle}이라는 네 개의 인자가 +필요하다. + +이러한 요구사항을 {\bf 사전 조건(precondition)}이라고 부른다. 함수 +실행 전에 기본적인 조건이 참이어야 하기 때문이다. 반대로 말하면, +함수의 끝에 있는 조건을 {\bf 사후 조건(postcondition)}이라 부른다. +사후 조건은 의도된 함수의 결과와 (예, 원을 이루는 선 그리기), 의도하지 +않은 부차적 동작의 결과(거북이를 이동한다거나 다른 변경들)를 포함한다. \index{precondition} \index{postcondition} -Preconditions are the responsibility of the caller. If the caller -violates a (properly documented!) precondition and the function -doesn't work correctly, the bug is in the caller, not the function. +사전 조건를 잘 지정하는 것은 호출하는 함수의 책임이다. 호출하는 함수가 +(문서화를 잘했는데도 불구하고) 전제 조건의 값을 제대로 지정하지 못하면 +함수는 정확하게 동작하지 않는다. 함수에 문제가 있어서가 아니라 +호출하는 함수에 버그가 있어서 잘못된 결과를 얻은 것이다. + +사전 조건이 충족되었더라도 사후 조건이 아니라면 버그는 함수에 있다. +명료한 사전/사후 조건은 디버깅하는데 도움이 된다. -If the preconditions are satisfied and the postconditions are -not, the bug is in the function. If your pre- and postconditions -are clear, they can help with debugging. \section{용어 해설} @@ -3312,48 +3310,45 @@ \section{용어 해설} \begin{description} -\item[method:] A function that is associated with an object and called -using dot notation. +\item[메소드(method):] 객체에 속해 있는 함수로 호출하기 위해 닷표기법을 + 사용함 \index{method} -\item[loop:] A part of a program that can run repeatedly. +\item[반복문(루프, loop):] 반복적으로 실행되는 프로그램의 한 부분 \index{loop} -\item[encapsulation:] The process of transforming a sequence of -statements into a function definition. +\item[캡슐화(encapsulation):] 일련의 문장들을 함수 정의로 변환하는 과정 \index{encapsulation} -\item[generalization:] The process of replacing something -unnecessarily specific (like a number) with something appropriately -general (like a variable or parameter). +\item[일반화(generalization):] 불필요하게 구체적인(특정 숫자와 같은) + 것을 좀 더 일반적인(변수나 매개 변수) 것으로 교체하는 과정 \index{generalization} -\item[keyword argument:] An argument that includes the name of -the parameter as a ``keyword''. +\item[키워드 인자(keyword argument):] 매개 변수 명을 ``키워드''로 + 인자에 포함하는 것 \index{keyword argument} \index{argument!keyword} -\item[interface:] A description of how to use a function, including -the name and descriptions of the arguments and return value. +\item[인터페이스(interface):] 함수의 사용법에 대한 설명으로 이름과 + 인자에 대한 설명 그리고 리턴 값을 포함함 \index{interface} -\item[refactoring:] The process of modifying a working program to - improve function interfaces and other qualities of the code. +\item[리팩터링(refactoring):] 동작하는 프로그램의 함수의 인터페이스와 + 코드를 개선하는 과정 \index{refactoring} -\item[development plan:] A process for writing programs. +\item[개발 계획(development plan):] 프로그램을 작성하는 과정 \index{development plan} -\item[docstring:] A string that appears at the top of a function - definition to document the function's interface. +\item[참고 문자열(docstring):] 함수 정의의 시작 부분에 작성된 함수의 + 인터페이스에 대한 설명 \index{docstring} -\item[precondition:] A requirement that should be satisfied by -the caller before a function starts. +\item[사전 조건(precondition):] 호출한 함수가 해당 함수를 실행하기 전에 + 만족해야 할 조건 \index{precondition} -\item[postcondition:] A requirement that should be satisfied by -the function before it ends. +\item[사후 조건(postcondition):] 함수가 종료하기 전에 만족시켜야 할 요구 사항 \index{precondition} \end{description} @@ -3364,23 +3359,20 @@ \section{연습 문제} \begin{exercise} -Download the code in this chapter from +이 장의 코드를 다음의 주소에서 다운 받자. \url{http://thinkpython2.com/code/polygon.py}. \begin{enumerate} -\item Draw a stack diagram that shows the state of the program -while executing {\tt circle(bob, radius)}. You can do the -arithmetic by hand or add {\tt print} statements to the code. +\item {\tt circle(bob, radius)}가 실행 중일 때 프로그램의 스택 상태도를 + 그려라. 손으로 계산하거나 {\tt print}문을 코드에 넣어도 된다. \index{stack diagram} -\item The version of {\tt arc} in Section~\ref{refactoring} is not -very accurate because the linear approximation of the -circle is always outside the true circle. As a result, -the Turtle ends up a few pixels away from the correct -destination. My solution shows a way to reduce -the effect of this error. Read the code and see if it makes -sense to you. If you draw a diagram, you might see how it works. +\item \ref{refactoring}절의 {\tt arc}는 아주 정확한 것은 아니다. 원의 + 선형 근사치는 언제나 원 밖에 존재하기 때문이다. 그 결과로 거북이는 + 정확한 위치에서 몇 픽셀씩 벗어나게 된다. 여기에 나와 있는 해법은 그 + 에러를 줄일 수 있는 방법을 제시한다. 코드를 읽어보고 이해가 가는지 + 보라. 그림을 그리면 어떻게 동작하는지 알 수 있을 것이다. \end{enumerate} @@ -3389,25 +3381,25 @@ \section{연습 문제} \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/flowers.pdf}} -\caption{Turtle flowers.} +\caption{거북이 꽃.} \label{fig.flowers} \end{figure} \begin{exercise} \index{flower} -Write an appropriately general set of functions that -can draw flowers as in Figure~\ref{fig.flowers}. +일반 함수들을 작성해서 그림~\ref{fig.flowers}의 꽃을 그려보라. -Solution: \url{http://thinkpython2.com/code/flower.py}, -also requires \url{http://thinkpython2.com/code/polygon.py}. + +해법: \url{http://thinkpython2.com/code/flower.py}, +필요한 것 \url{http://thinkpython2.com/code/polygon.py}. \end{exercise} \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/pies.pdf}} -\caption{Turtle pies.} +\caption{거북이 파이.} \label{fig.pies} \end{figure} @@ -3415,10 +3407,10 @@ \section{연습 문제} \begin{exercise} \index{pie} -Write an appropriately general set of functions that -can draw shapes as in Figure~\ref{fig.pies}. +그림~\ref{fig.pies}를 그릴 수 있는 일반 함수들을 작성하라. + -Solution: \url{http://thinkpython2.com/code/pie.py}. +해법: \url{http://thinkpython2.com/code/pie.py}. \end{exercise} @@ -3427,10 +3419,9 @@ \section{연습 문제} \index{turtle typewriter} \index{typewriter, turtle} -The letters of the alphabet can be constructed from a moderate number -of basic elements, like vertical and horizontal lines and a few -curves. Design an alphabet that can be drawn with a minimal -number of basic elements and then write functions that draw the letters. +영문 철자는 수직과 수평 선 그리고 몇 개의 곡선의 기본 요소들로 구성되어 +있다. 이 기본 요소들을 최소한으로 사용하여 그릴 수 있는 철자를 +설계해보라. 그리고, 그 철자들을 그리는 함수를 작성하라. You should write one function for each letter, with names \verb"draw_a", \verb"draw_b", etc., and put your functions From c8d307c02b6c4b37d043090a9895b8d4be33ca49 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Sat, 1 Jul 2017 18:33:43 +0900 Subject: [PATCH 05/13] logical expression --- book_kr/book.tex | 153 ++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 83 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 7a8eee0..660195c 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -3423,54 +3423,48 @@ \section{연습 문제} 있다. 이 기본 요소들을 최소한으로 사용하여 그릴 수 있는 철자를 설계해보라. 그리고, 그 철자들을 그리는 함수를 작성하라. -You should write one function for each letter, with names -\verb"draw_a", \verb"draw_b", etc., and put your functions -in a file named {\tt letters.py}. You can download a -``turtle typewriter'' from \url{http://thinkpython2.com/code/typewriter.py} -to help you test your code. - -You can get a solution from \url{http://thinkpython2.com/code/letters.py}; -it also requires -\url{http://thinkpython2.com/code/polygon.py}. +\verb"draw_a"와 \verb"draw_b"같은 식으로 각 철자마다 함수를 만들어서 +{\tt letters.py} 안에 저장하라. +\url{http://thinkpython2.com/code/typewriter.py}에 ``거북이 +타자기(turtle typewriter)''를 다운로드 받아 코드를 시험해볼 수 있다. + +\url{http://thinkpython2.com/code/letters.py}에 다운로드 받을 수 +있다. \url{http://thinkpython2.com/code/polygon.py}도 필요할 것이다. + \end{exercise} \begin{exercise} -Read about spirals at \url{http://en.wikipedia.org/wiki/Spiral}; then -write a program that draws an Archimedian spiral (or one of the other -kinds). Solution: \url{http://thinkpython2.com/code/spiral.py}. + \url{http://en.wikipedia.org/wiki/Spiral}에서 나선에 대해 읽은 후 + 아르케메데스의 나선(또는 그와 유사한 나선)을 그리는 프로그램을 작성해 + 보라. 해답은 \url{http://thinkpython2.com/code/spiral.py}. \index{spiral} \index{Archimedian spiral} \end{exercise} -\chapter{Conditionals and recursion} - -The main topic of this chapter is the {\tt if} statement, which -executes different code depending on the state of the program. -But first I want to introduce two new operators: floor division -and modulus. - +\chapter{조건문과 재귀문} +%Conditionals and recursion +프로그램의 상태에 따라 다른 코드를 실행하는 {\tt if} 문이 이 장의 핵심 +주제이다. 그 전에 내림 나눗셈 연산자와 나머지 연산자를 살펴보자. -\section{Floor division and modulus} -The {\bf floor division} operator, \verb"//", divides -two numbers and rounds down to an integer. For example, suppose the -run time of a movie is 105 minutes. You might want to know how -long that is in hours. Conventional division -returns a floating-point number: +\section{내림 나눗셈과 나머지 연산자} +%Floor division and modulus +%{\ +{\bf 내림 나눗셈} 연산자 \verb"//"는 두 수를 나누어 얻은 결과 값의 정수 값을 취한다. 예를 들어, 105분 길이의 영화가 있다고 했을 때 몇 시간짜리 영화인지 궁금할 때가 있다. 이런 경우 일반 나눗셈을 사용하면 부동소수점 값을 얻는다. \begin{verbatim} >>> minutes = 105 >>> minutes / 60 1.75 \end{verbatim} -But we don't normally write hours with decimal points. Floor -division returns the integer number of hours, dropping the -fraction part: +하지만, 일반적으로 시간을 소수점으로 표현하지 않는다. 내림 나눗셈은 +소수점 부분을 버리고 정수부분만 리턴한다. + \begin{verbatim} >>> minutes = 105 @@ -3479,7 +3473,7 @@ \section{Floor division and modulus} 1 \end{verbatim} -To get the remainder, you could subtract off one hour in minutes: +나머지를 원하면 60분에서 계산된 시간 값을 제외한 나머지 분을 빼면 된다. \begin{verbatim} >>> remainder = minutes - hours * 60 @@ -3494,8 +3488,8 @@ \section{Floor division and modulus} \index{modulus operator} \index{operator!modulus} -An alternative is to use the {\bf modulus operator}, \verb"%", which -divides two numbers and returns the remainder. +이런 복잡한 계산 대신 나눗셈 후 나머지 값을 리턴하는 {\bf 나머지 + 연산자} \verb"%"를 사용할 수 있다. \begin{verbatim} >>> remainder = minutes % 60 @@ -3503,33 +3497,29 @@ \section{Floor division and modulus} 45 \end{verbatim} % -The modulus operator is more useful than it seems. For -example, you can check whether one number is divisible by another---if -{\tt x \% y} is zero, then {\tt x} is divisible by {\tt y}. +나머지 연산자는 보기보다 매우 유용한다. 한 가지 예를 들어 보면, 나머지 +연산자는 어떤 값이 서로 나누어 떨어지는 지 확인할 때 쓸 수있다. {\tt + x \% y}가 영이라면 {\tt x}는 {\tt y}로 나누어 떨어진다. \index{divisibility} -Also, you can extract the right-most digit -or digits from a number. For example, {\tt x \% 10} yields the -right-most digit of {\tt x} (in base 10). Similarly {\tt x \% 100} -yields the last two digits. +또한, 어떤 숫자의 가장 오른쪽 자리수를 얻을 때 나머지 연산자를 쓸 수 +있다. {\tt x \% 10}을 계산하면 {\tt x}(십진수라 가정)의 1의 자리 값을 +얻는다. 마찬가지로 {\tt x \% 100}을 하면 마지막 두 자리 수를 얻는다. -If you are using Python 2, division works differently. The -division operator, \verb"/", performs floor division if both -operands are integers, and floating-point division if either -operand is a {\tt float}. +Python 2를 사용 중이라면 나눗셈은 다르게 동작한다. 나눗셈 연산자 +\verb"/"은 두 수가 모두 정수이면 내림 나눗셈을하고 두 값 중 하나라도 +{\tt 실수} 형면 부동소수점 나눗셈을 한다. \index{Python 2} -\section{Boolean expressions} +\section{불 표현식} +%Boolean expressions \index{boolean expression} \index{expression!boolean} \index{logical operator} \index{operator!logical} -A {\bf boolean expression} is an expression that is either true -or false. The following examples use the -operator {\tt ==}, which compares two operands and produces -{\tt True} if they are equal and {\tt False} otherwise: +{\bf 불 표현식(boolean expression)}은 참또는 거짓을 나타내는 표현식이다. 다음의 예들은 두 피연산자를 비교하는 {\tt ==} 연산자를 사용한다. 두 값이 동일하면 {\tt True(참)}을 다르면 {\tt False(거짓)}이다. \begin{verbatim} >>> 5 == 5 @@ -3538,8 +3528,8 @@ \section{Boolean expressions} False \end{verbatim} % -{\tt True} and {\tt False} are special -values that belong to the type {\tt bool}; they are not strings: +이 값은 문자열이 아니고, {\tt bool(불)} 데이터 형에 속한{\tt True}와 +{\tt False}는 특별한 값이다. \index{True special value} \index{False special value} \index{special value!True} @@ -3554,36 +3544,34 @@ \section{Boolean expressions} \end{verbatim} % -The {\tt ==} operator is one of the {\bf relational operators}; the -others are: +{\tt ==} 연산자는 {\bf 관계 연산자(relational operator)} 중 하나이다. +나머지는 다음과 같다. \begin{verbatim} - x != y # x is not equal to y - x > y # x is greater than y - x < y # x is less than y - x >= y # x is greater than or equal to y - x <= y # x is less than or equal to y + x != y # x 는 y와 같지 않음 + x > y # x 는 y보다 큼 + x < y # x 는 y보다 작음 + x >= y # x 는 y보다 크거나 같음 + x <= y # x 는 y보다 작거나 같음 y \end{verbatim} % -Although these operations are probably familiar to you, the Python -symbols are different from the mathematical symbols. A common error -is to use a single equal sign ({\tt =}) instead of a double equal sign -({\tt ==}). Remember that {\tt =} is an assignment operator and -{\tt ==} is a relational operator. There is no such thing as -{\tt =<} or {\tt =>}. +이 연산자들이 익숙해 보일 수 있지만, Python에서 사용하는 기호가 수학 +기호와 다르다. 가장 흔한 실수는 하나의 등호({\tt =})를 써서 두 값이 +같은지 비교((\tt ==})하는 것이다. {\tt =}는 할당 연산자이고 {\tt ==}가 +관계 연산자인 것을 기억해야 한다. 그리고 {\tt =<}나 {\tt =>}와 같은 +연산자는 없다. + \index{relational operator} \index{operator!relational} -\section {Logical operators} -\index{logical operator} -\index{operator!logical} - -There are three {\bf logical operators}: {\tt and}, {\tt -or}, and {\tt not}. The semantics (meaning) of these operators is -similar to their meaning in English. For example, -{\tt x > 0 and x < 10} is true only if {\tt x} is greater than 0 -{\em and} less than 10. +\section {논리 연산자} +%Logical operators +\index{logical operator} \index{operator!logical} 세 개의 {\bf 논리 + 연산자(logical operator)}가 있다. 각각은 {\tt and}, {\tt or}, 그리고 +{\tt not}이다. 이 연산자들의 의미는 영어에서의 각 단어의 의미와 같다. +예를 들어, {\tt x > 0 and x < 10} 은 {\tt x}가 0보다 크{\em고} 10보다 +10보다 작을 때 참이 된다. \index{and operator} \index{or operator} \index{not operator} @@ -3591,26 +3579,25 @@ \section{Boolean expressions} \index{operator!or} \index{operator!not} -{\tt n\%2 == 0 or n\%3 == 0} is true if {\em either or both} of the -conditions is true, that is, if the number is divisible by 2 {\em or} -3. +{\tt n\%2 == 0 or n\%3 == 0} 은 {\em 둘 중 하나만} 또는 {\em둘 다} 참일 +때 참이 된다. 즉, 2 {\em 또는} 3으로 나누어 지거는 경우이다. -Finally, the {\tt not} operator negates a boolean -expression, so {\tt not (x > y)} is true if {\tt x > y} is false, -that is, if {\tt x} is less than or equal to {\tt y}. +마지막으로 {\tt not} 연산자는 불 표현식의 반대 값을 취한다. {\tt not + (x > y)}는 {\tt x > y}가 거짓일 때 참이 된다. 즉, {\tt x}가 {\tt + y}보다 작거나 같은 경우이다. -Strictly speaking, the operands of the logical operators should be -boolean expressions, but Python is not very strict. -Any nonzero number is interpreted as {\tt True}: +정확하게 말하면, 논리 연산자의 피연산자는 불 표현식이어야하지만, +Python이 그렇게 엄격하지는 않다. 0이 아닌 어떤 수이기만 하면 {\tt + True}으로 인식한다. \begin{verbatim} >>> 42 and True True \end{verbatim} % -This flexibility can be useful, but there are some subtleties to -it that might be confusing. You might want to avoid it (unless -you know what you are doing). +이러한 유연성이 도움이 될 때도 있지만, 미묘한 부분도 있기 때문에 혼돈이 +있을 수도 있다. 이렇게 사용하는 것은 피하는게 좋다(뭘 하는지 정확히 +알고 있다면 모를까). \section{Conditional execution} From 36ed85079b557d0a33b580a98e2685af54b2aa01 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Sat, 1 Jul 2017 23:30:03 +0900 Subject: [PATCH 06/13] recursion --- book_kr/book.tex | 229 ++++++++++++++++++++++++----------------------- 1 file changed, 115 insertions(+), 114 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 660195c..a6d10f7 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -884,7 +884,7 @@ \section{최초의 프로그램} \ref{funcchap} 장에서 다룰 것이다. \index{function} \index{print function} -Python 2에서는 \texttt{print} 문은 함수가 아니라서 괄호를 사용하지 +Python 2에서는 \texttt{print}문은 함수가 아니라서 괄호를 사용하지 않는다는 것이 약간 다르다. \index{Python 2} @@ -1264,7 +1264,7 @@ \section{연습 문제} \begin{enumerate} -\item \texttt{print} 문에서 괄호 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? +\item \texttt{print}문에서 괄호 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? \item 문자열을 출력한다고 했을 때 따옴표 중 하나 또는 둘 다 입력하지 않으면 어떻게 될까? @@ -1438,7 +1438,7 @@ \section{수식과 문장} \end{verbatim} % 첫 줄은 할당문으로 {\tt n}에 값을 부여하고 있고 두 번째 줄은 {\tt - n}에 할당된 값을 출력하는 \texttt{print} 문이다. + n}에 할당된 값을 출력하는 \texttt{print}문이다. 문장을 입력하면, 인터프리터는 {\bf 실행(excute)}한다. 실행한다는 의미는 그 문장이 뜻하는 데로 동작한다는 것이다. 일반적으로 문장에는 값이 할당되지 않는다. @@ -1524,7 +1524,7 @@ \section{스크립트 모드} \end{verbatim} 그리고 이 문장들을 스크립트로 저장하여 실행해보자. 결과가 어떻게 -되는가? 스크립트의 각 수식을 \texttt{print} 문으로 변환하여 다시 +되는가? 스크립트의 각 수식을 \texttt{print}문으로 변환하여 다시 실행해보자. @@ -1741,7 +1741,7 @@ \section{용어 해설} \item[계산(evaluate):] 하나의 값을 얻기 위해 연산하여 수식을 간단화하는 것 \item[문장(statement):] 명령이나 어떤 동작을 뜻하는 코드의 일부분. - 지금까지는 봐왔던 문장은 할당하는 것과 \texttt{print} 문이 있다. + 지금까지는 봐왔던 문장은 할당하는 것과 \texttt{print}문이 있다. \index{statement} \item[실행(execute):] 문장에 적힌 그대로를 수행 @@ -2081,7 +2081,7 @@ \section{새로운 함수의 추가} %body 내용 -\texttt{print} 문에 문자열은 큰따옴표로 싸여있다. 작은 따옴표나 +\texttt{print}문에 문자열은 큰따옴표로 싸여있다. 작은 따옴표나 큰따옴표나 동일하다. 대부분의 사람들은 작은 따옴표를 사용하지만, 예외적으로 작은 따옴표(아포스트로피 또는 생략 기호)가 문자열 중에 포함된 경우에만 큰따옴표를 사용한다. @@ -2594,7 +2594,7 @@ \section{용어 해설} \index{import statement} \index{statement!import} -\item[모듈 객체(module object):] {\tt import} 문으로 생성되는 값으로 +\item[모듈 객체(module object):] {\tt import}문으로 생성되는 값으로 모듈에서 정의한 값들을 사용할 수 있도록 함 \index{module} @@ -2738,7 +2738,7 @@ \section{연습 문제} % 이 문장들의 결과는 \verb"'+ -'"이다. -{\tt print} 문에 인자가 없다면 현재 출력 중이던 줄을 종료하고 다음 +{\tt print}문에 인자가 없다면 현재 출력 중이던 줄을 종료하고 다음 줄로 넘어간다. \item 네 개의 행과 열이 있는 격자 무늬를 그리는 함수를 작성하여라. @@ -2874,7 +2874,7 @@ \section{간단한 반복} bob.fd(100) \end{verbatim} % -{\tt for} 문을 쓰면 훨씬 간결하게 똑같은 일을 해 낼 수 있다. 다음의 +{\tt for}문을 쓰면 훨씬 간결하게 똑같은 일을 해 낼 수 있다. 다음의 예제를 {\tt mypolygon.py}에 추가하고 다시 실행시켜보자. \index{for loop} \index{loop!for} @@ -2894,11 +2894,11 @@ \section{간단한 반복} Hello! \end{verbatim} % -이 예제가 {\tt for} 문을 쓰는 가장 간단한 형태이다. 나중에 좀 더 +이 예제가 {\tt for}문을 쓰는 가장 간단한 형태이다. 나중에 좀 더 살펴보자. 지금의 예제만으로도 정사각형을 그리는 프로그램을 더 단순하게 다시 작성할 수 있을 것이다. 성공할 때까지 시도해보자. -여기에 {\tt for} 문을 써서 정사각형을 그리는 코드가 있다. +여기에 {\tt for}문을 써서 정사각형을 그리는 코드가 있다. \begin{verbatim} @@ -2907,11 +2907,11 @@ \section{간단한 반복} bob.lt(90) \end{verbatim} % -{\tt for} 문의 문법은 함수 정의와 유사하다. 콜론으로 끝이 나는 +{\tt for}문의 문법은 함수 정의와 유사하다. 콜론으로 끝이 나는 헤더와 들여쓰기된 내용으로 구성된다. 내용에는 문장이 몇 개라도 포함될 수 있다. -{\tt for} 문은 {\bf 반복문(루프, loop)}이라고도 불린다. 실행의 +{\tt for}문은 {\bf 반복문(루프, loop)}이라고도 불린다. 실행의 흐름이 내용을 한 번 다 실행하고 다시 처음으로 돌아가서 실행하기 때문이다. 이 경우에는 내용을 4번 반복한다. \index{loop} @@ -2990,7 +2990,7 @@ \section{캡슐화} % 가장 안쪽의 문장의 {\tt fd}와 {\tt lt}는 두 번 들여쓰기가 되어 {\tt for} 반복문 안에 있다는 것과 반복문은 함수 정의 내에 있다는 것을 -나타낸다. 그 다음 줄의 {\tt square(bob)} 문장은 왼쪽 끝에 있기 때문에 +나타낸다. 그 다음 줄의 {\tt square(bob)}문은 왼쪽 끝에 있기 때문에 {\tt for} 반복문이나 함수 정의 내에 있지 않다는 것을 뜻한다. 함수 내의 {\tt t}는 {\tt bob}과 동일한 거북이를 가리키기 때문에 {\tt @@ -3095,7 +3095,7 @@ \section{인터페이스 설계} % 첫 줄은 반지름을 {\tt r}로 하는 원의 둘레를 $ 2 \pi r$로 계산한다. {\tt math.pi}를 쓰기 때문에 {\tt math} 모듈을 불러와야 한다. -{\tt import} 문장은 관례적으로 항상 스크립트의 첫 줄에 적는다. +{\tt import}문은 관례적으로 항상 스크립트의 첫 줄에 적는다. 근사한 원의 둘레는 {\tt n}개의 선으로 표현하였고, {\tt length}는 그 선의 길이를 나타낸다. 결과적으로 {\tt polygon}은 50각형을 그려서 @@ -3447,7 +3447,7 @@ \section{연습 문제} \chapter{조건문과 재귀문} %Conditionals and recursion -프로그램의 상태에 따라 다른 코드를 실행하는 {\tt if} 문이 이 장의 핵심 +프로그램의 상태에 따라 다른 코드를 실행하는 {\tt if}문이 이 장의 핵심 주제이다. 그 전에 내림 나눗셈 연산자와 나머지 연산자를 살펴보자. @@ -3600,7 +3600,8 @@ \section{불 표현식} 알고 있다면 모를까). -\section{Conditional execution} +\section{조건부 실행} +%Conditional execution \label{conditional.execution} \index{conditional statement} @@ -3608,32 +3609,32 @@ \section{Conditional execution} \index{if statement} \index{statement!if} \index{conditional execution} -In order to write useful programs, we almost always need the ability -to check conditions and change the behavior of the program -accordingly. {\bf Conditional statements} give us this ability. The -simplest form is the {\tt if} statement: + +프로그램을 유용하게 만들려면 프로그램이 상황에 맞게 동작할 수 있도록 +조건을 검사하는 능력이 반드시 필요하다. {\bf 조건문(conditional + statement)}이 바로 그 능력을 갖고 있다. 그 중 가장 간단한 것은 {\tt + if}문이다. \begin{verbatim} if x > 0: print('x is positive') \end{verbatim} % -The boolean expression after {\tt if} is -called the {\bf condition}. If it is true, the indented -statement runs. If not, nothing happens. +{\tt if}문 이후의 불 표현식은 {\bf 조건(condition)}이라 부른다. +참이라면, 의도한 문장이 실행되고 그렇지 않다면 아무 일도 일어 나지 +않는다. \index{condition} \index{compound statement} \index{statement!compound} -{\tt if} statements have the same structure as function definitions: -a header followed by an indented body. Statements like this are -called {\bf compound statements}. +헤더와 들여쓰기된 내용으로 구성된 함수 정의처럼 {\tt if}문도 헤더와 +내용을 갖고 있다. 이런 류의 문장들을 {\bf 복합 문장(compound + statement)}라고 부른다. -There is no limit on the number of statements that can appear in -the body, but there has to be at least one. -Occasionally, it is useful to have a body with no statements (usually -as a place keeper for code you haven't written yet). In that -case, you can use the {\tt pass} statement, which does nothing. +내용에 포함될 수 있는 문장의 수가 정해지지 않았지만 최소한 하나는 +있어야 한다. 때로는 어떤 문장도 없는 내용이 필요할 때도 있다(아직 적지 +않은 코드를 대신해서 자리만 차지하는 기호를 쓸 수도 있다). 그 때에는 +아무 일도 하지 않는 {\tt pass}문을 쓰면 된다. \index{pass statement} \index{statement!pass} @@ -3643,15 +3644,16 @@ \section{Conditional execution} \end{verbatim} % -\section{Alternative execution} +\section{선택적 실행} +%Alternative execution \label{alternative.execution} \index{alternative execution} \index{else keyword} \index{keyword!else} -A second form of the {\tt if} statement is ``alternative execution'', -in which there are two possibilities and the condition determines -which one runs. The syntax looks like this: +{\tt if}문의 두 번째 형식은 ``선택적 실행(aternative +execution)''이다. 두 가지 대안이 존재하고 조건 검사를 통해 대안 중 +하나를 선택하여 실행한다. 문법은 다음과 같다. \begin{verbatim} if x % 2 == 0: @@ -3660,23 +3662,22 @@ \section{Alternative execution} print('x is odd') \end{verbatim} % -If the remainder when {\tt x} is divided by 2 is 0, then we know that -{\tt x} is even, and the program displays an appropriate message. If -the condition is false, the second set of statements runs. -Since the condition must be true or false, exactly one of the -alternatives will run. The alternatives are called {\bf - branches}, because they are branches in the flow of execution. -\index{branch} +{\tt x}를 2로 나눈 나머지가 0이라면 {\tt x}가 짝수이고, 프로그램은 +걸맞는 메시지를 표시한다. 조건이 거짓이라면, 두 번째 부분의 문장이 +실행된다. 조건은 참이거나 거짓이기 때문에 둘 중에 정확히 하나만 +선택적으로 실행된다. 실행의 흐름이 분리되므로 이러한 종류의 선택지를 +{\bf 분기(branch)}라고 부른다. \index{branch} -\section{Chained conditionals} +\section{연쇄 조건문} +%Chained conditionals \index{chained conditional} \index{conditional!chained} -Sometimes there are more than two possibilities and we need more than -two branches. One way to express a computation like that is a {\bf -chained conditional}: +두 개 이상의 가능성이 있는 경우 두개 이상의 분기가 필요하다. 이런 류의 +연산을 {\bf 연쇄적 조건문(chained conditional)}이다. + \begin{verbatim} if x < y: @@ -3687,10 +3688,9 @@ \section{Chained conditionals} print('x and y are equal') \end{verbatim} % -{\tt elif} is an abbreviation of ``else if''. Again, exactly one -branch will run. There is no limit on the number of {\tt -elif} statements. If there is an {\tt else} clause, it has to be -at the end, but there doesn't have to be one. +{\tt elif}는 ``else if''의 약어이다. 다시 한 번 말하지만, 선택된 +분기가 실행된다. {\tt elif}문이 몇 개가 있던 상관없다. {\tt else} +절을 만나면 거기가 마지막이지만, 꼭 필요한 것은 아니다. \index{elif keyword} \index{keyword!elif} @@ -3703,19 +3703,20 @@ \section{Chained conditionals} draw_c() \end{verbatim} % -Each condition is checked in order. If the first is false, -the next is checked, and so on. If one of them is -true, the corresponding branch runs and the statement -ends. Even if more than one condition is true, only the -first true branch runs. +각 조건은 순차적으로 검사된다. 처음 조건이 거짓이면 다음 조건을 +검사하는 식이다. 참인 조건을 만나면 해당 분기가 실행되고 {\tt if}문은 +종료한다. 여러 개의 조건이 참이 될 수는 있는지 첫 번째 참이 조건만 +실행이 된다. -\section{Nested conditionals} + +\section{중첩된 조건문} +%Nested conditionals \index{nested conditional} \index{conditional!nested} -One conditional can also be nested within another. We could have -written the example in the previous section like this: +조건문은 다른 조건문 내에 포함될 수 있다. 전 절에서 봤던 예제를 다음과 +같이 적을 수도 있다. \begin{verbatim} if x == y: @@ -3727,19 +3728,18 @@ \section{Nested conditionals} print('x is greater than y') \end{verbatim} % -The outer conditional contains two branches. The -first branch contains a simple statement. The second branch -contains another {\tt if} statement, which has two branches of its -own. Those two branches are both simple statements, -although they could have been conditional statements as well. +처음 만나는 조건문은 분기가 두개다. 첫 번째 분기는 간단한 +\texttt{printf}문이다. 두 번째 분기는 또 다른 {\tt if}문을 포함하고 +있다. 내부의 {\tt if}문도 두 개의 분기를 갖고 있다. 각 분기의 내용도 +간단한 문장이지만, 이 문장들도 또 다른 조건문이었을 수도 있다. + +문장 들여쓰기를 하면 구조가 시각적으로 명확해지긴 하지만, {\bf 중첩된 + 조건문(nested conditionals)}을 사용하면 읽기가 어려워진다. 가능하면 +쓰지 않는 방법을 찾는 것이 좋다. -Although the indentation of the statements makes the structure -apparent, {\bf nested conditionals} become difficult to read very -quickly. It is a good idea to avoid them when you can. +논리 연산자를 쓰면 중첩된 조건문이 간단해지는 경우가 많다. 다음의 +코드를 하나의 조건문으로 바꿔보자. -Logical operators often provide a way to simplify nested conditional -statements. For example, we can rewrite the following code using a -single conditional: \begin{verbatim} if 0 < x: @@ -3747,15 +3747,15 @@ \section{Nested conditionals} print('x is a positive single-digit number.') \end{verbatim} % -The {\tt print} statement runs only if we make it past both -conditionals, so we can get the same effect with the {\tt and} operator: +{\tt print}문은 두 개의 조건문을 모두 통과 했을 때만 실행이 된다. 이와 +같은 경우에 {\tt and} 연산자를 쓰면 동일한 효과를 볼 수 있다. \begin{verbatim} if 0 < x and x < 10: print('x is a positive single-digit number.') \end{verbatim} -For this kind of condition, Python provides a more concise option: +이와 같은 조건문에 Python은 더 간단한 표기법을 제공한다. \begin{verbatim} if 0 < x < 10: @@ -3763,78 +3763,80 @@ \section{Nested conditionals} \end{verbatim} -\section{Recursion} +\section{재귀문} +%Recursion \label{recursion} \index{recursion} -It is legal for one function to call another; -it is also legal for a function to call itself. It may not be obvious -why that is a good thing, but it turns out to be one of the most -magical things a program can do. -For example, look at the following function: +어느 한 함수가 또 다른 함수를 부르는 것은 전혀 이상하지 않다. 그렇기 +때문에 어떤 함수가 자기 자신을 부르는 것도 가능하다. 함수가 자신을 +부르는 것이 유용한 것인지 확신이 서지 않을 수도 있다. 나중에 +알게되겠지만, 프로그램이 할 수 있는 가장 마법같은 일 중 +하나가 재귀적 호출이다. 예로 다음의 함수를 살펴보자. + \begin{verbatim} def countdown(n): if n <= 0: - print('Blastoff!') + print('발사!') else: print(n) countdown(n-1) \end{verbatim} % -If {\tt n} is 0 or negative, it outputs the word, ``Blastoff!'' -Otherwise, it outputs {\tt n} and then calls a function named {\tt -countdown}---itself---passing {\tt n-1} as an argument. +{\tt n}이 0이거나 음수이면 ``발사!''고 표시하고 그 외의 경우에는 {\tt + n}을 화면에 적고 {\tt n-1}을 인자로하여 자기 자신({\tt countdown})을 +호출한다. -What happens if we call this function like this? +다음과 같이 함수를 호출하면 어떻게 될까? \begin{verbatim} >>> countdown(3) \end{verbatim} % -The execution of {\tt countdown} begins with {\tt n=3}, and since -{\tt n} is greater than 0, it outputs the value 3, and then calls itself... +{\tt countdown}은 {\tt n=3}에서 실행된다. {\tt n}은 0보다 크기 때문에 +3을 출력하고 자신을 호출한다. + \begin{quote} -The execution of {\tt countdown} begins with {\tt n=2}, and since -{\tt n} is greater than 0, it outputs the value 2, and then calls itself... +{\tt countdown}은 {\tt n=2}에서 실행된다. {\tt n}은 0보다 크기 때문에 +2을 출력하고 자신을 호출한다. + \begin{quote} -The execution of {\tt countdown} begins with {\tt n=1}, and since -{\tt n} is greater than 0, it outputs the value 1, and then calls itself... +{\tt countdown}은 {\tt n=1}에서 실행된다. {\tt n}은 0보다 크기 때문에 +1을 출력하고 자신을 호출한다. + \begin{quote} -The execution of {\tt countdown} begins with {\tt n=0}, and since {\tt -n} is not greater than 0, it outputs the word, ``Blastoff!'' and then -returns. +{\tt countdown}은 {\tt n=0}에서 실행된다. {\tt n}은 0이기 때문에 ``발사!''라고 화면에 표시하고 리턴한다. \end{quote} -The {\tt countdown} that got {\tt n=1} returns. \end{quote} -The {\tt countdown} that got {\tt n=2} returns. +{\tt n=2}을 받은 {\tt countdown}이 리턴한다. \end{quote} -The {\tt countdown} that got {\tt n=3} returns. +{\tt n=3}을 받은 {\tt countdown}이 리턴한다. -And then you're back in \verb"__main__". So, the -total output looks like this: +그리고 나면, \verb"__main__"으로 돌아온다. 최종적으로 다음과 같이 +표시된다. \index{main} \begin{verbatim} 3 2 1 -Blastoff! +발사! \end{verbatim} % -A function that calls itself is {\bf recursive}; the process of -executing it is called {\bf recursion}. +함수가 자기 자신을 호출하는 것을 보고 {\bf 재귀적(recursive)}이라고 +한다. {\bf 재귀문(recursion)}은 함수를 재귀적으로 실행시키는 과정을 +말한다. \index{recursion} \index{function!recursive} -As another example, we can write a function that prints a -string {\tt n} times. +또 다른 예로, 어떤 문자열을 {\tt n}번 표시하는 함수를 작성해보자. \begin{verbatim} def print_n(s, n): @@ -3844,21 +3846,20 @@ \section{Recursion} print_n(s, n-1) \end{verbatim} % -If {\tt n <= 0} the {\bf return statement} exits the function. The -flow of execution immediately returns to the caller, and the remaining -lines of the function don't run. +{\tt n <= 0}이면 {\bf 리턴문(return statement)}으로 함수가 종료된다. +실행의 흐름은 호출한 함수에게 즉시 리턴된다. 그리고 함수의 나머지 +부분은 실행되지 않는다. \index{return statement} \index{statement!return} -The rest of the function is similar to {\tt countdown}: it displays -{\tt s} and then calls itself to display {\tt s} $n-1$ additional -times. So the number of lines of output is {\tt 1 + (n - 1)}, which -adds up to {\tt n}. +함수의 나머지 부분은 {\tt countdown}과 유사하다. {\tt s}를 표시하고 +$n-1$번 {\tt s}를 출력하도록 자기 자신을 다시 호출한다. 결과로 +표시되는 줄의 수가 {\tt 1 + (n - 1)}이기 때문에 총 {\tt n}번이 된다. + -For simple examples like this, it is probably easier to use a {\tt -for} loop. But we will see examples later that are hard to write -with a {\tt for} loop and easy to write with recursion, so it is -good to start early. +이처럼 간단한 예에서는 {\tt for} 루프를 사용하는게 더 쉬울 수 도 있다. +하지만 우리가 이후에 보게 될 좀 더 복잡한 예제들은 {\tt for} 루프로 +표현하기가 어렵다. 어려운 거라면 미리 시작해서 익숙해지는 것이 좋다. \index{for loop} \index{loop!for} From d6989a0eb862c79c82e4758225c86f47df8ad292 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Wed, 5 Jul 2017 08:53:04 +0900 Subject: [PATCH 07/13] user input --- book_kr/book.tex | 188 +++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 97 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index a6d10f7..972d1d3 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -3557,7 +3557,7 @@ \section{불 표현식} % 이 연산자들이 익숙해 보일 수 있지만, Python에서 사용하는 기호가 수학 기호와 다르다. 가장 흔한 실수는 하나의 등호({\tt =})를 써서 두 값이 -같은지 비교((\tt ==})하는 것이다. {\tt =}는 할당 연산자이고 {\tt ==}가 +같은지 비교({\tt ==})하는 것이다. {\tt =}는 할당 연산자이고 {\tt ==}가 관계 연산자인 것을 기억해야 한다. 그리고 {\tt =<}나 {\tt =>}와 같은 연산자는 없다. @@ -3640,7 +3640,7 @@ \section{조건부 실행} \begin{verbatim} if x < 0: - pass # TODO: need to handle negative values! + pass # TODO: 음수 처리해야 함! \end{verbatim} % @@ -3657,9 +3657,9 @@ \section{선택적 실행} \begin{verbatim} if x % 2 == 0: - print('x is even') + print('x는 짝수') else: - print('x is odd') + print('x는 음수') \end{verbatim} % {\tt x}를 2로 나눈 나머지가 0이라면 {\tt x}가 짝수이고, 프로그램은 @@ -3864,70 +3864,70 @@ \section{재귀문} \index{loop!for} -\section{Stack diagrams for recursive functions} +\section{재귀 함수의 스택 상태도} +%Stack diagrams for recursive functions \label{recursive.stack} \index{stack diagram} \index{function frame} \index{frame} -In Section~\ref{stackdiagram}, we used a stack diagram to represent -the state of a program during a function call. The same kind of -diagram can help interpret a recursive function. +\ref{stackdiagram}절에서 함수 호출 중에 프로그램의 상태를 스택 상태도로 +표현하였었다. 똑같은 그림을 재귀문을 이해하는데도 쓸 수 있다. -Every time a function gets called, Python creates a -frame to contain the function's local variables and parameters. -For a recursive function, there might be more than one frame on the -stack at the same time. +함수가 호출될 때마다 Python은 프레임을 생성하여 함수의 지역 변수와 매개 +변수를 저장한다. 재귀문을 쓰게 되면 스택에 하나 이상의 프레임이 +동시에 여러 개가 존재할 수 있다. -Figure~\ref{fig.stack2} shows a stack diagram for {\tt countdown} called with -{\tt n = 3}. +그림~\ref{fig.stack2}은 {\tt countdown}을 {\tt n = 3}을 인자로 하여 +호출했을 때의 스택 상태도를 나타낸다. \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/stack2.pdf}} -\caption{Stack diagram.} +\caption{스택 상태도.} \label{fig.stack2} \end{figure} - -As usual, the top of the stack is the frame for \verb"__main__". -It is empty because we did not create any variables in -\verb"__main__" or pass any arguments to it. +스택의 최상위 프레임에 \verb"__main__"가 있다. 프레임에 아무 것도 없는 +이유는 \verb"__main__"가 어떤 변수도 생성하지 않았고 인자도 전달받지 +못했기 때문이다. \index{base case} \index{recursion!base case} -The four {\tt countdown} frames have different values for the -parameter {\tt n}. The bottom of the stack, where {\tt n=0}, is -called the {\bf base case}. It does not make a recursive call, so -there are no more frames. +네 개의 {\tt countdown} 프레임들은 매개 변수 {\tt n}이 모두 다르다. +{\tt n = 0}이 있는 스택 프레임을 {\bf 기준 케이스(base case)}라 +부른다. 더 이상 재귀 호출을 하지 않기 때문에 그 이하로는 프레임이 +없다. -As an exercise, draw a stack diagram for \verb"print_n" called with -\verb"s = 'Hello'" and {\tt n=2}. -Then write a function called \verb"do_n" that takes a function -object and a number, {\tt n}, as arguments, and that calls -the given function {\tt n} times. +연습삼아 \verb"s = 'Hello'"와 {\tt n=2}를 인자로 \verb"print_n"가 +호출되었을 때의 스택 상태도를 그려보자. 그리고 함수 객체와 {\tt n}을 +인자로 하는 \verb"do_n" 함수를 만들어서 그 함수를 {\tt n}번 호출해 +보자. -\section{Infinite recursion} + +\section{무한 재귀문} +%Infinite recursion \index{infinite recursion} \index{recursion!infinite} \index{runtime error} \index{error!runtime} \index{traceback} -If a recursion never reaches a base case, it goes on making -recursive calls forever, and the program never terminates. This is -known as {\bf infinite recursion}, and it is generally not -a good idea. Here is a minimal program with an infinite recursion: +재귀문이 기준 케이스에 도달하지 못한다면 재귀문은 끝없이 호출되고 +프로그램은 절대로 종료하지 않는다. 이것이 {\bf 무한 재귀문(infinite + recursion)}이고 일반적으로 나쁘다. 무한 재귀문의 한 짧은 +예를 살펴보자. + \begin{verbatim} def recurse(): recurse() \end{verbatim} % -In most programming environments, a program with infinite recursion -does not really run forever. Python reports an error -message when the maximum recursion depth is reached: +대부분의 프로그래밍 환경에서 무한 재귀문을 갖는 프로그램이 무한히 +동작하는 일은 없다. 프로그램이 최대 재귀 가능 횟수에 도달하면 Python은 +오류 메시지를 보고 한다. \index{exception!RuntimeError} \index{RuntimeError} @@ -3942,28 +3942,28 @@ \section{Infinite recursion} RuntimeError: Maximum recursion depth exceeded \end{verbatim} % -This traceback is a little bigger than the one we saw in the -previous chapter. When the error occurs, there are 1000 -{\tt recurse} frames on the stack! +이 트레이스백은 이 전 장에서 살펴보았던 보다 좀 더 길다. 오류가 +발생하면서 스택에 1,000개의 {\tt recurse} 프레임이 생겼다. + +실수로 무한 재귀문을 만나게 되면 재귀 호출에 기준 케이스가 있는지 +함수를 확인해야 한다. 기준 케이스가 있다면 그 부분에 도달 가능한지 +확인해야 한다. -If you encounter an infinite recursion by accident, review -your function to confirm that there is a base case that does not -make a recursive call. And if there is a base case, check whether -you are guaranteed to reach it. -\section{Keyboard input} +\section{키보드 입력} +%Keyboard input \index{keyboard input} -The programs we have written so far accept no input from the user. -They just do the same thing every time. +지금까지 작성한 모든 프로그램은 사용자 입력이 없었다. 실행하면 +똑같은 동작만 했다. + +Python은 {\tt input}이라는 내장 함수를 제공한다. 이 함수는 잠시 멈춰서 +사용자가 입력하기를 기다린다. 사용자가 {\sf Return} 또는 {\sf + Enter}키를 누르면 프로그램은 계속 동작하고 \verb"input"은 사용자가 +입력한 문자열을 리턴한다. Python 2에서는 똑같은 일을 하는 함수를 +\verb"raw_input"이라 부른다. -Python provides a built-in function called {\tt input} that -stops the program and -waits for the user to type something. When the user presses {\sf - Return} or {\sf Enter}, the program resumes and \verb"input" -returns what the user typed as a string. In Python 2, the same -function is called \verb"raw_input". \index{Python 2} \index{input function} \index{function!input} @@ -3975,71 +3975,69 @@ \section{Keyboard input} 'What are you waiting for?' \end{verbatim} % -Before getting input from the user, it is a good idea to print a -prompt telling the user what to type. \verb"input" can take a -prompt as an argument: +사용자로 부터 입력을 받기 전에 어떤 것을 입력할지 알려주는 것이 좋다. +\verb"input"는 인자로 프롬프트의 내용을 갖는다. \index{prompt} \begin{verbatim} ->>> name = input('What...is your name?\n') -What...is your name? -Arthur, King of the Britons! +>>> name = input('당신은 누구죠?\n') +당신은 누구죠? +영국의 왕, 아서! >>> name -'Arthur, King of the Britons!' +'영국의 왕, 아서!' \end{verbatim} % -The sequence \verb"\n" at the end of the prompt represents a {\bf - newline}, which is a special character that causes a line break. -That's why the user's input appears below the prompt. \index{newline} +프롬프트의 마지막 부분의 \verb"\n"은 {\bf 새 줄(newline)}을 나타내는 +특수 기호로 줄을 바꾼다. 그렇기 때문에 사용자 입력 위치가 프롬프트 아래에 있다. +\index{newline} -If you expect the user to type an integer, you can try to convert -the return value to {\tt int}: +정수를 입력하기를 바란다면 리턴 값을 {\tt int}으로 변환할 수 있다. \begin{verbatim} ->>> prompt = 'What...is the airspeed velocity of an unladen swallow?\n' +>>> prompt = '짐을 메달고 있지 않은 제비의 속도는?\n' >>> speed = input(prompt) -What...is the airspeed velocity of an unladen swallow? +짐을 메달고 있지 않은 제비의 속도는? 42 >>> int(speed) 42 \end{verbatim} % -But if the user types something other than a string of digits, -you get an error: +하지만 사용자가 숫자 말고 다른 것을 입력하면 오류가 발생한다. \begin{verbatim} >>> speed = input(prompt) -What...is the airspeed velocity of an unladen swallow? -What do you mean, an African or a European swallow? +짐을 메달고 있지 않은 제비의 속도는? +그 제비가 아프리카 제비야 아니면 영국 제비야? >>> int(speed) ValueError: invalid literal for int() with base 10 \end{verbatim} % -We will see how to handle this kind of error later. +이런 류의 오류를 다루는 법을 나중에 보도록 하겠다. \index{ValueError} \index{exception!ValueError} -\section{Debugging} +\section{디버깅} +%Debugging \label{whitespace} \index{debugging} \index{traceback} -When a syntax or runtime error occurs, the error message contains -a lot of information, but it can be overwhelming. The most -useful parts are usually: +문법 오류나 실행 중에 발생하는 오류에는 많은 정보가 담겨 있다. 때로는 +벅차게 많을 수도 있다. 그 중에 중요한 정보들은 다음과 같다. + \begin{itemize} -\item What kind of error it was, and +\item 어떤 종류의 오류인가 -\item Where it occurred. +\item 어디서 발생했는가 \end{itemize} -Syntax errors are usually easy to find, but there are a few -gotchas. Whitespace errors can be tricky because spaces and -tabs are invisible and we are used to ignoring them. +문법 오류는 대체적으로 찾기가 쉽지만 몇 개는 눈에 잘 안 띄기도 한다. +사이띄기와 탭 문자 같은 공백과 관련한 오류들은 보이지 않기 때문에 쉽게 +지나치곤 한다. 그래서 찾기가 쉽지 않다. \index{whitespace} \begin{verbatim} @@ -4051,18 +4049,15 @@ \section{Debugging} IndentationError: unexpected indent \end{verbatim} % -In this example, the problem is that the second line is indented by -one space. But the error message points to {\tt y}, which is -misleading. In general, error messages indicate where the problem was -discovered, but the actual error might be earlier in the code, -sometimes on a previous line. +이 예제에서의 문제는 두 번째 줄이 한 칸 들여쓰기되어 있다는 것이다. +그렇지만 오류 메시지는 {\tt y}를 가리키고 있기 때문에 오해하기 쉽다. +일반적으로 오류 메시지는 오류가 발견된 시점을 나타내기 때문에 실제 +오류는 코드의 이전에서 이미 있었을 수도 있다. 심지어는 전 줄에 오류가 +있었을 수도 있다. \index{error!runtime} \index{runtime error} -The same is true of runtime errors. Suppose you are trying -to compute a signal-to-noise ratio in decibels. The formula -is $SNR_{db} = 10 \log_{10} (P_{signal} / P_{noise})$. In Python, -you might write something like this: +실행 중 발생 오류에서도 마찬가지다. 신호대잡음비를 데시벨로 계산한다고 해보자. 계산식은 $SNR_{db} = 10 \log_{10} (P_{signal} / P_{noise})$이다. Python에서는 이 식을 작성하면 다음과 같다. \begin{verbatim} import math @@ -4073,7 +4068,7 @@ \section{Debugging} print(decibels) \end{verbatim} % -When you run this program, you get an exception: +이 프로그램을 실행하면 예외처리가 된다. % \index{exception!OverflowError} \index{OverflowError} @@ -4085,16 +4080,15 @@ \section{Debugging} ValueError: math domain error \end{verbatim} % -The error message indicates line 5, but there is nothing -wrong with that line. To find the real error, it might be -useful to print the value of {\tt ratio}, which turns out to -be 0. The problem is in line 4, which uses floor division -instead of floating-point division. +이 오류 메시지는 5번 줄을 가리키고 있지만 그 줄에는 문제가 없다. 실제 +오류를 찾으려면 {\tt ratio}의 값을 출력해보는게 좋다. 출력해보면 0 +값을 리턴 받는다. 실제 문제는 내림 나눗셈을 하는 4번 줄에 있다. +소수점 단위의 나눗셈을 했어야 했다. \index{floor division} \index{division!floor} -You should take the time to read error messages carefully, but don't -assume that everything they say is correct. +오류 메시지를 읽는데 충분한 시간을 들여야 하겠지만, 그 하는 말을 모두 +참이라 믿어서는 안된다. \section{용어 해설} From 2eb5c03c9191f2282ea8df9f12c1f008f21a8d65 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Wed, 5 Jul 2017 11:07:56 +0900 Subject: [PATCH 08/13] excercises --- book_kr/book.tex | 211 ++++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 114 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 972d1d3..ff64a8e 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -3236,12 +3236,12 @@ \section{개발 계획} 이 과정에는 몇 가지 단점이 있다. 그 대안들은 이후에 살펴볼 것이다. 그래도 이 방법은 프로그램을 함수로 나누는 어떻게 나눌지 개발 전에 미리 알 수 없는 경우라면 충분히 의미있다. 개발하면서 설계도 같이 할 수 있기 때문이다. -\section{참고 문자열} +\section{설명 문자열} %docstring \label{docstring} \index{docstring} -함수의 시작 부분에 인터페이스를 설명하는 글을 {\bf 참고 +함수의 시작 부분에 인터페이스를 설명하는 글을 {\bf 설명 문자열(docstring)}이라 한다(doc은 documentation의 약어이다. 예를 살펴보자. @@ -3255,7 +3255,7 @@ \section{참고 문자열} t.lt(angle) \end{verbatim} % -관례상 모든 참고 문자열은 멀티라인 문자열이라고도 불리는 세 개의 +관례상 모든 설명 문자열은 멀티라인 문자열이라고도 불리는 세 개의 큰따옴표로 싸여있다. 세 개의 큰따옴표는 여러 줄에 걸친 문자열을 표현하는데 사용된다. \index{quotation mark} @@ -3265,7 +3265,7 @@ \section{참고 문자열} \index{string!multiline} 이 함수를 사용하는데 간결하기는 하지만 꼭 필요한 정보를 포함하고 있다. -참고 문자열은 함수가 어떤 일을 하는지 요약한다(상세 동작 설명은 +설명 문자열은 함수가 어떤 일을 하는지 요약한다(상세 동작 설명은 제외한다). 매개 변수가 함수의 동작에 미치는 영향과 각 매개 변수는 어떤 데이터 형을 갖는지를 설명한다(당연한 경우는 제외한다). @@ -3340,7 +3340,7 @@ \section{용어 해설} \item[개발 계획(development plan):] 프로그램을 작성하는 과정 \index{development plan} -\item[참고 문자열(docstring):] 함수 정의의 시작 부분에 작성된 함수의 +\item[설명 문자열(docstring):] 함수 정의의 시작 부분에 작성된 함수의 인터페이스에 대한 설명 \index{docstring} @@ -3628,7 +3628,7 @@ \section{조건부 실행} \index{statement!compound} 헤더와 들여쓰기된 내용으로 구성된 함수 정의처럼 {\tt if}문도 헤더와 -내용을 갖고 있다. 이런 류의 문장들을 {\bf 복합 문장(compound +내용을 갖고 있다. 이런 류의 문장들을 {\bf 복합문(compound statement)}라고 부른다. 내용에 포함될 수 있는 문장의 수가 정해지지 않았지만 최소한 하나는 @@ -3676,7 +3676,7 @@ \section{연쇄 조건문} \index{conditional!chained} 두 개 이상의 가능성이 있는 경우 두개 이상의 분기가 필요하다. 이런 류의 -연산을 {\bf 연쇄적 조건문(chained conditional)}이다. +연산을 {\bf 연쇄 조건문(chained conditional)}이다. \begin{verbatim} @@ -3733,7 +3733,7 @@ \section{중첩된 조건문} 있다. 내부의 {\tt if}문도 두 개의 분기를 갖고 있다. 각 분기의 내용도 간단한 문장이지만, 이 문장들도 또 다른 조건문이었을 수도 있다. -문장 들여쓰기를 하면 구조가 시각적으로 명확해지긴 하지만, {\bf 중첩된 +문장 들여쓰기를 하면 구조가 시각적으로 명확해지긴 하지만, {\bf 중첩 조건문(nested conditionals)}을 사용하면 읽기가 어려워진다. 가능하면 쓰지 않는 방법을 찾는 것이 좋다. @@ -4096,70 +4096,63 @@ \section{용어 해설} \begin{description} -\item[floor division:] An operator, denoted {\tt //}, that divides two - numbers and rounds down (toward negative infinity) to an integer. +\item[내림 나눗셈(floor division):] {\tt //}로 표시되는 연산자로서 두 + 수를 나눈 결과를 정수가 되도록 소수점을 버림 \index{floor division} \index{division!floor} -\item[modulus operator:] An operator, denoted with a percent sign -({\tt \%}), that works on integers and returns the remainder when one -number is divided by another. +\item[나머지 연산자(modulus operator):] 퍼센트({\tt \%}) 기호를 갖는 + 연산자로 두 정수를 나눈 나머지 값을 돌려줌 \index{modulus operator} \index{operator!modulus} -\item[boolean expression:] An expression whose value is either -{\tt True} or {\tt False}. +\item[불 표현식(boolean expression):] 결과가 항상 참({\tt True})이거나 + 거짓({\tt False})인 표현식 \index{boolean expression} \index{expression!boolean} -\item[relational operator:] One of the operators that compares -its operands: {\tt ==}, {\tt !=}, {\tt >}, {\tt <}, {\tt >=}, and {\tt <=}. +\item[관계 연산자(relational operator):] 피연산자를 비교하는 연산자로서 + 다음의 종류가 있음: {\tt ==}, {\tt !=}, {\tt >}, {\tt <}, {\tt >=}, + {\tt <=}. -\item[logical operator:] One of the operators that combines boolean -expressions: {\tt and}, {\tt or}, and {\tt not}. +\item[논리 연산자(logical operator):] 불 표현식들을 서로 연결하는 + 연산자: {\tt and}, {\tt or}, {\tt not}이 있음 -\item[conditional statement:] A statement that controls the flow of -execution depending on some condition. +\item[조건문(conditional statement):] 어떤 조건에 따라 실행의 흐름을 + 결정하는 문장 \index{conditional statement} \index{statement!conditional} -\item[condition:] The boolean expression in a conditional statement -that determines which branch runs. +\item[조건(condition):] 조건문에서 어떤 분기가 실행될지를 결정하는 불 표현식 \index{condition} -\item[compound statement:] A statement that consists of a header -and a body. The header ends with a colon (:). The body is indented -relative to the header. +\item[복합문(compound statement):] 헤더와 내용으로 구성된 문장으로 + 헤더는 콜론(:)으로 끝이 나나. 복합문의 내용은 헤더 위치에서 + 상대적으로 들여쓰기함 \index{compound statement} -\item[branch:] One of the alternative sequences of statements in -a conditional statement. +\item[분기(branch):] 조건문에서 선택적으로 실행되는 일련의 문장 \index{branch} -\item[chained conditional:] A conditional statement with a series -of alternative branches. +\item[연쇄 조건문(chained conditional):] 여러 개의 선택적 분기문으로 구성된 조건문 \index{chained conditional} \index{conditional!chained} -\item[nested conditional:] A conditional statement that appears -in one of the branches of another conditional statement. +\item[중첩 조건문(nested conditional):] 어떤 조건문의 분기 내있는 또 다른 조건문 \index{nested conditional} \index{conditional!nested} -\item[return statement:] A statement that causes a function to -end immediately and return to the caller. +\item[리턴문(return statement):] 함수를 호출한 문장으로 즉시 리턴하는 문장 -\item[recursion:] The process of calling the function that is -currently executing. +\item[재귀문(recursion):] 현재 실행 중인 함수를 호출하는 과정 \index{recursion} -\item[base case:] A conditional branch in a -recursive function that does not make a recursive call. +\item[기준 케이스(base case):] 재귀문에서 재귀 호출을 하지 않는 조건 분기 \index{base case} -\item[infinite recursion:] A recursion that doesn't have a -base case, or never reaches it. Eventually, an infinite recursion -causes a runtime error. +\item[무한 재귀문(infinite recursion):] 기준 케이스가 없거나 절대 + 도달하지 못하는 재귀문. 무한 재귀문을 실행하면 실행 중 오류가 + 발생하게 됨 \index{infinite recursion} \end{description} @@ -4169,10 +4162,10 @@ \section{연습 문제} \begin{exercise} -The {\tt time} module provides a function, also named {\tt time}, that -returns the current Greenwich Mean Time in ``the epoch'', which is -an arbitrary time used as a reference point. On UNIX systems, the -epoch is 1 January 1970. +{\tt time} 모듈은 {\tt time} 함수를 제공한다. 임의의 기준 시점에서 +시작하는 ``에포크(the epoch)''를 기준으로 현재 그린위치 평균시를 +리턴함. UNIX 시스템에서는 에포크는 1970 1월 1일이다. + \begin{verbatim} >>> import time @@ -4180,9 +4173,8 @@ \section{연습 문제} 1437746094.5735958 \end{verbatim} -Write a script that reads the current time and converts it to -a time of day in hours, minutes, and seconds, plus the number of -days since the epoch. +현재 시간을 읽어서 시, 분, 초, 그리고 에포크로부터 현재까지 지난 날 +수를 리턴하는 스크립트를 작성하라. \end{exercise} @@ -4190,29 +4182,28 @@ \section{연습 문제} \begin{exercise} \index{Fermat's Last Theorem} -Fermat's Last Theorem says that there are no positive integers -$a$, $b$, and $c$ such that +페르마의 마지막 정리는 $n$이 2보다 큰 경우 $a$, $b$, $c$의 양의 정수에 +대해 다음의 방정식은 해를 갖지 않는다는 정리이다. \[ a^n + b^n = c^n \] % -for any values of $n$ greater than 2. \begin{enumerate} -\item Write a function named \verb"check_fermat" that takes four -parameters---{\tt a}, {\tt b}, {\tt c} and {\tt n}---and -checks to see if Fermat's theorem holds. If -$n$ is greater than 2 and +\item 네 개의 변수---{\tt a}, {\tt b}, {\tt c}, {\tt n}---를 받아 $n$이 + 2보다 큰 경우에 대해 페르마의 마지막 정리가 참인지 검사하는 + \verb"check_fermat" 함수를 작성하라. \[a^n + b^n = c^n \] % -the program should print, ``Holy smokes, Fermat was wrong!'' -Otherwise the program should print, ``No, that doesn't work.'' +위의 식이 참이라면 ``어머나, 페르마가 틀렸었네!'', 거짓이라면 ``역시 +없구나.''를 출력하도록 만들어라. + -\item Write a function that prompts the user to input values -for {\tt a}, {\tt b}, {\tt c} and {\tt n}, converts them to -integers, and uses \verb"check_fermat" to check whether they -violate Fermat's theorem. +\item 사용자가 {\tt a}, {\tt b}, {\tt c}, {\tt n} 값을 정하도록 하고, + 입력 받은 값을 정수로 변환하여 \verb"check_fermat"의 입력으로 쓰는 + 함수를 만들어라. 입력 받은 값으로 페르마의 정리가 참인지 + 확인해보자. \end{enumerate} @@ -4222,39 +4213,35 @@ \section{연습 문제} \begin{exercise} \index{triangle} -If you are given three sticks, you may or may not be able to arrange -them in a triangle. For example, if one of the sticks is 12 inches -long and the other two are one inch long, you will -not be able to get the short sticks to meet in the middle. For any -three lengths, there is a simple test to see if it is possible to form -a triangle: +임의의 세 개의 막대기의 길이에 따라 삼각형 만들기 가능 여부가 +결정된다. 예를 들어, 한 막대기가 12인치이고 다른 두 개가 각각 +1인치라고 해보자. 작은 두 개의 막대기로는 중간에서 만날 수가 없다. +임의의 세 길이가 있을 때 삼각형 만들기가 가능한지 확인하는 간단한 +테스트가 있다. \begin{quotation} -If any of the three lengths is greater than the sum of the other - two, then you cannot form a triangle. Otherwise, you - can. (If the sum of two lengths equals the third, they form - what is called a ``degenerate'' triangle.) + 세 선분 중 하나의 선분이 나머지 두 선분의 합보다 길면 삼각형을 만들 + 수 없다. 짧으면 삼각형을 만들 수 있다. (두 선분의 길의의 합이 세 + 번째 길이와 같으면 ``퇴화(degenerate)'' 삼각형이라고 한다.) \end{quotation} \begin{enumerate} -\item Write a function named \verb"is_triangle" that takes three - integers as arguments, and that prints either ``Yes'' or ``No'', depending - on whether you can or cannot form a triangle from sticks with the - given lengths. +\item 세 개의 정수를 인자로하여 주어진 수로 삼각형 만들기가 가능한지 + 여부를 판단하는 \verb"is_triangle" 함수를 작성하라. 가능하면 + ``Yes'' 불가능하면 ``No''를 출력하도록 하라. -\item Write a function that prompts the user to input three stick - lengths, converts them to integers, and uses \verb"is_triangle" to - check whether sticks with the given lengths can form a triangle. +\item 사용자로 부터 세 정수를 입력받아, 그 수를 정수로 변환하고, + \verb"is_triangle"를 사용하여 주어진 정수로 삼각형을 만들 수 있는지 + 판단하는 함수를 작성하라. \end{enumerate} \end{exercise} \begin{exercise} -What is the output of the following program? -Draw a stack diagram that shows the state of the program -when it prints the result. +다음 프로그램의 결과가 무엇인가? +프로그램이 결과를 표시할 때의 스택 상태도를 그려보아라. \begin{verbatim} def recurse(n, s): @@ -4268,26 +4255,23 @@ \section{연습 문제} \begin{enumerate} -\item What would happen if you called this function like this: {\tt - recurse(-1, 0)}? +\item 이 함수를 {\tt recurse(-1, 0)}으로 호출하면 어떻게 될까? -\item Write a docstring that explains everything someone would need to - know in order to use this function (and nothing else). +\item 이 함수를 사용하기 위해 필요한 모든 정보를 담은 설명 문자열을 작성하라. \end{enumerate} \end{exercise} - -The following exercises use the {\tt turtle} module, described in -Chapter~\ref{turtlechap}: +다음의 문제들은 \ref{turtlechap}장에서 설명한 {\tt turtle} 모듈을 사용한다. \index{TurtleWorld} \begin{exercise} + +다음의 함수를 읽고 어떤 동작을 하는지 생각해보자(필요하면 +\ref{turtlechap}장의 예제를 읽어보자). 생각한 데로 동작하는지 +실행해보자. -Read the following function and see if you can figure out -what it does (see the examples in Chapter~\ref{turtlechap}). Then run it -and see if you got it right. \begin{verbatim} def draw(t, length, n): @@ -4309,58 +4293,57 @@ \section{연습 문제} \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/koch.pdf}} -\caption{A Koch curve.} +\caption{코흐 곡선.} \label{fig.koch} \end{figure} \begin{exercise} \index{Koch curve} -The Koch curve is a fractal that looks something like -Figure~\ref{fig.koch}. To draw a Koch curve with length $x$, all you -have to do is +코흐 곡선(The Koch curve)는 그림 \ref{fig.koch}처럼 보이는 프랙탈 곡선이다. 길이 $x$를 사용하여 코흐 곡선을 그려라. 그리는 방법은 다음과 같다. + \begin{enumerate} -\item Draw a Koch curve with length $x/3$. +\item $x/3$의 길이로 코흐 곡선을 그린다. -\item Turn left 60 degrees. +\item 왼쪽으로 60도 회전한다. -\item Draw a Koch curve with length $x/3$. +\item $x/3$의 길이로 코흐 곡선을 그린다. -\item Turn right 120 degrees. +\item 오른쪽으로 120도 회전한다. -\item Draw a Koch curve with length $x/3$. +\item $x/3$의 길이로 코흐 곡선을 그린다. -\item Turn left 60 degrees. +\item 왼쪽으로 60도 회전한다. -\item Draw a Koch curve with length $x/3$. +\item $x/3$의 길이로 코흐 곡선을 그린다. \end{enumerate} -The exception is if $x$ is less than 3: in that case, -you can just draw a straight line with length $x$. +만약, $x$가 3보다 작으면 $x$만큼의 길이로 직선을 그리면 된다. \begin{enumerate} -\item Write a function called {\tt koch} that takes a turtle and -a length as parameters, and that uses the turtle to draw a Koch -curve with the given length. +\item 거북이 객체와 길이를 매개 변수로 하는 {\tt koch} 함수를 + 작성하라. 이 함수로 주어진 길이로 거북이를 사용하여 코흐 곡선을 + 그려보아라. -\item Write a function called {\tt snowflake} that draws three -Koch curves to make the outline of a snowflake. +\item 세 개의 코흐 곡선으로 눈송이의 외각선을 그리는 {\tt snowflake} + 함수를 작성하라. -Solution: \url{http://thinkpython2.com/code/koch.py}. +해답: \url{http://thinkpython2.com/code/koch.py}. -\item The Koch curve can be generalized in several ways. See -\url{http://en.wikipedia.org/wiki/Koch_snowflake} for examples and -implement your favorite. +\item 코흐 곡선을 일반화하는 방법은 여러 개가 + 있다. \url{http://en.wikipedia.org/wiki/Koch_snowflake}에 나와 있는 + 것 중 마음에 드는 것을 골라 만들어 보자. \end{enumerate} \end{exercise} -\chapter{Fruitful functions} +\chapter{열매가 있는 함수} +%Fruitful functions \label{fruitchap} Many of the Python functions we have used, such as the math From 6dbcd5547a23a6553b88f65832196e59b1826191 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Fri, 7 Jul 2017 22:01:15 +0900 Subject: [PATCH 09/13] fruitful function --- book_kr/book.tex | 688 ++++++++++++++++++++++------------------------- 1 file changed, 316 insertions(+), 372 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index ff64a8e..3a4369e 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -748,7 +748,7 @@ \section*{Contributor List} % START THE BOOK \mainmatter -\chapter{프로그래밍의 길} +\chapter{프로그래밍의 정도} %The way of the program 이 책의 목적은 컴퓨터 과학자처럼 생각하는 방법을 알려주는 것이다. 그 @@ -764,7 +764,7 @@ \chapter{프로그래밍의 길} 해결이라는 것은 문제를 정의한 후 해답을 찾기 위해 창의적으로 생각하여 얻은 해답을 정확하고 명료하게 표현하는 것이다. 나중에 알게 되겠지만, 프로그래밍을 배우는 과정은 문제 해결 능력을 키우는 최고의 기회이다. -그래서, 이 장의 제목을 ``프로그래밍의 길''이라고 지었다. +그래서, 이 장의 제목을 ``프로그래밍의 정도''라 지었다. 어떤 수준에서는 프로그래밍을 배우게 될 것이다. 그 자체로도 매우 유용한 @@ -4346,32 +4346,31 @@ \chapter{열매가 있는 함수} %Fruitful functions \label{fruitchap} -Many of the Python functions we have used, such as the math -functions, produce return values. But the functions we've written -are all void: they have an effect, like printing a value -or moving a turtle, but they don't have a return value. In -this chapter you will learn to write fruitful functions. +우리가 사용한 수학 함수와 같은 많은 Python 함수들은 리턴 값이 있지만, +우리가 작성한 함수들은 리턴 값이 없다. 대신 값을 출력하거나 거북이를 +이동시키는 것과 같은 영향만 있다. 이 장에서는 열매가 있는 함수에 대해 +배울 것이다. -\section{Return values} + +\section{리턴 값} +%Return values \index{return value} -Calling the function generates a return -value, which we usually assign to a variable or use as part of an -expression. +함수 호출에는 리턴 값이 있는데, 보통은 이 값을 변수에 할당하거나 어떤 +수식의 일부로 사용한다. + \begin{verbatim} e = math.exp(1.0) height = radius * math.sin(radians) \end{verbatim} % -The functions we have written so far are void. Speaking casually, -they have no return value; more precisely, -their return value is {\tt None}. +지금까지 우리는 비어 있는 함수들을 작성했었다. 격식 없게는 리턴 값이 +없었고, 좀 정확하게는 그 함수들의 리턴 값은 {\tt None}이 었다. -In this chapter, we are (finally) going to write fruitful functions. -The first example is {\tt area}, which returns the area of a circle -with the given radius: +이 장에서는 (마침내) 열매가 있는 함수를 작성할 것이다. 첫 번째 예제는 +전달 받은 반지름으로 원의 넓이를 리턴하는 {\tt area} 함수이다. \begin{verbatim} def area(radius): @@ -4379,12 +4378,11 @@ \section{Return values} return a \end{verbatim} % -We have seen the {\tt return} statement before, but in a fruitful -function the {\tt return} statement includes -an expression. This statement means: ``Return immediately from -this function and use the following expression as a return value.'' -The expression can be arbitrarily complicated, so we could -have written this function more concisely: +우리가 봤던 열매가 있는 함수에서의 {\tt + return}문은 수식이 포함되 있었다. 리턴문은 ``리턴 값으로 +따라오는 수식을 사용하여 즉시 리턴하라''는 의미를 갖고 있다. 리턴할 +수식이 복잡해도 괜찮기 때문에 이 예제의 함수를 좀 더 간결하게 작성 해 +볼 수도 있다. \index{return statement} \index{statement!return} @@ -4393,13 +4391,12 @@ \section{Return values} return math.pi * radius**2 \end{verbatim} % -On the other hand, {\bf temporary variables} like {\tt a} can make -debugging easier. +그렇기는 하지만, {\bf 임시 변수}로 사용한 {\tt a}가 있어 좀 더 쉽게 +디버깅할 수도 있다. \index{temporary variable} \index{variable!temporary} -Sometimes it is useful to have multiple return statements, one in each -branch of a conditional: +때로는 조건문의 분기마다 리턴문이 있는 경우도 있다. \begin{verbatim} def absolute_value(x): @@ -4409,18 +4406,15 @@ \section{Return values} return x \end{verbatim} % -Since these {\tt return} statements are in an alternative conditional, -only one runs. +각 {\tt return}문이 선택지마다 있기 때문에 그 중 어느 하나만 실행된다. -As soon as a return statement runs, the function -terminates without executing any subsequent statements. -Code that appears after a {\tt return} statement, or any other place -the flow of execution can never reach, is called {\bf dead code}. +리턴문이 실행되면 실행 중이던 함수는 다음 문장을 수행하지 않고 즉시 +종료한다. {\tt return}문 이후의 문장이나 실행의 흐름 상 도달하지 않는 +코드를 {\bf 죽은 코드(dead code)}라 부른다. \index{dead code} -In a fruitful function, it is a good idea to ensure -that every possible path through the program hits a -{\tt return} statement. For example: +열매가 있는 함수에서는 프로그램의 어떤 실행 흐름이더라도 {\tt + return}문에 도달하도록 하는 것이 좋다. 예를 들어보자. \begin{verbatim} def absolute_value(x): @@ -4430,11 +4424,9 @@ \section{Return values} return x \end{verbatim} % -This function is incorrect because if {\tt x} happens to be 0, -neither condition is true, and the function ends without hitting a -{\tt return} statement. If the flow of execution gets to the end -of a function, the return value is {\tt None}, which is not -the absolute value of 0. +이 함수는 잘못되었다. 만약 {\tt x}가 0이면 두 선택지 모두 거짓이 +된다. 그러면 {\tt return}문에 도달하지 않고 종료하게 된다. 이 경우의 +리턴 값은 {\tt None}이지 0의 절대치가 아니다. \index{None special value} \index{special value!None} @@ -4443,94 +4435,88 @@ \section{Return values} None \end{verbatim} % -By the way, Python provides a built-in function called -{\tt abs} that computes absolute values. +참고로, Python의 내부 함수 중에는 절대치를 계산하는 {\tt abs} 함수가 있다. \index{abs function} \index{function!abs} -As an exercise, write a {\tt compare} function -takes two values, {\tt x} and {\tt y}, and returns {\tt 1} if {\tt x > y}, -{\tt 0} if {\tt x == y}, and {\tt -1} if {\tt x < y}. +연습 문제로 {\tt x}와 {\tt y} 두 수를 받아 {\tt x > y}이면 {\tt 1}을 +리턴하고 {\tt x == y}이면 {\tt 0}을 그리고 {\tt x < y}이면 {\tt -1}을 +리턴하는 {\tt compare} 함수를 작성해보자. \index{compare function} \index{function!compare} -\section{Incremental development} +\section{점진적 개발} +%Incremental development \label{incremental.development} \index{development plan!incremental} -As you write larger functions, you might find yourself -spending more time debugging. +큰 함수를 작성하다 보면 디버깅에 더 많은 시간을 쓰는 때가 있다. -To deal with increasingly complex programs, -you might want to try a process called -{\bf incremental development}. The goal of incremental development -is to avoid long debugging sessions by adding and testing only -a small amount of code at a time. +엄청나게 복잡한 프로그램을 작성하기 위해 {\bf 점진적 개발(incremental + development)} 방법론을 시도해 볼 것을 권한다. 점진적 개발 방법론의 +목적은 아주 작은 크기의 코드를 추가하고 그 부분에 대한 디버깅을 하여 +디버깅에 너무 오랜 시간을 쓰는 것을 피하도록 한다. \index{testing!incremental development} \index{Pythagorean theorem} -As an example, suppose you want to find the distance between two -points, given by the coordinates $(x_1, y_1)$ and $(x_2, y_2)$. -By the Pythagorean theorem, the distance is: +예를 들어, $(x_1, y_1)$과 $(x_2, y_2)$의 좌표를 갖는 두 점 사이의 +거리를 잰다고 해보자. 피타고라스의 정리에 따라 거리는 다음과 같이 +계산할 수 있다. \begin{displaymath} \mathrm{distance} = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} \end{displaymath} % -The first step is to consider what a {\tt distance} function should -look like in Python. In other words, what are the inputs (parameters) -and what is the output (return value)? +첫 단계는 Python에서 {\tt distance} 함수를 정의하는 것이다. 입력 +값(매개 변수)은 무엇인지 출력 값(리턴 값)은 무엇인지를 정해야 한다. -In this case, the inputs are two points, which you can represent -using four numbers. The return value is the distance represented by -a floating-point value. +이 경우에는 입력 값은 네 개의 수로 이루어진 두 개의 점이다. 리턴 값은 +부동소수점으로 표현되는 거리이다. -Immediately you can write an outline of the function: +입력과 출력 값이 정해지면 함수의 구조를 잡을 수 있다. \begin{verbatim} def distance(x1, y1, x2, y2): return 0.0 \end{verbatim} % -Obviously, this version doesn't compute distances; it always returns -zero. But it is syntactically correct, and it runs, which means that -you can test it before you make it more complicated. +당연하겠지만, 이 버전의 함수는 거리를 계산할 수 없다. 이 함수는 언제는 +0만 리턴한다. 문법적으로는 정확하고 실행도 가능하다. 좀 더 복잡해지기 +전에 검사가 가능하다는 말이다. + +함수를 시험해 보려면 샘플 인자 값으로 호출하면 된다. -To test the new function, call it with sample arguments: \begin{verbatim} >>> distance(1, 2, 4, 6) 0.0 \end{verbatim} % -I chose these values so that the horizontal distance is 3 and the -vertical distance is 4; that way, the result is 5, the hypotenuse -of a 3-4-5 triangle. When testing a function, it is -useful to know the right answer. +두 점 사이의 수평 거리가 3 차이나고 수직 거리가 4 차이 나도록 점들을 +선택했다. 피타고라스의 수에 따라 직각 삼각형의 세 변의 길이의 비가 +3:4:5 이기 때문에 결과는 5가 되야 한다. 정답을 알면 함수 검사가 +수월해지는 법이다. \index{testing!knowing the answer} -At this point we have confirmed that the function is syntactically -correct, and we can start adding code to the body. -A reasonable next step is to find the differences -$x_2 - x_1$ and $y_2 - y_1$. The next version stores those values in -temporary variables and prints them. +이제 이 함수가 문법적으로 정확하다는 것을 확인했으니 내용에 코드를 +추가해도 된다. 다음으로 밟아야 할 순서는 $x_2 - x_1$과 $y_2 - y_1$의 +계산으로 점 간의 차를 구하는 것이다. 다음 버전의 함수는 차를 계산하고 +임시 변수에 저장한 후 화면에 표시하는 것이다. + \begin{verbatim} def distance(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 - print('dx is', dx) - print('dy is', dy) + print('dx는', dx) + print('dy는', dy) return 0.0 \end{verbatim} % -If the function is working, it should display \verb"dx is 3" and -\verb"dy is 4". If so, we know that the function is getting the right -arguments and performing the first computation correctly. If not, -there are only a few lines to check. +함수가 동작한다면, \verb"dx는 3" 그리고 \verb"dy는 4"를 출력할 것이다. 그리고 그렇게 출력되었다면 인자도 함수에 제대로 전달했고 첫 계산도 정확히 수행했다는 것을 알 수 있다. 만약 잘못 나왔다면 검사해야 할 코드가 몇 줄 되지 않는 것에 위안을 얻으면 된다. -Next we compute the sum of squares of {\tt dx} and {\tt dy}: +그 다음 과정은 {\tt dx}와 {\tt dy}의 제곱의 합을 계산해야 한다. \begin{verbatim} def distance(x1, y1, x2, y2): @@ -4541,9 +4527,9 @@ \section{Incremental development} return 0.0 \end{verbatim} % -Again, you would run the program at this stage and check the output -(which should be 25). -Finally, you can use {\tt math.sqrt} to compute and return the result: +마찬가지로, 변경한 코드를 실행해보고 결과가 맞는지 검사해봐야 +한다(결과는 25다). 마지막으로 {\tt math.sqrt}를 써서 결과를 리턴하면 +된다. \index{sqrt} \index{function!sqrt} @@ -4556,76 +4542,65 @@ \section{Incremental development} return result \end{verbatim} % -If that works correctly, you are done. Otherwise, you might -want to print the value of {\tt result} before the return -statement. +지금까지 제대로 동작했다면, 다 끝났다. 확인하기 원한다면 리턴하기 전에 +{\tt result}를 출력하면 된다. -The final version of the function doesn't display anything when it -runs; it only returns a value. The {\tt print} statements we wrote -are useful for debugging, but once you get the function working, you -should remove them. Code like that is called {\bf scaffolding} -because it is helpful for building the program but is not part of the -final product. +함수의 최종 버전은 실행했을 때 아무 것도 출력하지 않는다. 그저 값만 +리턴할 뿐 이다. {\tt print}문은 디버깅 때문에 포함한 것이기 때문에 +함수가 동작한다면 제거해야 한다. 이런 류의 코드를 보고 {\bf + 발판(scaffolding)}이라 한다. 프로그램을 작성하는데 도움은 되지만 +최종 결과물의 일부는 아니기 때문이다. \index{scaffolding} -When you start out, you should add only a line or two of code at a -time. As you gain more experience, you might find yourself writing -and debugging bigger chunks. Either way, incremental development -can save you a lot of debugging time. +처음 시작할 때는 한 두 줄의 코드만 추가해야 한다. 좀 더 익숙해지면 좀 +더 긴 길이의 코드를 작성하고 디버깅할 수 있게 된다. 초보이던 +전문가이던, 점진적 개발 방법론은 디버깅 시간을 엄청나게 줄일 수 있다. -The key aspects of the process are: +방법론의 핵심은 다음과 같다. \begin{enumerate} -\item Start with a working program and make small incremental changes. -At any point, if there is an error, you should have a good idea -where it is. +\item 동작하는 프로그램으로 부터 시작하여 점진적인 변화를 만들어라. 그래야 어떤 순간이라도 오류를 발견하면 어디에 원인이 있는지 쉽게 찾을 수 있다. -\item Use variables to hold intermediate values so you can -display and check them. +\item 중간 값들을 변수에 저장하여 출력해보고 검사 할 수 있게 만들어라 -\item Once the program is working, you might want to remove some of -the scaffolding or consolidate multiple statements into compound -expressions, but only if it does not make the program difficult to -read. +\item 프로그램이 동작한다면 발판으로 사용한 코드를 삭제하고 여러 줄로 작성한 문장들을 복합문으로 통합해라. 단, 통합했을 때 코드 읽기가 너무 어려워지면 안된다. \end{enumerate} -As an exercise, use incremental development to write a function -called {\tt hypotenuse} that returns the length of the hypotenuse of a -right triangle given the lengths of the other two legs as arguments. -Record each stage of the development process as you go. +연습삼아 {\tt hypotenuse}라는 함수를 만들어 보자. 이 함수는 직각 +삼각형의 빗변을 계산하는 함수로 다른 두 변의 길이를 인자로 받는다. +개발 과정의 각 단계를 거칠 때마다 결과를 표시하도록 해보자. \index{hypotenuse} -\section{Composition} +\section{합성} +%Composition \index{composition} \index{function composition} -As you should expect by now, you can call one function from within -another. As an example, we'll write a function that takes two points, -the center of the circle and a point on the perimeter, and computes -the area of the circle. +이제는 이미 알리라 생각이 되지만, 함수 내에서 다른 함수를 호출하는 것이 +가능하다. 원의 중심 점과 원주 위의 한 점을 받아 원의 면적을 계산하는 +함수로 예를 들어 보자. + +{\tt xc}와 {\tt yc}에 원의 중심 점을 저장하고 원주 위의 한 점은 {\tt + xp}와 {\tt yp}에 저장된다고 하자. 첫 번째 단계는 이 두 점을 사용하여 +원의 반지름을 계산하는 것이다.이미 작성한 {\tt distance} 함수를 +사용하자. -Assume that the center point is stored in the variables {\tt xc} and -{\tt yc}, and the perimeter point is in {\tt xp} and {\tt yp}. The -first step is to find the radius of the circle, which is the distance -between the two points. We just wrote a function, {\tt -distance}, that does that: \begin{verbatim} radius = distance(xc, yc, xp, yp) \end{verbatim} % -The next step is to find the area of a circle with that radius; -we just wrote that, too: +다음으로 반지름을 사용하여 원의 면적을 구하자. 이것도 이미 작성했었다. \begin{verbatim} result = area(radius) \end{verbatim} % -Encapsulating these steps in a function, we get: +이 모든 단계들을 한 함수로 캡슐화 해보자. \index{encapsulation} \begin{verbatim} @@ -4635,9 +4610,9 @@ \section{Composition} return result \end{verbatim} % -The temporary variables {\tt radius} and {\tt result} are useful for -development and debugging, but once the program is working, we can -make it more concise by composing the function calls: +임시 변수 {\tt radius}와 {\tt result}는 개발과 디버깅하는 과정에서만 +유용하기 때문에 프로그램이 제대로 동작하면 다음과 같이 간결하게 함수 +호출을 합성할 수 있다. \begin{verbatim} def circle_area(xc, yc, xp, yp): @@ -4645,12 +4620,14 @@ \section{Composition} \end{verbatim} % -\section{Boolean functions} +\section{불 함수} +%Boolean functions \label{boolean} -Functions can return booleans, which is often convenient for hiding -complicated tests inside functions. \index{boolean function} -For example: +함수는 불 값을 리턴할 수 있다. 그렇게 하면 복잡한 검사문을 함수에 감출 +수 있기 때문에 유용하다. +\index{boolean function} +예를 살펴 보자. \begin{verbatim} def is_divisible(x, y): @@ -4660,11 +4637,11 @@ \section{Boolean functions} return False \end{verbatim} % -It is common to give boolean functions names that sound like yes/no -questions; \verb"is_divisible" returns either {\tt True} or {\tt False} -to indicate whether {\tt x} is divisible by {\tt y}. +불 함수의 이름은 참/거짓을 묻는 질문처럼 만드는 것이 일반적이다. +\verb"is_divisible"은 {\tt x}가 {\tt y}로 나누어 떨어지는지 {\tt True} +또는 {\tt False}로 리턴한다. -Here is an example: +사용 예를 보자. \begin{verbatim} >>> is_divisible(6, 4) @@ -4673,15 +4650,16 @@ \section{Boolean functions} True \end{verbatim} % -The result of the {\tt ==} operator is a boolean, so we can write the -function more concisely by returning it directly: +{\tt ==} 연산자의 결과는 참 또는 거짓이기때문에 그 결과를 바로 +리턴하도록 함수를 간결하게 작성할 수 있다. + \begin{verbatim} def is_divisible(x, y): return x % y == 0 \end{verbatim} % -Boolean functions are often used in conditional statements: +불 함수는 조건문에 많이 쓰인다. \index{conditional statement} \index{statement!conditional} @@ -4690,20 +4668,21 @@ \section{Boolean functions} print('x is divisible by y') \end{verbatim} % -It might be tempting to write something like: +아래와 같이 쓰고 싶은 유혹이 들 수 있다. \begin{verbatim} if is_divisible(x, y) == True: print('x is divisible by y') \end{verbatim} % -But the extra comparison is unnecessary. +두 번 검사는 불필요하다. -As an exercise, write a function \verb"is_between(x, y, z)" that -returns {\tt True} if $x \le y \le z$ or {\tt False} otherwise. +연습삼아 \verb"is_between(x, y, z)" 함수를 작성해보자. 이 함수는 $x +\le y \le z$이면 {\tt True}를 아니면 {\tt False}를 리턴한다. -\section{More recursion} +\section{또 다시 재귀문} +%More recursion \label{more.recursion} \index{recursion} \index{Turing complete language} @@ -4711,68 +4690,61 @@ \section{More recursion} \index{Turing, Alan} \index{Turing Thesis} -We have only covered a small subset of Python, but you might -be interested to know that this subset is a {\em complete} -programming language, which means that anything that can be -computed can be expressed in this language. Any program ever written -could be rewritten using only the language features you have learned -so far (actually, you would need a few commands to control devices -like the mouse, disks, etc., but that's all). - -Proving that claim is a nontrivial exercise first accomplished by Alan -Turing, one of the first computer scientists (some would argue that he -was a mathematician, but a lot of early computer scientists started as -mathematicians). Accordingly, it is known as the Turing Thesis. -For a more complete (and accurate) discussion of the Turing Thesis, -I recommend Michael Sipser's book {\em Introduction to the -Theory of Computation}. - -To give you an idea of what you can do with the tools you have learned -so far, we'll evaluate a few recursively defined mathematical -functions. A recursive definition is similar to a circular -definition, in the sense that the definition contains a reference to -the thing being defined. A truly circular definition is not very -useful: +Python의 일부만을 다뤘지만, 지금까지 다룬 내용이 프로그래밍 언어의 +{\em 전부}라는 사실을 알았으면 좋겠다. 지금의 언어로 연산하고 싶은 +어떤 것이든 다 표현할 수 있다. 누군가가 만든 프로그램도 지금까지 배운 +것들만으로 다시 만들 수 있다(사실 마우스, 디스크같은 것들을 다루려면 +다른 명령어들이 필요하겠지만 그게 다다). + +이 주장을 증명하는 것은 쉽지 않은 일이긴 하지만 최초의 컴퓨터 과학자인 +앨런 튜링(Alan Turing)이 증명했다(그가 수학자라고 주장하는 사람들이 +있기는 하지만, 초창기의 대부분의 컴퓨터 과학자들인 수학자로 시작했다). +그의 이름을 따서 튜링 명제라 한다. 이에 관한 완전하고(정확한) 논고는 +마이클 싶서(Michael Sipser)의 책 {\em Introduction to the Theory of + Computation}을 읽어보기를 바란다. + +지금까지 배운 도구들로 무엇을 할 수 있는지 보이기 위해 재귀적으로 +정의된 수학 함수를 살펴보도록 하겠다. 정의하는 대상을 정의에서 다시 +사용한다는 점에서 재귀적 정의는 순환 정의와 유사하다. 순환 정의는 +그렇게 도움이 되지 않는다. + \begin{description} -\item[vorpal:] An adjective used to describe something that is vorpal. +\item[vorpal:] vorpal한 것을 나타내는 형용사 \index{vorpal} \index{circular definition} \index{definition!circular} \end{description} -If you saw that definition in the dictionary, you might be annoyed. On -the other hand, if you looked up the definition of the factorial -function, denoted with the symbol $!$, you might get something like -this: +사전에서 이런 단어를 만나면 짜증이 날 것이다. 반면, $!$로 표기하는 +계승(factorial) 함수는 다음과 같이 정의 된다. % \begin{eqnarray*} && 0! = 1 \\ && n! = n (n-1)! \end{eqnarray*} % -This definition says that the factorial of 0 is 1, and the factorial -of any other value, $n$, is $n$ multiplied by the factorial of $n-1$. +이 정의는 0의 계승은 1이고 어떤 값 $n$의 계승은 $n$ 곱하기 $n-1$의 +계승으로 정의된다. -So $3!$ is 3 times $2!$, which is 2 times $1!$, which is 1 times -$0!$. Putting it all together, $3!$ equals 3 times 2 times 1 times 1, -which is 6. +그래서, $3!$은 3 곱하기 $2!$이고, 다시 2곱하기 $1!$, 그리고 1 곱하기 +$0!$이 된다. 정리하면 $3!$은 3 곱하기 2 곱하기 1 곱하기 1이고, +계산하면 6이다. \index{factorial function} \index{function!factorial} \index{recursive definition} -If you can write a recursive definition of something, you can -write a Python program to evaluate it. The first step is to decide -what the parameters should be. In this case it should be clear -that {\tt factorial} takes an integer: +어떤 것을 재귀문으로 정의하였다면 Pytho 프로그램을 써서 평가해면 된다. +먼저, 매개 변수를 정한다. {\tt factorial}의 경우 당연히 정수를 +전달해야 한다. \begin{verbatim} def factorial(n): \end{verbatim} % -If the argument happens to be 0, all we have to do is return 1: +인자가 0이라면 1을 리턴하면 된다. \begin{verbatim} def factorial(n): @@ -4780,9 +4752,8 @@ \section{More recursion} return 1 \end{verbatim} % -Otherwise, and this is the interesting part, we have to make a -recursive call to find the factorial of $n-1$ and then multiply it by -$n$: +그 외의 경우를 다루는 방법이 흥미로운데, 재귀 호출을 써서 $n-1$의 +계승을 계산한 후 $n$으로 곱하면 된다. \begin{verbatim} def factorial(n): @@ -4794,111 +4765,99 @@ \section{More recursion} return result \end{verbatim} % -The flow of execution for this program is similar to the flow of {\tt -countdown} in Section~\ref{recursion}. If we call {\tt factorial} -with the value 3: +이 프로그램의 실행의 흐름은 \ref{recursion}장에서 본 {\tt countdown}의 +실행 흐름과 비슷하다. {\tt factorial}의 인자로 3을 주고 시작하면 다음과 +같이 동작한다. + -Since 3 is not 0, we take the second branch and calculate the factorial -of {\tt n-1}... +3은 0이 아니기 때문에 두 번째 분기를 선택하여 {\tt n-1}의 계승을 계산한다. \begin{quote} -Since 2 is not 0, we take the second branch and calculate the factorial of -{\tt n-1}... + 2은 0이 아니기 때문에 두 번째 분기를 선택하여 {\tt n-1}의 계승을 + 계산한다. - \begin{quote} - Since 1 is not 0, we take the second branch and calculate the factorial - of {\tt n-1}... + \begin{quote} + 1은 0이 아니기 때문에 두 번째 분기를 선택하여 {\tt n-1}의 계승을 + 계산한다. \begin{quote} - Since 0 equals 0, we take the first branch and return 1 - without making any more recursive calls. + 0은 0이기 때문에 더 이상 재귀 호출을 하지 않고 첫 번째 분기를 + 선택하여 1을 리턴한다. \end{quote} - - The return value, 1, is multiplied by $n$, which is 1, and the - result is returned. + 리턴 값 1을 $n$과 곱한 결과를 리턴한다. 이 때, $n$은 1이다. \end{quote} + 리턴 값 1을 $n$과 곱한 결과를 리턴한다. 이 때, $n$은 2이다. -The return value, 1, is multiplied by $n$, which is 2, and the -result is returned. \end{quote} +리턴 값 2을 $n$과 곱한 결과를 리턴한다. 이 때, $n$은 3이다. 계산 결과 6이 처음 재귀 호출 과정을 시작한 함수의 리턴 값이 된다. -The return value (2) is multiplied by $n$, which is 3, and the result, 6, -becomes the return value of the function call that started the whole -process. \index{stack diagram} -Figure~\ref{fig.stack3} shows what the stack diagram looks like for -this sequence of function calls. +그림~\ref{fig.stack3}이 함수의 실행 흐름에 따른 스택 상태도를 나타낸다. \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/stack3.pdf}} -\caption{Stack diagram.} +\caption{스택 상태도} \label{fig.stack3} \end{figure} -The return values are shown being passed back up the stack. In each -frame, the return value is the value of {\tt result}, which is the -product of {\tt n} and {\tt recurse}. +리턴 값이 스택 위로 전달되는 것을 볼 수 있다. 각 프레임에 나타난 리턴 +값은 {\tt n}과 {\tt recurse}의 곱인 {\tt result}이다. \index{function frame} \index{frame} -In the last frame, the local -variables {\tt recurse} and {\tt result} do not exist, because -the branch that creates them does not run. +마지막 프레임에는 {\tt recurse}와 {\tt result}가 없다. 이 변수들을 +생성하는 분기가 실행되지 않았기 때문이다. -\section{Leap of faith} + +\section{믿음의 도약} +%Leap of faith \index{recursion} \index{leap of faith} -Following the flow of execution is one way to read programs, but -it can quickly become overwhelming. An -alternative is what I call the ``leap of faith''. When you come to a -function call, instead of following the flow of execution, you {\em -assume} that the function works correctly and returns the right -result. - -In fact, you are already practicing this leap of faith when you use -built-in functions. When you call {\tt math.cos} or {\tt math.exp}, -you don't examine the bodies of those functions. You just -assume that they work because the people who wrote the built-in -functions were good programmers. - -The same is true when you call one of your own functions. For -example, in Section~\ref{boolean}, we wrote a function called -\verb"is_divisible" that determines whether one number is divisible by -another. Once we have convinced ourselves that this function is -correct---by examining the code and testing---we can use the function -without looking at the body again. +실행 흐름에 따라 프로그램을 읽는 것도 한 방법이기는 하지만, 코드의 +길이에 압도될 수도 있다. 그 대안으로 ``믿음의 도약(leap of faith)''을 +하는 방법을 소개하겠다. 함수 호출을 만나면 실행 흐름대로 그 함수의 +내용을 다 읽는 대신, 그 함수가 제대로 동작하고 리턴 값도 제대로 +전달한다고 가정 하자. + +사실, 내장 함수은 이미 제대로 동작한다는 믿음을 갖고 사용했었다. {\tt + math.cos}나 {\tt math.exp}를 호출 했을 때 그 함수의 내용을 일일이 +확인해보지 않았다. 그저 내장 함수들은 훌륭한 프로그래머가 작성했을 +것이라 믿고 동작할 것이라 생각했다. + +자신이 작성한 함수도 똑같은 믿음을 갖고 사용해도 된다. +\ref{boolean}절에서 작성한 \verb"is_divisible"을 떠올려 보자. 이 +함수가 정확하다고 믿은 순간---코드 확인과 검사를 거친 후---그 함수의 +내용을 다시 읽어보지 않고 사용했다. \index{testing!leap of faith} -The same is true of recursive programs. When you get to the recursive -call, instead of following the flow of execution, you should assume -that the recursive call works (returns the correct result) and then ask -yourself, ``Assuming that I can find the factorial of $n-1$, can I -compute the factorial of $n$?'' It is clear that you -can, by multiplying by $n$. +재귀 프로그램도 다르지 않다. 재귀 호출을 만나면 실행 흐름을 쫓는 대신 +재귀 호출이 제대로 동작한다고 믿어보자(그리고 정확한 결과도 리턴한다고 +해보자). 그리고 ``$n-1$의 계승을 구할 수 있다고 한다면 $n$의 계승도 +계산할 수 있을까?''라고 물어야 한다. $n$만 곱하면 되기 때문에 당연히 +가능하다. + +물론, 작성을 다 하지 않은 함수를 제대로 동작한다고 가정하는게 이상할 수 +있지만 그렇기 때문에 믿음의 도약이라 부르는 것이다. -Of course, it's a bit strange to assume that the function works -correctly when you haven't finished writing it, but that's why -it's called a leap of faith! -\section{One more example} +\section{또 하나의 예} +%One more example \label{one.more.example} -\index{fibonacci function} -\index{function!fibonacci} -After {\tt factorial}, the most common example of a recursively -defined mathematical function is {\tt fibonacci}, which has the -following definition (see - \url{http://en.wikipedia.org/wiki/Fibonacci_number}): +\index{fibonacci function} \index{function!fibonacci} {\tt factorial}을 +살펴보았는데, 가장 흔한 재귀적으로 정의한 수학 함수는 {\tt + fibonacci}이다. 정의는 다음과 같다(참고: +\url{http://en.wikipedia.org/wiki/Fibonacci_number}). % \begin{eqnarray*} && \mathrm{fibonacci}(0) = 0 \\ @@ -4906,7 +4865,7 @@ \section{One more example} && \mathrm{fibonacci}(n) = \mathrm{fibonacci}(n-1) + \mathrm{fibonacci}(n-2) \end{eqnarray*} % -Translated into Python, it looks like this: +Python으로 해석하면 다음과 같다. \begin{verbatim} def fibonacci(n): @@ -4918,18 +4877,18 @@ \section{One more example} return fibonacci(n-1) + fibonacci(n-2) \end{verbatim} % -If you try to follow the flow of execution here, even for fairly -small values of $n$, your head explodes. But according to the -leap of faith, if you assume that the two recursive calls -work correctly, then it is clear that you get -the right result by adding them together. +아무리 작은 $n$이라 할지라도 이 함수의 실행 흐름을 따라가려면 머리가 +터질 것이다. 믿음의 도약을 한다고 생각하고 두개의 재귀 호출이 제대로 +동작한다고 믿어보자. 그러면 결과들을 더했을 때 올바른 값을 얻는다는 +것이 명확해질 것이다. \index{flow of execution} -\section{Checking types} +\section{데이터 형 검사} +%Checking types \label{guardian} -What happens if we call {\tt factorial} and give it 1.5 as an argument? +{\tt factorial}을 호출 할 때 인자가 1.5면 어떻게 될까? \index{type checking} \index{error checking} \index{factorial function} @@ -4940,36 +4899,33 @@ \section{Checking types} RuntimeError: Maximum recursion depth exceeded \end{verbatim} % -It looks like an infinite recursion. How can that be? The function -has a base case---when {\tt n == 0}. But if {\tt n} is not an integer, -we can {\em miss} the base case and recurse forever. +무한 재귀문 오류인 것처럼 보인다. 어째서 그럴가? {\tt n == 0}이라는 +기준 케이스도 있는데 말이다. {\tt n}이 정수가 아니면 기준 케이스에 +도달 못하고 영원히 재귀 호출을 하게 된다. \index{infinite recursion} \index{recursion!infinite} -In the first recursive call, the value of {\tt n} is 0.5. -In the next, it is -0.5. From there, it gets smaller -(more negative), but it will never be 0. +첫 번째 재귀 호출에서 {\tt n}의 값은 0.5이다. 그 다음에는 -0.5가 +된다. 그 이후에는 수는 작아지기만 하지 절대로 0은 안된다. -We have two choices. We can try to generalize the {\tt factorial} -function to work with floating-point numbers, or we can make {\tt - factorial} check the type of its argument. The first option is -called the gamma function and it's a -little beyond the scope of this book. So we'll go for the second. +두 가지 선택이 있다. {\tt factorial} 함수를 일반화해서 부동소수점 수도 +계산할 수 있게 하거나 {\tt factorial}이 인자의 데이터 형을 검사할 수도 +있다. 첫 번째는 감마 함수라고 부르고 이 책이 다룰 수 있는 범위 밖에 +있다. 그러니 두 번째 것을 시도해보자. \index{gamma function} -We can use the built-in function {\tt isinstance} to verify the type -of the argument. While we're at it, we can also make sure the -argument is positive: +내부 함수 중 {\tt isinstance}을 사용해서 인자의 데이터 형을 검사할 수 +있다. 그와 동시에 인자로 받은 값이 양수인지도 확인할 수 있다. \index{isinstance function} \index{function!isinstance} \begin{verbatim} def factorial(n): if not isinstance(n, int): - print('Factorial is only defined for integers.') + print('정수에 대해서만 정의되어 있음.') return None elif n < 0: - print('Factorial is not defined for negative integers.') + print('음의 정수에 대해서는 정의 안됨.') return None elif n == 0: return 1 @@ -4977,77 +4933,69 @@ \section{Checking types} return n * factorial(n-1) \end{verbatim} % -The first base case handles nonintegers; the -second handles negative integers. In both cases, the program prints -an error message and returns {\tt None} to indicate that something -went wrong: +첫 기준 케이스는 정수가 아닌 경우를 다루고 두 번째는 음의 정수를 +다룬다. 두 경우다 프로그램은 오류 메시지를 출력 하고 무언가 +잘못되었다는 것을 표시하기 위해 {\tt None}을 리턴한다. + \begin{verbatim} >>> print(factorial('fred')) -Factorial is only defined for integers. +정수에 대해서만 정의되어 있음. None >>> print(factorial(-2)) -Factorial is not defined for negative integers. +음의 양수에 대해서는 정의 안됨. None \end{verbatim} % -If we get past both checks, we know that $n$ is positive or -zero, so we can prove that the recursion terminates. +두 검사를 통과했다면, $n$은 양수의 정수이거나 0이라는 것을 알기 때문에 +재귀문이 종료한다는 것을 증명할 수 있다. \index{guardian pattern} \index{pattern!guardian} -This program demonstrates a pattern sometimes called a {\bf guardian}. -The first two conditionals act as guardians, protecting the code that -follows from values that might cause an error. The guardians make it -possible to prove the correctness of the code. +이 프로그램은 {\bf 가디언(guardian}, 보호자{\bf)}이라는 패턴을 +사용하였다. 첫 두 조건문이 오류가 발생할만한 값들로부터 코드를 +보호하는 가디언 역할을 한다. 가디언 패턴으로 코드의 정확성을 증명할 수 +있다. -In Section~\ref{raise} we will see a more flexible alternative to printing -an error message: raising an exception. +\ref{raise}절에서는 오류 메시지를 출력하는 것보다 좀 더 유연한 대안인 +엑셉션(exception, 예외) 처리에 대해 살펴 볼 것이다. -\section{Debugging} +\section{디버깅} +%Debugging \label{factdebug} - -Breaking a large program into smaller functions creates natural -checkpoints for debugging. If a function is not -working, there are three possibilities to consider: +큰 프로그램을 작은 함수들로 나누어 작성하는 것은 디버깅을 할 수 있는 지점들을 자연스럽게 만드는 효과가 있다. 함수가 동작하지 않을 때 검사해 볼 세가지가 있다. \index{debugging} \begin{itemize} -\item There is something wrong with the arguments the function -is getting; a precondition is violated. +\item 함수가 전달 받는 인자에 문제가 있다. 사전 조건이 잘못되었다. -\item There is something wrong with the function; a postcondition -is violated. +\item 함수에 문제가 있다. 사후 조건이 잘못되었다. -\item There is something wrong with the return value or the -way it is being used. +\item 리턴 값 또는 그 값을 사용하는데 문제가 있다. \end{itemize} -To rule out the first possibility, you can add a {\tt print} statement -at the beginning of the function and display the values of the -parameters (and maybe their types). Or you can write code -that checks the preconditions explicitly. +첫 가능성을 제거하려면 함수 시작부분에 {\tt print}문을 써서 매개 변수의 +값(그리고 데이터 형)을 출력해 보면 된다. 또는 사전 조건이 정확한지 +검사하는 코드를 명시적으로 작성하면 된다. \index{precondition} \index{postcondition} -If the parameters look good, add a {\tt print} statement before each -{\tt return} statement and display the return value. If -possible, check the result by hand. Consider calling the -function with values that make it easy to check the result -(as in Section~\ref{incremental.development}). +매개 변수가 맞아 보이면 모든 {\tt return}문 전에 {\tt print}문을 +삽입하여 리턴 값을 검사해보자. 함수 호출의 결과를 수기로도 +검산해보자. 검산이 쉬운 값을 넣어 함수를 +호출해보자(\ref{incremental.development}절을 참고하자). -If the function seems to be working, look at the function call -to make sure the return value is being used correctly (or used -at all!). +함수가 제대로 동작하는 것처럼 보이면 호출하는 문장에서 리턴 값을 +정확하게 사용하는지(또는 사용은 하는지) 확인해보자. \index{flow of execution} -Adding print statements at the beginning and end of a function -can help make the flow of execution more visible. -For example, here is a version of {\tt factorial} with -print statements: + +함수가 시작할 때 그리고 끝날 때 {\tt print}문을 넣어보면 실행 흐름을 +시각화하는데 도움이 된다. 다음은 {\tt factorial}에 {\tt print}문을 넣은 +버전이다. \begin{verbatim} def factorial(n): @@ -5063,8 +5011,8 @@ \section{Debugging} return result \end{verbatim} % -{\tt space} is a string of space characters that controls the -indentation of the output. Here is the result of {\tt factorial(4)} : +{\tt space}는 공백 문자열로 결과의 들여쓰기 정도를 나타낸다. 다음은 +{\tt factorial(4)}의 결과이다. \begin{verbatim} factorial 4 @@ -5079,9 +5027,9 @@ \section{Debugging} returning 24 \end{verbatim} % -If you are confused about the flow of execution, this kind of -output can be helpful. It takes some time to develop effective -scaffolding, but a little bit of scaffolding can save a lot of debugging. +실행 흐름이 혼란스럽다면 이런 식으로 결과를 표시하는 것도 도움이 된다. +효과적인 발판을 만드는 것은 시간이 걸리지만 작은 발판이라할지라도 +디버깅 시간을 크게 줄일 수 있다. \section{용어 해설} @@ -5089,27 +5037,26 @@ \section{용어 해설} \begin{description} -\item[temporary variable:] A variable used to store an intermediate value in -a complex calculation. +\item[임시변수(temporary variable):] 복잡한 계산의 중간 값을 저장하는데 + 사용하는 변수 \index{temporary variable} \index{variable!temporary} -\item[dead code:] Part of a program that can never run, often because -it appears after a {\tt return} statement. +\item[죽은 코드(dead code):] 대체적으로 {\tt return}문 다음에 오는 + 코드로 프로그램에서 실행되지 않는 부분 \index{dead code} -\item[incremental development:] A program development plan intended to -avoid debugging by adding and testing only -a small amount of code at a time. +\item[점진적 개발(incremental development):] 한 번에 작은 크기의 코드를 + 추가하고 검사하여 디버깅 시간을 줄이려는 프로그램 걔발 계획 \index{incremental development} -\item[scaffolding:] Code that is used during program development but is -not part of the final version. +\item[발판(scaffolding):] 프로그램 개발 중에는 사용되나 최종 버전에는 + 제외되는 코드 \index{scaffolding} -\item[guardian:] A programming pattern that uses a conditional -statement to check for and handle circumstances that -might cause an error. +\item[가디언(보호자, guardian):] 오류를 발생시킬 수도 있는 상황을 + 조건문으로 처리하거나 검사하는 프로그래밍 패턴 + \index{guardian pattern} \index{pattern!guardian} @@ -5121,7 +5068,7 @@ \section{연습 문제} \begin{exercise} -Draw a stack diagram for the following program. What does the program print? +다음 프로그램의 스택 상태도를 그려라. 프로그램은 무엇을 표시하는가? \index{stack diagram} \begin{verbatim} @@ -5150,7 +5097,7 @@ \section{연습 문제} \begin{exercise} \label{ackermann} -The Ackermann function, $A(m, n)$, is defined: +아커만 함수 $A(m, n)$은 다음과 같이 정의 되었다. \begin{eqnarray*} A(m, n) = \begin{cases} @@ -5160,11 +5107,11 @@ \section{연습 문제} \end{cases} \end{eqnarray*} % -See \url{http://en.wikipedia.org/wiki/Ackermann_function}. -Write a function named {\tt ack} that evaluates the Ackermann function. -Use your function to evaluate {\tt ack(3, 4)}, which should be 125. -What happens for larger values of {\tt m} and {\tt n}? -Solution: \url{http://thinkpython2.com/code/ackermann.py}. +상세 설명은 \url{http://en.wikipedia.org/wiki/Ackermann_function}을 +참고하라. 아커만 함수를 계산하는 {\tt ack} 함수를 작성하라. {\tt + ack(3, 4)}의 값을 구하고 125가 맞는지 확인하라. {\tt m}이나 {\tt + n}이 더 큰 값이면 어떻게 되는가? 해답은 +\url{http://thinkpython2.com/code/ackermann.py}에 있다. \index{Ackermann function} \index{function!ack} @@ -5173,15 +5120,13 @@ \section{연습 문제} \begin{exercise} \label{palindrome} - -A palindrome is a word that is spelled the same backward and -forward, like ``noon'' and ``redivider''. Recursively, a word -is a palindrome if the first and last letters are the same -and the middle is a palindrome. +회문(pallindrome)은 ``noon''과 ``redivider''처럼 단어의 순방향 철자가 +역방향 철자와 동일한 단어를 뜻한다. 재귀적으로 표현했을 때, 첫 글자와 +마지막 글자가 같고 중간 부분이 회문이면 그 단어는 회문이다. \index{palindrome} -The following are functions that take a string argument and -return the first, last, and middle letters: +다음의 함수들은 문자열을 인자로 받아 첫 글자, 마지막 글자, 그리고 +중간의 글자들을 리턴한다. \begin{verbatim} def first(word): @@ -5194,33 +5139,32 @@ \section{연습 문제} return word[1:-1] \end{verbatim} % -We'll see how they work in Chapter~\ref{strings}. +동작 방식은 \ref{strings}장에서 살펴볼 것이다. \begin{enumerate} -\item Type these functions into a file named {\tt palindrome.py} -and test them out. What happens if you call {\tt middle} with -a string with two letters? One letter? What about the empty -string, which is written \verb"''" and contains no letters? +\item {\tt palindrome.py}라는 이름을 함수들을 저장하고 검사해보자. 두 + 글자 길이의 단어를 {\tt middle} 함수에 인자로 전달하면 어떻게 + 되는가? 한 글자이면 어떻게 되는가? 빈 문자열 \verb"''"을 인자로 + 전달하면 어떻게 되는가? -\item Write a function called \verb"is_palindrome" that takes -a string argument and returns {\tt True} if it is a palindrome -and {\tt False} otherwise. Remember that you can use the -built-in function {\tt len} to check the length of a string. +\item 문자열을 인자로 받아 그 문자열이 회문이면 {\tt True}를 아니면 + {\tt False}를 리턴하는 \verb"is_palindrome" 함수를 작성하라. 참고로 + 문자열의 길이를 확인하기 위해 내장 함수인 {\tt len}을 쓸 수 있다. \end{enumerate} -Solution: \url{http://thinkpython2.com/code/palindrome_soln.py}. +해답: \url{http://thinkpython2.com/code/palindrome_soln.py}. \end{exercise} \begin{exercise} -A number, $a$, is a power of $b$ if it is divisible by $b$ -and $a/b$ is a power of $b$. Write a function called -\verb"is_power" that takes parameters {\tt a} and {\tt b} -and returns {\tt True} if {\tt a} is a power of {\tt b}. -Note: you will have to think about the base case. + 어떤 수 $a$는 $b$로 나눌 수 있고 $a/b$가 $b$의 거듭제곱이면 $a$는 + $b$의 거듭제곱이다. {\tt a}와 {\tt b}를 매개 변수로 받아 {\tt a}가 + {\tt b}의 거듭제곱이면 {\tt True}를 리턴하는 \verb"is_power" 함수를 + 작성하라. 참고: 기준 케이스 선정이 중요하다. + \end{exercise} @@ -5229,19 +5173,19 @@ \section{연습 문제} \index{greatest common divisor (GCD)} \index{GCD (greatest common divisor)} -The greatest common divisor (GCD) of $a$ and $b$ is the largest number -that divides both of them with no remainder. +$a$와 $b$의 최대 공약수(the Greatest Common Divisor, GCD)는 나머지 없이 +두 수를 나눌 수 있는 가장 큰 수이다. + +최대 공약수를 찾는 한 방법은 $a$을 $b$로 나눴을 때의 나머지 $r$에 대해 +$gcd(a, b) = gcd(b, r)$의 관계가 성립한다는 관찰을 사용하면 된다. 기준 +케이스로 $gcd(a, 0) = a$를 사용하라. -One way to find the GCD of two numbers is based on the observation -that if $r$ is the remainder when $a$ is divided by $b$, then $gcd(a, -b) = gcd(b, r)$. As a base case, we can use $gcd(a, 0) = a$. +매개 변수 {\tt a}와 {\tt b}를 사용하고 최대 공약수를 리턴하는 +\verb"gcd" 함수를 작성하라. -Write a function called -\verb"gcd" that takes parameters {\tt a} and {\tt b} -and returns their greatest common divisor. -Credit: This exercise is based on an example from Abelson and -Sussman's {\em Structure and Interpretation of Computer Programs}. +출처: 애벨슨(Abelson)과 서스만(Sussman)의 {\em Structure and + Interpretation of Computer Programs}의 예제를 참고하였다. \end{exercise} From c2fdd520f1772f6e35544c59bf74555761f2c759 Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Sun, 9 Jul 2017 23:34:57 +0900 Subject: [PATCH 10/13] iteration: while --- book_kr/book.tex | 575 ++++++++++++++++++++++++----------------------- 1 file changed, 296 insertions(+), 279 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 3a4369e..31b9fdd 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -2543,7 +2543,8 @@ \section{용어 해설} 줄 수도 있고 그렇지 않을 수도 있음 \index{function} -\item[함수 정의(function definition):] 새로운 함수를 생성하는 문장으로 함수의 이름과 매개 변수들을 지정하고 그리고 문장들을 포함함 +\item[함수 정의(function definition):] 새로운 함수를 생성하는 문장으로 + 함수의 이름과 매개 변수들을 지정하고 그리고 문장들을 포함함 \index{function definition} \item[함수 객체(function object):] 함수 정의에 의해 생성되는 값. @@ -2688,7 +2689,9 @@ \section{연습 문제} 호출하여라. 이 때, \verb"print_twice" 함수의 인자는 \verb"'spam'"을 사용하여라. -\item 함수 객체와 값을 전달 받아 해당 함수를 4번 호출하고 값은 매개 변수로 사용하는 \verb"do_four"라는 새로운 함수를 정의하여라. 이 함수의 내용에는 네 개가 아니라 두 개의 문장만 있어야 한다. +\item 함수 객체와 값을 전달 받아 해당 함수를 4번 호출하고 값은 매개 + 변수로 사용하는 \verb"do_four"라는 새로운 함수를 정의하여라. 이 + 함수의 내용에는 네 개가 아니라 두 개의 문장만 있어야 한다. \end{enumerate} @@ -2838,7 +2841,8 @@ \section{Turtle 모듈} 있다. 펜을 내리면 \texttt{Turtle}이 이동한 흔적을 남길 수 있다. {\tt pu}와 {\tt pd}는 각각 펜을 들기와 펜 내리기를 뜻한다. -직각을 그리려면 다음의 줄들을 프로그램에 추가하자(위치는 {\tt bob}을 생성한 줄과 \verb"mainloop"를 호출하는 줄 사이에 삽입하면 된다. +직각을 그리려면 다음의 줄들을 프로그램에 추가하자(위치는 {\tt bob}을 +생성한 줄과 \verb"mainloop"를 호출하는 줄 사이에 삽입하면 된다. \begin{verbatim} bob.fd(100) @@ -3108,7 +3112,10 @@ \section{인터페이스 설계} circle} 함수를 부르는 사용자가 제어권을 갖도록 한다. \index{interface} -{\bf 인터페이스(interface)}는 함수를 어떻게 쓸 수 있는지 알려주는 요약이다. 어떤 매개 변수가 있고, 함수가 무엇을 하는지 그리고 어떤 결과를 리턴하는지 알려준다. 인터페이스가 ``단순하면'' 불필요한 세부 내용을 신경 쓰지 않고 원하는 것을 얻을 수 있다. +{\bf 인터페이스(interface)}는 함수를 어떻게 쓸 수 있는지 알려주는 +요약이다. 어떤 매개 변수가 있고, 함수가 무엇을 하는지 그리고 어떤 +결과를 리턴하는지 알려준다. 인터페이스가 ``단순하면'' 불필요한 세부 +내용을 신경 쓰지 않고 원하는 것을 얻을 수 있다. 이 예제에서는 그리려는 원의 크기를 정하기 위해 {\tt r}이 인터페이스에 포함되어 있다. {\tt n}은 원이 어떻게 표현되어야 하는가에 대한 정보를 @@ -3233,7 +3240,10 @@ \section{개발 계획} \end{enumerate} -이 과정에는 몇 가지 단점이 있다. 그 대안들은 이후에 살펴볼 것이다. 그래도 이 방법은 프로그램을 함수로 나누는 어떻게 나눌지 개발 전에 미리 알 수 없는 경우라면 충분히 의미있다. 개발하면서 설계도 같이 할 수 있기 때문이다. +이 과정에는 몇 가지 단점이 있다. 그 대안들은 이후에 살펴볼 것이다. +그래도 이 방법은 프로그램을 함수로 나누는 어떻게 나눌지 개발 전에 미리 +알 수 없는 경우라면 충분히 의미있다. 개발하면서 설계도 같이 할 수 있기 +때문이다. \section{설명 문자열} @@ -3455,7 +3465,11 @@ \section{내림 나눗셈과 나머지 연산자} %Floor division and modulus %{\ -{\bf 내림 나눗셈} 연산자 \verb"//"는 두 수를 나누어 얻은 결과 값의 정수 값을 취한다. 예를 들어, 105분 길이의 영화가 있다고 했을 때 몇 시간짜리 영화인지 궁금할 때가 있다. 이런 경우 일반 나눗셈을 사용하면 부동소수점 값을 얻는다. +{\bf 내림 나눗셈} 연산자 \verb"//"는 두 수를 나누어 얻은 결과 값의 정수 +값을 취한다. 예를 들어, 105분 길이의 영화가 있다고 했을 때 몇 시간 +짜리 영화인지 궁금할 때가 있다. 이런 경우 일반 나눗셈을 사용하면 +부동소수점 값을 얻는다. + \begin{verbatim} >>> minutes = 105 >>> minutes / 60 @@ -3519,7 +3533,10 @@ \section{불 표현식} \index{logical operator} \index{operator!logical} -{\bf 불 표현식(boolean expression)}은 참또는 거짓을 나타내는 표현식이다. 다음의 예들은 두 피연산자를 비교하는 {\tt ==} 연산자를 사용한다. 두 값이 동일하면 {\tt True(참)}을 다르면 {\tt False(거짓)}이다. +{\bf 불 표현식(boolean expression)}은 참또는 거짓을 나타내는 +표현식이다. 다음의 예들은 두 피연산자를 비교하는 {\tt ==} 연산자를 +사용한다. 두 값이 동일하면 {\tt True(참)}을 다르면 {\tt + False(거짓)}이다. \begin{verbatim} >>> 5 == 5 @@ -3808,8 +3825,9 @@ \section{재귀문} 1을 출력하고 자신을 호출한다. -\begin{quote} -{\tt countdown}은 {\tt n=0}에서 실행된다. {\tt n}은 0이기 때문에 ``발사!''라고 화면에 표시하고 리턴한다. +\begin{quote} +{\tt countdown}은 {\tt n=0}에서 실행된다. {\tt n}은 + 0이기 때문에 ``발사!''라고 화면에 표시하고 리턴한다. \end{quote} \end{quote} @@ -4057,7 +4075,9 @@ \section{디버깅} \index{error!runtime} \index{runtime error} -실행 중 발생 오류에서도 마찬가지다. 신호대잡음비를 데시벨로 계산한다고 해보자. 계산식은 $SNR_{db} = 10 \log_{10} (P_{signal} / P_{noise})$이다. Python에서는 이 식을 작성하면 다음과 같다. +실행 중 발생 오류에서도 마찬가지다. 신호대잡음비를 데시벨로 계산한다고 +해보자. 계산식은 $SNR_{db} = 10 \log_{10} (P_{signal} / +P_{noise})$이다. Python에서는 이 식을 작성하면 다음과 같다. \begin{verbatim} import math @@ -4300,7 +4320,9 @@ \section{연습 문제} \begin{exercise} \index{Koch curve} -코흐 곡선(The Koch curve)는 그림 \ref{fig.koch}처럼 보이는 프랙탈 곡선이다. 길이 $x$를 사용하여 코흐 곡선을 그려라. 그리는 방법은 다음과 같다. +코흐 곡선(The Koch curve)는 그림 \ref{fig.koch}처럼 보이는 프랙탈 +곡선이다. 길이 $x$를 사용하여 코흐 곡선을 그려라. 그리는 방법은 다음과 +같다. \begin{enumerate} @@ -4514,7 +4536,10 @@ \section{점진적 개발} return 0.0 \end{verbatim} % -함수가 동작한다면, \verb"dx는 3" 그리고 \verb"dy는 4"를 출력할 것이다. 그리고 그렇게 출력되었다면 인자도 함수에 제대로 전달했고 첫 계산도 정확히 수행했다는 것을 알 수 있다. 만약 잘못 나왔다면 검사해야 할 코드가 몇 줄 되지 않는 것에 위안을 얻으면 된다. +함수가 동작한다면, \verb"dx는 3" 그리고 \verb"dy는 4"를 출력할 것이다. +그리고 그렇게 출력되었다면 인자도 함수에 제대로 전달했고 첫 계산도 +정확히 수행했다는 것을 알 수 있다. 만약 잘못 나왔다면 검사해야 할 +코드가 몇 줄 되지 않는 것에 위안을 얻으면 된다. 그 다음 과정은 {\tt dx}와 {\tt dy}의 제곱의 합을 계산해야 한다. @@ -4560,11 +4585,15 @@ \section{점진적 개발} \begin{enumerate} -\item 동작하는 프로그램으로 부터 시작하여 점진적인 변화를 만들어라. 그래야 어떤 순간이라도 오류를 발견하면 어디에 원인이 있는지 쉽게 찾을 수 있다. +\item 동작하는 프로그램으로 부터 시작하여 점진적인 변화를 만들어라. + 그래야 어떤 순간이라도 오류를 발견하면 어디에 원인이 있는지 쉽게 찾을 + 수 있다. \item 중간 값들을 변수에 저장하여 출력해보고 검사 할 수 있게 만들어라 -\item 프로그램이 동작한다면 발판으로 사용한 코드를 삭제하고 여러 줄로 작성한 문장들을 복합문으로 통합해라. 단, 통합했을 때 코드 읽기가 너무 어려워지면 안된다. +\item 프로그램이 동작한다면 발판으로 사용한 코드를 삭제하고 여러 줄로 + 작성한 문장들을 복합문으로 통합해라. 단, 통합했을 때 코드 읽기가 + 너무 어려워지면 안된다. \end{enumerate} @@ -4794,7 +4823,8 @@ \section{또 다시 재귀문} \end{quote} -리턴 값 2을 $n$과 곱한 결과를 리턴한다. 이 때, $n$은 3이다. 계산 결과 6이 처음 재귀 호출 과정을 시작한 함수의 리턴 값이 된다. +리턴 값 2을 $n$과 곱한 결과를 리턴한다. 이 때, $n$은 3이다. 계산 결과 +6이 처음 재귀 호출 과정을 시작한 함수의 리턴 값이 된다. \index{stack diagram} @@ -4964,8 +4994,10 @@ \section{데이터 형 검사} \section{디버깅} %Debugging \label{factdebug} -큰 프로그램을 작은 함수들로 나누어 작성하는 것은 디버깅을 할 수 있는 지점들을 자연스럽게 만드는 효과가 있다. 함수가 동작하지 않을 때 검사해 볼 세가지가 있다. -\index{debugging} +큰 프로그램을 작은 함수들로 나누어 작성하는 것은 디버깅을 할 수 있는 +지점들을 자연스럽게 만드는 효과가 있다. 함수가 동작하지 않을 때 검사해 +볼 세가지가 있다. +\index{debugging} \begin{itemize} @@ -5190,25 +5222,27 @@ \section{연습 문제} \end{exercise} -\chapter{Iteration} +\chapter{반복} +%Iteration -This chapter is about iteration, which is the ability to run -a block of statements repeatedly. We saw a kind of iteration, -using recursion, in Section~\ref{recursion}. -We saw another kind, using a {\tt for} loop, -in Section~\ref{repetition}. In this chapter we'll see yet another -kind, using a {\tt while} statement. -But first I want to say a little more about variable assignment. +이 장에서는 문장을 되풀이하여 실행하는 기능인 반복을 다룬다. +\ref{recursion}절에서 재귀문을 사용한 반복의 일종을 살펴봤었다. +\ref{repetition}절에서 {\tt for} 루프도 봤었다. 이 장에서는 {\tt + while}문을 사용한 또 다른 반복문을 배울 것이다. 그 전에 변수 할당에 +대해 좀 더 이야기하고 시작하겠다. -\section{Reassignment} +\section{재할당} +%Reassignment \index{assignment} \index{statement!assignment} \index{reassignment} -As you may have discovered, it is legal to make more than one -assignment to the same variable. A new assignment makes an existing -variable refer to a new value (and stop referring to the old value). +같은 변수에 한 번 이상 값을 할당해도 괜찮다는 것을 이제 깨달았을 +것이다. 기존의 변수에 새로운 값을 할당하면 그 변수는 새로운 값을 +가리킨다(이전에 가리키던 값은 더 이상 가리키지 않는다). + + \begin{verbatim} >>> x = 5 @@ -5219,82 +5253,78 @@ \section{Reassignment} 7 \end{verbatim} % -The first time we display -{\tt x}, its value is 5; the second time, its -value is 7. +{\tt x}는 처음에 5를 그리고 두 번째 7이라는 값을 갖는다. -Figure~\ref{fig.assign2} shows what {\bf reassignment} looks -like in a state diagram. \index{state diagram} \index{diagram!state} +그림 \ref{fig.assign2}의 스택 상태도에 {\bf 재할당(reassignment)}를 나타냈다. +\index{state diagram} \index{diagram!state} -At this point I want to address a common source of -confusion. -Because Python uses the equal sign ({\tt =}) for assignment, it is -tempting to interpret a statement like {\tt a = b} as a -mathematical -proposition of equality; that is, the claim that {\tt a} and -{\tt b} are equal. But this interpretation is wrong. +현 시점에서 많이들 혼돈하는 것을 집고 넘어가자. Python에서 등호({\tt + =})를 사용하는데 이 기호를 수학 명제로서 {\tt a = b}를 +해석하려고한다. 수학에서는 {\tt a}와 {\tt b}가 서로 동일하다는 +주장이다. 하지만, 그렇게 해석하면 틀린 것이다. \index{equality and assignment} -First, equality is a symmetric relationship and assignment is not. For -example, in mathematics, if $a=7$ then $7=a$. But in Python, the -statement {\tt a = 7} is legal and {\tt 7 = a} is not. -Also, in mathematics, a proposition of equality is either true or -false for all time. If $a=b$ now, then $a$ will always equal $b$. -In Python, an assignment statement can make two variables equal, but -they don't have to stay that way: +첫째로 등가는 대칭적 관계를 나타내지만 할당은 대칭적이지 않다. 예를 +들어보자. 수학에서는 $a = 7$이면 $7 = a$이다. Python에서는 {\tt a = + 7 }이라는 문장은 괜찮지만 {\tt 7 = a}라는 문장은 틀린 문장이다. + + +수학에서는 어떤 식이 등가라면 그 주장은 항상 참이다. $a = b$라고 하면 +$a$는 항상 $b$와 동일하다. Python에서 할당문은 두 변수가 서로 동일하게 +만들지만 항상 그대로 유지되는 것은 아니다. + \begin{verbatim} >>> a = 5 ->>> b = a # a and b are now equal ->>> a = 3 # a and b are no longer equal +>>> b = a # a와 b는 같음 +>>> a = 3 # a와 b는 더 이상 같지 않음 >>> b 5 \end{verbatim} % -The third line changes the value of {\tt a} but does not change the -value of {\tt b}, so they are no longer equal. +세 번째 줄은 {\tt a}를 변경하지만 {\tt b}는 변경시키지 않는다. 그렇기 +때문에 둘은 더 이상 같지 않다. -Reassigning variables is often useful, but you should use it -with caution. If the values of variables change frequently, it can -make the code difficult to read and debug. +변수 재할당은 유용하지만 신중하게 사용해야 한다. 변수의 값이 자주 +바뀌면 코드 읽기와 디버깅이 어려워진다. \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/assign2.pdf}} -\caption{State diagram.} +\caption{스택 상태도} \label{fig.assign2} \end{figure} -\section{Updating variables} +\section{변수 갱신하기} +%Updating variables \label{update} \index{update} \index{variable!updating} -A common kind of reassignment is an {\bf update}, -where the new value of the variable depends on the old. +흔한 할당 방법은 {\bf 갱신(update)}이다. 이런 종류는 변수의 새로운 +값은 이전 변수의 값에 의존한다. \begin{verbatim} >>> x = x + 1 \end{verbatim} % -This means ``get the current value of {\tt x}, add one, and then -update {\tt x} with the new value.'' +이 문장은 ``현재 {\tt x}의 값에 1을 더하고 그 값으로 {\tt x}을 갱신한다. + +존재하지 않는 변수를 갱신하면 오류가 발생한다. 왜냐하면 Python은 +오른쪽의 표현을 먼저 계산하고 {\tt x}에 값으로 할당하기 때문이다. -If you try to update a variable that doesn't exist, you get an -error, because Python evaluates the right side before it assigns -a value to {\tt x}: \begin{verbatim} >>> x = x + 1 NameError: name 'x' is not defined \end{verbatim} % -Before you can update a variable, you have to {\bf initialize} -it, usually with a simple assignment: +변수의 값을 갱신하기 전에 변수를 먼저 간단한 할당문으로 {\bf + 초기화(initialize)}해야 한다. \index{initialization (before update)} \begin{verbatim} @@ -5302,131 +5332,124 @@ \section{Updating variables} >>> x = x + 1 \end{verbatim} % -Updating a variable by adding 1 is called an {\bf increment}; -subtracting 1 is called a {\bf decrement}. +변수의 값에 1을 더하는 것을 {\bf 증가(increment)}, 1을 빼는 것을 {\bf + 감소(decrement)}라 부른다. \index{increment} \index{decrement} -\section{The {\tt while} statement} +\section{{\tt while}문} +%The {\tt while} statement \index{statement!while} \index{while loop} \index{loop!while} \index{iteration} -Computers are often used to automate repetitive tasks. Repeating -identical or similar tasks without making errors is something that -computers do well and people do poorly. In a computer program, -repetition is also called {\bf iteration}. +컴퓨터는 반복적인 작업을 자동하는데 주로 사용된다. 동일하거나 유사한 +작업을 오류 없이 처리하는 것을 컴퓨터는 잘하지만 사람은 그렇지 못하다. +컴퓨터 프로그램에서 퇴풀이되는 작업을 {\bf 반복(iteration)}이라 한다. + +우리는 재귀문을 사용하여 반복하는 {\tt countdown}과 \verb"print_n" +함수를 봤었다. 반복 작업이 너무나 흔하기 때문에 Python은 언어 차원에서 +반복 기능을 제공하고 있다. 그 중 하나는 \ref{repetition}에서 봤던 +{\tt for}문이다. 다시 한 번 살펴볼 것이다. -We have already seen two functions, {\tt countdown} and -\verb"print_n", that iterate using recursion. Because iteration is so -common, Python provides language features to make it easier. -One is the {\tt for} statement we saw in Section~\ref{repetition}. -We'll get back to that later. +또 다른 것은 {\tt while}문이다. {\tt countdown}을 {\tt while}문으로 +바꿔서 다시 작성해보자. -Another is the {\tt while} statement. Here is a version of {\tt -countdown} that uses a {\tt while} statement: \begin{verbatim} def countdown(n): while n > 0: print(n) n = n - 1 - print('Blastoff!') + print('발사!') \end{verbatim} % -You can almost read the {\tt while} statement as if it were English. -It means, ``While {\tt n} is greater than 0, -display the value of {\tt n} and then decrement -{\tt n}. When you get to 0, display the word {\tt Blastoff!}'' +{\tt while}문이 마치 영어처럼 거의 자연스럽게 읽혀진다. 해석하면 +``{\tt n}이 0보다 큰 동안에 {\tt n}의 값을 표시하고 그 값을 +감소시킨다. 0이 되면 {\tt 발사!}라고 표시''가 된다. \index{flow of execution} -More formally, here is the flow of execution for a {\tt while} statement: +좀 더 체계적으로 {\tt while}문의 실행 흐름을 살펴보자. \begin{enumerate} -\item Determine whether the condition is true or false. +\item 조건이 참인지 거짓인지 판단한다. -\item If false, exit the {\tt while} statement -and continue execution at the next statement. +\item 거짓이면 {\tt while}문을 끝내고 다음 문장을 실행한다. -\item If the condition is true, run the -body and then go back to step 1. +\item 조건이 참이면 {\tt while}의 내용을 실행하고 첫 단계로 간다. \end{enumerate} -This type of flow is called a loop because the third step -loops back around to the top. +이와 같은 흐름을 루프(loop, 반복)라 부른다. 세 번째 단계가 처음으로 +되돌아 반복하기 때문이다. \index{condition} \index{loop} \index{body} -The body of the loop should change the value of one or more variables -so that the condition becomes false eventually and the loop -terminates. Otherwise the loop will repeat forever, which is called -an {\bf infinite loop}. An endless source of amusement for computer -scientists is the observation that the directions on shampoo, -``Lather, rinse, repeat'', are an infinite loop. +루프의 내용은 하나 또는 그 이상의 변수를 바꿔야 한다. 그래야 조건이 +언젠가는 거짓이 되서 루프가 끝이나기 때문이다. 그렇지 않으면 루프는 +무한히 되풀이될 것이다. 이런 경우를 {\bf 무한 루프(infinite loop)}이라 +부른다. 샴푸의 사용법을 읽어보면 컴퓨터 과학자들은 놀라지 않을 수가 +없다. ``비누거품, 린스, 반복''라고 써 있는데, 이는 무한 루프이기 +때문이다. \index{infinite loop} \index{loop!infinite} -In the case of {\tt countdown}, we can prove that the loop -terminates: if {\tt n} is zero or negative, the loop never runs. -Otherwise, {\tt n} gets smaller each time through the -loop, so eventually we have to get to 0. +{\tt countdown}의 경우 루프가 끝이 있음을 증명할 수 있다. 만약 {\tt + n}이 0이거나 음수이면 루프는 시작도 안된다. 그 외에는 0이 될 때까지 +매번 루프를 돌 때마다 {\tt n}은 감소된다. -For some other loops, it is not so easy to tell. For example: +어떤 루프의 경우에는 판단하기가 쉽지않다. 에를 들어보자. \begin{verbatim} def sequence(n): while n != 1: print(n) - if n % 2 == 0: # n is even + if n % 2 == 0: # n은 짝수 n = n / 2 - else: # n is odd + else: # n은 홀수 n = n*3 + 1 \end{verbatim} % -The condition for this loop is {\tt n != 1}, so the loop will continue -until {\tt n} is {\tt 1}, which makes the condition false. +이 루프의 조건은 {\tt n != 1}이기 때문에 루프는 {\tt n}이 {\tt 1}이 +되어 거짓이 될 때까지 계속된다. -Each time through the loop, the program outputs the value of {\tt n} -and then checks whether it is even or odd. If it is even, {\tt n} is -divided by 2. If it is odd, the value of {\tt n} is replaced with -{\tt n*3 + 1}. For example, if the argument passed to {\tt sequence} -is 3, the resulting values of {\tt n} are 3, 10, 5, 16, 8, 4, 2, 1. +프로그램은 루프를 돌 때마다 {\tt n}의 값을 표시하고 짝수 또는 홀수 +검사를 한다. 짝수라면 {\tt n}를 2로 나누고, 홀수라면 {\tt n}은 {\tt + n*3 +1}으로 대체된다. {\tt sequence}에 인자를 3으로 전달했다고 +해보자. {\tt n}의 결과는 3, 10, 5, 16, 8, 4, 2, 1이 된다. -Since {\tt n} sometimes increases and sometimes decreases, there is no -obvious proof that {\tt n} will ever reach 1, or that the program -terminates. For some particular values of {\tt n}, we can prove -termination. For example, if the starting value is a power of two, -{\tt n} will be even every time through the loop -until it reaches 1. The previous example ends with such a sequence, -starting with 16. +{\tt n}가 증가되기도 하고 감소하기도 하기 때문에 1에 반드시 +도달한다거나 프로그램이 종료한다는 증명은 간단하지 않다. {\tt n}이 +특정 값인 경우라면 종료한다는 것을 증명할 수 있다. 시작 값이 2의 +배수라면 {\tt n}은 매번 짝수가 되기 때문에 루프를 반복하다보면 1에 +도달하게 된다. 16으로 시작한 경우가 그렇게 끝이 난다. \index{Collatz conjecture} -The hard question is whether we can prove that this program terminates -for {\em all} positive values of {\tt n}. So far, no one has -been able to prove it {\em or} disprove it! (See - \url{http://en.wikipedia.org/wiki/Collatz_conjecture}.) +좀 더 어려운 질문은 이 프로그램이 {\em 모든} 양수에 대해서 +종료하는가이다. 아직까지는 그 어느 누구도 이것을 증명{\em 도} +반증하지{\em 도} 못했다! (참고: +\url{http://en.wikipedia.org/wiki/Collatz_conjecture}.) -As an exercise, rewrite the function \verb"print_n" from -Section~\ref{recursion} using iteration instead of recursion. +연습 문제로 \ref{recursion}절의 \verb"print_n" 함수를 반복문을 사용하여 +재작성해보라. -\section{{\tt break}} +\section{{\tt break}문} \index{break statement} \index{statement!break} -Sometimes you don't know it's time to end a loop until you get half -way through the body. In that case you can use the {\tt break} -statement to jump out of the loop. +때로는 루프의 반정도를 실행하기 전까지는 루프를 종료할 때가 되었는지 +모를 때가 있다. 그런 경우에 {\tt break}문을 사용하여 루프 밖으로 나올 +수 있다. -For example, suppose you want to take input from the user until they -type {\tt done}. You could write: +사용자가 {\tt done}을 입력하기 전까지 계속 입력을 받는 예를 살펴보자. +다음과 같이 작성하면 된다. \begin{verbatim} while True: @@ -5438,13 +5461,14 @@ \section{{\tt break}} print('Done!') \end{verbatim} % -The loop condition is {\tt True}, which is always true, so the -loop runs until it hits the break statement. +루프의 조건이 {\tt True}라고 되어 있기 때문에 항상 참이다. 이 루프는 +{\tt break}문을 만나기 전까지 계속 반복된다. + +되풀이 될 때마다 꺽쇠 표시로 사용자에게 입력을 요청한다. 사용자가 +{\tt done}이라 쓰면 {\tt break}문이 루프를 끝낸다. 그 외에는 사용자가 +무엇을 입력하든 그것을 화면에 표시하고 루프의 처음으로 되돌아 간다. +여기 실행 예시가 있다. -Each time through, it prompts the user with an angle bracket. -If the user types {\tt done}, the {\tt break} statement exits -the loop. Otherwise the program echoes whatever the user types -and goes back to the top of the loop. Here's a sample run: \begin{verbatim} > not done @@ -5453,30 +5477,29 @@ \section{{\tt break}} Done! \end{verbatim} % -This way of writing {\tt while} loops is common because you -can check the condition anywhere in the loop (not just at the -top) and you can express the stop condition affirmatively -(``stop when this happens'') rather than negatively (``keep going -until that happens''). +{\tt while} 루프를 이렇게 사용하는 두 가지 이유가 있다. 첫 째는 조건이 +루프 내 어디서든(루프 맨위에서 한 번이 아니라) 비교가 되기 때문이다. +두 번째는 종료 조건을 부정적으로(``이것이 발생하기 전까지 계속'') +표현하는 대신 긍정적으로(``이것이 발생하면 멈춤'') 표현할 수 있기 +때문이다. -\section{Square roots} +\section{제곱 근} +%Square roots \label{squareroot} \index{square root} -Loops are often used in programs that compute -numerical results by starting with an approximate answer and -iteratively improving it. +루프는 근사치를 구하고 반복적으로 그 값을 더 정확하게 만드는 수치해석 +프로그램에서 주로 쓰인다. \index{Newton's method} -For example, one way of computing square roots is Newton's method. -Suppose that you want to know the square root of $a$. If you start -with almost any estimate, $x$, you can compute a better -estimate with the following formula: +예를 들어 보자. 제곱 근을 구하는 방법 중 하나는 뉴튼의 기법(Newton's +method)이다. $a$의 제곱 근을 알고 싶다고 해보자. 어떤 추정치 $x$에서 +시작하든 다음의 식으로 좀 더 정확한 근사치를 얻을 수 있다. \[ y = \frac{x + a/x}{2} \] % -For example, if $a$ is 4 and $x$ is 3: +$a$는 4 $x$는 3이라고 해보자. \begin{verbatim} >>> a = 4 @@ -5486,8 +5509,8 @@ \section{Square roots} 2.16666666667 \end{verbatim} % -The result is closer to the correct answer ($\sqrt{4} = 2$). If we -repeat the process with the new estimate, it gets even closer: +정답에 좀 더 가까운 결과를 얻었다($\sqrt{4} = 2$). 이 과정을 새로운 +추정치로 반복한다면 좀 더 정답에 가까워진다. \begin{verbatim} >>> x = y @@ -5496,7 +5519,7 @@ \section{Square roots} 2.00641025641 \end{verbatim} % -After a few more updates, the estimate is almost exact: +몇 번 더 갱신하면 추정치는 거의 정답에 가까워진다. \index{update} \begin{verbatim} @@ -5510,10 +5533,10 @@ \section{Square roots} 2.00000000003 \end{verbatim} % -In general we don't know ahead of time how many steps it takes -to get to the right answer, but we know when we get there -because the estimate -stops changing: +일반적으로 이 과정을 몇 번이나 거쳐야 정답을 얻게 되는지 모른다. +그렇지만, 정답에 가까워지면 알게된다. 왜냐하면 추정치의 변화하지 않기 +때문이다. + \begin{verbatim} >>> x = y @@ -5526,9 +5549,8 @@ \section{Square roots} 2.0 \end{verbatim} % -When {\tt y == x}, we can stop. Here is a loop that starts -with an initial estimate, {\tt x}, and improves it until it -stops changing: +{\tt y == x}이면 멈추면 된다. 다음은 초기 추정치 {\tt x}로부터 변화가 +없을 때까지 정확도를 높이는 루프이다. \begin{verbatim} while True: @@ -5539,100 +5561,95 @@ \section{Square roots} x = y \end{verbatim} % -For most values of {\tt a} this works fine, but in general it is -dangerous to test {\tt float} equality. -Floating-point values are only approximately right: -most rational numbers, like $1/3$, and irrational numbers, like -$\sqrt{2}$, can't be represented exactly with a {\tt float}. +대부분의 {\tt a}는 동작을 하지만, {\tt float}형을 등호에 쓸 때는 +조심해야 한다. 부동소수점 값은 근사치이기 때문이다. $1/3$처럼 +유리수인 경우나 $\sqrt{2}$처럼 무리수인 경우의 대부분은 {\tt + float}형으로 그 값을 정확하게 표현될 수 없다는 것을 기억해야 한다. \index{floating-point} \index{epsilon} -Rather than checking whether {\tt x} and {\tt y} are exactly equal, it -is safer to use the built-in function {\tt abs} to compute the -absolute value, or magnitude, of the difference between them: +{\tt float}형인 {\tt x}와 {\tt y}가 서로 정확히 일치하는지 등호로 +검사하는 대신 내장 함수인 {\tt abs}를 사용하여 그 수의 절대치 또는 +크기를 비교하는 것이 좋다. \begin{verbatim} if abs(y-x) < epsilon: break \end{verbatim} % -Where \verb"epsilon" has a value like {\tt 0.0000001} that -determines how close is close enough. +\verb"epsilon"는 {\tt 0.0000001}와 같은 값으로 얼마나 작아야 같다고 할 +수 있는지 판단하는데 도움이 된다. -\section{Algorithms} +\section{알고리즘} +%Algorithms \index{algorithm} -Newton's method is an example of an {\bf algorithm}: it is a -mechanical process for solving a category of problems (in this -case, computing square roots). - -To understand what an algorithm is, it might help to start with -something that is not an algorithm. When you learned to multiply -single-digit numbers, you probably memorized the multiplication table. -In effect, you memorized 100 specific solutions. That kind of -knowledge is not algorithmic. - -But if you were ``lazy'', you might have learned a few -tricks. For example, to find the product of $n$ and 9, you can -write $n-1$ as the first digit and $10-n$ as the second -digit. This trick is a general solution for multiplying any -single-digit number by 9. That's an algorithm! +뉴튼의 기법은 {\bf 알고리즘(algorithm)}의 예이다. 어떤 종류의 문제(이 +경우에는 제곱 근의 계산)를 해결하기 위한 기계적인 과정이다. + +알고리즘이 무엇인지 이해하기 위해서는 알고리즘이 아닌 무엇인가로부터 +시작하는 것이 좋겠다. 한 자리 수 숫자로 곱셉하는 법을 배웠을 때 +구구단을 외웠을 것이다. 사실상은 100개의 서로 다른 해답을 외웠을 +뿐이다. 이런 종류의 지식은 알고리즘적 접근이 전혀 아니다. + +당신이 만약 ``게으르다면'' 요령을 배울 필요가 있다. 예를 들어 어떤 수 +$n$과 9의 곱을 구한다고 해보자. 일의 자리에 $n-1$을 쓰고 십의 자리에 +$10-n$을 쓰면 된다. 이 요령은 한 자리 수 숫자와 9의 곱에 대한 일반 +해이다. 이런 것이 바로 알고리즘이다! \index{addition with carrying} \index{carrying, addition with} \index{subtraction!with borrowing} \index{borrowing, subtraction with} -Similarly, the techniques you learned for addition with carrying, -subtraction with borrowing, and long division are all algorithms. One -of the characteristics of algorithms is that they do not require any -intelligence to carry out. They are mechanical processes where -each step follows from the last according to a simple set of rules. +올림이 있는 덧셈이나 빌려서 뺄셈하기와 나눗셈하는 기술들이 모두 +알고리즘이다. 알고리즘이 갖는 특성 중 하나는 지적 능력이 전혀 필요 +없다는 것이다. 기계적으로 간단한 규칙에 따라 이전 단계에서 다음 단계를 +따르면 되기 때문이다. + +알고리즘의 실행은 지겨운 일이지만 설계하는 것은 흥미진진하고 지적으로 +도전적이다. 뿐만아니라 컴퓨터 과학의 중심이기도 하다. -Executing algorithms is boring, but designing them is interesting, -intellectually challenging, and a central part of computer science. +사람들이 자연스럽게 어려움 없이 또는 깊이 생각하지 않고 하는 것들 +중에는 알고리즘으로 표현하기 매우 어려운 것들이 있다. 자연어 인식이 +좋은 예이다. 우리는 하지만 아직까지 {\em 어떻게} 그렇게 할 수 있는지 +누구도 설명하지 못했다. 최소한 알고리즘으로 풀어내지는 못했다. -Some of the things that people do naturally, without difficulty or -conscious thought, are the hardest to express algorithmically. -Understanding natural language is a good example. We all do it, but -so far no one has been able to explain {\em how} we do it, at least -not in the form of an algorithm. -\section{Debugging} +\section{디버깅} +%Debugging \label{bisectbug} -As you start writing bigger programs, you might find yourself -spending more time debugging. More code means more chances to -make an error and more places for bugs to hide. +프로그램의 크기가 커지다보면 더 많은 시간을 디버깅에 쓰게 되는 것을 +보게 된다. 더 많은 코드는 오류를 만들 확률이 많아지고 버그가 숨을 곳이 +더 많아진다는 말이다. \index{debugging!by bisection} \index{bisection, debugging by} -One way to cut your debugging time is ``debugging by bisection''. -For example, if there are 100 lines in your program and you -check them one at a time, it would take 100 steps. +디버깅 시간을 줄이는 방법 중 하나는 ``등분으로 디버깅하기''이다. 예를 +들어 100 줄짜리 프로그램이 있다고 했을 때 한 줄씩 검사한다면 100번 +검사해야 한다. + +대신에, 문제를 반으로 쪼개보자. 프로그램의 중간 또는 그 근처에 있는 +중간 과정의 값 중 검사할 수 있는 것을 확인해보자. {\tt print}문(증명을 +도와줄 어떤 것)을 추가한 후 프로그램을 실행하자. -Instead, try to break the problem in half. Look at the middle -of the program, or near it, for an intermediate value you -can check. Add a {\tt print} statement (or something else -that has a verifiable effect) and run the program. -If the mid-point check is incorrect, there must be a problem in the -first half of the program. If it is correct, the problem is -in the second half. +중간 점검이 부정확하다면 전반부에 오류가 있다는 말이다. 정확하다면 +문제는 후반부에 있다. -Every time you perform a check like this, you halve the number of -lines you have to search. After six steps (which is fewer than 100), -you would be down to one or two lines of code, at least in theory. +이런 식으로 검사를 할 때마다 검사해야할 줄의 수를 반씩 줄여나가면 +된다. 이론상으로는 이 과정을 6번(100번 보다 작다) 반복하면 검사해야 할 +줄의 수가 하나 또는 두 줄 정도가 된다. + +실제로는 ``프로그램의 중간''이 늘 명확하지도 않고 그 부분을 검사한다는 +것이 가능하지도 않다. 정확한 중간 지점을 찾기 위해 라인 수를 세서 +반으로 나눈다는 것도 말이 안된다. 대신에 오류가 있을만한 부분을 +생각해보고 검사 문장을 쉽게 삽입할 수 있는 위치를 생각해보자. 그리고 +검사 문장 삽입 위치 전과 그 후에 오류가 있을 확률이 서로 비슷한 지점에 +검사 문장을 삽입하자. -In practice it is not always clear what -the ``middle of the program'' is and not always possible to -check it. It doesn't make sense to count lines and find the -exact midpoint. Instead, think about places -in the program where there might be errors and places where it -is easy to put a check. Then choose a spot where you -think the chances are about the same that the bug is before -or after the check. @@ -5642,35 +5659,29 @@ \section{용어 해설} \begin{description} -\item[reassignment:] Assigning a new value to a variable that -already exists. +\item[재할당(reassignment):] 이미 존재하는 변수에 새로운 값을 할당하는 것. \index{reassignment} -\item[update:] An assignment where the new value of the variable -depends on the old. +\item[갱신(update):] 변수의 새로운 값이 이전 값에 의존하는 할당문. \index{update} -\item[initialization:] An assignment that gives an initial value to -a variable that will be updated. +\item[초기화(initialization):] 갱신될 변수에 초기 값을 할당하는 것. \index{initialization!variable} -\item[increment:] An update that increases the value of a variable -(often by one). +\item[증가(increment):] 변수의 값을 증가 시키는 갱신(주로 1 증가). \index{increment} -\item[decrement:] An update that decreases the value of a variable. +\item[감소(decrement):] 변수의 값을 감소 시키는 갱신. \index{decrement} -\item[iteration:] Repeated execution of a set of statements using -either a recursive function call or a loop. +\item[반복(iteration):] 재귀 함수 호출이나 루프를 사용하여 문장들을 + 되풀이하여 실행하는 것 \index{iteration} -\item[infinite loop:] A loop in which the terminating condition is -never satisfied. +\item[무한 루프(infinite loop):] 종료 조건이 절대로 충족되지 않는 루프. \index{infinite loop} -\item[algorithm:] A general process for solving a category of -problems. +\item[알고리즘(algorithm):] 어떤 종류의 문제를 해결하는 일반적인 과정. \index{algorithm} \end{description} @@ -5682,14 +5693,13 @@ \section{연습 문제} \begin{exercise} \index{algorithm!square root} -Copy the loop from Section~\ref{squareroot} -and encapsulate it in a function called -\verb"mysqrt" that takes {\tt a} as a parameter, chooses a -reasonable value of {\tt x}, and returns an estimate of the square -root of {\tt a}. \index{encapsulation} +\ref{squareroot} 절의 루프문을 복사하여 \verb"mysqrt"라는 함수로 +캡슐화하라. 이 때 {\tt a}를 매개 변수로하고 타당한 {\tt x}을 +선정하자. 그리고 {\tt a}의 제곱 근의 추정치를 리턴하도록 하라. +\index{encapsulation} -To test it, write a function named \verb"test_square_root" -that prints a table like this: +검사를 위해 \verb"test_square_root"라는 함수를 만들고 다음과 같이 +출력하도록 만들자. \begin{verbatim} a mysqrt(a) math.sqrt(a) diff @@ -5705,10 +5715,9 @@ \section{연습 문제} 9.0 3.0 3.0 0.0 \end{verbatim} % -The first column is a number, $a$; the second column is the square -root of $a$ computed with \verb"mysqrt"; the third column is the -square root computed by {\tt math.sqrt}; the fourth column is the -absolute value of the difference between the two estimates. +첫 번재 열은 숫자 $a$이다. 두 번째 열은 \verb"mysqrt"으로 계산된 $a$의 +제곱근이다. 세 번째 열은 {\tt math.sqrt}으로 계산된 제곱 근이다. 네 +번째 열은 두 추정치의 차이의 절대치를 나타낸다. \end{exercise} @@ -5716,8 +5725,8 @@ \section{연습 문제} \index{eval function} \index{function!eval} -The built-in function {\tt eval} takes a string and evaluates -it using the Python interpreter. For example: +내장 함수인 {\tt eval}은 문자열을 받아 Python 인터프리터를 사용하여 +계산한다. 다음 예를 살펴보자. \begin{verbatim} >>> eval('1 + 2 * 3') @@ -5729,12 +5738,12 @@ \section{연습 문제} \end{verbatim} % -Write a function called \verb"eval_loop" that iteratively -prompts the user, takes the resulting input and evaluates -it using {\tt eval}, and prints the result. +반복저으로 사용자의 입력을 기다리는 \verb"eval_loop" 함수를 +작성해보자. 전달받은 값을 {\tt eval} 함수로 계산하고 그 결과를 +출력하도록 만들자. -It should continue until the user enters \verb"'done'", and then -return the value of the last expression it evaluated. +사용자가 \verb"'done'"을 입력하기 전까지 계속 동작하고 종료하면서 +마지막 계산한 수식의 결과를 표시하도록 만들자. \end{exercise} @@ -5742,22 +5751,19 @@ \section{연습 문제} \begin{exercise} \index{Ramanujan, Srinivasa} -The mathematician Srinivasa Ramanujan found an -infinite series -that can be used to generate a numerical -approximation of $1 / \pi$: +스리니바사 라마누잔(Srinivasa Ramanujan)은 무한 급수를 발견하였다. +무한 급수는 $1 / \pi$의 근사치를 구하는데 쓰인다. \index{pi} \[ \frac{1}{\pi} = \frac{2\sqrt{2}}{9801} \sum^\infty_{k=0} \frac{(4k)!(1103+26390k)}{(k!)^4 396^{4k}} \] -Write a function called \verb"estimate_pi" that uses this formula -to compute and return an estimate of $\pi$. It should use a {\tt while} -loop to compute terms of the summation until the last term is -smaller than {\tt 1e-15} (which is Python notation for $10^{-15}$). -You can check the result by comparing it to {\tt math.pi}. +위의 공식을 사용하여 $\pi$의 추청지를 계산하여 리턴하는 +\verb"estimate_pi" 함수를 작성해보자. {\tt while} 루프를 사용하여 +추정치의 마지막 항이 {\tt 1e-15}(Python에서 $10^{-15}$의 표기)보다 작을 +때까지 반복하라. 얻은 결과는 {\tt math.pi}와 비교해 볼 수 있다. -Solution: \url{http://thinkpython2.com/code/pi.py}. +해답: \url{http://thinkpython2.com/code/pi.py}. \end{exercise} @@ -6305,7 +6311,8 @@ \section{String comparison} against a man armed with a Pineapple. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} \index{traversal} @@ -6990,7 +6997,8 @@ \section{Looping with indices} Using \verb"is_reverse" from Section~\ref{isreverse}. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} \index{testing!is hard} \index{program testing} @@ -8023,7 +8031,8 @@ \section{List arguments} -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} Careless use of lists (and other mutable objects) @@ -9060,7 +9069,8 @@ \section{Global variables} hard to debug. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} As you work with bigger datasets it can become unwieldy to @@ -9959,7 +9969,8 @@ \section{Sequences of sequences} \index{iterator} -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} \index{data structure} \index{shape error} @@ -10914,7 +10925,8 @@ \section{Data structures} generation exceeded the time spent in conversion. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} When you are debugging a program, and especially if you are @@ -11742,7 +11754,8 @@ \section{Writing modules} restart the interpreter and then import the module again. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} \index{whitespace} @@ -12392,7 +12405,8 @@ \section{Copying} returns a new Rectangle instead of modifying the old one. -\section{Debugging} +\section{디버깅} +%Debugging \label{hasattr} \index{debugging} @@ -12867,7 +12881,8 @@ \section{Prototyping versus planning} for error). -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} A Time object is well-formed if the values of {\tt minute} and {\tt @@ -13618,7 +13633,8 @@ \section{Polymorphism} applied to a type you never planned for. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} It is legal to add attributes to objects at any point in the execution @@ -14404,7 +14420,8 @@ \section{Class diagrams} like list and dict are usually not included in class diagrams. -\section{Debugging} +\section{디버깅} +%Debugging \index{debugging} Inheritance can make debugging difficult because when you invoke a From 633f3a76ee448f707a23d220ea466052d1e433dc Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Tue, 11 Jul 2017 09:51:03 +0900 Subject: [PATCH 11/13] started on string --- book_kr/book.tex | 111 ++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 31b9fdd..753baae 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -1465,7 +1465,7 @@ \section{스크립트 모드} \url{http://tinyurl.com/thinkpython2e}에 기록해 놓았다. Python이 두 가지 모드를 지원하기 때문에 스크립트로 저장하기 전에 대화식 -모드로 실험해볼 수 있다. 하지만 대화식 모드와 스크립트 모드간의 차이가 +모드로 실험해볼 수 있다. 하지만 대화식 모드와 스크립트 모드간의 차이≈가 있기 때문에 그렇게 사용하면 혼란스러울 수 있다. \index{interactive mode} \index{script mode} @@ -3526,14 +3526,14 @@ \section{내림 나눗셈과 나머지 연산자} \index{Python 2} -\section{불 표현식} +\section{Boolean 표현식} %Boolean expressions \index{boolean expression} \index{expression!boolean} \index{logical operator} \index{operator!logical} -{\bf 불 표현식(boolean expression)}은 참또는 거짓을 나타내는 +{\bf Boolean 표현식(boolean expression)}은 참또는 거짓을 나타내는 표현식이다. 다음의 예들은 두 피연산자를 비교하는 {\tt ==} 연산자를 사용한다. 두 값이 동일하면 {\tt True(참)}을 다르면 {\tt False(거짓)}이다. @@ -3599,11 +3599,11 @@ \section{불 표현식} {\tt n\%2 == 0 or n\%3 == 0} 은 {\em 둘 중 하나만} 또는 {\em둘 다} 참일 때 참이 된다. 즉, 2 {\em 또는} 3으로 나누어 지거는 경우이다. -마지막으로 {\tt not} 연산자는 불 표현식의 반대 값을 취한다. {\tt not +마지막으로 {\tt not} 연산자는 boolean 표현식의 반대 값을 취한다. {\tt not (x > y)}는 {\tt x > y}가 거짓일 때 참이 된다. 즉, {\tt x}가 {\tt y}보다 작거나 같은 경우이다. -정확하게 말하면, 논리 연산자의 피연산자는 불 표현식이어야하지만, +정확하게 말하면, 논리 연산자의 피연산자는 boolean 표현식이어야하지만, Python이 그렇게 엄격하지는 않다. 0이 아닌 어떤 수이기만 하면 {\tt True}으로 인식한다. @@ -3637,7 +3637,7 @@ \section{조건부 실행} print('x is positive') \end{verbatim} % -{\tt if}문 이후의 불 표현식은 {\bf 조건(condition)}이라 부른다. +{\tt if}문 이후의 boolean 표현식은 {\bf 조건(condition)}이라 부른다. 참이라면, 의도한 문장이 실행되고 그렇지 않다면 아무 일도 일어 나지 않는다. \index{condition} @@ -4126,8 +4126,8 @@ \section{용어 해설} \index{modulus operator} \index{operator!modulus} -\item[불 표현식(boolean expression):] 결과가 항상 참({\tt True})이거나 - 거짓({\tt False})인 표현식 +\item[Boolean 표현식(boolean expression):] 결과가 항상 참({\tt + True})이거나 거짓({\tt False})인 표현식 \index{boolean expression} \index{expression!boolean} @@ -4135,7 +4135,7 @@ \section{용어 해설} 다음의 종류가 있음: {\tt ==}, {\tt !=}, {\tt >}, {\tt <}, {\tt >=}, {\tt <=}. -\item[논리 연산자(logical operator):] 불 표현식들을 서로 연결하는 +\item[논리 연산자(logical operator):] Boolean 표현식들을 서로 연결하는 연산자: {\tt and}, {\tt or}, {\tt not}이 있음 \item[조건문(conditional statement):] 어떤 조건에 따라 실행의 흐름을 @@ -4143,7 +4143,7 @@ \section{용어 해설} \index{conditional statement} \index{statement!conditional} -\item[조건(condition):] 조건문에서 어떤 분기가 실행될지를 결정하는 불 표현식 +\item[조건(condition):] 조건문에서 어떤 분기가 실행될지를 결정하는 boolean 표현식 \index{condition} \item[복합문(compound statement):] 헤더와 내용으로 구성된 문장으로 @@ -4649,11 +4649,11 @@ \section{합성} \end{verbatim} % -\section{불 함수} +\section{Boolean 함수} %Boolean functions \label{boolean} -함수는 불 값을 리턴할 수 있다. 그렇게 하면 복잡한 검사문을 함수에 감출 +함수는 bool 값을 리턴할 수 있다. 그렇게 하면 복잡한 검사문을 함수에 감출 수 있기 때문에 유용하다. \index{boolean function} 예를 살펴 보자. @@ -4666,7 +4666,7 @@ \section{불 함수} return False \end{verbatim} % -불 함수의 이름은 참/거짓을 묻는 질문처럼 만드는 것이 일반적이다. +Boolean 함수의 이름은 참/거짓을 묻는 질문처럼 만드는 것이 일반적이다. \verb"is_divisible"은 {\tt x}가 {\tt y}로 나누어 떨어지는지 {\tt True} 또는 {\tt False}로 리턴한다. @@ -4688,7 +4688,7 @@ \section{불 함수} return x % y == 0 \end{verbatim} % -불 함수는 조건문에 많이 쓰인다. +Boolean 함수는 조건문에 많이 쓰인다. \index{conditional statement} \index{statement!conditional} @@ -5768,50 +5768,49 @@ \section{연습 문제} \end{exercise} -\chapter{Strings} +\chapter{문자열} +%Strings \label{strings} -Strings are not like integers, floats, and booleans. A string -is a {\bf sequence}, which means it is -an ordered collection of other values. In this chapter you'll see -how to access the characters that make up a string, and you'll -learn about some of the methods strings provide. +문자열은 정수나 부동소수점 그리고 boolean 과같지 않다. 문자열은 {\bf + 수열(sequence)}로서 여러 값들의 순차 컬렉션이다. 이 장에서는 +문자열을 이루는 글자들을 접근하는 방법과 몇 개의 문자열 관련 메소드를 +배울 것이다. \index{sequence} +%ordered collection 순차 컬렉션 - -\section{A string is a sequence} +\section{문자열은 수열이다} +%A string is a sequence \index{sequence} \index{character} \index{bracket operator} \index{operator!bracket} -A string is a sequence of characters. -You can access the characters one at a time with the -bracket operator: + +문자열은 글자들의 수열이다. 각 글자를 각괄호를 사용해 접근할 수 있다. \begin{verbatim} >>> fruit = 'banana' >>> letter = fruit[1] \end{verbatim} % -The second statement selects character number 1 from {\tt -fruit} and assigns it to {\tt letter}. +두 번째 문장은 {\tt fruit}의 첫 글자를 {\tt letter}에 할당한다. \index{index} -The expression in brackets is called an {\bf index}. -The index indicates which character in the sequence you -want (hence the name). +각괄호에 쓰인 표현식을 {\bf 색인(index)}이라 한다. 색인(이름에서 알 수 +있듯이)은 수열에서 원하는 글자를 가리킨다. -But you might not get what you expect: +그렇지만 기대한 글자가 아닐 수 있다. \begin{verbatim} >>> letter 'a' \end{verbatim} % -For most people, the first letter of \verb"'banana'" is {\tt b}, not -{\tt a}. But for computer scientists, the index is an offset from the -beginning of the string, and the offset of the first letter is zero. +대부분의 사람에게 \verb"'banana'"의 첫 글자는 {\tt a}가 아니라 {\tt + b}이다. 그렇지만 컴퓨터 과학자에게는 색인 첫 글자로부터 떨어진 +위치를 뜻하기 때문에 첫 글자의 첫 글자로부터 떨어진 위치는 0이다. + \begin{verbatim} >>> letter = fruit[0] @@ -5819,13 +5818,11 @@ \section{A string is a sequence} 'b' \end{verbatim} % -So {\tt b} is the 0th letter (``zero-eth'') of \verb"'banana'", {\tt - a} is the 1th letter (``one-eth''), and {\tt n} is the 2th letter -(``two-eth''). \index{index!starting at zero} \index{zero, index - starting at} +{\tt b}가 \verb"'banana'"의 0번째 글자이고 {\tt a}와 {\tt n}가 각각 +1번째와 2번째 글자이다. +\index{index!starting at zero} \index{zero, index starting at} -As an index you can use an expression that contains variables and -operators: +변수와 연산자로 구성된 표현식을 색인으로 사용할 수 있다. \index{index} \begin{verbatim} @@ -5837,8 +5834,8 @@ \section{A string is a sequence} \end{verbatim} % -But the value of the index has to be an integer. Otherwise you -get: +기억해야 할 것은 색인은 항상 정수여야 한다는 것이다. 그렇지 않으면 +다음과 같은 오류가 발생한다. \index{exception!TypeError} \index{TypeError} @@ -5852,8 +5849,7 @@ \section{{\tt len}} \index{len function} \index{function!len} -{\tt len} is a built-in function that returns the number of characters -in a string: +문자열의 글자 수를 리턴하는 {\tt len}는 내장 함수이다. \begin{verbatim} >>> fruit = 'banana' @@ -5861,8 +5857,7 @@ \section{{\tt len}} 6 \end{verbatim} % -To get the last letter of a string, you might be tempted to try something -like this: +문자열의 마지막 글자를 얻으려고 할 때 다음과 같이 하면 될 것 같다는 생각이 든다. 그렇지만 안된다. \index{exception!IndexError} \index{IndexError} @@ -5872,10 +5867,10 @@ \section{{\tt len}} IndexError: string index out of range \end{verbatim} % -The reason for the {\tt IndexError} is that there is no letter in {\tt -'banana'} with the index 6. Since we started counting at zero, the -six letters are numbered 0 to 5. To get the last character, you have -to subtract 1 from {\tt length}: +{\tt IndexError}가 발생하는 이유는 {\tt 'banana'}에서 색인 6 위치에는 +글자가 없기 때문이다. 0에서 숫자를 세기 시작하기 때문에 6 글자의 +색인은 0에서 시작해서 5에서 끝난다. 그러므로 마지막 글자를 얻으려면 +{\tt length}에서 1 뺀 값을 사용해야 한다. \begin{verbatim} >>> last = fruit[length-1] @@ -5883,14 +5878,15 @@ \section{{\tt len}} 'a' \end{verbatim} % -Or you can use negative indices, which count backward from -the end of the string. The expression {\tt fruit[-1]} yields the last -letter, {\tt fruit[-2]} yields the second to last, and so on. +또는 색인을 음수로 쓰면 된다. 문자열을 역방향으로 셀 수 있다. {\tt + fruit[-1]}이라는 표현식은 마지막 글자를 {\tt fruit[-2]}은 끝에서 +2번째 글자를 나타내는 식이다. \index{index!negative} \index{negative index} -\section{Traversal with a {\tt for} loop} +\section{{\tt for} 루프로 순회하기} +%Traversal with a {\tt for} loop \label{for} \index{traversal} \index{loop!traversal} @@ -5899,11 +5895,7 @@ \section{Traversal with a {\tt for} loop} \index{statement!for} \index{traversal} -A lot of computations involve processing a string one character at a -time. Often they start at the beginning, select each character in -turn, do something to it, and continue until the end. This pattern of -processing is called a {\bf traversal}. One way to write a traversal -is with a {\tt while} loop: +문자열의 각 글자 단위로 처리하는 연산들이 많다. 보통은 첫 글자에서 시작해서, 마지막 글자에 도달하기 까지 각 글자로 무언가를 한다. 이런 류의 작업을 {\bf 순회(traversal)}이라 부른다. 순회문을 작성하는 한 가지 방법은 {\tt while} 루프를 쓰는 것이다. \begin{verbatim} index = 0 @@ -5913,6 +5905,7 @@ \section{Traversal with a {\tt for} loop} index = index + 1 \end{verbatim} % + This loop traverses the string and displays each letter on a line by itself. The loop condition is {\tt index < len(fruit)}, so when {\tt index} is equal to the length of the string, the From 47e8bc8b1b1da6632f2cfd64238f6320be2812ba Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Tue, 18 Jul 2017 14:07:36 +0900 Subject: [PATCH 12/13] chapter strings --- book_kr/book.tex | 483 +++++++++++++++++++++++------------------------ 1 file changed, 237 insertions(+), 246 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index 753baae..c594541 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -5895,7 +5895,10 @@ \section{{\tt for} 루프로 순회하기} \index{statement!for} \index{traversal} -문자열의 각 글자 단위로 처리하는 연산들이 많다. 보통은 첫 글자에서 시작해서, 마지막 글자에 도달하기 까지 각 글자로 무언가를 한다. 이런 류의 작업을 {\bf 순회(traversal)}이라 부른다. 순회문을 작성하는 한 가지 방법은 {\tt while} 루프를 쓰는 것이다. +문자열의 각 글자 단위로 처리하는 연산들이 많다. 보통은 첫 글자에서 +시작해서, 마지막 글자에 도달하기 까지 각 글자로 무언가를 한다. 이런 +류의 작업을 {\bf 순회(traversal)}이라 부른다. 순회문을 작성하는 한 +가지 방법은 {\tt while} 루프를 쓰는 것이다. \begin{verbatim} index = 0 @@ -5906,36 +5909,35 @@ \section{{\tt for} 루프로 순회하기} \end{verbatim} % -This loop traverses the string and displays each letter on a line by -itself. The loop condition is {\tt index < len(fruit)}, so -when {\tt index} is equal to the length of the string, the -condition is false, and the body of the loop doesn't run. The -last character accessed is the one with the index {\tt len(fruit)-1}, -which is the last character in the string. +이 루프는 문자열을 순회하면서 한 글자씩 출력한다. 루프의 조건은 {\tt + index < len(fruit)}이기 때문에 {\tt index}가 문자열의 길이와 같게 될 +때까지 동작한다. 조건이 맞지 않으면 루프가 실행되지 않는다. +마지막으로 접근되는 글자는 문자열의 마지막 글자인 {\tt len(fruit)-1}번 +색인이다. -As an exercise, write a function that takes a string as an argument -and displays the letters backward, one per line. +연습삼아 문자열을 인자로 입력받아 각 줄에 한 글자씩 역순으로 출력하는 +함수를 만들어 보자. -Another way to write a traversal is with a {\tt for} loop: +순회문을 작성하는 또 다른 방법은 {\tt for} 루프를 사용하는 것이다. \begin{verbatim} for letter in fruit: print(letter) \end{verbatim} % -Each time through the loop, the next character in the string is assigned -to the variable {\tt letter}. The loop continues until no characters are -left. +루프를 순회할 때마다 다음 글자가 {\tt letter} 변수에 할당된다. 루프는 +더 이상 글자가 없을 때까지 계속 실행된다. + \index{concatenation} \index{abecedarian} \index{McCloskey, Robert} -The following example shows how to use concatenation (string addition) -and a {\tt for} loop to generate an abecedarian series (that is, in -alphabetical order). In Robert McCloskey's book {\em Make -Way for Ducklings}, the names of the ducklings are Jack, Kack, Lack, -Mack, Nack, Ouack, Pack, and Quack. This loop outputs these names in -order: +다음 예제는 연결(문자열 더하기)하는 방법과 {\tt for} 루프를 사용하여 +알파벳 순으로 된 시리즈(series)를 만드는 방법을 소개한다. 로버트 +맥클로스키(Robert McCloskey)의 책 {\em Make Way for Ducklings}에 나오는 +오리들의 이름은 Jack, Kack, Lack, Mack, Nack, Ouack, Pack, 그리고 +Quack이다. 이 루프는 이 이름들을 알파벳 순서대로 출력한다. + \begin{verbatim} prefixes = 'JKLMNOPQ' @@ -5945,7 +5947,7 @@ \section{{\tt for} 루프로 순회하기} print(letter + suffix) \end{verbatim} % -The output is: +결과는 다음과 같다. \begin{verbatim} Jack @@ -5958,18 +5960,21 @@ \section{{\tt for} 루프로 순회하기} Qack \end{verbatim} % -Of course, that's not quite right because ``Ouack'' and ``Quack'' are -misspelled. As an exercise, modify the program to fix this error. +이 결과가 완전히 정확한 것은 아니다. ``Ouack''과 ``Quack'' 스펠링이 +잘못되었기 때문이다. 연습 문제로 이 오류를 고쳐보라. + -\section{String slices} +\section{문자열 조각} +%String slices \label{slice} \index{slice operator} \index{operator!slice} \index{index!slice} \index{string!slice} \index{slice!string} -A segment of a string is called a {\bf slice}. Selecting a slice is -similar to selecting a character: +문자열 중 일 부분을 {\bf 조각(slice)}이라 부른다. 조각을 선택하는 +방법은 글자를 선택하는 방법과 동일하다. + \begin{verbatim} >>> s = 'Monty Python' @@ -5979,11 +5984,12 @@ \section{String slices} 'Python' \end{verbatim} % -The operator {\tt [n:m]} returns the part of the string from the -``n-eth'' character to the ``m-eth'' character, including the first but -excluding the last. This behavior is counterintuitive, but it might -help to imagine the indices pointing {\em between} the -characters, as in Figure~\ref{fig.banana}. +{\tt [n:m]} 연산자가 ``n 번째'' 글자부터 ``m 번째'' 글자까지를 +리턴한다. 이 때, 첫글자는 포함되고 마지막 글자는 미포함이라는 것에 +주의해야 한다. 이와 같은 동작은 비직관적이지만, 그림 +\ref{fig.banana}에서 보인 것처럼 색인 번호가 글자들 사이를 가리키고 +있다고 생각하면 이해하는데 도움이 된다. + \begin{figure} \centerline @@ -5992,9 +5998,8 @@ \section{String slices} \label{fig.banana} \end{figure} -If you omit the first index (before the colon), the slice starts at -the beginning of the string. If you omit the second index, the slice -goes to the end of the string: +첫 번째 색인(콜론 앞의 숫자)을 쓰지 않으면 조각은 문자열의 첫 위치부터 +시작한다. 두 번째 색인을 쓰지 않으면 문자열의 끝까지를 리턴한다. \begin{verbatim} >>> fruit = 'banana' @@ -6004,8 +6009,8 @@ \section{String slices} 'ana' \end{verbatim} % -If the first index is greater than or equal to the second the result -is an {\bf empty string}, represented by two quotation marks: +첫 색인이 두 번째 색인보다 크거나 같으면 두 개의 따옴표만 있는 {\bf 빈 + 문자열(empty string)}을 얻는다. \index{quotation mark} \begin{verbatim} @@ -6014,24 +6019,24 @@ \section{String slices} '' \end{verbatim} % -An empty string contains no characters and has length 0, but other -than that, it is the same as any other string. +빈 문자열은 글자를 포함하지 않기 때문에 길이가 0이라는 것 외에는 다른 +문자열과 다를 바가 없다. -Continuing this example, what do you think -{\tt fruit[:]} means? Try it and see. +이 예제로 계속 이어가 보자. {\tt fruit[:]}는 어떤 의미를 갖는 +표현일까? 한 번 실행해보자. \index{copy!slice} \index{slice!copy} -\section{Strings are immutable} +\section{문자열의 불변성} +%Strings are immutable \index{mutability} \index{immutability} \index{string!immutable} -It is tempting to use the {\tt []} operator on the left side of an -assignment, with the intention of changing a character in a string. -For example: +문자열의 글자를 바꾸려는 의도로 {\tt[]} 연산자를 할당문의 왼편에 놓고 +쓰고 싶을 수도 있다. 다음의 예를 살펴보자. \index{TypeError} \index{exception!TypeError} @@ -6041,20 +6046,19 @@ \section{Strings are immutable} TypeError: 'str' object does not support item assignment \end{verbatim} % -The ``object'' in this case is the string and the ``item'' is -the character you tried to assign. For now, an object is -the same thing as a value, but we will refine that definition -later (Section~\ref{equivalence}). +여기서 ``객체(object)''는 문자열이고 ``항목(item)''은 할당하려고 했던 +글자를 뜻한다. 현재로서는 객체는 값과 동일하다고 이해하고 +넘어가자. \ref{equivalence}절에서 객체에 대한 정확한 정의를 다루도록 +하겠다. \index{object} \index{item} \index{item assignment} \index{assignment!item} \index{immutability} -The reason for the error is that -strings are {\bf immutable}, which means you can't change an -existing string. The best you can do is create a new string -that is a variation on the original: +이와 같은 오류의 원인은 문자열의 {\bf 불변성(immutable)} 때문이다. 한 +번 정의된 문자열은 변경할 수 없다는 말이다. 원래의 문자열을 변경하는 +가장 좋은 방법은 새로운 문자열을 만드는 것이다. \begin{verbatim} >>> greeting = 'Hello, world!' @@ -6063,16 +6067,16 @@ \section{Strings are immutable} 'Jello, world!' \end{verbatim} % -This example concatenates a new first letter onto -a slice of {\tt greeting}. It has no effect on -the original string. +이 예제는 {\tt greeting} 문자열의 조각에 새로운 첫 글자를 연결하고 +있다. 원래의 문자열에는 어떤 변경도 일어나지 않는다. \index{concatenation} -\section{Searching} +\section{검색} +%Searching \label{find} -What does the following function do? +다음 함수가 하는 일은? \index{find function} \index{function!find} @@ -6086,39 +6090,36 @@ \section{Searching} return -1 \end{verbatim} % -In a sense, {\tt find} is the inverse of the {\tt []} operator. -Instead of taking an index and extracting the corresponding character, -it takes a character and finds the index where that character -appears. If the character is not found, the function returns {\tt --1}. +{\tt find}는 {\tt []} 연산자의 역이라고 생각할 수 있다. 문자열에서 +색인 위치의 글자를 추출하는 대신 글자를 전달받아 문자열에서 몇 번째 +위치에 해당 글자가 있는지 리턴하고 있다. 해당 글자가 없다면 함수는 +{\tt -1}을 리턴한다. -This is the first example we have seen of a {\tt return} statement -inside a loop. If {\tt word[index] == letter}, the function breaks -out of the loop and returns immediately. +처음으로 {\tt return}문이 루프안에 있는 예제를 살펴보았다. {\tt + word[index] == letter}라면 함수는 루프에서 벗어나 즉시 리턴한다. -If the character doesn't appear in the string, the program -exits the loop normally and returns {\tt -1}. +문자열에서 찾고자 하는 글자가 없다면 프로그램은 루프에서 정상적으로 +빠져나와서 {\tt -1}을 리턴한다. -This pattern of computation---traversing a sequence and returning -when we find what we are looking for---is called a {\bf search}. +수열을 순회하면서 찾고자 하는 것을 발견하면 리턴하는 종류의 연산을 +{\bf 검색(search)}이라 한다. \index{traversal} \index{search pattern} \index{pattern!search} -As an exercise, modify {\tt find} so that it has a -third parameter, the index in {\tt word} where it should start -looking. +연습 문제로 {\tt find} 함수에 세 번째 매개 변수를 추가해보라. 이 매개 +변수는 {\tt word}에서 찾기 시작해야 할 색인 번호 이다. -\section{Looping and counting} +\section{루프와 합계} +%Looping and counting \label{counter} \index{counter} \index{counting and looping} \index{looping and counting} \index{looping!with strings} -The following program counts the number of times the letter {\tt a} -appears in a string: +다음은 문자열에서 {\tt a}가 몇 번 있는지 세는 프로그램이다. \begin{verbatim} word = 'banana' @@ -6129,35 +6130,32 @@ \section{Looping and counting} print(count) \end{verbatim} % -This program demonstrates another pattern of computation called a {\bf -counter}. The variable {\tt count} is initialized to 0 and then -incremented each time an {\tt a} is found. -When the loop exits, {\tt count} -contains the result---the total number of {\tt a}'s. +이 프로그램은 {\bf 카운터(counter)}라는 연산 패턴을 나타낸다. {\tt + count} 변수는 최초에 0으로 초기화하고 {\tt a}를 만날 때마다 1씩 +증가를 한다. 루프를 종료하면 {\tt count}는 문자열 내의 {\tt a}의 +개수가 저장된다. -\index{encapsulation} -As an exercise, encapsulate this code in a function named {\tt -count}, and generalize it so that it accepts the string and the -letter as arguments. +\index{encapsulation} 연습 문제로 이 코드를 {\tt count}라는 함수 +이름으로 캡슐화해보자. 그리고 일반화하여 문자열과 셀 글자를 인자로 +받도록 해보자. -Then rewrite the function so that instead of -traversing the string, it uses the three-parameter version of {\tt -find} from the previous section. +그 후에는 만들었던 세 개의 인자를 전달 받는 {\tt find} 함수를 사용하여 +문자열 순회 부분을 제거해보자. -\section{String methods} +\section{문자열 메소드} +%String methods \label{optional} -Strings provide methods that perform a variety of useful operations. -A method is similar to a function---it takes arguments and -returns a value---but the syntax is different. For example, the -method {\tt upper} takes a string and returns a new string with -all uppercase letters. +문자열을 조작할 수 있는 다양한 메소드가 있다. 메소드는 함수처럼 인자를 +전달 받고 리턴 값을 갖고 있지만, 문법이 다르다. 예를 들어 {\tt + upper}라는 메소드는 전달 받은 문자열을 모두 대문자로 변환하여 +리턴한다. \index{method} \index{string!method} -Instead of the function syntax {\tt upper(word)}, it uses -the method syntax {\tt word.upper()}. +함수 문법처럼 {\tt upper(word)}라고 쓰는 대신 메소드는 {\tt + word.upper()}라고 쓴다. \begin{verbatim} >>> word = 'banana' @@ -6166,19 +6164,20 @@ \section{String methods} 'BANANA' \end{verbatim} % -This form of dot notation specifies the name of the method, {\tt -upper}, and the name of the string to apply the method to, {\tt -word}. The empty parentheses indicate that this method takes no -arguments. +메소드의 이름인 {\tt upper}와 메소드를 적용할 문자열의 이름 {\tt + word}와 함께 닷 표기법으로 써야 한다. 빈괄호를 쓰는 것은 인자를 받지 +않기 때문이다. \index{parentheses!empty} \index{dot notation} -A method call is called an {\bf invocation}; in this case, we would -say that we are invoking {\tt upper} on {\tt word}. +메소드 호출을 함수 호출과는 다른 의미로 {\bf 호출(invocation)}이라고 +부른다. 지금의 경우에는 {\tt word}에 대해서 {\tt upper} 메소드를 +호출(invoke)했다. +% 재번역 A method call is called an {\bf invocation}; in this case, we would +% say that we are invoking {\tt upper} on {\tt word}. \index{invocation} -As it turns out, there is a string method named {\tt find} that -is remarkably similar to the function we wrote: +이제 볼 {\tt find}라는 메소드는 우리가 작성했던 코드와 동작이 매우 유사하다. \begin{verbatim} >>> word = 'banana' @@ -6187,19 +6186,19 @@ \section{String methods} 1 \end{verbatim} % -In this example, we invoke {\tt find} on {\tt word} and pass -the letter we are looking for as a parameter. +이 예제에서는 {\tt word}에 대해서 {\tt find}라는 메소드를 호출하면서 그 +메소드에 우리가 찾는 글자를 인자로 전달 한다. -Actually, the {\tt find} method is more general than our function; -it can find substrings, not just characters: +사실은 {\tt find} 메소드는 우리가 작성한 코드보다 더 일반화가 잘되어 +있다. 글자만 찾는 것이 아니라 문자열 중 일부분을 찾을 수도 있다. \begin{verbatim} >>> word.find('na') 2 \end{verbatim} % -By default, {\tt find} starts at the beginning of the string, but -it can take a second argument, the index where it should start: +기본적으로 {\tt find}는 문자열의 처음 부분에서 시작하지만 두 번째 +인자로 시작해야 하는 색인을 쓸 수 있다. \index{optional argument} \index{argument!optional} @@ -6208,9 +6207,8 @@ \section{String methods} 4 \end{verbatim} % -This is an example of an {\bf optional argument}; -{\tt find} can -also take a third argument, the index where it should stop: +이 예제는 {\tt find} 메소드가 세 번째 {\bf 선택적 인자(optional + argument)}로 멈춰야 할 색인도 받을 수 있다는 것을 보여준다. \begin{verbatim} >>> name = 'bob' @@ -6218,22 +6216,24 @@ \section{String methods} -1 \end{verbatim} % -This search fails because {\tt b} does not -appear in the index range from {\tt 1} to {\tt 2}, not including {\tt -2}. Searching up to, but not including, the second index makes -{\tt find} consistent with the slice operator. +이 검색은 색인 {\tt 1}에서 {\tt 2} 전까지의 색인에 {\tt b}가 없기 +때문에 실패하였다. 두 번째 색인을 포함하지 않고 그 전까지만 검색하기 +때문에 {\tt find}는 문자열 조각 연산과 일관성있게 동작한다. -\section{The {\tt in} operator} +\section{{\tt in} 연산} +%The {\tt in} operator \label{inboth} \index{in operator} \index{operator!in} \index{boolean operator} \index{operator!boolean} -The word {\tt in} is a boolean operator that takes two strings and -returns {\tt True} if the first appears as a substring in the second: +{\tt in}이라는 단어는 포함 여부를 나타내는 boolean 연산자이다. 두 개의 +문자열을 인자로 받아서 첫 번째 문자열이 두 번째 문자열에 +부분문자열이라면 {\tt True}를 리턴한다. + \begin{verbatim} >>> 'a' in 'banana' @@ -6242,8 +6242,8 @@ \section{The {\tt in} operator} False \end{verbatim} % -For example, the following function prints all the -letters from {\tt word1} that also appear in {\tt word2}: +예를 들어 다음의 함수는 {\tt word1} 중 {\tt word2}에 포함되는 글자들을 +모두 출력한다. \begin{verbatim} def in_both(word1, word2): @@ -6252,12 +6252,23 @@ \section{The {\tt in} operator} print(letter) \end{verbatim} % -With well-chosen variable names, -Python sometimes reads like English. You could read -this loop, ``for (each) letter in (the first) word, if (the) letter -(appears) in (the second) word, print (the) letter.'' +변수명을 잘짓는다면 Python이 영어처럼 읽히기도 한다. + +\begin{tabular}{l} +for (each) letter in (the first) word, \\ +\begingroup\scriptsize +(첫 번째) 단어에 포함된 (각) 글자들에대해 \endgroup\\ +if (the) letter (appears) in (the second) word,\\ +\begingroup\scriptsize +(해당) 글자가 (두 번째) 단어에 포함되어 있다면 \endgroup\\ + print (the) letter. \\ +\begingroup\scriptsize +(포함된) 글자를 출력하라. \endgroup +\end{tabular} + + +다음의 예에서는 사과(apples)와 오렌지(oranges)를 비교한 결과이다. -Here's what you get if you compare apples and oranges: \begin{verbatim} >>> in_both('apples', 'oranges') @@ -6267,19 +6278,19 @@ \section{The {\tt in} operator} \end{verbatim} % -\section{String comparison} +\section{문자열 비교} +%String comparison \index{string!comparison} \index{comparison!string} -The relational operators work on strings. To see if two strings are equal: +관계 연산자는 문자열도 다룰 수 있다. 두 문자열이 동일한지 보려면 다음처럼 하면 된다. \begin{verbatim} if word == 'banana': print('All right, bananas.') \end{verbatim} % -Other relational operations are useful for putting words in alphabetical -order: +다른 관계 연산자들은 입력받은 단어들을 알파벳 순으로 정렬하는데 유용하다. \begin{verbatim} if word < 'banana': @@ -6290,18 +6301,18 @@ \section{String comparison} print('All right, bananas.') \end{verbatim} % -Python does not handle uppercase and lowercase letters the same way -people do. All the uppercase letters come before all the -lowercase letters, so: +Python은 대소문자를 사람들이 하듯이 구분하지 않는다. 모든 대문자는 +모든 소문자 전에 나타난다. 그러므로 다음과 같은 결과를 얻게 된다. \begin{verbatim} Your word, Pineapple, comes before banana. \end{verbatim} % -A common way to address this problem is to convert strings to a -standard format, such as all lowercase, before performing the -comparison. Keep that in mind in case you have to defend yourself -against a man armed with a Pineapple. +이런 류의 문제에 대응하는 일반적인 방법은 비교 전에 대문자를 소문자로 +바꾸어 문자열을 표준 형식으로 변환하는 것이다. 문자열 비교할 때 이런 +차이를 잘 기억하고 실수하지 않도록 하자. + +% 원문 Keep that in mind in case you have to defend yourself against a man armed with a Pineapple. \section{디버깅} @@ -6309,11 +6320,11 @@ \section{디버깅} \index{debugging} \index{traversal} -When you use indices to traverse the values in a sequence, -it is tricky to get the beginning and end of the traversal -right. Here is a function that is supposed to compare two -words and return {\tt True} if one of the words is the reverse -of the other, but it contains two errors: +색인을 사용하여 수열의 값을 순회할 때 첫 시작 지점과 끝 지점을 제대로 +지정하는게 까다로울 수 있다. 다음의 함수는 두 단어를 비교하고 한 +단어가 다른 단어의 역순인 경우 {\tt True}를 리턴한다. 하지만, 두 개의 +오류가 있다. + \begin{verbatim} def is_reverse(word1, word2): @@ -6332,23 +6343,21 @@ \section{디버깅} return True \end{verbatim} % -The first {\tt if} statement checks whether the words are the -same length. If not, we can return {\tt False} immediately. -Otherwise, for the rest of the function, we can assume that the words -are the same length. This is an example of the guardian pattern -in Section~\ref{guardian}. +첫 {\tt if}문은 두 단어의 길이가 같은지 비교한다. 서로 다르면 {\tt + False}를 즉시 리턴한다. 아니면, 함수가 끝날 때까지 두 단어의 길이는 +같다고 가정할 수 있다. 이 용법은 \ref{guardian} 절에서 다룬 가디언 +패턴의 예이다. \index{guardian pattern} \index{pattern!guardian} \index{index} -{\tt i} and {\tt j} are indices: {\tt i} traverses {\tt word1} -forward while {\tt j} traverses {\tt word2} backward. If we find -two letters that don't match, we can return {\tt False} immediately. -If we get through the whole loop and all the letters match, we -return {\tt True}. +{\tt i}와 {\tt j}는 색인이다. {\tt i}는 {\tt word1}을 순방향으로 +순회하고 {\tt j}는 {\tt word2}를 역방향으로 순회한다. 각 단어의 글자가 +서로 맞지 않다면 즉시 {\tt Flase}를 리턴한다. 루프를 모두 끝내고 각 +단어의 모든 글자가 동일하다면 {\tt True}를 리턴한다. -If we test this function with the words ``pots'' and ``stop'', we -expect the return value {\tt True}, but we get an IndexError: +``pots''와 ``stop''이라는 단어로 검사를 했을 때 {\tt True}를 리턴하길 +기대하겠지만, IndexError(색인 오류)가 발생한다. \index{IndexError} \index{exception!IndexError} @@ -6360,9 +6369,8 @@ \section{디버깅} IndexError: string index out of range \end{verbatim} % -For debugging this kind of error, my first move is to -print the values of the indices immediately before the line -where the error appears. +저자가 이런 류의 오류를 디버깅하는 방법은 오류 발생 지점 바로 전 줄에서 +색인을 출력해보는 것이다. \begin{verbatim} while j > 0: @@ -6374,7 +6382,7 @@ \section{디버깅} j = j-1 \end{verbatim} % -Now when I run the program again, I get more information: +다시 프로그램을 실행해보면 다음과 같은 정보를 얻는다. \begin{verbatim} >>> is_reverse('pots', 'stop') @@ -6383,12 +6391,11 @@ \section{디버깅} IndexError: string index out of range \end{verbatim} % -The first time through the loop, the value of {\tt j} is 4, -which is out of range for the string \verb"'pots'". -The index of the last character is 3, so the -initial value for {\tt j} should be {\tt len(word2)-1}. +루프를 처음 돌 때 {\tt j}의 값이 4라서 문자열 \verb"'pots'"의 범위를 +벗어난다. 이 문자열의 마지막 문자의 색인은 3이기 때문에 {\tt j}의 초기 +값은 {\tt len(word2)-1}이 되어야 한다. -If I fix that error and run the program again, I get: +오류를 수정하여 다시 실행한 결과는 다음과 같다. \begin{verbatim} >>> is_reverse('pots', 'stop') @@ -6398,26 +6405,26 @@ \section{디버깅} True \end{verbatim} % -This time we get the right answer, but it looks like the loop only ran -three times, which is suspicious. To get a better idea of what is -happening, it is useful to draw a state diagram. During the first -iteration, the frame for \verb"is_reverse" is shown in -Figure~\ref{fig.state4}. \index{state diagram} \index{diagram!state} +이제야 결과가 정확하게 나왔다. 하지만 루프가 3번만 실행된 것이 +이상해보인다. 이 문제를 이해하기 위해 상태도를 그려보자. 첫 루프에서 +\verb"is_reverse"의 프레임의 상태는 그림 \ref{fig.state4}에 나타나 +있다. +\index{state diagram} \index{diagram!state} \begin{figure} \centerline {\includegraphics[scale=0.8]{figs/state4.pdf}} -\caption{State diagram.} +\caption{상태도.} \label{fig.state4} \end{figure} -I took some license by arranging the variables in the frame -and adding dotted lines to show that the values of {\tt i} and -{\tt j} indicate characters in {\tt word1} and {\tt word2}. +임의로 프레임 내의 변수들의 자리를 재배치하였고 점선을 사용하여 {\tt + i}와 {\tt j}가 각각 {\tt word1}과 {\tt word2}의 글자들을 나타내는 +것을 표현하였다. -Starting with this diagram, run the program on paper, changing the -values of {\tt i} and {\tt j} during each iteration. Find and fix the -second error in this function. +이 그림을 시작점으로 해서 종이 위에서 프로그램의 실행 과정을 +따라가보자. 반복할 때마다 {\tt i}와 {\tt j}의 값을 바꿔보자. 함수에 +있는 두 번째 오류를 찾아 고쳐보자. \label{isreverse} @@ -6426,51 +6433,47 @@ \section{용어 해설} \begin{description} -\item[object:] Something a variable can refer to. For now, -you can use ``object'' and ``value'' interchangeably. +\item[객체(object):] 변수를 가리킬 수 있는 무엇. ``객체(object)''와 + ``값(value)''를 교차하여 사용할 수 있다. 앞으로 더 정확하게 정의할 + 것이다. \index{object} -\item[sequence:] An ordered collection of -values where each value is identified by an integer index. +\item[수열(sequence):] 정수 색인으로 구분되는 값들의 여러 값들의 순차 컬렉션 \index{sequence} -\item[item:] One of the values in a sequence. +\item[아이템(item):] 수열에 포함된 값 중 하나 \index{item} -\item[index:] An integer value used to select an item in -a sequence, such as a character in a string. In Python -indices start from 0. +\item[색인(index):] 수열에 있는 아이템을 선택하기 위한 정수 값. + Python의 색인은 0에서 시작한다. \index{index} -\item[slice:] A part of a string specified by a range of indices. +\item[조각(slice):] 색인 범위로 지정된 문자열의 일부 \index{slice} -\item[empty string:] A string with no characters and length 0, represented -by two quotation marks. +\item[빈 문자열(empty string):] 길이가 0이고 글자가 포함안된 문자열로 + 두 개의 연속된 따옴표로 표현된다. \index{empty string} -\item[immutable:] The property of a sequence whose items cannot -be changed. +\item[불변성(immutable):] 수열의 특성으로 변경 불가능한 아이템들을 갖는 + 수열을 뜻함 \index{immutability} -\item[traverse:] To iterate through the items in a sequence, -performing a similar operation on each. +\item[순회(traverse):] 수열의 아이템들을 하나씩 방문하면서 유사한 동작을 수행함 \index{traversal} -\item[search:] A pattern of traversal that stops -when it finds what it is looking for. +\item[검색(search):] 순회 패턴 중 하나로 찾는 것을 발견하면 멈춤 \index{search pattern} \index{pattern!search} -\item[counter:] A variable used to count something, usually initialized -to zero and then incremented. +\item[카운터(counter):] 보통 0으로 초기화된 후 증가하는 값으로 무언가를 + 셀 때 사용하는 변수 \index{counter} -\item[invocation:] A statement that calls a method. +\item[호출(invocation):] 메소드를 호출하는 문장 \index{invocation} -\item[optional argument:] A function or method argument that is not -required. +\item[선택적 인자(optional argument):] 함수나 메소드의 인자 중 꼭 필요하지 않은 것 \index{optional argument} \index{argument!optional} @@ -6484,17 +6487,16 @@ \section{연습 문제} \index{string method} \index{method!string} -Read the documentation of the string methods at -\url{http://docs.python.org/3/library/stdtypes.html#string-methods}. -You might want to experiment with some of them to make sure you -understand how they work. {\tt strip} and {\tt replace} are -particularly useful. - -The documentation uses a syntax that might be confusing. -For example, in \verb"find(sub[, start[, end]])", the brackets -indicate optional arguments. So {\tt sub} is required, but -{\tt start} is optional, and if you include {\tt start}, -then {\tt end} is optional. +\url{http://docs.python.org/3/library/stdtypes.html#string-methods}에 +설명된 문자열 메소드들의 문서을 읽어보자. 어떻게 동작하는지 알 수 +있도록 몇 개는 꼭 실험해보기 바란다. {\tt strip}과 {\tt replace}는 +특히 유용하므로 실험해보기 바란다. + +이 문서는 어쩌면 혼돈스러운 문법을 사용하고 있다. 예를 들어 +\verb"find(sub[, start[, end]])"에서 사용된 각괄호는 선택적 인자를 +나타낸다. {\tt sub}은 필수이지만 {\tt start}는 선택적이다. {\tt + start}를 선택한 경우에만 해당하는데, 선택했다면 {\tt end}가 선택적 +인자이다. \index{optional argument} \index{argument!optional} @@ -6505,11 +6507,9 @@ \section{연습 문제} \index{count method} \index{method!count} -There is a string method called {\tt count} that is similar -to the function in Section~\ref{counter}. Read the documentation -of this method -and write an invocation that counts the number of {\tt a}'s -in \verb"'banana'". +{\tt count}라는 문자열 메소드가 있는데, \ref{counter}절에서 본 함수와 +유사하다. 이 메소드에 대한 문서를 읽어보고 \verb"'banana'"에 {\tt a}가 +몇 개 있는지 세는 호출문을 작성해보자. \end{exercise} @@ -6518,10 +6518,10 @@ \section{연습 문제} \index{slice operator} \index{operator!slice} -A string slice can take a third index that specifies the ``step -size''; that is, the number of spaces between successive characters. -A step size of 2 means every other character; 3 means every third, -etc. +문자열 조각 연산자는 ``증감폭(step size)''를 지정할 수 있는 세 번째 +색인이 있다. 이 값을 지정하면 지정된 칸만큼 떨어진 글자를 선택한다. +예를 들어 증감폭이 2이면 홀수 번째만 선택하고 3이면 3배수 위치의 값만 +선택한다. \begin{verbatim} >>> fruit = 'banana' @@ -6529,21 +6529,20 @@ \section{연습 문제} 'bnn' \end{verbatim} -A step size of -1 goes through the word backwards, so -the slice \verb"[::-1]" generates a reversed string. +증감폭을 -1로 지정하면 역순으로 순회한다. \verb"[::-1]"라고 쓰면 +역순으로 표기된 문자열을 얻는다. \index{palindrome} -Use this idiom to write a one-line version of \verb"is_palindrome" -from Exercise~\ref{palindrome}. +이 표현을 사용하여 연습문제 \ref{palindrome}의 \verb"is_palindrome"을 +한 줄로 표현해보자. \end{exercise} \begin{exercise} -The following functions are all {\em intended} to check whether a -string contains any lowercase letters, but at least some of them are -wrong. For each function, describe what the function actually does -(assuming that the parameter is a string). + 다음은 문자열이 소문자로 구성되었는지 검사하도록 {\em 의도}한 + 함수들이다. 이들 중 어떤 것들은 잘못되었다. 각 함수마다 무슨 동작을 + 하는지 설명해보라(문자열을 매개 변수로 받는다 가정하자). \begin{verbatim} def any_lowercase1(s): @@ -6586,41 +6585,33 @@ \section{연습 문제} \index{rotation, letter} \label{exrotate} -A Caesar cypher is a weak form of encryption that involves ``rotating'' each -letter by a fixed number of places. To rotate a letter means -to shift it through the alphabet, wrapping around to the beginning if -necessary, so 'A' rotated by 3 is 'D' and 'Z' rotated by 1 is 'A'. +카이사르의 암호(Ceasar cypher)은 알파벳 상의 글자를 고정된 위치만큼 회전하여 다른 글자로 치환하는 방식이다. 이 말의 뜻은 'A'라는 글자를 3 회전하면 'D'가 되고 'Z'를 1 회전하면 'A'가 되도록 한다는 말이다. -To rotate a word, rotate each letter by the same amount. -For example, ``cheer'' rotated by 7 is ``jolly'' and ``melon'' rotated -by -10 is ``cubed''. In the movie {\em 2001: A Space Odyssey}, the -ship computer is called HAL, which is IBM rotated by -1. +단어를 회전하려면 각 글자를 같은 크기만큼 회전하여 치환하면 된다. 예를 +들어 ``cheer''를 7 회전하면 ``jolly''가 되고 ``melon''을 -10회전하면 +cubed''가 된다. {\em 2001: 스페이스 오디세이}라는 영화에 나오는 +디스커버리호의 주컴퓨터 HAL은 IBM을 -1 회전한 글자이다. %For example ``sleep'' %rotated by 9 is ``bunny'' and ``latex'' rotated by 7 is ``shale''. -Write a function called \verb"rotate_word" -that takes a string and an integer as parameters, and returns -a new string that contains the letters from the original string -rotated by the given amount. +함수 \verb"rotate_word"를 작성하여 문자열과 정수를 매개 변수로 받아 +정수만큼 문자열을 회전한 카이사르의 암호를 리턴해보자. -You might want to use the built-in function {\tt ord}, which converts -a character to a numeric code, and {\tt chr}, which converts numeric -codes to characters. Letters of the alphabet are encoded in alphabetical -order, so for example: +글자를 숫자로 변환시키는 내장 함수 {\tt ord}와 숫자를 글자로 변환하는 내장 함수 {\tt chr}를 사용해서 작성해보자. 알파벳의 글자들은 순차적으로 부호화되어 있다. 예를 들어 보자. \begin{verbatim} >>> ord('c') - ord('a') 2 \end{verbatim} -Because \verb"'c'" is the two-eth letter of the alphabet. But -beware: the numeric codes for upper case letters are different. +\verb"'c'"는 \verb"'a'"에서 두 번째 떨어진 위치에 있기 때문에 결과가 +2가 된다. 대문자는 다르게 부호화되어 있다는 것에 주의하다. -Potentially offensive jokes on the Internet are sometimes encoded in -ROT13, which is a Caesar cypher with rotation 13. If you are not -easily offended, find and decode some of them. Solution: -\url{http://thinkpython2.com/code/rotate.py}. +인터넷에 떠도는 불쾌한 농담들은 ROT13으로 부호화된 것들이 많다. +ROT13은 카이사르 암호로 13번 회전했다는 뜻이다. 무덤덤한 독자라면 찾아 +바꿔 읽어 보자. 해답은 \url{http://thinkpython2.com/code/rotate.py}에 +있다. \end{exercise} From e2f0ddd3a0348752943d34464a1c6c4b96f9b74a Mon Sep 17 00:00:00 2001 From: Seongjin Lee Date: Sun, 30 Jul 2017 23:07:25 +0900 Subject: [PATCH 13/13] updated --- book_kr/book.tex | 156 +++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/book_kr/book.tex b/book_kr/book.tex index c594541..5480dc6 100644 --- a/book_kr/book.tex +++ b/book_kr/book.tex @@ -6616,37 +6616,38 @@ \section{연습 문제} \end{exercise} -\chapter{Case study: word play} +\chapter{사례 연구: 단어 놀이} +%Case study: word play \label{wordplay} -This chapter presents the second case study, which involves -solving word puzzles by searching for words that have certain -properties. For example, we'll find the longest palindromes -in English and search for words whose letters appear in -alphabetical order. And I will present another program development -plan: reduction to a previously solved problem. +이 번 장에서는 두 번째의 사례 연구를 선보인다. 특정 성질을 갖는 +단어들을 찾아 단어 퍼즐을 푸는 프로그램이다. 예를 들어 영어에 존재하는 +긴 회문을 찾아 알파벳 순으로 글자가 나타나는 단어들을 찾을 것이다. +그리고 나서 이전에 해결한 문제의 해법을 응용하는 다른 프로그램 개발 +계획에 대해 설명할 것이다. -\section{Reading word lists} + +\section{단어 목록 읽어 들이기} +%Reading word lists \label{wordlist} -For the exercises in this chapter we need a list of English words. -There are lots of word lists available on the Web, but the one most -suitable for our purpose is one of the word lists collected and -contributed to the public domain by Grady Ward as part of the Moby -lexicon project (see \url{http://wikipedia.org/wiki/Moby_Project}). It -is a list of 113,809 official crosswords; that is, words that are -considered valid in crossword puzzles and other word games. In the -Moby collection, the filename is {\tt 113809of.fic}; you can download -a copy, with the simpler name {\tt words.txt}, from -\url{http://thinkpython2.com/code/words.txt}. +이 장에서의 활용할 예제들은 영어 단어의 목록이 있어야 한다. 웹에는 +무수히 많은 단어 목록들이 있지만 우리의 목적에 가장 적합한 목록은 +Grady Ward가 공개적으로 유지 관리 및 기여하고 있는 모비 어휘목록 +프로젝트 (Moby lexicon project, +\url{http://wikipedia.org/wiki/Moby_Project} 참고)이다. 이 목록은 +113,809개의 공식 십자 낱말 풀이용 단어들이다. 십자 낱말 풀이와 다른 +단어 놀이에 적합한 단어 목록이다. 이 모비 목록은 {\tt + 113809of.fic}이라는 이름을 갖고 있지만 +\url{http://thinkpython2.com/code/words.txt}에서 {\tt words.txt}라는 +쉬운 이름으로 내려 받아 사용하면 된다. \index{Moby Project} \index{crosswords} -This file is in plain text, so you can open it with a text -editor, but you can also read it from Python. The built-in -function {\tt open} takes the name of the file as a parameter -and returns a {\bf file object} you can use to read the file. +이 파일은 서식이 없어서 어떤 문서 편집기로 열어도 되지만, Python에서 이 +파일을 읽어보자. 파일 이름을 매개 변수로 {\tt open}이라는 내장 함수에 +전달하면 해당 파일을 읽을 수 있는 {\bf 파일 객체}를 리턴 받는다. \index{open function} \index{function!open} \index{plain text} @@ -6658,10 +6659,11 @@ \section{Reading word lists} >>> fin = open('words.txt') \end{verbatim} % -{\tt fin} is a common name for a file object used for input. The file -object provides several methods for reading, including {\tt readline}, -which reads characters from the file until it gets to a newline and -returns the result as a string: \index{readline method} +{\tt fin}은 입력으로 전달 받은 파일 객체를 나타내는 일반적인 이름이다. +파일 객체는 읽기를 위한 여러 메소드를 제공하는데 그 중에는 {\tt + readline}도 포함된다. 이 메소드는 파일에서 줄 바꿈(newline) 기호를 만나기 +전까지의 글자들을 읽은 후 해당 문자열을 리턴한다. +\index{readline method} \index{method!readline} \begin{verbatim} @@ -6669,23 +6671,21 @@ \section{Reading word lists} 'aa\r\n' \end{verbatim} % -The first word in this particular list is ``aa'', which is a kind of -lava. The sequence \verb"\r\n" represents two whitespace characters, -a carriage return and a newline, that separate this word from the -next. +이 목록에서 첫 번째 단어는 ``aa''로 용암의 일종이다. 그 뒤에 따라오는 +\verb"\r\n"은 두 개의 공백 문자로 리턴(carriage return)과 줄 바꿈을 +나타내며 다음 단어와 지금의 단어를 구분하는 역할을 한다. -The file object keeps track of where it is in the file, so -if you call {\tt readline} again, you get the next word: +파일 객체는 파일에서의 현재 위치를 기억하고 있기 때문에 또 한 번 {\tt + readline}을 호출하면 그 다음 단어를 얻는다. \begin{verbatim} >>> fin.readline() 'aah\r\n' \end{verbatim} % -The next word is ``aah'', which is a perfectly legitimate -word, so stop looking at me like that. -Or, if it's the whitespace that's bothering you, -we can get rid of it with the string method {\tt strip}: +그 다음 단어는 ``aah''이며, 이 단어도 전혀 이상하지 않은 낱말이다. +만약 공백 문자가 거슬린다면 {\tt strip}이라는 문자열 메소드를 이용하여 +없앨 수 있다. \index{strip method} \index{method!strip} @@ -6696,9 +6696,8 @@ \section{Reading word lists} 'aahed' \end{verbatim} % -You can also use a file object as part of a {\tt for} loop. -This program reads {\tt words.txt} and prints each word, one -per line: +{\tt for} 루프에 파일 객체를 사용할 수도 있다. 다음의 프로그램은 {\tt + words.txt}를 읽어서 각 단어를 한 줄씩 읽는 동작을 한다. \index{open function} \index{function!open} @@ -6713,34 +6712,36 @@ \section{Reading word lists} \section{연습 문제} %Exercises -There are solutions to these exercises in the next section. -You should at least attempt each one before you read the solutions. +이 연습 문제들에 대한 해답은 다음 절에 나와 있다. 해법을 읽어보기 전에 +풀어 보기 바란다. -\begin{exercise} -Write a program that reads {\tt words.txt} and prints only the -words with more than 20 characters (not counting whitespace). +\begin{exercise} + {\tt words.txt}를 읽는 프로그램을 작성하여 (공백을 포함하지 않고) 20 + 글자 이상이 되는 단어들만 출력 해보자. \index{whitespace} \end{exercise} \begin{exercise} -In 1939 Ernest Vincent Wright published a 50,000 word novel called -{\em Gadsby} that does not contain the letter ``e''. Since ``e'' is -the most common letter in English, that's not easy to do. + 1939년에 Ernest Vincent Wright가 {\em Gadsby}라는 50,000 단어로 된 + 소설을 출판하였다. 그 소설에는 영어에서 가장 흔한 글자 중 하나인 + ``e''가 포함되어 있지 않다. 그런 글을 쓴다는 것이 쉬운 일은 아니었을 + 것이다. + + 사실 이 흔한 글자를 쓰지 않고는 사적인 생각을 하기도 어렵다. + 처음에는 매우 느리겠지만 조심스럽게 오랜 시간 동안 훈련을 하다보면 할 + 수 있게 된다. -In fact, it is difficult to construct a solitary thought without using -that most common symbol. It is slow going at first, but with caution -and hours of training you can gradually gain facility. + 설명은 여기까지. -All right, I'll stop now. + \verb"has_no_e"이라는 함수를 작성하여 전달 받은 단어에 ``e''가 없다면 + {\tt True}를 리턴하도록 하자. -Write a function called \verb"has_no_e" that returns {\tt True} if -the given word doesn't have the letter ``e'' in it. + 이전 절에서 사용한 프로그램을 수정하여 ``e''를 포함하고 있지 않은 + 단어들만 출력하도록 한 뒤 단어 목록에서 ``e''를 포함하고 있지 않은 + 단어의 백분율을 계산해보자. -Modify your program from the previous section to print only the words -that have no ``e'' and compute the percentage of the words in the list -that have no ``e''. \index{lipogram} \end{exercise} @@ -6748,16 +6749,14 @@ \section{연습 문제} \begin{exercise} -Write a function named {\tt avoids} -that takes a word and a string of forbidden letters, and -that returns {\tt True} if the word doesn't use any of the forbidden -letters. + 단어와 금지 문자열을 입력 받는 {\tt avoids}라는 함수를 작성해보자. + 만약 이 함수가 {\tt True}를 리턴하면 해당 단어는 금지 문자열을 쓰고 + 있지 않다는 뜻이다. -Modify your program to prompt the user to enter a string -of forbidden letters and then print the number of words that -don't contain any of them. -Can you find a combination of 5 forbidden letters that -excludes the smallest number of words? + 사용자가 금지 문자를 입력하도록 프로그램을 수정한 후 금지 문자열을 + 포함하지 않는 단어가 총 몇 개인지 출력하도록 해보자. 가장 적은 수의 + 단어들을 목록에서 제거하도록 문자 다섯 개로 이루어진 금지 문자 집합을 + 구성할 수 있겠는가? \end{exercise} @@ -6765,30 +6764,30 @@ \section{연습 문제} \begin{exercise} -Write a function named \verb"uses_only" that takes a word and a -string of letters, and that returns {\tt True} if the word contains -only letters in the list. Can you make a sentence using only the -letters {\tt acefhlo}? Other than ``Hoe alfalfa?'' + 단어와 문자열을 입력 받는 \verb"uses_only" 라는 함수를 작성하여 + 전달한 문자열로만 이루어진 단어인 경우에만 {\tt True}를 리턴하도록 + 해보자. {\tt acefhlo}만으로 로 이루어진 문장을 만들 수 있겠는가? + ``Hoe alfalfa''외에 다른 문장을 만들어보자. \end{exercise} \begin{exercise} -Write a function named \verb"uses_all" that takes a word and a -string of required letters, and that returns {\tt True} if the word -uses all the required letters at least once. How many words are there -that use all the vowels {\tt aeiou}? How about {\tt aeiouy}? + 단어와 꼭 사용해야 하는 글자로 이루어진 문자열을 입력 받는 + \verb"uses_all" 라는 함수를 작성해보자. 이 함수는 꼭 사용해야 하는 + 문자열의 글자들을 최소한 한 번 사용하면 {\tt True}를 리턴한다. {\tt + aeiou}를 모두 사용하는 단어는 몇 개나 있는가? {\tt aeiouy}를 + 사용하는 하는 단어는 몇 개나 있나? \end{exercise} \begin{exercise} -Write a function called \verb"is_abecedarian" that returns -{\tt True} if the letters in a word appear in alphabetical order -(double letters are ok). -How many abecedarian words are there? + 단어의 글자들이 알파벳 순으로 나열이 되어 있으면 {\tt True}를 + 리턴하는 \verb"is_abecedarian"이라는 함수를 작성해보자(두 번 연속 + 사용되는 경우도 인정된다). 알파벳 순으로 된 단어가 몇 개나 되는가? \index{abecedarian} @@ -6796,7 +6795,8 @@ \section{연습 문제} -\section{Search} +\section{검색} +%Search \label{search} \index{search pattern} \index{pattern!search}