Team Project: OOLALA
Computer Science is a science of abstraction, creating the right model for a problem and devising the appropriate mechanizable techniques to solve it. — A. Aho and J. Ullman
Specification
In teams, write a Java program from scratch using OpenJFX, following Google's Java Style Guide, that implements the following CompSci 101 level applications:
These applications may seem very different on the surface, but their small programming languages are based on the same syntax and operate by controlling one or more "turtles" that can draw by leaving a trail as they move. So your team should be able to write an Object-Oriented Language Architecture for Little Applications, OOLALA, that provides a common interpreter that allows users to enter small programs interactively that are evaluated and visualized differently.
While the exact User Interface for each program is up to your team to decide, they should all allow the user to:
- enter and run programs interactively
- display the results of executing the commands visually
- see errors that may result from entered commands in a user friendly way (i.e., not just printed to the console or crashing the program)
- load a program from a file
- save the current program to a file
- clear the environment back to its starting state
- see commands previously run and run them again by clicking on them (rather than having to copy/paste them by hand)
- set a color to use for the pen or turtle(s)
- set a background color for the display area
Any text displayed in the User Interface should be able to appear in at least two other languages (you can use Google Translate if no one on your team can do it). You are not required to change the language dynamically, since that would require calling methods like setText()
directly on each element. You are also not required to correspondly change the language in which application commands are understood, but it is encouraged.
Test your program using JUnit (with assertions both for typical situations and possible thrown Exceptions) to verify it works as intended. Generally, aim to create a test class for each of your concrete classes with at least two well-named tests for each non-trivial public
method (more than two are expected for complex methods) and try to achieve at least 75% Line
test coverage of each class.
Deliverables
This project will be submitted in stages:
- Basic: implement the basic, "core", parts of the project
- Complete: implement a complete, well designed, version of the project
CompSci Context
This project highlights the following interesting and foundational Computer Science concepts. You are not expected to write a general or complete version of any of these concepts, but learning about them may help provide a context to begin thinking about some design issues or connect your work in this course to the broader computing community.
- Turtle Graphics was invented as part of the Logo programming language designed to teach programming to children by allowing them to control a physical robot. Users could issue commands such as FORWARD 50 to make the robot actually move 50 steps or RIGHT 90 to make it turn ninety degrees. The turtle robot carried a pen to produce drawings on paper put down under the robot. The turtle, which has since moved on to the computer screen, has become Logo's most familiar feature. In fact, most modern languages and platforms have an implementation, including being the core of the current modern children's programming environment Scratch. Additionally, it has helped people think differently about teaching geometry, social science, and especially programming.
- Abstract Syntax Trees are the data structure underlying all programming languages, from HTML to JavaScript to Java, in which the leaves represent values in an expression and the internal nodes represent operations on those values. The inherent hierarchical nature of trees precisely captures operator precedence and provide a convenient mechanism for storing, traversing, and transforming expressions. Note that, unlike binary trees, each node of an Abstract Syntax Tree can have any number of children, modeling operators with one, two, or even arbitrary numbers of arguments.
- Parsing the tree's structure from a simple string requires knowing the set of separator characters (e.g., whitespace and semi-colon in Java) and recognizing the expected tokens in the separated strings and their relationship (e.g., Java keywords, operators, and parentheses). During the parsing process, tokens are converted into useful objects and separators are typically thrown out. An error is thrown if the input string contains structural errors (e.g., an incomplete expression or an unrecognized word). The resulting parsed commands will be evaluated to run the program (e.g., to control a "turtle" that can move, turn, and draw).
- The read-eval-print loop allows users to build their programs interactively and is available for languages such as the command line, Python, JavaScript in your Browser, and Java. In this way, the view sends a program to the model, which returns it as a set of commands for controlling the turtle (or its pen) that the view uses to display the results. So the two sides combine to receive, parse, and evaluate commands from the user, then displaying their results or reporting any errors encountered along the way (and not crashing!).
Design Specifications
The functionality features emphasize design goals, so your focus should be implementing them in such a way as to promote creating abstractions that generalize your core code, not simply as special cases added without a clear plan. Ideally, a well-designed program will make implementing new features easier so, when choosing a new feature to implement, look for something that fits into your design or refactor your code first to accommodate it. Specifically, your design should be thoughtful and intentional: clearly avoiding duplicate code structures and making it easy to add more of these kinds of applications without changing the existing code.
Adding functionality not related to an abstraction or resulting in poor code that diminishes your overall design efforts will not be rewarded. Specifically, the credit you receive for a functionality feature will be in proportion to how clearly it shows that your core classes are closed to modification while open to extension. Thus, a program with fewer features, but plenty of clear paths to easy expansion, is worth more than a program with many features but lacking clean code and good abstractions.
In addition to following the course Code Design Habits Checklist, your project design should clearly show the your progress learning the topics we have discussed so far in the course:
- Clean code. Write your code primarily for communication: to avoid duplication, to support your team mates, and so that it can be easily understood by others.
- Use multiple classes and multiple packages. Divide your code into several classes that each have an active, useful, purpose (i.e., non-get/set methods)
- Encapsulation: Create classes, based on their behavior rather than their state, to hide the each part's implementation decisions.
- Build abstractions. Create inheritance hierarchies to define common methods that can be implemented in multiple ways in separate concrete classes.
- Avoid hardcoded values. Move typical "magic" values into files, rather than compiled into your program, using resources, properties, and styles.
- Exceptions. Communicate errors in a thoughtful, intentional, manner rather than returning
null
or other error prone values.
- Separate Model/View.
Create a cleanly structured GUI that is separated from the model and what information (including errors) needs to be returned from the model.
- Design Principles. Structure the core of your project to reduce dependencies, making your designs more understandable, flexible, and maintainable.
Individual Responsibilities when Working as a Team
These projects requires steady, consistent, work — only by putting in consistent time each week will you see measurable progress and not have to pull "heroic" all-nighters.
Although this is a team project, everyone has individual responsibilities to the team that can be summed up as follows:
- actively participating in all team meetings
- contributing clean code to the main repository regularly in reasonably sized chunks
- solving at least one "interesting" design problem
- going above and beyond to help another team mate at least once during the project
Unfortunately conflicts are likely to occur, so please let the Teaching Team know as soon as possible — even if it has happened just once or twice since it is better to deal with the situation early rather than having a disaster at the end when little can be done to get back on track.