6.031
6.031 — Software Construction
Spring 2022

Problem Set 0: Turtle Graphics

Part I (#0 – #4) due
before class Wednesday, February 2, 2022, 11:00 am

Alpha due
Monday, February 7, 2022, 10:00 pm
Code reviews due
Friday, February 11, 2022, 11:00 am
Beta due
Monday, February 14, 2022, 10:00 pm

Welcome to 6.031!

This course is about three essential properties of software:

Safe from bugsEasy to understandReady for change
Correct today and correct in the unknown future. Communicating clearly with future programmers, including future you. Designed to accommodate change without rewriting.

The purpose of this problem set is to:

  • introduce the tools we will use in 6.031, including TypeScript, VS Code, Mocha, and Git;
  • introduce the process for 6.031 problem sets;
  • and practice basic TypeScript and start using tools from the standard library.

You should focus in this problem set on writing code that is safe from bugs and easy to understand using the techniques we discuss in class.

You must install the required tools and complete Part I (problems 0 through 4) before class on Wednesday, February 2.


Part I

Problem 0: Install and set up

Read and complete the Getting Started guide. The guide will step through:

  • installing Node, TypeScript, VS Code, and Git
  • configuring Git
  • learning and practicing the basics of Git

You need to complete all the steps in the guide before you start working on this problem set.

Problem 1: Clone

This process will be identical for each problem set.

  1. Create your remote repository with the starting code for the problem set by visiting didit.mit.edu/6.031/sp22. Go to psets/ps0 and click the button to create your repository. You will only be able to create a repo after the course signup forms are processed and the problem set is announced, which happens after the first class meeting.

    • If you can’t create a repo after the ps0 announcement, you are not registered for 6.031. Contact the staff (how?) to check your status.

    • If you are a listener or not taking 6.031 for credit, you can’t create a repo. See instructions below to clone from a read-only remote.

  2. Open the terminal (Git Bash on Windows) and go to the directory (using cd) where you would like to store your code. For example, that might be a directory named Source in your home directory.

    If you are unfamiliar with using the command line, Getting Started step 6 introduces key commands like cd and mkdir.

  3. Clone your repo. You will access the remote repository over SSH from your laptop.

    Note: Getting Started step 7 has setup you must perform before using Git.

    Find your git clone command at the top of your psets/ps0 page on Didit. It is a long command that looks something like this:

    git clone ... git@github.mit.edu:6031-sp22/ps0-«username».git

    Copy this entire command, paste it into your terminal, and run it. The result should be a directory named ps0-«username» with the starting code for the problem set. Keep the terminal window open — you will also use it to commit your code.

    • If git clone says “does not appear to be a git repository” or “could not read from remote repository”, check your repository URL for typos. Make sure your repository is listed on Didit.

      Check that you can authenticate to github.mit.edu in the last part of Getting Started step 7.

    • If you are a listener or not taking 6.031 for credit, you can clone problem set repositories using a modified URL: after ps0, omit the dash-username. You will not be able to push to this repository, it’s a read-only remote.

  4. After cloning your repository, install its required packages:

    In your terminal, use cd to change directory into your clone:

    cd ps0-«username»

    Then run npm install to install the packages required by the problem set:

    npm install

    You should see something like “audited 138 packages” – the exact number may be different, but it should be much greater than 1. If you see “audited 1 package” instead, then you are probably in the wrong folder. Make sure you cd into your clone.

    You may see warning messages labeled “npm WARN”, which you can likely ignore.

    But if you see error lines labeled “npm ERR!”, then something is wrong. Get help.

    using Run pane in Visual Studio Code to run npm start
  5. Finally, open the project in VS Code so you can work on it:

    • MacOS: File → Open

    • Windows/Linux: File → Open Folder…

    Select the root directory of your clone (ps0-«username») by navigating to it and clicking Open. Your Explorer pane should now have PS0-«USERNAME» as the root folder, as shown on the right.

Problem 2: Collaboration policy

To check your understanding of the policy, answer these questions:

reading exercises

Standard library

I can import and use classes from the JavaScript/TypeScript standard library.

(missing explanation)

Online resources

(missing explanation)

I can read or post to the class Piazza forum while writing some part of my solution.

(missing explanation)

I can publicly post part of my solution online as part of a portfolio of code to show to recruiters.

(missing explanation)

Getting and giving help

I can write my solution while sitting near (or on a video call with) another person writing theirs.

(missing explanation)

I can write some part of my solution in lab or office hours.

(missing explanation)

I can get help from someone else while their own solution is visible to me or them.

(missing explanation)

I can get help from a friend who took the course last semester.

(missing explanation)

I can talk about ways to solve the problem set with another student in the class.

(missing explanation)

I can write my solution while sitting near (or on a video call with) another person writing theirs, talking about specific algorithmic steps to make sure we both got it.

(missing explanation)

Use of student course materials

I can show or send my solution to another student in the class.

(missing explanation)

I can look at someone else’s solution to get help writing part of my solution.

(missing explanation)

I can use someone else’s solution to check my own solution, for example by running their tests on my code.

(missing explanation)

My solution can include code that I wrote while taking this class in a previous semester.

(missing explanation)

At the end of every problem set, you will answer a few questions similar to these about how you collaborated on the assignment.

Problem 3: Turtle graphics and drawSquare

Logo is a programming language created at MIT that originally was used to move a robot around in space. Turtle graphics, added to the Logo language, allows programmers to issue a series of commands to an on-screen “turtle” that moves, drawing a line as it goes. Turtle graphics have also been added to many different programming languages, including Python, where it is part of the standard library.

In this problem set, we will be playing with a simple version of turtle graphics for TypeScript that contains a restricted subset of the Logo language:

  • forward(units)
    Moves the turtle in the current direction by units pixels. Following the original Logo convention, the turtle starts out facing up.
  • turn(degrees)
    Rotates the turtle by angle degrees to the right (clockwise).

You can see the definitions of these commands in turtle.ts.

Now look at the source code in turtlesoup.ts, in the src folder.

  1. Your first task is to implement drawSquare(turtle:Turtle, sideLength:number), using the two methods introduced above: forward and turn. The specification comment above drawSquare leaves several things unspecified, like which direction to turn, so those decisions are up to you as the implementer.

  2. Once you’ve implemented the method, go to the main method in turtlesoup.ts. This main method creates a new turtle and instructs the turtle to draw on screen. There should be a call to drawSquare already there, but commented out. Uncomment this call so that your drawSquare will be called when the code is run.

    Then run main. There are two ways to do it, which both do the same thing:

    • From the terminal, in your ps0-«username» folder, run:

      npm start

      using Run pane in Visual Studio Code to run npm start
    • From VS Code: open the Run pane with View → Run, and choose “npm start” from the dropdown at the top of the pane, as shown on the right. Then use Run → Start Debugging from the menubar. This will open a terminal pane inside VS Studio and run npm start there.

      using Run pane in Visual Studio Code to run npm start

      If your Run pane just has three big buttons on it, like the image shown on the right, then make sure you have ps0-«username» as the root folder in your Explorer pane, as described above.

  3. After npm start runs, you will see any output or errors from your program. If the program succeeds, the resulting drawing will be written to output.html, and a browser tab will pop up showing the drawing.

Problem 4: Commit and push your work so far

After you’ve finished implementing the drawSquare function, let’s do a first commit.

  1. First, in the terminal, change directory (cd) to your clone, and take a look around with

    git status

    which shows you files that have been created, deleted, and modified in the project directory. You should see turtlesoup.ts listed under “Changes not staged for commit.” This means Git sees the change, but you have not (yet) asked Git to include the change as part of your next commit.

  2. You can run the command

    git diff

    to see your changes. (Note: when the diff is more than one page long, use the arrow keys. Press q to quit the diff.)

  3. Before committing, files must be staged for commit. Staging a file is as simple as

    git add <filename>

    so use

    git add src/turtlesoup.ts

    to stage the file. You should also stage the test file if you’ve added more tests.

  4. In addition, it’s always a good idea to review your commits before committing to them. Run

    git status

    again to see that your changes are now listed under “Changes to be committed.”

    Now try running

    git diff

    and notice that those changes are no longer shown in the diff output!

    So instead use

    git diff --staged

    to see exactly what Git will record if you commit now.

  5. Ready? To perform the commit,

    git commit

    will actually commit the changes locally, after opening your default editor to allow you to write a commit message. Your message should be formatted according to the Git standard: a short summary that fits on one line, followed by a blank line and a longer description if necessary.

    If Git warns you about configuring your default identity or you can’t edit your commit message, you did not follow the instructions in the Getting Started guide. Getting Started step 7 has setup you must perform before using Git.

    Now run

    git status

    once more to see that your changes are no longer listed and that you are now ahead of origin/main by 1 commit.

  6. Use the command

    git lol

    to see the history of commits in your project. (git lol is not a misspelling; it is an alias for the git log command that we configured in Getting Started step 7.)

    Right now, the log should show three commits: an initial commit with the starting code, a commit when you created your problem set repo, and the commit you made just now.

    Important: only the local history has the new commit at this point; it is not stored in your remote repository. This is one important aspect where Git is different from centralized systems such as Subversion and CVS.

    Find the ID of the commit you just made (git lol shows it as a hexadecimal number like 3d60b25), and use it to view your changes again:

    git show <commit>

    You should see the changes you just made.

  7. In order to share the changes with your remote repository (which is the one we will be using for grading), you need to push to the remote repository, with

    git push origin main

    At this point, the remote repository on github.mit.edu now has the same history as your local repository. It is important to remember that we will be grading the history in the repository on github.mit.edu; if you forget to push, we won’t see your commits.

Didit: when you push your commit, the Didit system will run a subset of the autograder on your code. Didit clones its own copy of your code from what you’ve pushed to github.mit.edu, compiles it, and runs some tests.

Visit Didit after you push to see the report. Right now, all tests will fail since you’ve only implemented drawSquare and it has no public tests. As you work, and especially as a deadline approaches, it is your responsibility to check Didit’s build report and ensure that we can compile and run your code.

github.mit.edu: you can browse the contents of your remote repository by visiting github.mit.edu/​6031-sp22 or following links from Didit to github.mit.edu.


Part II

Problem 5: Drawing circles

For detailed requirements, read the specifications of each function to be implemented above its declaration in turtlesoup.ts.

Restrictions

In this problem set, you should only need to edit turtlesoup.ts. You should not change any of the method signatures (what’s a method signature?) in that file, or you risk receiving zero points on the problem set.

You are free to add new helper methods inside turtlesoup if you want, and you can add tests to turtlesoupTest if you want, but this isn’t required.

Don’t change any other TypeScript files or add new TypeScript files to this problem set.

  1. Implement chordLength, reading the specification comment above it carefully to understand what it should do. (You can also click this link to see the same specification on a web page.)

    There’s a simple formula for the length of a chord of a circle; try to derive it before searching the web.

  2. Run the public tests that we provided.

      chordLength
         acute angle, integer result
         right angle, decimal result
         obtuse angle, decimal result
    
      distance
        1) for p1.x = p2.x, p1.y != p2.y
        2) for p1.x != p2.x, p1.y != p2.y
        3) for p1.x = p2.x, p1.y = p2.y
    
    ...
    
      3 passing (20ms)
      9 failing
    
    ...                                           
    

    In 6.031, we use Mocha, a widely-adopted JavaScript testing library. We’ll see more about Mocha, and about testing in general, in an upcoming class. For now, let’s focus on running the provided tests against your implementation. By convention, Mocha tests are in a subfolder named test, and add Test or test to the name of the source file they are testing. So the public tests for this problem set are in test/turtlesoupTest.ts.

    To run the Mocha tests in turtlesoupTest, use npm test, which you can do one of two ways:

    • From the terminal, in your ps0-«username» folder: run npm test.

    • From VS Code: go to the Run pane, choose “npm test” from the dropdown menu, and run your program from the Run menu.

    If your implementation of chord­Length is correct, you should see green check marks next to the chord­Length tests in the list of results, as shown on the right. (You may have to scroll your terminal window upwards to see this.)

    The red lines in the remaining sections of the test report, and the “9 failed” in the summary at the bottom, indicates that those tests have failed. That shouldn’t surprise us, since the other tests are exercising methods we haven’t implemented yet. Once they are passing, all those tests will turn into green check marks!

  3. Try breaking your chord­Length implementation (make it return a wrong answer) and run the tests again.

      chordLength
        1) acute angle, integer result
        2) right angle, decimal result
        3) obtuse angle, decimal result
    
      distance
        4) for p1.x = p2.x, p1.y != p2.y
        5) for p1.x != p2.x, p1.y != p2.y
        6) for p1.x = p2.x, p1.y = p2.y
    
    ...
    
      0 passing (20ms)
      12 failing
    
      1) chordLength
           acute angle, integer result:
         Error: implement me!
          at chordLength (src/turtlesoup.ts:29:11)
          at Context.<anonymous> (test/turtlesoupT
          at processImmediate (node:internal/timer
    
      2) chordLength
           right angle, decimal result:
         Error: implement me!
          at chordLength (src/turtlesoup.ts:29:11)
          at Context.<anonymous> (test/turtlesoupT
          at processImmediate (node:internal/timer
    ...                                           
    

    The chordLength tests in the summary at the top should now be red. Each failing test has a number corresponding to a section below, with a brief explanation of what went wrong, and a stack trace. In the VS Code terminal, hovering over a filename in the stack trace turns it into a hyperlink, and Ctrl-clicking (or Command-clicking) will bring up the code for that stack frame. This is most useful for lines that correspond to your code; this stack trace will also contain lines for JavaScript libraries or Mocha itself, which are less useful to look at.

    • If hovering over a filename doesn’t underline it, then make sure you are in the Terminal pane of Visual Studio Code (not in the Debug Console pane, and not in an external terminal window).

    Try Ctrl or Command-clicking on one of the test/turtlesoupTest.ts lines in the stack trace, and look at the code for the test. On that line, you should see a call to your chord­Length implementation with particular values for its arguments, within a call to assertAlmostEqual() that checks whether your implementation’s return value was correct. A Mocha test generally has this form: it calls your implementation, then makes one or more assertions about the value that your implementation returned.

    Hover your mouse over assertAlmostEqual() to learn more about what this method does. Hovering over a class or method name is a good way to get a compact overview of its documentation in VS Code:

    function assertAlmostEqual(actual: number, expected: number, delta: number, message?: string): void

    Assert that two numbers are equal within a given error tolerance.
    @param actual — answer actually returned by the module being tested
    @param expected — answer expected by the test
    @param delta — actual is considered equal to expected if it’s within +/- delta
    @param message — optional message with extra information about this test case, to display when the assertion fails

  4. Enough breaking: fix your implementation so it’s correct again. Make sure the test passes with a green check .

    Passing the public Mocha tests we provide does not necessarily mean that your code is perfect. You need to review the function specifications carefully. In future problem sets, we’ll also expect you to write your own Mocha tests to verify your code.

  5. Implement drawApproximateCircle.

    Use your implementation of chordLength. To test this function, change the main method to call drawApproximateCircle and verify that you see what you expect.

Commit to Git. Once you’re happy with your implementations of these functions, commit and push! Committing frequently – whenever you’ve fixed a bug or added a working and tested feature – is a good way to use version control, and will be a good habit to have for your team projects. Pro tip: for short commit messages, you can skip the editor popup using git commit -m, e.g.:

git commit -m "implemented chordLength and drawApproximateCircle"

Problem 6: Calculating distances and points

  1. Implement distance.

    This function calculates the distance between two points, where the points are represented by the Point class defined in turtle.ts.

    Remember to run the Mocha tests.

  2. Implement findTriangleIncenter.

    This function finds a certain central point of a triangle called its incenter. There are several ways to solve this problem, which you can learn about on the web. You should use your distance method as appropriate.

  3. Implement findShortestPath.

    You should use your distance method as appropriate.

    The performance of your solution is not important, as long as it runs fast enough for testing purposes (less than a second on up to 5 points). Try a brute-force approach first, then optionally think about how to make it faster.

    For information on how to use JavaScript’s Array and Set types, look up Array and Set in the Mozilla Developer Network (MDN) library documentation.

  4. At this point, Mocha should be passing distanceTest, findTriangleIncenterTest and findShortestPathTest.

Commit to Git. Once you’re happy with your solutions for this problem, commit and push!

Problem 7: Personal art

Implement drawPersonalArt.

In this function, you have the freedom to draw a piece of art you wish, with some complexity and aesthetic appeal. Your work will be judged both on aesthetics and on the code used to draw it.

Your art should need more than a few lines of code, so just drawing a few lines or polygons is not sufficient. Use helper methods, loops, etc. rather than simply listing forward and turn commands.

For drawPersonalArt only, you may also use the color method of Turtle to change the pen color. You may only use the provided colors.

Here are some examples of the kinds of images you can generate procedurally with turtle graphics, though note that many of them use more commands than what we’ve provided here.

Modify the main method to see the results of your function.


Submitting

Make sure you commit AND push your work to your repository on github.mit.edu. We will use the state of your repository on github.mit.edu as of 10:00pm on the deadline date. When you git push, the continuous build system attempts to compile your code and run the public tests (which are only a subset of the autograder tests). You can always review your build results at didit.mit.edu/6.031/sp22.

Didit feedback is provided on a best-effort basis:

  • There is no guarantee that Didit tests will run within any particular timeframe, or at all. If you push code close to the deadline, the large number of submissions will slow the turnaround time before your code is examined.
  • If you commit and push right before the deadline, the Didit build does not have to complete in order for that commit to be graded.
  • Passing some or all of the public tests on Didit is no guarantee that you will pass the full battery of autograding tests — but failing them is almost sure to mean lost points on the problem set.

Grading

Your overall ps0 grade will be computed as approximately:
~50% alpha autograde + ~5% alpha manual grade + ~35% beta autograde + ~10% beta manual grade

The autograder tests will not change from alpha to beta.

Manual grading of the alpha may examine any part of the problem set. Manual grading of the beta may also examine any part, including how you addressed code review feedback.