Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

In this assignment, you will enter, store, and retrieve information about ships. You have been provided with a JavaFX GUI, a JUnit test file, and

In this assignment, you will enter, store, and retrieve information about ships. You have been provided with a JavaFX GUI, a JUnit test file, and an interface file that will guide you in developing the application. (Note: the information about each ship is not exactly as the maritime experts would state it. Follow these requirements instead.)

Operation:

When the user starts the application, the following window will be presented (JavaFX GUI provided):

The user will select a radio button specifying which type of ship they wish to create. The ship type text field will be pre-populated, but the user will type in the Ships name and year built, and for a cargo ship, the tonnage, or for a cruise ship, the number of passengers.

If the user selects the Warship radio button, another set of radio buttons will be displayed corresponding to six categories of warship. If the user decides to enter a general warship (i.e., not one of the six sub-types), they are presented with appropriate textboxes.

If the user decides to enter one of the six sub-categories of warships by selecting a radio button, they will be provided with a pre-populated ship type and appropriate text fields to fill in.

In any of the above cases, the user will then select the Add a Ship button to create an instance of the specified ship and add it to the ShipRegistry arraylist. If the user wishes to return to the radio-buttons for the three class of ships, they can select Reset the Ship Types.

To present a window showing the current ships, the user should select Display Ships. The ships should be displayed in sorted order, by the alphabetic order of the ship name.

To read from a file, select the Read File button. The user will be presented with a file explorer from which they can select an input file. If the file is correctly formatted, each line will become a ship added to the ShipRegistry. Similarly, to write the current ShipRegistry to a file, the user selects Write Ships.

Specifications

General - Write a Java program to allow the user to enter information about a ship, add it to a registry, write the ship information to a file, and read the information into the registry.

Create an abstract class called Ship with private fields name and year of type String, and type of ShipType, and public getters and setters for each. The field name represents the name of the ship, year is the year commissioned, and type is a string that represents one of the enumeration values below.

Data Elements: Create three classes that inherit from Ship: CargoShip, CruiseShip, and WarShip. Instances of WarShip will be further refined into five types, but will all be WarShip objects.

Create an enumeration class named ShipType.java that has the following values: CARGO, CRUISE, WARSHIP, CARRIER, CRUISER, DESTROYER, MINE_SWEEPER, and SUBMARINE. These categories are meant to represent the following:

CARGO a merchant ship carrying cargo

CRUISE a passenger ship

WARSHIP a general warship, which is not further refined by the following categories (we will record guns, torpedoes, and aircraft, although older warships only had guns)

CARRIER an aircraft carrier

CRUISER a cruiser (while cruisers have sophisticated electronic and sonar equipment, missile launchers, etc, which define them, we will simplify them by just recording a number of guns)

DESTROYER a destroyer (while destroyer have torpedo launchers, missile launchers, depth charges, and sophisticated electronic and sonar equipment, etc, we will simplify them by just recording a number of guns)

MINE_SWEEPER a counter-mine ship (while mine-sweepers have sophisticated electronics, sonar, other counter-mine equipment, we will simplify them by just recording a number of guns)

SUBMARINE a submarine (while modern submarines have missile launch capability, we will simplify them by just recording a number of torpedo launchers)

Create a Data Manager class called ShipRegistry that implements ShipRegistryInterface. It will contain an Arraylist which holds Ship objects (Cargo, Cruise, and Warship all extending Ship). It will have methods required by the ShipRegistryInterface, i.e., addShip, getShips, getShipDescriptions, getWarshipDescriptions, readFile, and writeFile.

Create a toString method for each ship class that will return a String describing the ships name, year commissioned, and type, and the following field or fields depending on ship type. For each ship type, the fourth and subsequent fields will be:

CARGO number of tons of cargo

CRUISE number of passengers

WARSHIP number of guns, number of torpedo launchers, and number of aircraft

CARRIER number of aircraft

CRUISER number of guns

DESTROYER number of guns

MINE_SWEEPER number of guns

SUBMARINE number of torpedo launchers

Create a toString() method for the ShipRegistry class that sorts the current ships according to the alphabetic order of the ships name, and then iterates through the current ships and appends each ships toString method to the string returned. This will require the Ship class to implement the Comparable interface, which requires Ship to implement the compareTo method. This method should get the ships names and compare the names using the library compareTo method for Strings.

Create a writeString method for each ship class and category that returns an exact string that will be written to an output file, and then perhaps read back in. The writeString method for each type of ship will have the following form. Note that all fields are separated by commas, so that the output file that is written using this method becomes a comma-delimited file (e.g., a csv file). These methods do need to write in exactly the following format. The first three fields are the string representation, and the subsequent field(s) is a string representation of an integer.

CARGO name,shipType,year,tonnage

CRUISE name,shipType,year,passengers

WARSHIP name,shipType,year,guns,torpedos,aircraft

CARRIER name,shipType,year,aircraft

CRUISER name,shipType,year,guns

DESTROYER name,shipType,year,guns

MINE_SWEEPER name,shipType,year,guns

SUBMARINE name,shipType,year,torpedoes

Your ShipRegistry methods must pass the JUnit Test class (provided). Do not modify this file. You also are provided a JUnit STUDENT Test file, which you should modify to further test your program. Your program will also be tested by private JUnit tests run by the instructor.

Create Javadoc for your classes.

Turn in all your java code, including ShipRegistryInterface.java, ShipRegistryTest.java, and ShipRegistrySTUDENTTest.java.

Create and turn in a final UML Class Diagram and a Design Reflection Word document, explaining how your initial design was modified, and how your final design differs from or matches the design solution.

***DriverFX.java***

import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class DriverFX extends Application { private static final double CANVAS_WIDTH = 600; private static final double CANVAS_HEIGHT = 3500; private static final double WINDOW_HEIGHT = 350; public static void main(String[] args) { launch(); } @Override /** * start is required by the class Application and is called by launch * It initializes MainPaneFX, which returns the main panel */ public void start(Stage stage) throws Exception { MainPaneFX mainPane = new MainPaneFX(CANVAS_WIDTH, CANVAS_HEIGHT); BorderPane root = mainPane.getMainPane(); Scene scene = new Scene(root, CANVAS_WIDTH, WINDOW_HEIGHT); stage.setScene(scene); stage.setTitle("Ship Registry"); stage.show(); } } 

***MainPaneFX.java***

import java.io.File;

import java.io.IOException; import java.io.PrintWriter; import java.util.Scanner; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Group; import javafx.scene.Parent; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.stage.FileChooser; /** * This panel is the basic pane, inside which other panes are placed. * @author ralexander */ public class MainPaneFX { private BorderPane mainPane; private HBox buttonPanel, inputBlock; private VBox inputLabels, inputPanel; private Button readButton, exitButton, resetButton, addButton, printButton, writeButton; RadioButton [] shipRadioButtons, warshipRadioButtons; private TextField shipField, nameField, yearField, tonsField, pxField, acField, gunsField, torpField; private Label shipLabel, nameLabel, yearLabel, tonsLabel, pxLabel, acLabel, gunsLabel, torpLabel; private HBox shipRadioBox, warshipRadioBox; //The manager is the way the GUI communicates with the worker code private ShipRegistry ships; /** * The MainPanel constructor sets up the GUI with buttons, radio buttons, and a display area. */ MainPaneFX(double CANVAS_WIDTH, double CANVAS_HEIGHT) { mainPane = new BorderPane(); //create the dataManager instance ships = new ShipRegistry(); //create the exitButton exitButton = new Button("Exit"); exitButton.setTooltip(new Tooltip("Select to close the application")); exitButton.setOnAction(event -> System.exit(0) ); //create the button to read input from a file resetButton = new Button("Reset the Ship Types"); resetButton.setTooltip(new Tooltip("Reset the radio buttons for selecting ships")); resetButton.setOnAction(event -> { clearFieldVisibility(); shipRadioBox.setVisible(true); warshipRadioBox.setVisible(false); for (int i=0; i < shipRadioButtons.length; i++) { shipRadioButtons[i].setSelected(false); } }); addButton = new Button("Add a ship"); addButton.setTooltip(new Tooltip("Add a ship with info entered by user")); addButton.setOnAction(event -> { try { int tons = 0, pax = 0, guns = 0, ac = 0, torps = 0; String name = nameField.getText(); if (name.equals("")) name="unknown"; String year = yearField.getText(); if (year.equals("")) year="unknown"; String type = shipField.getText(); if (!tonsField.getText().equals("")) tons = Integer.parseInt(tonsField.getText()); if (!pxField.getText().equals("")) pax = Integer.parseInt(pxField.getText()); if (!gunsField.getText().equals("")) guns = Integer.parseInt(gunsField.getText()); if (!acField.getText().equals("")) ac = Integer.parseInt(acField.getText()); if (!torpField.getText().equals("")) torps = Integer.parseInt(torpField.getText()); System.out.println("Name: "+name+", Year Built: "+year+", Type: "+type+", "+tons + " Tons, "+pax + " Passengers, "+ac + " Aircraft, "+guns + " Guns, "+torps + " Torpedoes"); ships.addShip(name, type, year, tons, pax, guns, torps, ac); } catch (NumberFormatException e) { JOptionPane.showMessageDialog(null, e.getMessage()+" expected an integer."); } }); //create the button to read input from a file readButton = new Button("Read File"); readButton.setTooltip(new Tooltip("Read an input file")); /* * When the read button is pushed, user is prompted to select an input file * and ship data is read in. */ readButton.setOnAction(event -> { try { readFile(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }); //create the button to display input to the user printButton = new Button("Display Ships"); printButton.setTooltip(new Tooltip("Display the Ship Registry")); /* * When the read button is pushed, user is prompted to select an input file * and ship data is read in. */ printButton.setOnAction(event -> { JOptionPane.showMessageDialog(null, ships.toString()); }); //create the button to display input to the user writeButton = new Button("Write Ships"); writeButton.setTooltip(new Tooltip("Write the Ship Registry to a file")); /* * When the read button is pushed, user is prompted to select an input file * and ship data is read in. */ writeButton.setOnAction(event -> { try { writeFile(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }); //tonsField, pxField, acField, gunsField, torpField; tonsField = new TextField(); pxField = new TextField(); acField = new TextField(); gunsField = new TextField(); torpField = new TextField(); shipField = new TextField(""); nameLabel = new Label("Ship's Name"); yearLabel = new Label("Year Built"); shipLabel = new Label("Ship Type"); tonsLabel = new Label("Tonnage"); pxLabel = new Label("Passengers"); acLabel = new Label("Aircraft"); gunsLabel = new Label("Guns"); torpLabel = new Label("Torpedoes"); shipRadioBox = new HBox(); shipRadioBox.setAlignment(Pos.CENTER); //{ShipType.CARGO.toString(), ShipType.CRUISE.toString(), ShipType.WARSHIP.toString()}; String [] shipRadioLabels = ships.getShipDescriptions(); ToggleGroup shipRadioGroup = new ToggleGroup(); shipRadioButtons = new RadioButton[shipRadioLabels.length]; for (int i=0; i < shipRadioLabels.length; i++) { int index = i; shipRadioButtons[i] = new RadioButton(shipRadioLabels[i]); shipRadioButtons[i].setToggleGroup(shipRadioGroup); shipRadioButtons[i].setPadding(new Insets(10,10,10,10)); } shipRadioBox.getChildren().addAll(shipRadioButtons); //{ShipType.CARRIER.toString(), ShipType.CRUISER.toString(), ShipType.DESTROYER.toString(), ShipType.MINE_SWEEPER.toString(), ShipType.SUBMARINE.toString()}; String [] warshipRadioLabels = ships.getWarshipDescriptions(); ToggleGroup warshipRadioGroup = new ToggleGroup(); warshipRadioButtons = new RadioButton[warshipRadioLabels.length]; for (int i=0; i < warshipRadioLabels.length; i++) { warshipRadioButtons[i] = new RadioButton(warshipRadioLabels[i]); warshipRadioButtons[i].setToggleGroup(warshipRadioGroup); warshipRadioButtons[i].setPadding(new Insets(10,10,10,10)); } warshipRadioBox = new HBox(); warshipRadioBox.setAlignment(Pos.CENTER); warshipRadioBox.getChildren().addAll(warshipRadioButtons); warshipRadioBox.setVisible(false); //CARGO shipRadioButtons[0].setOnAction( event -> { clearFieldVisibility(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, tonsLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, tonsField); shipField.setText("Cargo"); tonsLabel.setVisible(true); tonsField.setVisible(true); }); //CRUISE shipRadioButtons[1].setOnAction( event -> { clearFieldVisibility(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, pxLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, pxField); shipField.setText("Cruise"); pxLabel.setVisible(true); pxField.setVisible(true); }); //WARSHIP shipRadioButtons[2].setOnAction( event -> { shipField.setText("Warship"); shipRadioBox.setVisible(false); warshipRadioBox.setVisible(true); clearFieldVisibility(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, gunsLabel, acLabel, torpLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, gunsField, acField, torpField); shipField.setText("Warship"); gunsLabel.setVisible(true); gunsField.setVisible(true); acLabel.setVisible(true); acField.setVisible(true); torpLabel.setVisible(true); torpField.setVisible(true); }); //CARRIER warshipRadioButtons[0].setOnAction( event -> { shipField.setText("Carrier"); gunsField.clear(); acField.setEditable(true); torpField.clear(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, acLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, acField); }); //CRUISER warshipRadioButtons[1].setOnAction( event -> { shipField.setText("Cruiser"); gunsField.setEditable(true); acField.clear(); torpField.clear(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, gunsLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, gunsField); }); //DESTROYER warshipRadioButtons[2].setOnAction( event -> { shipField.setText("Destroyer"); acField.clear(); torpField.clear(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, gunsLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, gunsField); }); //MINE_SWEEPER warshipRadioButtons[3].setOnAction( event -> { shipField.setText("Mine Sweeper"); acField.clear(); torpField.clear(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, gunsLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, gunsField); }); //SUBMARINE warshipRadioButtons[4].setOnAction( event -> { shipField.setText("Submarine"); acField.clear(); gunsField.clear(); inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, torpLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField, torpField); }); VBox shipInfo = new VBox(); shipInfo.setAlignment(Pos.CENTER); shipInfo.setStyle("-fx-border-color: gray;"); VBox.setMargin(shipInfo,new Insets(10,40,10,40)); shipInfo.getChildren().addAll(shipLabel, shipRadioBox, warshipRadioBox); //add the shipInfo VBox to the top section of the main panel mainPane.setTop(shipInfo); //create the buttonPanel buttonPanel = new HBox(); buttonPanel.setVisible(true); buttonPanel.setAlignment(Pos.CENTER); HBox.setMargin(exitButton, new Insets(10,10,10,10)); HBox.setMargin(addButton, new Insets(10,10,10,10)); HBox.setMargin(resetButton, new Insets(10,10,10,10)); HBox.setMargin(readButton, new Insets(10,10,10,10)); HBox.setMargin(printButton, new Insets(10,10,10,10)); buttonPanel.getChildren().addAll(addButton, resetButton, readButton, printButton, writeButton, exitButton); //add the panel to the bottom section of the main panel mainPane.setBottom(buttonPanel); VBox.setMargin(nameLabel, new Insets(12,10,5,10)); VBox.setMargin(yearLabel, new Insets(12,10,5,10)); VBox.setMargin(shipLabel, new Insets(12,10,5,10)); VBox.setMargin(gunsLabel, new Insets(12,10,5,10)); VBox.setMargin(acLabel, new Insets(12,10,5,10)); VBox.setMargin(torpLabel, new Insets(12,10,5,10)); VBox.setMargin(pxLabel, new Insets(12,10,5,10)); VBox.setMargin(tonsLabel, new Insets(12,10,5,10)); inputLabels=new VBox(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel, gunsLabel, acLabel, torpLabel, pxLabel, tonsLabel); nameField = new TextField(); yearField = new TextField(); VBox.setMargin(nameField, new Insets(5,10,5,10)); VBox.setMargin(yearField, new Insets(5,10,5,10)); VBox.setMargin(shipField, new Insets(5,10,5,10)); VBox.setMargin(gunsField, new Insets(5,10,5,10)); VBox.setMargin(acField, new Insets(5,10,5,10)); VBox.setMargin(torpField, new Insets(5,10,5,10)); VBox.setMargin(pxField, new Insets(5,10,5,10)); VBox.setMargin(tonsField, new Insets(5,10,5,10)); inputPanel=new VBox(); inputPanel.getChildren().addAll(nameField, yearField, shipField, gunsField, acField, torpField, pxField, tonsField); HBox.setMargin(inputLabels, new Insets(10,0,10,10)); HBox.setMargin(inputPanel, new Insets(10,10,10,0)); inputBlock=new HBox(); inputBlock.setAlignment(Pos.CENTER); inputBlock.getChildren().addAll(inputLabels, inputPanel); mainPane.setCenter(inputBlock); clearFieldVisibility(); } private void writeFile() { //Use JFileChooser instead of FileChooser so selected file can be a new one, as well as an existing one JFileChooser cf = new JFileChooser(); cf.setDialogTitle("Choose a *.csv file to write to"); cf.showOpenDialog(null); File file = cf.getSelectedFile(); if(file != null) ships.writeFile(file); } private void readFile() throws IOException { File file; FileChooser chooser = new FileChooser(); file = chooser.showOpenDialog(null); if(file != null) ships.readFile(file); } private void clearFieldVisibility() { inputLabels.getChildren().clear(); inputPanel.getChildren().clear(); inputLabels.getChildren().addAll(nameLabel, yearLabel, shipLabel); inputPanel.getChildren().addAll(nameField, yearField, shipField); nameLabel.setVisible(true); nameField.setVisible(true); yearLabel.setVisible(true); yearField.setVisible(true); shipLabel.setVisible(true); shipField.setVisible(true); nameField.setText(""); yearField.setText(""); shipField.setText(""); gunsField.setText(""); acField.setText(""); torpField.setText(""); pxField.setText(""); tonsField.setText(""); } public BorderPane getMainPane() { return mainPane; } } 

***ShipRegistryInterface.java***

import java.io.File;

import java.util.ArrayList; /** * ShipRegistry is a Data Manager that keeps a list of ships. Note that this list is not precise in its naval jargon. * @author ralexander */ public interface ShipRegistryInterface { /** * shipList is an ArrayList holding Ship references */ ArrayList shipList = null; /** * The getShips method returns the current shipList * @return ArrayList shipList */ public ArrayList getShips(); /** * The addShip method adds ships to the ShipRegistry's ArrayList, distinguishing by type, * creating a ship instance of the correct type, and specifying the correct parameters according to its type. * This method does not add in any sorted order - the ships are held in the order they are added * @param name A string representing the name of the ship * @param type A string representing one of "Cargo", "Cruise", "Warship", "Carrier", "Cruiser","Destroyer","Mine Sweeper",or "Submarine" * @param year A string representing the year launched * @param tons A string representing the number of tons of cargo (net register tonnage (NRT)) the ship can carry * @param pax A string representing the number of passengers a cruise ship can carry * @param guns A string representing the number of guns a warship can carry. "Guns" is loosely defined, not according to naval jargon * @param torpedoes A string representing the number of torpedoes a warship can carry. * @param aircraft A string representing the number of aircraft a warship can nominally carry. */ public void addShip(String name, String type, String year, int tons, int pax, int guns, int torpedoes, int aircraft); /** * The readFile method reads from the input file, one line at a time, assuming each line represents data for one ship. * It assumes that the second field is a string representing the ship type, * one of "Cargo", "Cruise", "Warship", "Carrier", "Cruiser","Destroyer","Mine Sweeper",or "Submarine". * It further assumes specific formats for each type of ship, as follows: * Cargo: name,"Cargo",year,tons * Cruise: name,"Cruise",year,passengers * Warship: name,"Warship",year,guns,aircraft,torpedoes * Carrier: name,"Carrier",year,aircraft * Cruiser, Destroyer, and Mine Sweeper: name,type,year,guns * Submarine: name,"Submarine",year,torpedoes * It then calls addShip to instantiate it and add it to the ShipRegistry's ArrayList * @param file the file of type File to read from, assumed to be a csv file (comma-delimited) in the above order. */ public void readFile(File file); /** * The writeFile method writes to a specified file, either creating a new file or appending to the end of an existing file. * It iterates through ShipRegistry's ArrayList, writes one line at a time representing data for each ship. * It writes the second field as a string representing the ship type, * one of "Cargo", "Cruise", "Warship", "Carrier", "Cruiser","Destroyer","Mine Sweeper",or "Submarine". * It further writes specific formats for each type of ship, as follows: * Cargo: name,"Cargo",year,tons * Cruise: name,"Cruise",year,passengers * Warship: name,"Warship",year,guns,aircraft,torpedoes * Carrier: name,"Carrier",year,aircraft * Cruiser, Destroyer, and Mine Sweeper: name,type,year,guns * Submarine: name,"Submarine",year,torpedoes * @param file the file of type File to write to */ public void writeFile(File file); /** * The getShipDescriptions method is used in the GUI to set the radio button labels for basic ship types * @return the string array {ShipType.CARGO.toString(), ShipType.CRUISE.toString(), ShipType.WARSHIP.toString()}; */ public String[] getShipDescriptions(); /** * The getWarshipDescriptions method is used in the GUI to set the radio button labels for the five warship types * @return the string array {ShipType.CARRIER.toString(), ShipType.CRUISER.toString(), ShipType.DESTROYER.toString(), ShipType.MINE_SWEEPER.toString(), ShipType.SUBMARINE.toString()}; */ public String[] getWarshipDescriptions(); } 

***ships.csv***

Edmund Fitzgerald / Cargo / 1958 / 8713

Enterprise (CVN-65) / Carrier / 1960 / 90

Queen Elizabeth 2 / Cruise / 1967 / 1777

Queen Mary 2 / Cruise / 2003 / 2620

Constitution / Warship / 1798 / 44 / 0 / 0

Bainbridge (DD-1) / Destroyer / 1903 / 7

Ardent (MCM-12) / Mine Sweeper / 1994 / 2

Antietam (CG-54) / Cruiser / 1986 / 18

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions

Question

What will you do or say to Anthony about this issue?

Answered: 1 week ago