Lab 0 2015

From 6.034 Wiki

Revision as of 22:16, 4 September 2008 by RobSpeer (Talk | contribs)
Jump to: navigation, search
  • Released: Thursday, September 4
  • Due: Friday, September 12

__NUMBERS__

Contents

The purpose of this lab is to familiarize you with this term's lab system and to serve as a diagnostic for 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 from http://www.python.org/download/ . All the lab code will require at least version 2.3.

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

Note that "idle" does not currently run on Solaris Athena machines; the current Athena Solaris version of Python is too old to support it. In general, we recommend that you use Linux Athena when possible. We will support Solaris machines, but you'll probably have a better experience running on your own personal computer or on Linux Athena machines.

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.
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 download a key from https://6.034.scripts.mit.edu:444/fall08/tester/ . 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 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 the command line

Working from a command line is probably the easiest way to run the tester. 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 run the online tester and submit your code.

You should run the tester early and often. Think of it as being like the "Check" button from 6.01. It makes sure you're not losing points unnecessarily.

Using the Python prompt

You might find it difficult to run Python from the command line on your system (especially on Windows). In that case, you can also use the Python prompt to run the tester.

Assuming that your Python session is running from the same directory as your code, you run the offline tester as follows:

>>> from tester import *
>>> test_offline()

Similarly, you run the online tester with test_online().

Warning: Most Python interpreters will not reload code once it is imported, even if you change the code. You will not be able to test changes to your code until you restart the interpreter. We recommend using the command line.

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. 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.

Please fill in the answers to the following questions in the definitions at the end of lab0.py:

  • When did you take 6.01?
  • How many hours did 6.01 projects take you?
  • How well do you feel you learned the material in 6.01?
  • How many hours did this lab take you?

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.

Questions? Issues?

It's quite likely that this lab -- or, in particular, the grader system -- will have issues that need to be fixed or things that need to be clarified. After all, we have never done this in Python before, and we have also never had a grader with instant feedback before.

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

Errata

Before 5 PM on Thursday, algebra.py contained some syntax that would only work in Python 2.4 and later. You can redownload the code if you need it to work on Python 2.3.

Before 6 PM on Thursday, the offline tester claimed to be expecting a string such as "1" as the answer to the multiple choice question; it actually expected just the number. The tester has been updated to accept either.

The directions previously said that you could test through IDLE with the functions offline_tester() and online_tester(). The functions are actually named test_offline() and test_online().

Personal tools