For this step, you will only need to modify, and thus focus on, the following class: • ReadShapeFile.java You will also need to look at only the constructors of the following classes: Figure 1: Empty Window with a Title: Shape Booooi- iinggg Frame • Circle.java • Oval.java Pretend the rest of the code does not exist. This is how we break large programs into smaller components that a human can understand and work with. It’s also how the rest of engineering works as well. Think about how the parts of a car engine are compartmentalised nicely into components. You don’t need to hold the entire functionality of the engine in your head at one time – just the component you are working on and how it interfaces with the rest of the system. It is very important that you only modify code in the files you are asked to modify. If your development environment suggests to change code outside these files don’t do it – even if it makes things magically compile and the red text disappears. Please assume the mistake is in the code you have just written and not in the code supplied. It is important you do not modify code supplied (except where indicated) because this could cause Autograder to fail to properly read your submission. In the first step of the assignment, you’ll create a file reader that reads the shape files supplied to you. Each line of the shape file specifies a shape. The format of this line differs depending on the shape to be created. 2 Fortunately, the first entry of the line always indicates what shape is to be created from this input. For exam- ple, to create a circle: circle To create an Oval, the line in the file would be as fol- lows: oval All these entries are on a single line of the file. I have broken them into two lines for readability. Angular brackets are placeholders for numbers/values as fol- lows: • - time in milliseconds since the start of the program after which the shape is inserted • - The starting position of the shape in the plane • - The velocity of the shape as a vec- tor • -Trueiftheshapeisfilledandfalse otherwise • - The colour of the shape For circle only, you have: • - the diameter of the circle For oval only, you have: • - the width and height (major and minor axis) of the oval. You cannot modify the file format in this assignment. These files will be automatically on autograder and if you modify file format your program marking will fail. In ReadShapeFile.java, write methods to read files consisting of circles and ovals only. Also, you can assume that the file is sorted by insertion time. This means that the lines of the file must be in increas- ingorder. I would start by trying to read a single line of the file followed by multiple lines, printing them to the screen to ensure you are reading the data correctly. Then, cre- ate instances of the shape objects and print them out. You can do this by calling the toString() method that has already been given to you. If the file does not exist, quit the program grace- fullyandoutputCould not find to the screen (standard out) with re- placed by the file that will not open. However, you can assume that each line of the file has the cor- rect syntax. To test your code, please try to run the TwoRedCircles.txt file. Start by printing out each line your read to the terminal to make sure you are reading the data correctly. Then, create instances of the objects and use the toString() method to print out the object and make sure that it is being cre- ated correctly. Writing this file reader is worth a total of 25 marks. Part marks will be given if correct information is printed to the screen using toString(). //read shape file code * This class reads a shape file. For the format of this shape file, see the assignment description. * Also, please see the shape files ExampleShapes.txt, ExampleShapesStill.txt, and TwoRedCircles.txt * * @author you * */ import javafx.scene.paint.Color; import java.io.*; import java.util.Scanner; public class ReadShapeFile { // TODO: You will likely need to write four methods here. One method to // construct each shape // given the Scanner passed as a parameter. I would suggest static // methods in this case. /** * Reads the data file used by the program and returns the constructed queue * * @param in * the scanner of the file * @return the queue represented by the data file */ private static Queue readLineByLine(Scanner in) { Queue shapeQueue = new Queue(); //read in the shape files and place them on the Queue //Right now, returning an empty Queue. You need to change this. return shapeQueue; } /** * Method to read the file and return a queue of shapes from this file. The * program should handle the file not found exception here and shut down the * program gracefully. * * @param filename * the name of the file * @return the queue of shapes from the file */ public static Queue readDataFile(String filename) { // HINT: You might want to open a file here. Scanner in = null; //you may want a Scanner here? return ReadShapeFile.readLineByLine(in); } } //circle.java /** * Circle.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * Circle is a shape that can be drawn to the screen, either * filled with colour or opaque. * Its position is determined by the upper left corner of * the circle's bounding rectangle. */ public class Circle extends ClosedShape { //The diameter of the circle private int diameter; /** * Creates a circle. * @param x The display component's x position. * @param y The display component's y position. * @param vx The display component's x velocity. * @param vy The display component's y velocity. * @param diameter The diameter of the circle. * @param colour The line colour or fill colour. * @param isFilled True if the circle is filled with colour, false if opaque. */ public Circle (int insertionTime, int x, int y, int vx, int vy, int diameter, Color colour, boolean isFilled) { super (insertionTime, x, y, vx, vy, colour, isFilled); this.diameter = diameter; } /** * Method to convert a circle to a string. */ public String toString () { String result = "This is a circle\n"; result += super.toString (); result += "Its diameter is " + this.diameter + "\n"; return result; } /** * @param Resets the diameter. */ public void setDiameter (int diameter) { this.diameter = diameter; } /** * @return The diameter of the circle. */ public int getDiameter() { return diameter; } /** * @return The width of the circle */ public int getWidth() { return diameter; } /** * @return The height of the circle */ public int getHeight() { return diameter; } /** * Draw the circle on the screen. * @param g The graphics object of the scene component. */ public void draw (GraphicsContext g) { g.setFill( colour ); g.setStroke( colour ); if (isFilled) { g.fillOval( x, y, diameter, diameter ); } else { g.strokeOval( x, y, diameter, diameter ); } } } //Oval.java /** * Oval.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * * Oval is an oval shape that can be drawn to the screen, either * filled with colour or opaque. * Its position is determined by the upper left corner of the * oval's bounding rectangle */ public class Oval extends ClosedShape { //The width and height of the oval (major and minor axis) private int width, height; /** * Creates an oval. * @param x The display component's x position. * @param y The display component's y position. * @param vx The display component's x velocity. * @param vy The display component's y velocity. * @param width The width of the oval (in pixels). * @param height The height of the oval (in pixels). * @param colour The line colour or fill colour. * @param isFilled True if the oval is filled with colour, false if opaque. */ public Oval (int insertionTime, int x, int y, int vx, int vy, int width, int height, Color colour, boolean isFilled) { super (insertionTime, x, y, vx, vy, colour, isFilled); this.width = width; this.height = height; } /** * Method to convert an oval to a string. */ public String toString () { String result = "This is an oval\n"; result += super.toString (); result += "Its width is " + this.width + " and its height is " + this.height + "\n"; return result; } /** * @param width Resets the width. */ public void setWidth (int width) { this.width = width; } /** * @param height Resets the height. */ public void setHeight (int height) { this.height = height; } /** * @return The width of the oval. */ public int getWidth() { return width; } /** * @return The height of the oval. */ public int getHeight() { return height; } /** * Draw the oval. * @param g The graphics object of the drawable component. */ public void draw (GraphicsContext g) { g.setFill (colour); g.setStroke( colour ); if (isFilled) { g.fillOval( x, y, width, height ); } else { g.strokeOval( x, y, width, height ); } } } // ClosedShape.java /** * ClosedShape.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * A ClosedShape is any shape that can be drawn without * taking a pencil off a piece of paper. * It's representation on computer has a line colour * and a position on the drawable screen component. * It can be filled in with colour or opaque. * This class is a super class for all shapes. */ public abstract class ClosedShape { /** * The x position of the Shape. */ protected int x; /** * The y position of the Shape. */ protected int y; /** * The x position of the Shape. */ protected int xVec; /** * The y position of the Shape. */ protected int yVec; /** * The line colour of the shape, or the filled in * colour if the Shape has fill. */ protected Color colour; /** * Determines if the Shape has a fill colour or not. */ protected boolean isFilled; /** * Encodes the insertion time into the scene */ private int insertionTime; /** * Creates a closed shape object. * @param x The x position. * @param y the y position. * @param colour The line or fill colour. * @param isFilled True if the shape is filled, false if not. */ protected ClosedShape (int insertionTime, int x, int y, int vx, int vy, Color colour, boolean isFilled) { this.x = x; this.y = y; this.xVec = vx; this.yVec = vy; this.colour = colour; this.isFilled = isFilled; this.insertionTime = insertionTime; } /** * The method returns a string suitable for printing. * @return string to print out shape. */ public String toString () { String result = ""; result += "Its position is " + x + " " + y + "\n"; result += "Its velocity is " + xVec + " " + yVec + "\n"; result += "Its colour is " + colour + "\n"; if (isFilled) result += "It is filled" + "\n"; else result += "It is not filled" + "\n"; result += "It should be inserted at " + insertionTime + "\n"; return result; } /** * Resets the x position. */ public void setX (int x) { this.x = x; } /** * Resets the y position. */ public void setY (int y) { this.y = y; } /** * Resets the x vector */ public void setVecX (int x) { this.xVec = x; }//end setVecX /** * Resets the y position. */ public void setVecY (int y) { this.yVec = y; }//end setVecY /** * Resets the colour. */ public void setColour (Color colour) { this.colour = colour; } /** * Sets the shape to filled. */ public void setFilled () { isFilled = true; } /** * Sets the shape to unfilled. */ public void unsetFilled () { isFilled = false; } /** * Sets the insertion time. */ public void setInsertionTime (int time) { insertionTime = time; } /** * @return The x position value. */ public int getX() { return x; } /** * @return The y position value. */ public int getY() { return y; } /** * @return The colour. */ public Color getColour() { return colour; } /** * @return True if the shape is filled, false if not. */ public boolean isFilled() { return isFilled; } /** * @return the insertion time. */ public int getInsertionTime () { return insertionTime; } /** * Puts the shape back in bounds in X */ public void putInBoundsX (double winX) { if (x < 0) x = 0; if (x + this.getWidth() > winX) { x = (int) (winX - Math.ceil (this.getWidth ())); } }//end inBoundsX; /** * Puts the shape back in bounds */ public void putInBoundsY (double winY) { if (y < 0) y = 0; if (y + this.getHeight() > winY) { y = (int) (winY - Math.ceil (this.getHeight ())); } }//end inBoundsY; /** * Bounces the shape off a vertical wall */ public void bounceX () { xVec = -xVec; } /** * Bounces the shape off a horizontal wall */ public void bounceY () { yVec = -yVec; } /** * Returns true if the shapes have gone out of bounds in X */ public boolean outOfBoundsX (double winX) { return (x + this.getWidth()> winX) || (x < 0); } /** * Returns true if the shapes have gone out of bounds in Y */ public boolean outOfBoundsY (double winY) { return (y + this.getHeight() > winY) || (y < 0); } /** * Takes in a direction and a velocity and moves the shape * in that direction on unit */ public void move () { x += xVec; y += yVec; } /** * Draws the object to the current component. Abstract method. * @param g The graphics object associated with the drawing component. */ public abstract void draw (GraphicsContext g); /** * Get the width of the current component * @return the width of the shape */ public abstract int getWidth (); /** * Get the height of the current component * @return the height of the shape */ public abstract int getHeight (); Modify the readshapefile and print circle //TwoRedCircles.txt circle 2000 250 250 -3 1 true 80 255 0 0 circle 4000 250 250 3 -1 false 80 255 0 0

Database System Concepts
7th Edition
ISBN:9780078022159
Author:Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Publisher:Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Chapter1: Introduction
Section: Chapter Questions
Problem 1PE
icon
Related questions
Question
For this step, you will only need to modify, and thus focus on, the following class: • ReadShapeFile.java You will also need to look at only the constructors of the following classes: Figure 1: Empty Window with a Title: Shape Booooi- iinggg Frame • Circle.java • Oval.java Pretend the rest of the code does not exist. This is how we break large programs into smaller components that a human can understand and work with. It’s also how the rest of engineering works as well. Think about how the parts of a car engine are compartmentalised nicely into components. You don’t need to hold the entire functionality of the engine in your head at one time – just the component you are working on and how it interfaces with the rest of the system. It is very important that you only modify code in the files you are asked to modify. If your development environment suggests to change code outside these files don’t do it – even if it makes things magically compile and the red text disappears. Please assume the mistake is in the code you have just written and not in the code supplied. It is important you do not modify code supplied (except where indicated) because this could cause Autograder to fail to properly read your submission. In the first step of the assignment, you’ll create a file reader that reads the shape files supplied to you. Each line of the shape file specifies a shape. The format of this line differs depending on the shape to be created. 2 Fortunately, the first entry of the line always indicates what shape is to be created from this input. For exam- ple, to create a circle: circle To create an Oval, the line in the file would be as fol- lows: oval All these entries are on a single line of the file. I have broken them into two lines for readability. Angular brackets are placeholders for numbers/values as fol- lows: • - time in milliseconds since the start of the program after which the shape is inserted • - The starting position of the shape in the plane • - The velocity of the shape as a vec- tor • -Trueiftheshapeisfilledandfalse otherwise • - The colour of the shape For circle only, you have: • - the diameter of the circle For oval only, you have: • - the width and height (major and minor axis) of the oval. You cannot modify the file format in this assignment. These files will be automatically on autograder and if you modify file format your program marking will fail. In ReadShapeFile.java, write methods to read files consisting of circles and ovals only. Also, you can assume that the file is sorted by insertion time. This means that the lines of the file must be in increas- ingorder. I would start by trying to read a single line of the file followed by multiple lines, printing them to the screen to ensure you are reading the data correctly. Then, cre- ate instances of the shape objects and print them out. You can do this by calling the toString() method that has already been given to you. If the file does not exist, quit the program grace- fullyandoutputCould not find to the screen (standard out) with re- placed by the file that will not open. However, you can assume that each line of the file has the cor- rect syntax. To test your code, please try to run the TwoRedCircles.txt file. Start by printing out each line your read to the terminal to make sure you are reading the data correctly. Then, create instances of the objects and use the toString() method to print out the object and make sure that it is being cre- ated correctly. Writing this file reader is worth a total of 25 marks. Part marks will be given if correct information is printed to the screen using toString(). //read shape file code * This class reads a shape file. For the format of this shape file, see the assignment description. * Also, please see the shape files ExampleShapes.txt, ExampleShapesStill.txt, and TwoRedCircles.txt * * @author you * */ import javafx.scene.paint.Color; import java.io.*; import java.util.Scanner; public class ReadShapeFile { // TODO: You will likely need to write four methods here. One method to // construct each shape // given the Scanner passed as a parameter. I would suggest static // methods in this case. /** * Reads the data file used by the program and returns the constructed queue * * @param in * the scanner of the file * @return the queue represented by the data file */ private static Queue readLineByLine(Scanner in) { Queue shapeQueue = new Queue(); //read in the shape files and place them on the Queue //Right now, returning an empty Queue. You need to change this. return shapeQueue; } /** * Method to read the file and return a queue of shapes from this file. The * program should handle the file not found exception here and shut down the * program gracefully. * * @param filename * the name of the file * @return the queue of shapes from the file */ public static Queue readDataFile(String filename) { // HINT: You might want to open a file here. Scanner in = null; //you may want a Scanner here? return ReadShapeFile.readLineByLine(in); } } //circle.java /** * Circle.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * Circle is a shape that can be drawn to the screen, either * filled with colour or opaque. * Its position is determined by the upper left corner of * the circle's bounding rectangle. */ public class Circle extends ClosedShape { //The diameter of the circle private int diameter; /** * Creates a circle. * @param x The display component's x position. * @param y The display component's y position. * @param vx The display component's x velocity. * @param vy The display component's y velocity. * @param diameter The diameter of the circle. * @param colour The line colour or fill colour. * @param isFilled True if the circle is filled with colour, false if opaque. */ public Circle (int insertionTime, int x, int y, int vx, int vy, int diameter, Color colour, boolean isFilled) { super (insertionTime, x, y, vx, vy, colour, isFilled); this.diameter = diameter; } /** * Method to convert a circle to a string. */ public String toString () { String result = "This is a circle\n"; result += super.toString (); result += "Its diameter is " + this.diameter + "\n"; return result; } /** * @param Resets the diameter. */ public void setDiameter (int diameter) { this.diameter = diameter; } /** * @return The diameter of the circle. */ public int getDiameter() { return diameter; } /** * @return The width of the circle */ public int getWidth() { return diameter; } /** * @return The height of the circle */ public int getHeight() { return diameter; } /** * Draw the circle on the screen. * @param g The graphics object of the scene component. */ public void draw (GraphicsContext g) { g.setFill( colour ); g.setStroke( colour ); if (isFilled) { g.fillOval( x, y, diameter, diameter ); } else { g.strokeOval( x, y, diameter, diameter ); } } } //Oval.java /** * Oval.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * * Oval is an oval shape that can be drawn to the screen, either * filled with colour or opaque. * Its position is determined by the upper left corner of the * oval's bounding rectangle */ public class Oval extends ClosedShape { //The width and height of the oval (major and minor axis) private int width, height; /** * Creates an oval. * @param x The display component's x position. * @param y The display component's y position. * @param vx The display component's x velocity. * @param vy The display component's y velocity. * @param width The width of the oval (in pixels). * @param height The height of the oval (in pixels). * @param colour The line colour or fill colour. * @param isFilled True if the oval is filled with colour, false if opaque. */ public Oval (int insertionTime, int x, int y, int vx, int vy, int width, int height, Color colour, boolean isFilled) { super (insertionTime, x, y, vx, vy, colour, isFilled); this.width = width; this.height = height; } /** * Method to convert an oval to a string. */ public String toString () { String result = "This is an oval\n"; result += super.toString (); result += "Its width is " + this.width + " and its height is " + this.height + "\n"; return result; } /** * @param width Resets the width. */ public void setWidth (int width) { this.width = width; } /** * @param height Resets the height. */ public void setHeight (int height) { this.height = height; } /** * @return The width of the oval. */ public int getWidth() { return width; } /** * @return The height of the oval. */ public int getHeight() { return height; } /** * Draw the oval. * @param g The graphics object of the drawable component. */ public void draw (GraphicsContext g) { g.setFill (colour); g.setStroke( colour ); if (isFilled) { g.fillOval( x, y, width, height ); } else { g.strokeOval( x, y, width, height ); } } } // ClosedShape.java /** * ClosedShape.java * @version 2.0.0 * Originally written by Bette Bultena but heavily modified for the purposes of * CSC-115 (Daniel Archambault and Liam OReilly) */ import javafx.scene.paint.Color; import javafx.scene.canvas.GraphicsContext; /** * A ClosedShape is any shape that can be drawn without * taking a pencil off a piece of paper. * It's representation on computer has a line colour * and a position on the drawable screen component. * It can be filled in with colour or opaque. * This class is a super class for all shapes. */ public abstract class ClosedShape { /** * The x position of the Shape. */ protected int x; /** * The y position of the Shape. */ protected int y; /** * The x position of the Shape. */ protected int xVec; /** * The y position of the Shape. */ protected int yVec; /** * The line colour of the shape, or the filled in * colour if the Shape has fill. */ protected Color colour; /** * Determines if the Shape has a fill colour or not. */ protected boolean isFilled; /** * Encodes the insertion time into the scene */ private int insertionTime; /** * Creates a closed shape object. * @param x The x position. * @param y the y position. * @param colour The line or fill colour. * @param isFilled True if the shape is filled, false if not. */ protected ClosedShape (int insertionTime, int x, int y, int vx, int vy, Color colour, boolean isFilled) { this.x = x; this.y = y; this.xVec = vx; this.yVec = vy; this.colour = colour; this.isFilled = isFilled; this.insertionTime = insertionTime; } /** * The method returns a string suitable for printing. * @return string to print out shape. */ public String toString () { String result = ""; result += "Its position is " + x + " " + y + "\n"; result += "Its velocity is " + xVec + " " + yVec + "\n"; result += "Its colour is " + colour + "\n"; if (isFilled) result += "It is filled" + "\n"; else result += "It is not filled" + "\n"; result += "It should be inserted at " + insertionTime + "\n"; return result; } /** * Resets the x position. */ public void setX (int x) { this.x = x; } /** * Resets the y position. */ public void setY (int y) { this.y = y; } /** * Resets the x vector */ public void setVecX (int x) { this.xVec = x; }//end setVecX /** * Resets the y position. */ public void setVecY (int y) { this.yVec = y; }//end setVecY /** * Resets the colour. */ public void setColour (Color colour) { this.colour = colour; } /** * Sets the shape to filled. */ public void setFilled () { isFilled = true; } /** * Sets the shape to unfilled. */ public void unsetFilled () { isFilled = false; } /** * Sets the insertion time. */ public void setInsertionTime (int time) { insertionTime = time; } /** * @return The x position value. */ public int getX() { return x; } /** * @return The y position value. */ public int getY() { return y; } /** * @return The colour. */ public Color getColour() { return colour; } /** * @return True if the shape is filled, false if not. */ public boolean isFilled() { return isFilled; } /** * @return the insertion time. */ public int getInsertionTime () { return insertionTime; } /** * Puts the shape back in bounds in X */ public void putInBoundsX (double winX) { if (x < 0) x = 0; if (x + this.getWidth() > winX) { x = (int) (winX - Math.ceil (this.getWidth ())); } }//end inBoundsX; /** * Puts the shape back in bounds */ public void putInBoundsY (double winY) { if (y < 0) y = 0; if (y + this.getHeight() > winY) { y = (int) (winY - Math.ceil (this.getHeight ())); } }//end inBoundsY; /** * Bounces the shape off a vertical wall */ public void bounceX () { xVec = -xVec; } /** * Bounces the shape off a horizontal wall */ public void bounceY () { yVec = -yVec; } /** * Returns true if the shapes have gone out of bounds in X */ public boolean outOfBoundsX (double winX) { return (x + this.getWidth()> winX) || (x < 0); } /** * Returns true if the shapes have gone out of bounds in Y */ public boolean outOfBoundsY (double winY) { return (y + this.getHeight() > winY) || (y < 0); } /** * Takes in a direction and a velocity and moves the shape * in that direction on unit */ public void move () { x += xVec; y += yVec; } /** * Draws the object to the current component. Abstract method. * @param g The graphics object associated with the drawing component. */ public abstract void draw (GraphicsContext g); /** * Get the width of the current component * @return the width of the shape */ public abstract int getWidth (); /** * Get the height of the current component * @return the height of the shape */ public abstract int getHeight (); Modify the readshapefile and print circle //TwoRedCircles.txt circle 2000 250 250 -3 1 true 80 255 0 0 circle 4000 250 250 3 -1 false 80 255 0 0
Expert Solution
steps

Step by step

Solved in 2 steps

Blurred answer
Knowledge Booster
Class
Learn more about
Need a deep-dive on the concept behind this application? Look no further. Learn more about this topic, computer-science and related others by exploring similar questions and additional content below.
Similar questions
  • SEE MORE QUESTIONS
Recommended textbooks for you
Database System Concepts
Database System Concepts
Computer Science
ISBN:
9780078022159
Author:
Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Publisher:
McGraw-Hill Education
Starting Out with Python (4th Edition)
Starting Out with Python (4th Edition)
Computer Science
ISBN:
9780134444321
Author:
Tony Gaddis
Publisher:
PEARSON
Digital Fundamentals (11th Edition)
Digital Fundamentals (11th Edition)
Computer Science
ISBN:
9780132737968
Author:
Thomas L. Floyd
Publisher:
PEARSON
C How to Program (8th Edition)
C How to Program (8th Edition)
Computer Science
ISBN:
9780133976892
Author:
Paul J. Deitel, Harvey Deitel
Publisher:
PEARSON
Database Systems: Design, Implementation, & Manag…
Database Systems: Design, Implementation, & Manag…
Computer Science
ISBN:
9781337627900
Author:
Carlos Coronel, Steven Morris
Publisher:
Cengage Learning
Programmable Logic Controllers
Programmable Logic Controllers
Computer Science
ISBN:
9780073373843
Author:
Frank D. Petruzella
Publisher:
McGraw-Hill Education