Java代写 | COMP90041: Final Project

本次Java代写是完成模拟交通运输工具的程序
COMP90041: Final Project  
Build an Ethical Engine (15 points)  
1
.1 The Abstract Class Character  
Character is an Abstract Class from which all character types inherit. This base class should be imple-  
mented as depicted in Figure 2. The class further comprises two enumeration types:  
c The University of Melbourne 2020, v1.4  
1

Figure 1: Scenario example: a self-driving car approaches a pedestrian crossing but its breaks fail. Your  
algorithm needs to decide between two cases. Left: The car will continue ahead and drive through the  
crossing resulting in one elderly man, one pregnant woman, one boy, and one dog losing their lives.  
Right: The car will swerve and crash into a concrete barrier resulting in the death of its passengers: one  
women, one man, and one baby. Note that the pedestrians abide by the law as they are crossing on a  
green signal (image source: http://moralmachine.mit.edu/).  
1
Gender must include the types FEMALE and MALE as well as a default option UNKNOWN, but  
can also include more diverse options if you so choose.  
2
BodyType includes the types AVERAGEATHLETIC, and OVERWEIGHT as well as a default  
option UNSPECIFIED.  
The Character Class should implement the constructors as depicted in Figure 2. Make sure the empty  
constructor initializes all attributes with appropriate default values.  
Age should be treated as a class invariant for which the following statement always yields true: age >= 0.  
1
.2 Classes Inheriting from Character.java  
Create at least two concrete classes that directly inherit from the abstract class Character:  
1
2
Person.java: scenarios are inhabited by people who exhibit a number of characteristics (e.g., age,  
gender, body type, profession etc.). In the scenarios, each person is either considered to be a  
passenger or a pedestrian. A person can be you.  
Animal.java: animals are part of the environment we live in. People walk their pets so make sure  
your program accounts for these, at least for: cats and dogs.  
1.2.1 The Class Person.java  
This class represents a human in the scenarios. On top of its parent methods, the class Person must at  
least include the following public methods:  
the constructor Person(int age, Profession profession, Gender gender, BodyType bodytype, boolean  
isPregnant).  
c The University of Melbourne 2020, v1.4  
2

Figure 2: UML Diagram for Character.java  
the copy constructor Person(Person otherPerson).  
getAgeCategory(): returns an enumeration value of the type AgeCategory depending on the person’s  
age with one of the following values:  
BABY : a person with an age between 0 and 4.  
CHILD: a person with an age between 5 and 16.  
ADULT: a person with an age between 17 and 68.  
SENIOR: a person with an age above 68.  
the public method getProfession(): returns an enumeration value of the type Profession, which  
must include the following values: DOCTOR, CEOCRIMINALHOMELESS, UNEMPLOYED,  
UNKNOWN. Only ADULTs have professions, other age categories should return the default value  
NONE. Additionally, you are tasked with coming up with at least two more categories you deem  
feasible.  
the public method isPregnant(): returns a boolean indicating whether the person is pregnant. For  
all instances of Person whose gender is not FEMALE this should return false.  
the public method setPregnant(boolean pregnant): sets the value returned by isPregnant() while  
preventing invalid states, such as a pregnant male.  
isYou(): returns a boolean indicating whether the person is representative of the user, e.g., you  
are one of the passengers in the car.  
the public method setAsYou(boolean isYou): sets the value of whether the person is representative  
of the user.  
the public method toString() must output a person’s characteristics according to the format shown  
below.  
Pregnancy should be treated as a class invariant for which the following statement always yields true:  
if the person’s gender is not female, the person cannot be pregnant. Also, only persons who belong to  
the age category ADULT have a profession.  
The public method toString() must return the following output format when printed to the command-  
line:  
[you] <bodyType> <age category> [profession] <gender> [pregnant]  
Note that attributes in brackets [] should only be shown if they apply, e.g., a baby does not have a  
profession so therefore the profession is not displayed. Here is an example:  
athletic adult doctor female  
c The University of Melbourne 2020, v1.4  
3

or  
average adult doctor female pregnant  
Similarly, here is an example if the person is you:  
you average baby male  
Note that words are in lowercase and separated by single spaces. Age is ignored in the output.  
1.2.2 The Class Animal.java  
This class represents animals in the scenarios. On top of its parent methods, the class Animal must  
include the following public methods:  
the constructor Animal(String species).  
the copy constructor Animal(Animal otherAnimal).  
the public method getSpecies(): returns a String indicating what type of species the animal repre-  
sents.  
the public method setSpecies(String species): sets the value returned by getSpecies().  
the public method isPet(): returns a boolean value depending whether the animal is a pet or wild  
animal.  
the public method toString() must output a pet’s characteristics according to the format shown  
below.  
The public method toString() must return the following output format when printed to the command-  
line:  
<species> [is pet]  
Here is an example:  
cat is pet  
Here is another example where isPet() returns false:  
bird  
Note that words are in lowercase, separated by single spaces, and that gender, age, and bodyType are  
ignored in the output.  
1
.3 The Class Scenario.java  
This class contains all relevant information about a presented scenario, including the car’s passengers  
and the pedestrians on the street as well as whether the pedestrians are crossing legally.  
Each scenario can have only one instance of Person for which isYou() returns true.  
The following public methods must be implemented:  
the constructor Scenario(Character[] passengers, Character[] pedestrians, boolean isLegalCrossing):  
you can use Arrays or ArrayLists in your class, but you need to make sure this constructor takes  
a person array as an argument.  
the public method hasYouInCar(): returns a boolean indicating whether you (the user) is in the  
car.  
c The University of Melbourne 2020, v1.4  
4

• lane, i.e., crossing the street.  
the public method getPassengers(): returns the cars’ passengers as a Character[] array.  
the public method getPedestrians(): returns the pedestrians as a Character[] array.  
the public method isLegalCrossing(): returns whether the pedestrians are legally crossing at the  
traffic light.  
• legally crossing the street.  
the public method getPassengerCount(): returns the number of passengers in the car (in int).  
the public method getPedestrianCount(): returns the number of pedestrians on the street (in int).  
the public method toString() must output the scenario according to the format shown below.  
The public method toString() must return the following output format when printed to the command-  
line:  
=
#
=
=====================================  
Scenario  
=====================================  
Legal Crossing: <yes/no>  
Passengers (<getPassengerCount>)  
.
.
<character.toString>  
Pedestrians (<getPedestrianCount)  
.
.
<character.toString>  
Here is an example for a legal crossing (green light):  
=
#
=
=====================================  
Scenario  
=====================================  
Legal Crossing: yes  
Passengers (4)  
cat is pet  
overweight child male  
average senior female  
athletic adult ceo female pregnant  
Pedestrians (3)  
average baby male  
average adult doctor male  
overweight adult homeless female  
Here is another example with you in the car and a (non-pregnant) women and pedestrians crossing the  
street at a red light (illegal crossing):  
=
#
=
=====================================  
Scenario  
=====================================  
Legal Crossing: no  
Passengers (2)  
c The University of Melbourne 2020, v1.4  
5

you average baby male  
average adult criminal female  
Pedestrians (2)  
average senior male  
average senior female  
Note that character characteristics are written in lower case and separated by single spaces. Your output  
must match the output specifications.  
1
.4 The Class EthicalEngine.java  
This class holds the main method and manages your program execution. It takes care of program  
parameters (see Section 4) as well as user input (see Section 5).  
This class also houses the decide(scenario) method, which implements the decision-making algorithm  
outputting either PEDESTRIANS or PASSENGERS depending on whom to save. The code must  
choose whom to save for any scenario.  
Decision Algorithm Your task is to implement the public static method decide(Scenario scenario)  
that either returns a value of the Enumeration type Decision, which is either PEDESTRIANS or PAS-  
SENGERS. Your code must choose whom to save for any scenario.  
To make the decision, your algorithm needs to consider the characteristics of the characters involved as  
well as the situation. You can take any of the characters’ characteristics (age, bodyType, profession,  
pets, etc.) into account when making your decision, but you must base your decision on at least 5  
characteristics–from the scenario itself (e.g., whether it’s a legal crossing) or from the characters’ at-  
tributes. Note that there is no right or wrong in how you design your algorithm. Execution is what  
matters here so make sure your code meets the technical specifications. But you may want to think  
about the consequences of your algorithmic design choices.  
2
Scenario Generator (10 points)  
The class ScenarioGenerator.java will be the basis of your simulation and shall be used to create a variety  
of scenarios. To guarantee a balanced set of scenarios, it is crucial to randomize as many elements as  
possible, including the number and characteristics of persons and animals involved in each scenario as  
well as the scenario itself.  
To be able to properly test your scenarios and make sure your results can be replicated, you must apply  
pseudorandomness. Therefore, you need to familiarize yourself first with the class java.util.random 1 and  
especially with the function setSeed(long seed).  
ScenarioGenerator.java must, therefore, include the following methods:  
the empty constructor ScenarioGenerator(): this constructor should set the seed to a truly random  
number  
the constructor ScenarioGenerator(long seed): this constructor sets the seed with a predefined  
value  
the constructor ScenarioGenerator(long seed, int passengerCountMinimum, int passengerCount-  
Maximum, int pedestrianCountMinimum, int pedestrianCountMaximum): this constructor sets  
the seed as well as the minimum and maximum number for both passengers and pedestrians with  
predefined values  
the public method setPassengerCountMin(int min): sets the minimum number of car passengers  
for each scenario  
the public method setPassengerCountMax(int max): sets the maximum number of car passengers  
for each scenario  
1https://docs.oracle.com/javase/8/docs/api/java/util/Random.html  
c The University of Melbourne 2020, v1.4  
6

the public method setPedestrianCountMin(int min): sets the minimum number of pedestrians for  
each scenario  
the public method setPedestrianCountMax(int max): sets the maximum number of pedestrians for  
each scenario  
the public method getRandomPerson() which returns a newly created instance of Person with  
random age, gender, bodyType, profession, and state of pregnancy  
the public method getRandomAnimal() which returns a newly created instance of Animal with  
random age, gender, bodyType, species, and whether it is a pet or not  
the public method generate() which returns a newly created instance of Scenario containing a  
random number of passengers and pedestrians with random characteristics as well as a randomly  
red or green light condition with you (the user) being either in the car, on the street, or absent.  
The method generate() will need to abide by the minimum and maximum counts previously set for  
passengers and pedestrians in the scenario. If these values have not been explicitly set they need to  
be implicitly (i.e., by default) set to 1 and 5 respectively. A minimum may never be larger than its  
corresponding maximum.  
3
Audit your Algorithm (10 points)  
An audit is an inspection of your algorithm with the goal of revealing inherent biases that may be built  
in as an (un)intended consequence. In this task, you will simulate a variety of scenarios and have your  
EthicalEngine decide on their outcomes.  
The class Audit.java should:  
1
2
3
. create a specific number of random scenarios,  
. allow your EthicalEngine to decide on each outcome,  
. and summarize the results for each characteristic in a so-called statistic of projected survival.  
The following methods must, therefore, be implemented:  
the empty constructor Audit()  
the public method run(int runs): runs the simulation by creating N = runs scenarios and running  
each scenario through the EthicalEngine using its decide(Scenario scenario) method. For each  
scenario you need to save the outcome and add the result to your statistic  
the public method setAuditType(String name): sets the name of the audit type. For example:  
Algorithm for an audit of your algorithm.  
the public method getAuditType(): returns the name of the audit. Default should be Unspecified.  
the public method toString(): returns a summary of the simulation in the format depicted below.  
If no simulation has been run, this method returns ”no audit available”.  
the public method printStatistic(): prints the summary returned by the toString() method to the  
command-line.  
3
.1 Statistic of Projected Survival  
Your statistic should list a number of factors, including:  
age category  
gender  
body type  
c The University of Melbourne 2020, v1.4  
7

profession  
pregnant  
class type (person or animal)  
species  
pets  
legality (red or green light)  
Your statistic should account for each value of each respective characteristic, that are present in the given  
scenarios. For example, if you had scenarios with overweight body types, overweight must be listed in  
the statistic. If none of your scenarios included this particular body type, it must not be listed there.  
Also, make sure that you only update the statistic for, let’s say cats, if a cat was present in the tested  
scenario. If there is no cat in a given scenario, you must not change the % of cats that survived in your  
audit.  
This is the output format (with pseudocode) of the statistic:  
=
#
=
<
=====================================  
<auditType> Audit  
=====================================  
% SAVED AFTER <int run> RUNS  
for each characterstic:>  
<characterstic>: <survival ratio>  
—  
average age: <average>  
Here is an example output:  
=
#
=
=====================================  
Algorithm Audit  
=====================================  
% SAVED AFTER 100 RUNS  
unemployed: 0.8  
doctor: 0.79  
ceo: 0.67  
green: 0.67  
senior: 0.66  
pregnant: 0.66  
female: 0.65  
athletic: 0.64  
overweight: 0.59  
baby: 0.55  
adult: 0.54  
you: 0.54  
unknown: 0.53  
person: 0.5  
criminal: 0.42  
homeless: 0.38  
male: 0.35  
red: 0.34  
child: 0.32  
animal: 0.15  
dog: 0.13  
cat: 0.14  
—  
average age: 34.6  
c The University of Melbourne 2020, v1.4  
8

The list of characteristics must be sorted in descending order of the survival ratio. Note that the last  
two lines are not part of the sorted statistic but are at a fixed position in the output. The average age is  
calculated across all survivors of class Person (animals are excluded) and displayed with one digit after  
the decimal place (you can simply clip it). Your statistic must not list animals by gender, age, or body  
type.  
3.1.1 Update your Statistic within an Audit  
If you run multiple scenarios within a particular audit, make sure to update your statistic rather than  
overwrite it. For example, you may run an audit subsequently over 10 (audit.run(10)), 50 (audit.run(50)),  
and 100 (audit.run(100)) scenarios and print an updated statistic after each run to the command-line.  
The result on the command-line should be three statistic outputs: the first with 10, the second with 60,  
and the last with 160 runs.  
3
.2 Save your Audit Results  
To save the results of your audit to a file, add the public method printToFile(String filepath) to your  
Audit class. The method prints the results of the toString() method to a target file named results.log.  
The filepath variable (e.g., ’logs/results.log’) includes both the target directory (logs/, in this case) and  
the filename (results.log). If results.log already exists in the target directory, you should append the new  
data rather than overwrite the existing file. If the file does not exist, your program should create it. If  
the directory specified by the filepath variable does not exist, your program should print the following  
error message to the command-line:  
ERROR: could not print results. Target directory does not exist.  
The results must be saved in ASCII code, i.e., human-readable.  
4
Import Scenarios from a Configuration File (10 points)  
Instead of generating scenarios solely randomly, you need to make sure in this task that your program  
can import scenarios from a data file. This will allow you to run audits on a consistent set of scenarios.  
In this task, you need to extend your EthicalEngine class to allow it to create scenarios based on data it  
reads from a configuration file.  
4
.1 Specify the Configuration File as Command-Line Argument  
The config file should be specified when your program is launched. In this task, you need to create a  
command-line option. Command-line options or so-called flags specify options that modify the operation  
of your program. Options follow the program execution command on the command-line, separated by  
spaces. Options can be specified in any order. The following program calls are equivalent and should be  
supported by your program:  
$ java EthicalEngine –config path/to/config.csv  
and  
$
java EthicalEngine -c path/to/config.csv  
The command line argument following the flag –config of -c respectively specifies the filepath where the  
configuration file (config.csv) is located. Your program should check whether the file is located at the  
specified location and handle a FileNotFoundException in case the file does not exist. In this case,  
your program should terminate with the following error message:  
ERROR: could not find config file.  
c The University of Melbourne 2020, v1.4  
9

4
.2 Parsing the Configuration File  
Next, your program nees to read in the config file. Table 1 lists the contents of config.csv, a so-called  
comma-separated values (CSV) file. The file contains a list of values, each separated by a comma.  
As can be seen in Table 1, the first line contains the headers, i.e., the names (and description) of each  
data field and can therefore be ignored by your program. Each subsequent row presents an instance of  
Character. Scenarios are preceded by a single line that starts with scenario: and indicates whether the  
scenario depicts a legal (green) or illegal (red) crossing. In this case, the first scenario describes a legal  
crossing  
scenario:green  
with 3 passengers and 3 pedestrians (on of which is a dog). In fact, the first data set describes the  
scenario depicted in Figure 1. The second scenario describes an illegal crossing with 4 pedestrians and  
2
car passengers.  
Your EthicalEngine class needs to be able to read in a config file as depicted in Table 1 and create a  
Scenario instance for each scenario the file contains. Note that a config file can contain any number of  
scenarios with any number of passengers and pedestrians. You can assume that all config files follow the  
same format with the columns ordered as shown in Table 1.  
4
.3 Handle Invalid Data Rows  
While reading in the config file line by line your program may encounter three types of exceptions, which  
your program should be able to handle:  
1
2
3
. Invalid number of data fields per row: in case the number of values in one row is less than or exceeds  
0 values a InvalidDataFormatException should be thrown. Your program should handle such  
exceptions by issuing the warning statement ”WARNING: invalid data format in config file in line  
linecount¿” to the command-line and skip the respective row then continue reading in the next  
1
¡
line.  
. Invalid data type: in case the value can not cast into an existing data type (e.g., a character where  
an int should be for age) a NumberFormatException should be thrown. Your program should  
handle such exceptions by issuing the warning statement ”WARNING: invalid number format in  
config file in line ¡linecount¿” to the command-line, assign a default value instead, and continue  
with the next value in that line.  
. Invalid field values: in case your program does not accommodate a specific value (e.g., skinny as a  
bodyType) a InvalidCharacteristicException should be thrown. Your program should handle  
such exceptions by issuing a warning statement ”WARNING: invalid characteristic in config file in  
line < linecount >” to the command-line, assign a default value instead, and continue with the  
next value in that line.  
Note that < linecount > depicts the line number in the config file where the error was found. While  
you can import the NumberFormatException from the package java.lang you will need to create custom  
exceptions for the other two.  
4
.4 Audit your Algorithm Using the Scenarios from the Config File  
Once your program has imported all scenarios from config.csv it should create a new Audit. Therefore,  
you need to extend your Audit class by adding two more methods:  
the constructor Audit(Scenario[] scenarios): this constructor creates a new instance with a fixed  
set of scenarios.  
the public method run(): runs the simulation with the scenarios specified and runs each scenario  
through the EthicalEngine using its decide(Scenario scenario) method.  
Use the printToFile(String path) method to show the results of your audit on the console-line as well as  
save your audit results to results.log. The program should terminate after showing the statistic.  
c The University of Melbourne 2020, v1.4  
10

Table 1: Contents of the configuration file (config.csv).  
5
Interactive Scenarios (10 points)  
Now it is time to let the user take over and be the judge. Therefore, you need to build an interactive  
console program, which presents the user with a number of ethical scenarios. These scenarios can either  
be randomly generated or imported from a config file. For each scenario the user is asked to make a  
decision about who should survive. The results are logged to a user file (user.log) but only if the user  
consents to it.  
5
.1 Program Setup  
As described in Section 4.1, we will use command-line options or so-called flags to initialize the execution  
of EthicalEngines. Therefore, you should add two more options as possible command-line arguments.  
Print Help Make sure your program provides a help documentation to tell users how to correctly call  
and execute your program. The help is a printout on the console telling users about each option that  
your program supports.  
The following program call should invoke the help:  
$ java EthicalEngine –help  
and  
$
java EthicalEngine -h  
The command-line output following the invocation of the help should look like this:  
EthicalEngine – COMP90041 – Final Project  
Usage: java EthicalEngine [arguments]  
Arguments:  
c or –config  
h or –help  
r or –results  
Optional: path to config file  
Print Help (this message) and exit  
Optional: path to results log file  
i or –interactive Optional: launches interactive mode  
c The University of Melbourne 2020, v1.4  
11

The help should be displayed when the –help or -h flag is set or if the –config flag is set without an  
argument (i.e., no path is provided). If the –config or -c flag is not set, your program should generate  
random scenarios.  
The flag –interactive or -i indicates the interactive user mode. Without this flag the audit from Section 3  
should kick in. Only if the –interactive or -i is set the program launches its interactive scenarios.  
The following command will launch the program with a config file in the interactive mode:  
$
java EthicalEngine -i -c config.csv  
Here is an example of launching the program in the interactive mode with random scenarios:  
java EthicalEngine -i  
$
5
.2 Program Execution  
You need to extend the EthicalEngine class to manage the user interaction and support the following  
program flow: show a welcome message, collect user consent for data collection, present 3 scenarios and  
have user judge these, show the statistic, and ask for another round of scenarios.  
Show Welcome Screen At the start of the program, a welcome message must be shown: your program  
should read in and display the contents of welcome.ascii to the user without modifying it. The message  
provides background information about Moral Machines and walks the user through the program flow.  
Next, your program should collect the user’s consent before saving any results. Explicit consent is crucial  
to make sure users are aware of any type of data collection. Your program should, therefore, ask for  
explicit user consent before logging any user responses to a file. After the welcome message, you program  
should therefore prompt the user with the following method on the command-line:  
Do you consent to have your decisions saved to a file? (yes/no)  
Only if the user confirms (yes), your program should save the user statistic to results.log. If the user  
selects no your program should function normally but not write any of the users’ decisions to the file (it  
should still display the statistic on the command-line though). If the user types in anything other than  
yes or no, an InvalidInputException should be thrown and the user should be prompted again:  
Invalid response. Do you consent to have your decisions saved to a file? (yes/no)  
5.2.1 Present Scenarios  
Once the user consented (or not), the scenario judging begins. Therefore, scenarios are either imported  
from the config file or (if the config file is not specified) randomly generated. Therefore, you should use  
the Audit class to keep track of the scenarios and decisions. Make sure to set the audit type to User  
using the method setAuditType(String name). Scenarios are presented one by one using the toString()  
method of the Scenario instance and printing its outputs to the command-line. Each scenario should be  
followed by a prompt saying:  
Who should be saved? (passenger(s) [1] or pedestrian(s) [2])  
Any of the following user inputs should be considered saving the passengers:  
passenger  
passengers  
1
Any of the these user inputs should be considered saving the pedestrians:  
pedestrian  
c The University of Melbourne 2020, v1.4  
12

pedestrians