CS 2102 Homework Assignment #4 [ready!]

Assigned: Tuesday November 14, 2006, 10:00 AM
Due: Monday November 20, 2006, 4:00 PM                **** NOTE NEW TIME ****

Guidelines:

Now available.

The context for this homework assignment is still General Chemistry. For more details, read here. The challenge here is to extend our original concept from HW3 into a full, dynamic design case study.

Description

This assignment is going to be known as the "Linked List" exercise. To achieve success on this project, you are going to have to develop a solid awareness of the way in which objects can be linked together into various linked lists of different structures.

Note that you will also need to have a working PeriodicTable; you won't be graded on it. Either copy your one from HW3 or use the one posted by the Professor. For simplicity, just copy/add it into the package you are developing for HW4.

  1. [25 pts.] Given your experience on HW3 you are now charged with making a key modification to the Molecule class. Specifically, we do not want to be restricted with the arbitrary constraint imposed by the implementation using two arrays (one for Elements, and one for counts).

    You guessed it. Your challenge is to rewrite the implementation of Molecule (while keeping the interface nearly the same) to use linked lists. You will create a class ElementNode to be used when storing a linked list of Elements. Since Molecule is going to be the class that manages a list of ElementNode objects, there is no need to create a separate ElementList class.

    As with HW3, your Molecule class must provide the following methods:

    (a) public Molecule (Element e, int count) -- to create a Molecule consisting of the repetition of the given Element. Also define the public Molecule() constructor with no arguments to construct an empty molecule.
    (b) public String toString() -- to return a String representation of the Molecule.
    (c) public boolean add (Element e, int count) -- to add to the end of the Molecule description the repetition of the given element. Use this method to convert the Molecule H2 into H2O2 by calling add(eO, 2) where eO is an object representing the Oxygen element, to be added twice. Given molecule H202, you would create molecule H2O2H2 by calling add(eH, 2) where eH represents the Hydrogen element, to be added twice. The method is still a boolean (because you can then reuse test cases from HW3); note, however, that the add method should always return true.
    (d) public float getMass () -- same as HW3; return the total mass of the molecule
    (e) public boolean equals (Object o) -- Determine if two objects represent equivalent information.
    (f) public int hashCode() -- a fan favorite. Same as HW3.
    (g) public boolean isEmpty() -- determine if the molecule has any elements at all in its definition.

    Once this implementation is ready, then you can complete the class by providing the following remove method, new for this homework, to complete the dynamic behavior necessary for these objects.

    (h) public boolean remove (Element e, int count) -- remove the given number of Element atoms from the Molecule. For example, given molecule H2O2H2, the result of remove (eH, 3) is going to be O2H (i.e., from left to right the elements are removed) where eH represents the Hydrogen element. In particular, the result cannot be HO2. If a request is made to remove more atoms of a given Element than exist in the molecule, then the available elements are indeed removed, but false is returned; true shall only be returned if there were at least 'count' of the given element in the Molecule. For example, given H2O2H2, calling remove (eH, 5) will return false and leave the molecule as O2.

    Note that you should be able to reuse the JUnit test cases from HW3 (copy/paste them into the package). This shows the reusability of test cases is an important concern. Either use your own test cases, or grab them from the professor's solution. However, you will have to add some new test cases to cover the remove method.
     
  2. [30 pts.] Write a MoleculeList class that represents (not surprisingly) a list of molecules. Your MoleculeList class will define a MoleculeNode head to represent the first Molecule in the list. Note that each MoleculeNode class stores a value (the Molecule being represented in the list), a count (number of repetitions), and a reference to the next MoleculeNode object in the list.

    The count is used to represent the following list of molecules: P4O10 + 6H2O. That is, each molecule can have a repetition count that reflects the essential ratio of molecules (here, for each P4O10 molecule, there are 6 H2O molecules).

    You need to write the following methods in MoleculeList:

    (a) public boolean equals (Object o) -- determine whether a MoleculeList is equivalent to another MoleculeList. Note that the signature must be a parameter of type Object. The comparison between MoleculeList objects is left-to-right; thus the list "P4O10 + 6H2O" is not equal to "6H2O + P4O10"
    (b) public MoleculeList () -- create a MoleculeList object that initially represents an empty list.
    (c) public boolean add (Molecule m, int ct) -- add to the end of the MoleculeList the given Molecule with repetition ct. Thus the functionality is to append a MoleculeNode object to the end of the Molecule, which is different from the prepend methods we have been using in class. If the molecule already exists within the Molecule list, then you should simply increment the count of the corresponding MoleculeNode. Thus, given a MoleculeList object representing "P4O10 + 6H2O", the MoleculeList object will be altered to represent "3P4O10 + 6H2O" after the invocation of add (m, 2) where m refers to a molecule P4O10.

    (d) public boolean remove (Molecule m, int ct) -- remove the given number of Molecules from the Molecule list and return true on success. If the operation removes all instances of the given Molecule from the MoleculeList, then the MoleculeNode representing this Molecule must be removed (i.e., there should never be a MoleculeNode in a MoleculeList whose ct is zero). The operation must return false if there aren't enough molecules of the desired type to remove. The removal occurs left to right. So given the list "6H2O + P4O10", after remove(mH, 3)  where mH refers to the H2O molecule, the list will be "3H2O + P4O10".
    (e) public boolean isEmpty() -- determines if this list is empty, that is, has no MoleculeNode objects in its list.
    (f) public String toString()  -- output a String representation of a Molecule list, using "+" between each Molecule. For example "P4O10 + 6H2O" would be output as "P4O10 + 6H2O".

    For ease of use, you should define the following methods for MoleculeNode:

    (g) public String toString() -- Represent the MoleculeNode element (part of a MoleculeList) as a String.
    (h) public MoleculeNode(Molecule m, int ct) -- constructor to write.
     
  3. [20 pts.] Design a set of JUnit test cases to properly validate the design/implementation of the MoleculeList and MoleculeNode classes. There are a lot of cases to consider. Make sure you try to cover them all. I would start by writing some documentation that describes the full set of test cases you can think of, then begin writing them, one at a time.
     
  4. [25 pts.] Write an Equation class, which represents a chemical equation, such as "CH4 + 2O2 = CO2 + 2H2O." In this equation, the left-hand side is the MoleculeList representing "CH4 + 2O2" (in chemistry, this represents the mixture of methane gas with Oxygen), while the right-hand side is the MoleculeList representing "CO2 + 2H2O" (in chemistry, this represents the release of carbon dioxide with water. Note how this traditional hydrocarbon conversion explains the reason for the incredible amount of CO2 generated in our world).

    (a) Equation must have two instance variables to represent the left and right hand side of the equation.
    (b) public Equation (MoleculeList left, MoleculeList right)  -- the constructor for this class, which takes as input the given left-hand side and right-hand side.
    (c) public boolean equals (Object o) -- determine whether an Equation is equivalent to another Equation object by comparing the equality of left- and right-hand MoleculeList objects.

    For this class, the most complex method you are to write is the following:

    (d) public boolean isBalanced() -- determine if the two sides of the equation are balanced in terms of the total number of atoms of each Element present. Thus, for example, the equation "CH4 + 2O2 = CO2 + 2H2O" balances because the left-hand side ("CH4 + 2O2") contains 1 Carbon (C) atom, 4 Hydrogen (H) atoms, and 4 Oxygen (O) atoms while the right-hand side ("CO2 + 2H2O") has the similar count.

    The isBalanced() method requires some thought. I would try the following algorithm:

     
    Input: MoleculeList m1 and m2

    Output: true if the same number of elements exist in list m1 and m2; false otherwise

    Approach:

    1. Create new MoleculeList target
    2. For every MoleculeNode m in list m1
           For every Element e in molecule m
              add to target Element e with the proper repetition count

    3. For every MoleculeNode n in list m2
           For every Element f in molecule n
              try to remove from target Element f with the proper repetition count
                if unable to remove, then molecule lists do not contains same # of atoms

    4. If target is once again an empty MoleculeList, then the two lists m1 and m2 must have originally contained the exact same number of Elements. So the equation is balanced.

    (e) public String toString() -- returns a String representation of an Equation. Thus for the Equation object represented by CH4 + 2O2 = CO2 + 2H2O, the String representation would be "CH4 + 2O2 = CO2 + 2H2O". Yes, there are extra spaces around the '+' and '=' characters.

    You will need to provide a set of JUnit test cases for the Equation class. Place them in a class called EquationTest.

     

All classes must be fully documented, according to the JavaDoc standard introduced in class and used throughout all class examples.

Extra questions (ungraded) may appear here.

Advanced

  1. Make MoleculeList equals(MoleculeList ml) support associativity. Thus it is certainly the case that MoleculeList m1+m2 should be equal to m2+m1, but the base functionality provided by this assignment does not require this.  Make it so.
  2. Hard, Interesting problem: Write a balance method for Equation that tries to balance the chemical equation in the left-hand side and the right-hand side. Thus, given a left-hand side of "CH4+O2" and a right-hand side of "CO2+H2O", this method would attempt to compute the proper match, which is "CH4+2O2 = CO2+2H2O".

Deliverables

Your goal is to turnin the Project files by Monday November 20th at 4:00 PM  Further details will be posted HERE showing the preferred means of uploading your solution to the TAs.

Please be aware that no late homeworks will be accepted. This means that we will grade as zero any homework not submitted by the above turnin means.


Notes

  1. [11/16/06 8:56 PM] Clarified that MoleculeList needs a toString() method
  2. [11/16/06 12:43 AM] Clarifications to Molecule.add() and Molecule.remove()
  3. [11/08/06 1:43 AM] Guidelines reviewed and ready to go.
  4. [11/08/06 9:27 PM] Homework 4 to be posted here.

©2006 George T. Heineman