-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopeel-report.tex
383 lines (303 loc) · 12.7 KB
/
popeel-report.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
%
% MENCIONAR ESTE REPORT EN LA PRESENTACION EN LA WEB ORIGINAL DE BITBUCKET
%
\documentclass[12pt]{article}
\title{A Software Simulator of the Very Simple Robot \emph{Popeel}%
%\thanks{}
\\ \medskip\Large
(or: Potato Peeling, Resurrected!)
}
\author{Jos\'e L. Balc\'azar \\
% {\vspace{-0.5cm}} \\
{Department of Computer Science} \\
{Universitat Polit\`ecnica de Catalunya}}
\usepackage{fullpage}
\usepackage{hyperref}
\usepackage{underscore}\makeatletter
%\usepackage[ruled,vlined]{algorithm2e} % DOUBTFUL...
%\newtheorem{theorem}{Theorem}
%\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{example}{Example}
% \def\cite#1{[{\sl #1}]} % remove this when the references are ready
\def\jlb#1{\par\noindent\smallskip{\bf\ [#1 --JLB]\par\smallskip}}
% \def\jlb#1{\relax}
% \usepackage{latexsym}
% \usepackage{multicol}
% \usepackage{enumitem}
\begin{document}
\maketitle
\begin{abstract}
We describe an open-source implementation of a
Python class that supports an old programming
exercise related to peeling potatoes.
\end{abstract}
\section{Introduction}% \label{s:intro}
Many years ago, at FIB, UPC \cite{FIB}, we used to
propose some simple, on-paper programming exercises
to newcoming students. They involved peeling potatoes,
one by one, and keeping a count of them, and fetching
fresh basketfuls of potatoes when necessary.
Mostly everyone with no previous programming
experience had some trouble solving the main
statement. Indeed, it happens to be a hardish but
instructive exercise at that level. However,
for novel programmers, writing programs on paper
(or a blackboard) and imagining their runtime effect
is difficult, and particularly so when the effect
is a runtime error.
Thus, often, a number of students had trouble simply understanding
what they were supposed to do \cite{PBblog} (but, what
potatoes are they talking about?, must I bring an actual
knife from home tomorrow?\dots) Eventually, we stopped
proposing this exercise; but, even now, after such long years,
many students of the time still vaguely remember,
if not the precise exercise, some approximate
notions of it.
\looseness=-1
These days, however, object orientation allows for
a simple syntax very similar to the on-paper exercise
of the old times, and one can easily provide on the
web a working implementation. We have decided
to create one \cite{Popeel}, and expect to use it in the early
lectures of the second edition of a first-year
course on Programming \cite{mireport} in a local
Degree on Bioinformatics~\cite{BDBI}.
As happened in the old times, in our implementation
there is a toy robot, Popeel, the
{\bf Po}tato {\bf peel}er, assumed to live in an
environment where an inexhaustible store of potatoes
(the \emph{pantry})
is available nearby. It also has a basket with a few
potatoes. It can pick one potato from the basket and
peel it but, of course, only if the basket is not empty. It can go
fetch more potatoes from the pantry,
but will complain
if asked to do so unnecessarily. The basic operations
offered by the class are to be used in writing small,
correct programs for specific tasks.
Each programming exercise sets up a task for the
robot, that usually includes peeling some potatoes
and that usually ends up putting the robot to sleep,
after having finished its task. However, if asked to
do something impossible, like peeling one potato
from the basket
when the basket is empty, Popeel will complain and
just go sleeping directly --- further requests for action
when it is sleeping will cause a bitter complain
and then going back to bed.
The reader is welcome to imagine it as a humanoid
robot but, for the time being, it is just a Python
class that informs of what is happening through
a monologue.
\section{The main class}
The program is freely available in open-source,
MIT-licensed form \cite{MITlicense} and you are welcome
to download it \cite{Popeel}.
The main class is, of course, {\tt Popeel}: a class
written in Python and compatible with both
Python2 and Python3.
The class is programmed so that it can be used in a course
{\it before} the students have been exposed to the
notion of a variable (and we are using it so).
It follows the ``singleton'' pattern: after
importing the class name, one just calls the methods as in
{\tt Popeel.peel_1_potato()} or {\tt Popeel.go_sleep()}
--- more precisely, they are ``@{\tt classmethod}'''s.
If variables are already conceptually available, then
one object of class {\tt Popeel}
can be declared as well, and used like with a regular class,
as in, say, {\tt p = Popeel()}. Then, its methods
can be called, as in {\tt p.peel_1_potato()} or
{\tt p.go_sleep()}, following the standard
Python object-oriented syntax; but, being a
singleton class, only one object of the class
will be allowed.
%\looseness=1
An alternative, ``non-singleton'' class is also
available: {\tt Popeel_}, with an extra underscore
at the end of its name. This variant can be used in a
fully standard form: as many objects of the class
as desired can be declared, and their
methods (now not anymore ``@{\tt classmethod}'''s!) %, but fully standard)
called in the usual way. However, if several
objects are in use, their messages will be likely
to show up in a confusing manner. The statements
we use {\tt Popeel} for only need one instance, and
we discourage, for the time being, the usage of this
standard variant of the class.
\subsection{Available operations}
The simple repertory of operations
offered by this class of objects is:
\begin{description}
\item{{\tt peel_1_potato():}} Will peel one potato
from the basket and report about it; however, will
complain and go sleeping if it has no potatoes at all
in the basket.
\item{{\tt refill_basket():}} Will go to the pantry
% main store
and refill the empty basket with a variable
quantity of potatoes; will do nothing (except complaining)
if it still has potatoes in the basket.
\item{{\tt discard_basket():}} Will return potatoes
left in the basket back to the pantry. Popeel likes
to do this when its task is complete.
\item{{\tt go_sleep():}} Popeel will complain if you
wake it up after going to bed --- and then return to
bed anyhow.
\item{{\tt set_task(int):}} Set the goal. Popeel aims now
at peeling the number of potatoes indicated as argument.
There is a default, implicit task for programs
that do not include a call to this method.
\item{{\tt is_basket_empty():}} Boolean function,
result as by its name.
\item{{\tt enough_potatoes():}} Boolean function, indicates
whether the task set (either explicitly through {\tt set_task}
or implicitly) has been accomplished.
%Recommended usage before sending Popeel to bed.
\end{description}
Somewhere in the download, we provide file
{\tt popeel_user.py}
with example usages of these operations.
% Some of these include {\tt print} statements,
% which may become unnecessary if the
% operations are run within the read-eval-print loop of
% an interpreter.
\section{Example tasks}
There is a main exercise task, that we leave for the
next section, as
% where we leave the
% goal quantity of potatoes to the initialization,
% which will set up {\tt Popeel} in a somewhat random state;
% we return to this in the next section. However,
it
is worthwhile to start with simpler tasks. All
the rest of this section assumes that you have
a Python interpreter available and that the
source code for the class, {\tt popeel.py}, is within
the appropriate system paths (most likely, it will
suffice to download it to some folder in your
equipment and run Python on program files in
the same folder).
\subsection{Peeling just one potato (and then taking a rest)}
It would seem that peeling one potato is to be
the simplest task to program on top of Popeel,
but actually a subsequent one is easier, as we
shall see.
% We always start with a declaration of an object
% of the class {\tt Popeel}, after importing the class
% to have it available to our program:
% \qquad{\tt from popeel import Popeel}
% \qquad{\tt p = Popeel()}
% (The identifier {\tt p} is arbitrary, any other
% name will do; but use it consistently later on.)
% One might guess that the subsequent instructions
% would be:
% \qquad{\tt p.peel_1_potato()}
% \qquad{\tt p.go_sleep()}
Indeed, one might guess that this program would
accomplish the task:
\qquad{\tt from popeel import Popeel}
\qquad{\tt Popeel.peel_1_potato()}
\qquad{\tt Popeel.go_sleep()}
You might see on your own why this solution is not correct;
otherwise, try it, insistingly, maybe even many times,
before reading further.
For your convenience, we provide
this program as file
{\tt popeel_simple_user.py} somewhere in the download.
% By the way, the simpler, quite intuitive, but equally wrong
% alternative using the singleton class is:
% \qquad{\tt from popeel import Popeel_}
% \qquad{\tt Popeel_.peel_1_potato()}
% \qquad{\tt Popeel_.go_sleep()}
%
Once you understand why this solution is not
correct, try and come up with a correct one
on your own.
The task of peeling two potatoes is postponed for the moment.
\subsection{Peeling all the potatoes in the basket}
In this exercise, we task Popeel with peeling a
variable number of potatoes: whatever ones it
happened to have in the basket upon being summoned,
which will be randomly chosen below a certain limit.
Thus, each run of this program will end up peeling a
different quantity of potatoes. Of course, once the
basket becomes empty, Popeel is to be sent to sleep.
% For your convenience, we provide this program as file
% {\tt popeel_first_user.py} but we heartily recommend to
% try
Try your hand at writing the program without looking
inside any file in the download. We believe it will
be easier than it seems.
\subsection{Peeling two basketfuls of potatoes}
Again each run of this program will end up peeling a
different quantity of potatoes, but this time, once
all the potatoes in the initial basket are peeled,
we refill the basket and peel all the potatoes again.
% And again, for your convenience, we provide a solution
% as file {\tt popeel_second_user.py} but we insist that you
% should write and thoroughly test your program before
% comparing it to our own.
% \subsection{Random Popeel programs}
% The download includes a number of programs created
% randomly, as well as a program, {\tt randprog.py}, that
% you can use yourself to create random programs on
% top of Popeel\dots\ and to guess what they do \emph{before}
% running them (but there is no need of your looking
% inside {\tt randprog.py} --- its essence is a so-called
% probabilistic generative grammar).
\subsection{Peeling two potatoes}
The section title says it all.
Write your own solution and test it
repeatedly and insistently before labeling it
as good!
Don't forget sending Popeel to bed.
Consider also the option of saving food by
returning left-over potatoes, which remain
unused in the basket, back to the pantry.
\section{The main exercise}
The main exercise is to peel a fixed amount of potatoes.
There is a default value (currently 35 potatoes)
which you can of course override by
calling {\tt Popeel.set_task(12)} if you want
to peel 12 potatoes, or whatever number you fancy.
Alternatively, use {\tt p.set_task(12)} if
you declare an object {\tt p} of class {\tt Popeel}
or of class {\tt Popeel_}.
Thus, say the program starts with:
\qquad{\tt from popeel import Popeel}
% \qquad{\tt p = Popeel()}
\qquad{\tt Popeel.set_task(12)}
How does it continue? We do not provide a solution:
it is your task to construct it, and we hope that
some readers will have learned something by doing
this exercise. We do provide, however, a couple of
examples of Popeel's monologue for two correct cases:
in one, it happens to start with no potatoes in the
basket (file {\tt popeel_correct_output_0.txt});
in the other, bearing in fact little essential difference,
it happens to start with some potatoes
in the
basket (file {\tt popeel_correct_output_6.txt}).
Of course, the exact quantities, and the places where
Popeel reports the number of potatoes peeled so far,
or needs to fetch more potatoes,
may vary, depending on the (somewhat random)
quantities of potatoes
obtained at each time of refilling the basket.
\begin{thebibliography}{10}
\bibitem{FIB}
\url{www.fib.upc.edu}
\bibitem{PBblog}
\url{https://patriciamiriam.wordpress.com/2017/02/14/carta-a-mi-tio-en-respuesta-a-la-suya-del-23-de-noviembre-de-1982/}
\bibitem{Popeel}
\url{https://bitbucket.org/balqui/popeel} (most recent advisable download
at the time of writing: \url{https://bitbucket.org/balqui/popeel/downloads/popeel-v0.1.2.zip}).
\bibitem{mireport}
\url{http://www.cs.upc.edu/~balqui/proal16.pdf}
\bibitem{BDBI}
\url{https://www.esci.upf.edu/en/bachelors-degree-in-bioinformatics/bachelors-degree-bioinformatics}
\bibitem{MITlicense}
\url{https://en.wikipedia.org/wiki/MIT_License}
\end{thebibliography}
\end{document}