Lab 0 2015

From 6.034 Wiki

(Difference between revisions)
Jump to: navigation, search
(Getting the problem set code)
Current revision (02:52, 30 August 2016) (view source)
m (Lab 0 moved to Lab 0 2015: new Lab 0 in fall 2016)
 
(132 intermediate revisions not shown.)
Line 1: Line 1:
-
__NUMBERS__
+
* '''Due''': Tuesday, September 15, at '''10:00PM'''
 +
* '''Lab File''': http://web.mit.edu/6.034/www/labs/lab0/lab0.zip
 +
* '''Grader''' : https://ai6034.mit.edu/labs
 +
 
 +
 
 +
 
 +
'''Note:''' As with all labs, you will need to have a [https://ai6034.mit.edu/labs key file] in order to submit.
 +
 
 +
 
__TOC__
__TOC__
-
The purpose of this problem set is to familiarize you with this
+
The purpose of this lab is to familiarize you with this
-
term's problem set system and to serve as a diagnostic for programming
+
term's lab system and to diagnose your programming
-
ability and facility with MIT Scheme. 6.034 uses MIT Scheme for  
+
ability and facility with Python. 6.034 uses Python for  
-
all of its problem sets and you will be called on to understand the
+
all of its labs, and you will be called on to understand the
functioning of large systems, as well as to write significant pieces
functioning of large systems, as well as to write significant pieces
of code yourself.  
of code yourself.  
Line 12: Line 20:
important that you be able to focus on the problems you are solving,
important that you be able to focus on the problems you are solving,
rather than the mechanical code necessary to implement the solution.
rather than the mechanical code necessary to implement the solution.
-
If you struggle with the problems in this problem set, you will likely
 
-
struggle with all subsequent problem sets as well, and 6.034 will be
 
-
very difficult for you.
 
-
If Scheme doesn't come back to you by the end of this problem set, we
+
If Python doesn't come back to you by the end of this lab, we
-
recommend that you seek extra help through the [http://hkn.mit.edu/act-tutoring.html Course 6/HKN tutoring program], which matches
+
recommend that you seek extra help through the [http://hkn.mit.edu/tutor.php Course 6/HKN tutoring program], which matches
students who want help with students who've taken and done well in a
students who want help with students who've taken and done well in a
class. The department pays the tutor, and the program comes highly
class. The department pays the tutor, and the program comes highly
recommended.
recommended.
-
;Scheme resources
+
;Python resources
-
Some resources to help you knock the rust off of your Scheme:
+
Some resources to help you knock the rust off of your Python:
-
* Your trusty 6.001 book, ''Structure and Interpretation of Computer Programming'', [http://mitpress.mit.edu/sicp/full-text/book/book.html available online]
+
* Any of the many good Python handbooks out there, such as:
-
* The standard Scheme documentation, which is called "[http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-2.html R5RS]"
+
** [http://diveintopython.net Dive Into Python], for experienced programmers
-
* [http://hkn.mit.edu/act-tutoring.html Course 6/HKN tutoring program]
+
** O'Reilly's [http://proquest.safaribooksonline.com/9780596513986/ Learning Python]
 +
** [http://www.greenteapress.com/thinkpython/ Think Python], for beginning programmers
 +
* The standard Python documentation, at [http://docs.python.org/] (the Library Reference and the Language Reference are particularly useful, if you know what you're looking for)
 +
* [https://hkn.mit.edu/tutoring Course 6/HKN tutoring program]
-
== Problem set logistics ==
 
-
The first thing you need to do is set up a 6.034 section in your
 
-
Athena files. From any Athena terminal, run these commands:
 
-
add 6.034
+
== Python ==
-
/mit/6.034/bin/6.034-setup
+
-
This script creates a <tt>6.034-psets</tt> directory in your Athena home directory, with a subdirectory for each problem set, and sets the permissions on them so that your TA can access the files in it. Changing these permissions may affect your grade.
+
There are a number of versions of Python available. This course will use standard Python ("CPython") from http://www.python.org/.  If you are running Python on your own computer, you should download and install Python 2.5,  Python 2.6, or Python 2.7 from http://www.python.org/download/ . All the lab code will require at least version 2.3.  '''Please note that our code is not designed to work with Python 3.'''
-
In order to get credit for a problem set, you '''must''' copy the files containing any code you wrote into the appropriate directory. This is how you submit your solutions.
+
<b>If you are using Windows:</b> When run on Windows, Python versions 2.6.5 through 2.7.3 seem to be incompatible with our server.  The recommended solution is to install a version of Python >= 2.7.4 or <= 2.6.4.  For example, Python 2.7.10 works well on Windows.
-
=== DrScheme ===
+
Mac OS X comes with Python 2.3 pre-installed, but the version you can download from python.org has better support for external libraries and a better version of IDLE.
-
There are many versions of Scheme out there. 6.001 used different ones in different places. In order for the code in this class to work, though, we need to standardize on one version of Scheme.
+
You can run the Python interpreter on Athena like this:
-
This class will be done entirely using the [http://www.drscheme.org DrScheme] environment. You may have used DrScheme to do your projects in 6.001. In fact, DrScheme supports several dialects of the Scheme language, so the one you should pick is called "PLT Textual".
+
<code>
 +
  add python
 +
  idle &
 +
</code>
-
You should '''not''' use 6.001 Scheme or MIT Scheme to do the problem sets! If you do, you will get strange error messages, and the TAs will not be able to help you.
+
You can, of course, edit Python files in a plain-text editor, and run them on Athena like this:
-
You run DrScheme on Athena like this:
+
<code>
 +
  add python
 +
  python filename.py
 +
</code>
-
add drscheme
+
=== Getting the lab code ===
-
drscheme &
+
-
You can also [http://www.drscheme.org download it] to run it on your own computer.
+
;If you are working on Athena
 +
:The code for the labs is in the 6.034 locker. You can get lab 0 like this:
-
=== Getting the problem set code ===
+
<code>
 +
  attach 6.034
 +
  mkdir -p ~/6.034-labs/lab0/
 +
  cp -R /mit/6.034/www/labs/lab0/* ~/6.034-labs/lab0/
 +
</code>
 +
:Then, you can edit the code in your ~/6.034-labs/lab0 directory. That way, you won't need to do anything to submit the code - it will already be in the right place.
 +
:You can ssh into linux.mit.edu to work on Athena from a different computer (thank you SIPB)
 +
;If you are working on another computer with Python
 +
:Create a folder for the lab.
 +
:Download this file and extract it: http://web.mit.edu/6.034/www/labs/lab0/lab0.zip
-
;If you are working on Athena
+
You can also view the code without downloading it: http://web.mit.edu/6.034/www/labs/lab0/
-
:The code for the problem sets is in the 6.034 locker. You can get problem set 0 like this: <code>cp /mit/6.034/psets-f06/ps0/* ~/6.034-psets/ps0/</code>
+
 
-
:Then, you can edit the code in your ~/6.034-psets/ps0 directory. That way, you won't need to do anything to submit the code - it will already be in the right place.
+
=== Getting the Submit Key ===
-
;If you are working on another computer with DrScheme
+
 
-
:Create a folder for the problem set.
+
In order to submit your labs, you must download a "key.py" file and place it in the same directory as your labs. The "key.py" file contains login information used by the tester to identify you personally to the testing server.  You can continue using the same key throughout the semester unless you change your Athena password, in which case you may need to download a new "key.py".
-
:Download this file and extract it: http://web.mit.edu/6.034/psets-f06/ps0/ps0.zip
+
-
You can also view the code without downloading it: http://web.mit.edu/6.034/psets-f06/ps0/
+
You can download a key from https://ai6034.mit.edu/labs . Make sure that you have an up-to-date [http://ca.mit.edu MIT Certificate] before going to this page.  Note that the page doesn't currently work in Apple's Safari Web browser (because of a bug in Safari regarding certificates); use Firefox/Chrome instead, or download the file on Athena.
=== Answering questions ===
=== Answering questions ===
-
The main file of this problem set is called <code>ps0.scm</code>. Open that file in DrScheme. The file contains a lot of (define) statements that you need to fill in with your solutions.
+
The main file of this lab is called <code>lab0.py</code>. Open that file in IDLE. The file contains a lot of incomplete statements that you need to fill in with your solutions.
-
The first thing to fill in is a multiple choice question. The answer should be extremely easy. Many problem sets will begin with some simple multiple choice questions to make sure you're on the right track.
+
The first thing to fill in is a multiple choice question. The answer should be extremely easy. Many labs will begin with some simple multiple choice questions to make sure you're on the right track.
=== Run the tester ===
=== Run the tester ===
-
Every problem set comes with a file called <code>tester.scm</code>. This file checks your answers to the problem set. For problems that ask you to provide a function, the tester will test your function with several different inputs and see if the output is correct. For multiple choice questions, the tester will tell you if your answer was right. Yes, that means that you never need to submit wrong answers to multiple choice questions.
+
Every lab comes with a file called <code>tester.py</code>. This file checks your answers to the lab. For problems that ask you to provide a function, the tester will test your function with several different inputs and see if the output is correct. For multiple choice questions, the tester will tell you if your answer was right. Yes, that means that you never need to submit wrong answers to multiple choice questions.
-
* Open the file <tt>tester.scm</tt> in DrScheme and click "Run".
+
The tester has two modes: "offline" mode (the default), and "online" or "submit" mode. The former runs some basic, self-contained internal tests on your code. It can be run as many times as you would like.  The latter runs some more tests, some of which may be randomly generated, and uploads your code to the 6.034 grader for grading.
-
* It should output the results of a lot of tests in your DrScheme window. You should pass one test (your answer to the multiple choice question), and fail the others, because you haven't solved those problems yet.
+
-
You should run the tester early and often, and definitely make sure you pass all the tests before you submit a problem set. Think of it as being like the "Check" button from 6.001. It makes sure you're not losing points unnecessarily.
+
You can run the online tester as many times as you want. If your code fails a test, you can submit it and try again. Because you always have the opportunity to fix your bugs, you can only get a 5 on a problem set if it passes all the tests. If your code fails a test, your grade will be 4 or below.
-
== Scheme programming ==
+
==== Using IDLE ====
-
Now it's time to write some Scheme.
+
 
 +
If you are using IDLE, or if you do not have easy access to a command line (as on Windows), IDLE can run the tester.
 +
 
 +
Open the <tt>tester.py</tt> file and run it using Run Module or F5.  This will run the offline tests for you.  When the offline tests pass (or when you're up against a deadline, or when you have questions for the staff) you can
 +
 
 +
  test_online()
 +
 
 +
to submit your code and run the online tests.
 +
 
 +
In fact, it will run the submission and online test just as soon as you pass the offline tests, saving you a few keystrokes.
 +
 
 +
You should run the tester (and submit!) early and often. Think of it as being like the "Check" button from 6.01. It makes sure you're not losing points unnecessarily.  Submitting your code makes it easy for the staff to look at it and help you.
 +
 
 +
==== Using the command line ====
 +
 
 +
If you realize just how much emacs and/or the command line rock, then you can open your operating system's Terminal or Command Prompt, and <code>cd</code> to the directory containing the files for Lab 0. Then, run:
 +
 
 +
<pre>python tester.py</pre>
 +
 
 +
to run the offline tester, and
 +
 
 +
<pre>python tester.py submit</pre>
 +
 
 +
to submit your code and run the online tester.
 +
 
 +
You should run the tester (and submit!) early and often. Think of it as being like the "Check" button from 6.01. It makes sure you're not losing points unnecessarily.  Submitting your code makes it easy for the staff to look at it and help you.
 +
 
 +
== Python programming ==
 +
Now it's time to write some Python.
=== Warm-up stretch ===
=== Warm-up stretch ===
Write the following functions:
Write the following functions:
-
* <tt>(cube n)</tt>, which takes in a number and returns its cube. For example, (cube 3) => 27.
+
* <tt>cube(n)</tt>, which takes in a number and returns its cube. For example, cube(3) => 27.
-
* <tt>(factorial n)</tt>, which takes in a non-negative integer ''n'' and returns ''n!'', which is the product of the integers from 1 to ''n''. (0! = 1 by definition.)
+
* <tt>factorial(n)</tt>, which takes in a non-negative integer ''n'' and returns ''n!'', which is the product of the integers from 1 to ''n''. (0! = 1 by definition.)
-
* <tt>(count-pattern pattern lst)</tt>, which counts the number of times a certain pattern of symbols appears in a list, including overlaps. So <tt>(count-pattern '(a b) '(a b c e b a b f))</tt> should return 2, and <tt>(count-pattern '(a b a) '(g a b a b a b a))</tt> should return 3.
+
::We suggest that you should write your functions so that they raise nice clean errors instead of dying messily when the input is invalid. For example, it would be nice if factorial rejected negative inputs right away; otherwise, you might loop forever. You can signal an error like this: <code>raise Exception, "factorial: input must not be negative"</code>
 +
::Error handling doesn't affect your lab grade, but on later problems it might save you some angst when you're trying to track down a bug.
 +
* <tt>count_pattern(pattern lst)</tt>, which counts the number of times a certain pattern of symbols appears in a list, including overlaps. So <tt>count_pattern( ('a', 'b'), ('a', 'b', 'c', 'e', 'b', 'a', 'b', 'f'))</tt> should return 2, and <tt>count_pattern(('a', 'b', 'a'), ('g', 'a', 'b', 'a', 'b', 'a', 'b', 'a'))</tt> should return 3.
=== Expression depth ===
=== Expression depth ===
One way to measure the complexity of a mathematical expression is the
One way to measure the complexity of a mathematical expression is the
-
depth of the expression describing it in Scheme. Write a program that
+
depth of the expression describing it in Python lists or tuples. Write a program that
finds the depth of an expression.
finds the depth of an expression.
For example:
For example:
-
* <tt>(depth 'x)} => 0</tt>
+
* <tt>depth('x') => 0</tt>
-
* <tt>(depth '(expt x 2)) => 1</tt>
+
* <tt>depth(('expt', 'x', 2)) => 1</tt>
-
* <tt>(depth '(+ (expt x 2) (expt y 2))) => 2</tt>
+
* <tt>depth(['+', ['expt', 'x', 2], ['expt', 'y', 2]]) => 2</tt>
-
* <tt>(depth '(/ (expt x 5) (expt (- (expt x 2) 1) (/ 5 2)))) => 4</tt>
+
* <tt>depth(('/', ('expt', 'x', 5), ('expt', ('-', ('expt', 'x', 2), 1), ('/', 5, 2)))) => 4</tt>
 +
 
 +
 
 +
Note that you can use the built-in Python "isinstance()" function to determine whether a variable points to a list of some sort.  "isinstance()" takes two arguments: the variable to test, and the type (or list of types) to compare it to.  For example:
 +
 
 +
<code><pre>
 +
>>> x = [1, 2, 3]
 +
>>> y = "hi!"
 +
>>> isinstance(x, (list, tuple))
 +
True
 +
>>> isinstance(y, (list, tuple))
 +
False
 +
</pre></code>
=== Tree reference ===
=== Tree reference ===
[[Image:Tree.gif|float|right]]
[[Image:Tree.gif|float|right]]
-
Your job is to write a procedure that is analogous to list-ref, but for trees. This "tree-ref" procedure will
+
Your job is to write a procedure that is analogous to list referencing, but for trees. This "tree_ref" procedure will
take a tree and an index, and return the part of the tree (a leaf or a subtree) at that index. For trees, indices
take a tree and an index, and return the part of the tree (a leaf or a subtree) at that index. For trees, indices
-
will have to be lists of integers. Consider the tree in Figure 1, represented by this Scheme list: <code>(((1 2) 3) (4
+
will have to be lists of integers. Consider the tree in Figure 1, represented by this Python tuple: <code>(((1, 2), 3), (4, (5, 6)), 7, (8, 9, 10))</code>
-
(5 6)) 7 (8 9 10))</code>
+
-
To select the element 9 out of it, we’d normally need to do something like <code>(second (fourth tree))</code>. Instead, we’d prefer to do <code>(tree-ref tree (list 3 1))</code> (note that we’re using zero-based indexing, as
+
To select the element 9 out of it, we’d normally need to do something like <code>tree[3][1]</code>. Instead, we’d prefer to do <code>tree_ref(tree, (3, 1))</code> (note that we’re using zero-based indexing, as
-
in list-ref, and that the indices come in top-down order; so an index of (3 1) means you should take the fourth
+
in list-ref, and that the indices come in top-down order; so an index of (3, 1) means you should take the fourth
branch of the main tree, and then the second branch of that subtree). As another example, the element 6
branch of the main tree, and then the second branch of that subtree). As another example, the element 6
-
could be selected by <code>(tree-ref tree (list 1 1 1))</code>.
+
could be selected by <code>tree_ref(tree, (1, 1, 1))</code>.
-
Note that it’s okay for the result to be a subtree, rather than a leaf. So <code>(tree-ref tree (list 0))</code>
+
Note that it’s okay for the result to be a subtree, rather than a leaf. So <code>tree_ref(tree, (0,))</code>
-
should return <code>((1 2) 3)</code>.
+
should return <code>((1, 2), 3)</code>.
-
== Matching ==
+
== Symbolic algebra ==
-
Throughout the semester, you will need to understand, manipulate, and extend complex algorithms imple-
+
Throughout the semester, you will need to understand, manipulate, and extend complex algorithms implemented in Python. You may also want to write more functions than we provide in the skeleton file for a lab.
-
mented in Scheme. You may also want to write more functions than we provide in the skeleton file for a
+
-
problem set.
+
-
In this problem, you will work with a small matcher system. If you have trouble with this problem, you
+
In this problem, you will complete a simple computer algebra system that reduces nested expressions made of sums and products into a <b>single sum of products</b>. For example, it turns the expression <code>(2 * (x + 1) * (y + 3))</code> into <code>((2 * x * y) + (2 * x * 3) + (2 * 1 * y) + (2 * 1 * 3))</code>. You could choose to simplify further, such as to ((2 * x * y) + (6 * x) + (2 * y) + 6)), but it is not necessary.
-
will have a hard time learning important course material by means of problem sets.
+
-
In this problem, you will work with the simple matcher in the <code>match.scm</code> file. You job will be to extend
+
-
the matcher program with a new type of variable that can match sequences as well as single elements in a
+
-
list.
+
-
The matcher is given two lists as input, one (the pattern) contains variables and the other (the data)
+
This procedure would be one small part of a symbolic math system, such as the integrator presented in Monday's lecture. You may want to keep in mind the principle of reducing a complex problem to a simpler one.
-
does not, and it returns a list of variable bindings that would make the pattern match the data. We denote
+
-
simple variables by a list whose first element is the symbol <code>?</code> and whose second element is the name of the
+
-
variable, e.g. <code>(? x)</code> represents the variable ''x''. For example:
+
-
* (match '(a (? x) c) '(a b c)) &rarr; (bindings (x b))
+
An algebraic expression can be simplified in this way by repeatedly applying the associative law and the distributive law.
 +
;Associative law
 +
:((a + b) + c) = (a + (b + c)) = (a + b + c)
 +
:((a * b) * c) = (a * (b * c)) = (a * b * c)
 +
;Distributive law
 +
:((a + b) * (c + d)) = ((a * c) + (a * d) + (b * c) + (b * d))
-
Note that the return value is a list, whose car is the symbol bindings and whose cdr is a list of lists
+
The code for this part of the lab is in <code>algebra.py</code>. It defines an abstract <code>Expression</code> class, <code>Sum</code> and <code>Product</code> expressions, and a method called <code>Expression.simplify()</code>. This method starts by applying the associative law for you, but it will fail to perform the distributive law. For that it delegates to a function called <code>do_multiply</code> that you need to write. Read the documentation in the code for more details.
-
(possibly null). The first element of the component lists is the name of a variable and the second element of
+
-
these lists is the matched value. Here are some more examples of successful matches:
+
-
* (match '(a ((? x) c) d) '(a (b c) d)) &rarr; (bindings (x b))
+
This exercise is meant to get you familiar with Python and using it to solve
-
* (match '(a ((? x) c) (? y)) '(a (b c) c)) &rarr; (bindings (y c) (x b))
+
an interesting problem. It is intended to be algorithmically straightforward.
-
* (match '(a (b c) d) '(a (b c) d)) &rarr; (bindings)
+
You should try to reason out the logic that you need for this function
 +
on your own.  If you're having trouble expressing that logic in Python,
 +
though, don't hesitate to ask a TA.
-
If a variable with the same name occurs more than once in a pattern, it must match equal parts of the
+
Some hints for solving the problem:
-
data:
+
* How do you use recursion to make sure that your result is thoroughly simplified?
 +
* In which case should you ''not'' recursively call <code>simplify()</code>?
-
* (match '(a (? x) c (? x) e) '(a b c b e)) &rarr; (bindings (x b))
+
== Survey ==
-
* (match '(a (? x) c (? x) e) '(a b c d e)) &rarr; ()
+
-
* (match '(a (? x) c (? y) e) '(a b c d e)) &rarr; (bindings (y d) (x b))
+
-
The code also supports nameless variables <code>(? _)</code>, which simply match but whose matching values are
+
We are always working to improve the class. Most labs will have at least one survey question at the end to help us with this. Your answers to these questions are purely informational, and will have no impact on your grade (as long as you answer the ones that are required).
-
not returned and not constrained to be equal:
+
-
* (match '(a (? ) c (? ) e) '(a b c b e)) &rarr; (bindings)
+
-
* (match '(a (? ) c (? ) e) '(a b c d e)) &rarr; (bindings)
+
-
A simple variable can match any component of the data list, but it will not match a sublist of the data:
+
Please answer these questions at the bottom of your <tt>lab0.py</tt> file:
-
* (match '(a (? x) d) ’(a b c d)) &rarr; ()
+
-
What we want to do in this problem is extend the matcher to handle a new class of variable – called
+
* <tt>PYTHON_EXPERIENCE</tt>: How much experience do you have with Python?
-
"segment variables" – that can match sublists of the data:
+
:: A. No experience (never used Python before this semester)
-
* (match '(a (* x) d) '(a b c d)) &rarr; (bindings (x (b c)))
+
:: B. Beginner (just started learning, e.g. took 6.0001)
-
* (match '(a (* x) d) '(a d)) &rarr; (bindings (x ()))
+
:: C. Intermediate (have used Python in a couple classes/projects)
-
* (match '((* x) a (* x) c) '(a c)) &rarr; (bindings (x ()))
+
:: D. Proficient (have used Python for multiple years or in many classes/projects)
-
* (match '((* x) a (* x) c) '(b a b c)) &rarr; (bindings (x (b)))
+
:: E. Expert (could teach a class on Python)
-
* (match '((* x) a (* x) c) '(b a d c)) &rarr; ()
+
-
* (match '((a (* x)) d e) '((a b c) d e)) &rarr; (bindings (x (b c)))
+
-
Note that the binding value of a segment variable is always a list, possibly a null list. Therefore,
+
* <tt>NAME</tt>: What is your name? (string)
-
* (match '((? x) a (* x) c) '(b a b c)) &rarr; ()
+
-
Because (* x) can not be bound to ’b, it must be bound to a list, such as ’(b).
+
* <tt>COLLABORATORS</tt>: Other than 6.034 staff, whom did you work with on this lab? (string, or empty string if you worked alone)
-
Note also that there is, in general, no unique assignment to the segment variables to produce a match.
+
* <tt>HOW_MANY_HOURS_THIS_LAB_TOOK</tt>: Approximately how many hours did you spend on this lab? (number or string)
-
We just want to produce some assignment if one exists.
+
-
Also, we treat the case of standalone segment variables that are not part of a list, that is <code>(match '(*
+
* (optional) <tt>SUGGESTIONS</tt>: What specific changes would you recommend, if any, to improve this lab for future years? (string)
-
x) ...)</code>, as immediate failures since it is not clear what it should mean. On the other hand, <code>(match '(?
+
-
x) ...)</code> always succeeds.
+
-
Your job is to extend the matcher to support segment variables. Most of the work has already been
+
== When you're done ==
-
done for you. What remains is to read and understand how the matcher works, then implement the missing
+
Remember to run the tester!  The tester will automatically upload your code to the 6.034 server for grading and collection.
-
functionality needed for the match-segment-variable function.
+
-
== Survey ==
+
== FAQ ==
 +
 
 +
It's quite possible that this lab -- or, in particular, the grader system -- will have issues that need to be fixed or things that need to be clarified.
 +
 
 +
If you have a question or a bug report, send an e-mail to [mailto:6.034-2015-support@mit.edu 6.034-2015-support@mit.edu].
 +
 
 +
 
 +
Q: When I submit to the online tester, it says I passed all the tests, but it shows my grade as 0.00.
 +
 
 +
A: Try downloading a new key.py file.
 +
 
 +
 
 +
Q: When I submit to the online tester, it hangs for a while and/or eventually prints a stack trace ending in '''httplib.BadStatusLine: ' ' '''
 +
 
 +
A: If you're using Windows, review the [[#Python|Python section]] and make sure you're using a compatible version of Python.  If that doesn't solve the problem, contact a TA.

Current revision


Note: As with all labs, you will need to have a key file in order to submit.


Contents

The purpose of this lab is to familiarize you with this term's lab system and to diagnose your programming ability and facility with Python. 6.034 uses Python for all of its labs, and you will be called on to understand the functioning of large systems, as well as to write significant pieces of code yourself.

While coding is not, in itself, a focus of this class, artificial intelligence is a hard subject full of subtleties. As such, it is important that you be able to focus on the problems you are solving, rather than the mechanical code necessary to implement the solution.

If Python doesn't come back to you by the end of this lab, we recommend that you seek extra help through the Course 6/HKN tutoring program, which matches students who want help with students who've taken and done well in a class. The department pays the tutor, and the program comes highly recommended.

Python resources

Some resources to help you knock the rust off of your Python:


Python

There are a number of versions of Python available. This course will use standard Python ("CPython") from http://www.python.org/. If you are running Python on your own computer, you should download and install Python 2.5, Python 2.6, or Python 2.7 from http://www.python.org/download/ . All the lab code will require at least version 2.3. Please note that our code is not designed to work with Python 3.

If you are using Windows: When run on Windows, Python versions 2.6.5 through 2.7.3 seem to be incompatible with our server. The recommended solution is to install a version of Python >= 2.7.4 or <= 2.6.4. For example, Python 2.7.10 works well on Windows.

Mac OS X comes with Python 2.3 pre-installed, but the version you can download from python.org has better support for external libraries and a better version of IDLE.

You can run the Python interpreter on Athena like this:

 add python
 idle &

You can, of course, edit Python files in a plain-text editor, and run them on Athena like this:

 add python
 python filename.py

Getting the lab code

If you are working on Athena
The code for the labs is in the 6.034 locker. You can get lab 0 like this:

 attach 6.034
 mkdir -p ~/6.034-labs/lab0/
 cp -R /mit/6.034/www/labs/lab0/* ~/6.034-labs/lab0/

Then, you can edit the code in your ~/6.034-labs/lab0 directory. That way, you won't need to do anything to submit the code - it will already be in the right place.
You can ssh into linux.mit.edu to work on Athena from a different computer (thank you SIPB)
If you are working on another computer with Python
Create a folder for the lab.
Download this file and extract it: http://web.mit.edu/6.034/www/labs/lab0/lab0.zip

You can also view the code without downloading it: http://web.mit.edu/6.034/www/labs/lab0/

Getting the Submit Key

In order to submit your labs, you must download a "key.py" file and place it in the same directory as your labs. The "key.py" file contains login information used by the tester to identify you personally to the testing server. You can continue using the same key throughout the semester unless you change your Athena password, in which case you may need to download a new "key.py".

You can download a key from https://ai6034.mit.edu/labs . Make sure that you have an up-to-date MIT Certificate before going to this page. Note that the page doesn't currently work in Apple's Safari Web browser (because of a bug in Safari regarding certificates); use Firefox/Chrome instead, or download the file on Athena.

Answering questions

The main file of this lab is called lab0.py. Open that file in IDLE. The file contains a lot of incomplete statements that you need to fill in with your solutions.

The first thing to fill in is a multiple choice question. The answer should be extremely easy. Many labs will begin with some simple multiple choice questions to make sure you're on the right track.

Run the tester

Every lab comes with a file called tester.py. This file checks your answers to the lab. For problems that ask you to provide a function, the tester will test your function with several different inputs and see if the output is correct. For multiple choice questions, the tester will tell you if your answer was right. Yes, that means that you never need to submit wrong answers to multiple choice questions.

The tester has two modes: "offline" mode (the default), and "online" or "submit" mode. The former runs some basic, self-contained internal tests on your code. It can be run as many times as you would like. The latter runs some more tests, some of which may be randomly generated, and uploads your code to the 6.034 grader for grading.

You can run the online tester as many times as you want. If your code fails a test, you can submit it and try again. Because you always have the opportunity to fix your bugs, you can only get a 5 on a problem set if it passes all the tests. If your code fails a test, your grade will be 4 or below.

Using IDLE

If you are using IDLE, or if you do not have easy access to a command line (as on Windows), IDLE can run the tester.

Open the tester.py file and run it using Run Module or F5. This will run the offline tests for you. When the offline tests pass (or when you're up against a deadline, or when you have questions for the staff) you can

 test_online()

to submit your code and run the online tests.

In fact, it will run the submission and online test just as soon as you pass the offline tests, saving you a few keystrokes.

You should run the tester (and submit!) early and often. Think of it as being like the "Check" button from 6.01. It makes sure you're not losing points unnecessarily. Submitting your code makes it easy for the staff to look at it and help you.

Using the command line

If you realize just how much emacs and/or the command line rock, then you can open your operating system's Terminal or Command Prompt, and cd to the directory containing the files for Lab 0. Then, run:

python tester.py

to run the offline tester, and

python tester.py submit

to submit your code and run the online tester.

You should run the tester (and submit!) early and often. Think of it as being like the "Check" button from 6.01. It makes sure you're not losing points unnecessarily. Submitting your code makes it easy for the staff to look at it and help you.

Python programming

Now it's time to write some Python.

Warm-up stretch

Write the following functions:

  • cube(n), which takes in a number and returns its cube. For example, cube(3) => 27.
  • factorial(n), which takes in a non-negative integer n and returns n!, which is the product of the integers from 1 to n. (0! = 1 by definition.)
We suggest that you should write your functions so that they raise nice clean errors instead of dying messily when the input is invalid. For example, it would be nice if factorial rejected negative inputs right away; otherwise, you might loop forever. You can signal an error like this: raise Exception, "factorial: input must not be negative"
Error handling doesn't affect your lab grade, but on later problems it might save you some angst when you're trying to track down a bug.
  • count_pattern(pattern lst), which counts the number of times a certain pattern of symbols appears in a list, including overlaps. So count_pattern( ('a', 'b'), ('a', 'b', 'c', 'e', 'b', 'a', 'b', 'f')) should return 2, and count_pattern(('a', 'b', 'a'), ('g', 'a', 'b', 'a', 'b', 'a', 'b', 'a')) should return 3.

Expression depth

One way to measure the complexity of a mathematical expression is the depth of the expression describing it in Python lists or tuples. Write a program that finds the depth of an expression.

For example:

  • depth('x') => 0
  • depth(('expt', 'x', 2)) => 1
  • depth(['+', ['expt', 'x', 2], ['expt', 'y', 2]]) => 2
  • depth(('/', ('expt', 'x', 5), ('expt', ('-', ('expt', 'x', 2), 1), ('/', 5, 2)))) => 4


Note that you can use the built-in Python "isinstance()" function to determine whether a variable points to a list of some sort. "isinstance()" takes two arguments: the variable to test, and the type (or list of types) to compare it to. For example:

>>> x = [1, 2, 3]
>>> y = "hi!"
>>> isinstance(x, (list, tuple))
True
>>> isinstance(y, (list, tuple))
False

Tree reference

float

Your job is to write a procedure that is analogous to list referencing, but for trees. This "tree_ref" procedure will take a tree and an index, and return the part of the tree (a leaf or a subtree) at that index. For trees, indices will have to be lists of integers. Consider the tree in Figure 1, represented by this Python tuple: (((1, 2), 3), (4, (5, 6)), 7, (8, 9, 10))

To select the element 9 out of it, we’d normally need to do something like tree[3][1]. Instead, we’d prefer to do tree_ref(tree, (3, 1)) (note that we’re using zero-based indexing, as in list-ref, and that the indices come in top-down order; so an index of (3, 1) means you should take the fourth branch of the main tree, and then the second branch of that subtree). As another example, the element 6 could be selected by tree_ref(tree, (1, 1, 1)).

Note that it’s okay for the result to be a subtree, rather than a leaf. So tree_ref(tree, (0,)) should return ((1, 2), 3).

Symbolic algebra

Throughout the semester, you will need to understand, manipulate, and extend complex algorithms implemented in Python. You may also want to write more functions than we provide in the skeleton file for a lab.

In this problem, you will complete a simple computer algebra system that reduces nested expressions made of sums and products into a single sum of products. For example, it turns the expression (2 * (x + 1) * (y + 3)) into ((2 * x * y) + (2 * x * 3) + (2 * 1 * y) + (2 * 1 * 3)). You could choose to simplify further, such as to ((2 * x * y) + (6 * x) + (2 * y) + 6)), but it is not necessary.

This procedure would be one small part of a symbolic math system, such as the integrator presented in Monday's lecture. You may want to keep in mind the principle of reducing a complex problem to a simpler one.

An algebraic expression can be simplified in this way by repeatedly applying the associative law and the distributive law.

Associative law
((a + b) + c) = (a + (b + c)) = (a + b + c)
((a * b) * c) = (a * (b * c)) = (a * b * c)
Distributive law
((a + b) * (c + d)) = ((a * c) + (a * d) + (b * c) + (b * d))

The code for this part of the lab is in algebra.py. It defines an abstract Expression class, Sum and Product expressions, and a method called Expression.simplify(). This method starts by applying the associative law for you, but it will fail to perform the distributive law. For that it delegates to a function called do_multiply that you need to write. Read the documentation in the code for more details.

This exercise is meant to get you familiar with Python and using it to solve an interesting problem. It is intended to be algorithmically straightforward. You should try to reason out the logic that you need for this function on your own. If you're having trouble expressing that logic in Python, though, don't hesitate to ask a TA.

Some hints for solving the problem:

  • How do you use recursion to make sure that your result is thoroughly simplified?
  • In which case should you not recursively call simplify()?

Survey

We are always working to improve the class. Most labs will have at least one survey question at the end to help us with this. Your answers to these questions are purely informational, and will have no impact on your grade (as long as you answer the ones that are required).

Please answer these questions at the bottom of your lab0.py file:

  • PYTHON_EXPERIENCE: How much experience do you have with Python?
A. No experience (never used Python before this semester)
B. Beginner (just started learning, e.g. took 6.0001)
C. Intermediate (have used Python in a couple classes/projects)
D. Proficient (have used Python for multiple years or in many classes/projects)
E. Expert (could teach a class on Python)
  • NAME: What is your name? (string)
  • COLLABORATORS: Other than 6.034 staff, whom did you work with on this lab? (string, or empty string if you worked alone)
  • HOW_MANY_HOURS_THIS_LAB_TOOK: Approximately how many hours did you spend on this lab? (number or string)
  • (optional) SUGGESTIONS: What specific changes would you recommend, if any, to improve this lab for future years? (string)

When you're done

Remember to run the tester! The tester will automatically upload your code to the 6.034 server for grading and collection.

FAQ

It's quite possible that this lab -- or, in particular, the grader system -- will have issues that need to be fixed or things that need to be clarified.

If you have a question or a bug report, send an e-mail to 6.034-2015-support@mit.edu.


Q: When I submit to the online tester, it says I passed all the tests, but it shows my grade as 0.00.

A: Try downloading a new key.py file.


Q: When I submit to the online tester, it hangs for a while and/or eventually prints a stack trace ending in httplib.BadStatusLine: ' '

A: If you're using Windows, review the Python section and make sure you're using a compatible version of Python. If that doesn't solve the problem, contact a TA.