Team Project: SLogo
Logo is the name for a philosophy of education and a continually evolving family of programming languages that aid in its realization. — Harold Abelson
Submitting Your Work
Use GIT to push your team's implementation to the master
branch of the provided, shared, slogo_teamNN
repository hosted in the course's Gitlab group.
As your submission for this project, use GIT to add
, commit
, and push
the following
doc
folder: all design documentation and any supporting images
src/main/java
folder: all project code
src/main/resources
folder: any images or program resource files
data
folder: all example program files
- top-level (no separate folder): project README, and otherwise no other files created by you
Your code is expected to follow the course coding conventions and follow Javadoc conventions.
Your team's project GIT repository must show many, purposeful, commits from all team members rather than just one or two large "kitchen sink" commits and marathon merging or redesign sessions. Specifically, we will be looking for deliberate attempts to regularly:
- integrate each other's work
- refactor code to improve its design
- test your functionality
We strongly suggest using the course's suggested GIT workflow for teams to manage this process.
Specifications
In teams, write a Java program from scratch using straight OpenJFX (without FXML), that provides an integrated development environment, IDE, for users to command a turtle to create drawings.
Implement a much simplified version of the original Logo programming language.
"Simple Logo", or SLogo, differs slightly to make it easier to parse but retains the features most commonly used by novice programmers. Your program must be able to properly run these example programs that use this simplified syntax. Builtin SLogo commands will be written in Java code but all of its other information will be read from an eXtensible Markup Language, XML, formatted file (the exact tags of this configuration file should be decided by your team), such as:
- canonical name
- alternate name variants (including in different languages) or those could be looked up in a properties file
- description
- example
- help documentation (such as parameters, return value, category, etc.) or those could be looked up in a reference file
- number of expected parameters
- implementing class name
While the exact User Interface for a SLogo IDE is up to your team to decide, it should help users experiment with and manage commands, building up complex programs from previously entered commands, and keep the turtle's visual representation appropriately updated. Specifically, it should also allow a user to:
- enter commands to the turtle interactively by entering text commands
- see the results of the turtle executing commands displayed visually
NOTE, the turtle starts in the center of the display which is considered (0, 0)
- see errors that result from entered commands in a user friendly way (i.e., not just printed to the console)
- see history of successful commands run previously
- see user-defined variables
- see user-defined commands
- set an image to use for the turtle (instead of the CSS style's default)
- set a background color for the turtle's display area (instead of the CSS style's default)
- set a color to use for the pen (instead of the CSS style's default)
- set the speed to animate the turtles' movement and turning (where the max speed does no animation, just displaying the final result)
NOTE, it is encouraged to also provide options to pause, step, restart, and reset the animation
- access help about available commands
NOTE, it must go beyond just linking to the assignment web page, such as using content from your XML data to make an organized reference page or integrated into the GUI like IntelliJ
- save the current user-defined commands and variables as well as load a file of commands, such as the given example programs
NOTE, it is encouraged to also provide the option to separately save the command history
- select from different languages used for the text displayed, including the language in which commands are understood — since Logo is used by children internationally (here are some example translations)
NOTE, this is most easily done before the main View is created (say on a "splash" or overview scene) because otherwise it requires actively resetting the text of every appropriate Node
already created
- select from different component styles (such as "dark" or "light" colors, Duke or UNC colors, small or larger fonts, etc.)
NOTE: this can be done before or after main View is created since changing the applied stylesheet has an immediate affect on all Node
s in the Scene
Your program must be tested using JUnit (with assertions both for typical situations and possible thrown Exceptions) to verify it works as intended. Additionally, use TestFX to simulate common user "actions" and verify the UI responds appropriately (including changing languages and styles) using JUnit assertions. 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 70% Line test coverage overall.
Deliverables
This project will be submitted in stages:
- Plan: plan your design for the project
- Test: thoroughly test initial part of the project
- Basic: build the "core" features of the project
- Change: extend the project by adding new features
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 simulations 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 using abstractions to remove dependencies on concrete classes. 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:
- Application Programmer's Interface (API). Change your focus from simply writing code that works to writing APIs, code that serves other parts of the program (other team members) and provides those parts with freedom to implement new features without regard to the internal workings of your code
- Model View Controller (MVC). Create a cleanly structured GUI that separates the view from model with controller(s) or observers that mediates the flow of information (including errors)
- Avoid hardcoded values. Move all "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, possibly using Java's
Optional
- Encapsulation. Key implementation details must be hidden such that they can be changed without impacting any other classes
- Interfaces. Be intentional about how you expect other classes to use your object by controlling its available methods
- Immutability. Be intentional about what data you expect to be modified by explicitly restricting what other classes can change, perhaps by using Records or interfaces
- Design Patterns. Find the right design to help you solve specific problems and adapt it to your specific situation taking into account its trade-offs
- Dependency Inversion Principle. Communicate between classes using abstractions, ensuring implementation details can more easily be changed, perhaps by using Lambda expressions
- Reflection. Minimally use Reflection to create objects from strings dynamically to avoid conditional chains, and perhaps to call methods dynamically as well
Additionally, the overall program should still be clearly divided into several packages: some that are "public", consisting primarily of abstractions that are used by other packages, and the rest "private", consisting primarily of concrete subclasses that are not imported or known about directly by other packages.
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.
- Application Programming Interface, or API, is a standard or contract for another class or program to access a class or program as a service, allowing programmers to create new applications of the original service. In general, APIs should be designed to be minimal but complete; powerful; consistent; hard to misuse; easy to extend; and lead others to write readable code well designed code. Thinking deliberately about each class' public methods as an API for others on your team can really improve how you approach the task of programming and design because it changes your perspective from simply trying to support specific features to trying provide a service that others can use but also extend. Thus API design is arguably the most critical part of designing a program, because it encourages you to create a collection of interconnected services that work together.
- Turtle Graphics was invented as part of the Logo programming language designed to teach programming to children by allowing them to learn programming by body syntonic prediction and reasoning and see the results by controlling 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 on a per expression basis and is available for languages such as the command line, Python, JavaScript in your Browser, and even Java (the command-line shell could also be considered such an environment). 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!).
As a dialect of Lisp, Logo is a powerful language for expressing programs. Although most of its complexity (and power) come from other elements than those that control the turtle, it is still amazing how expressive and compact it can be.
Individual Responsibilities when Working as a Team
This project 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
- regularly contributing clean code to the shared repository in reasonably sized chunks
- solving and coding at least one "interesting" design problem
- helping a teammate at least once by going above and beyond
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.
Resources
Here is an in browser Logo environment (used to power this interactive programming workshop).
For background and more complete information about logo consult these links:
Videos