You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Her ligger løsningsforslaget til eksamen 2021. I kombinasjon med kildekoden vil vi beskrive hva oppgaven spurt etter, samt ofte forekommende feil og misforståelser.

På gitlab finner dere full kode til alle deler i oppgaven.


Oppgaven handler om å holde oversikt over et pågaende vaksinestudie.

public class VaccineTrialVolunteer {

	public VaccineTrialVolunteer(String id, boolean placebo) {
		...
	}

	public String getId() {
		...
	}

	/* Whether the volunteer was given a placebo or the actual vaccine */
	public boolean isPlacebo() {
		...
	}

	/* Whether the volunteer got sick during the trial period, 
	 * the default value for this should be false */
	public boolean gotSick() {
		...
	}

	/*
	 * Updates whether the participant got sick during the trial period
	 */
	public void setGotSick(boolean gotSick) {
		...
	}

}


public class VaccineTrial {

	// Add any needed fields here

	/**
	 * Adds a new VaccineTrialVolunteer to the trial
	 * 
	 * @param id      The id of the volunteer
	 * 
	 * @param placebo Whether the volunteer was given a placebo, or the actual
	 *                vaccine
	 */

	public void addVolunteer(String id, boolean placebo) {
		// TODO
	}

	/**
	 * Returns whether the vaccine's effectiveness rate is higher than the provided
	 * limit. The effectiveness of the vaccine is calculated as follows: 
	 * 
	 * 1- (number of people that received the vaccine and got sick/
	 *         number of people that got sick)
	 * 
	 * If there is no sick people, the vaccine is not effective
	 * 
	 * @param limit A limit to compare against
	 * 
	 * @throws IllegalArgumentException If limit is not between (including) 0 and 1.
	 * 
	 * @return Whether the vaccine effectiveness rate is higher than the limit
	 */
	public boolean isMoreEffectiveThanLimit(double limit) {
		...

	}

	/**
	 * Updates the sick state of a VaccineTrialVolunteer
	 * 
	 * @param id The id of the volunteer to set sick.
	 * @throws IllegalArgumentException if there is no volunteer with the given id
	 */
	public void setSick(String id) {
		...
	}

	/**
	 * Get's the volunteer with the given ID
	 * 
	 * @param id The id of the volunteer to set sick.
	 * 
	 * @return The vaccine trial volunteer with the given ID. If the ID is not valid
	 *         for any volunteer, return null
	 */
	public VaccineTrialVolunteer getVolunteer(String id) {
		...
	}

}

Oppgave a) Utfyll klassen VaccineTrialVolunteer og alle metodene i denne klassen. Legg til nødvendige felt. VaccineTrialVolunteer skal ha følgende metoder:

  • VaccineTrialVolunteer(String id, boolean placebo) - Oppretter en ny frivillig deltaker, med den gitte ID-en og hvorvidt deltakeren fikk placebo eller faktiske vaksinen.
  • getId() - Henter ut ID-en til deltakeren.
  • isPlacebo() - Returnere hvorvidt deltakeren fikk placebo eller vaksine.
  • gotSick() - Returnere hvorvidt deltakeren ble syk i løpet av studien.
  • setGotSick(boolean gotSick) - Oppdaterer om deltakeren ble syk i løpet av studien.
public class VaccineTrialVolunteer {

	private final String id;
	private final boolean placebo; 
	private boolean gotSick;
	
	public VaccineTrialVolunteer(String id, boolean placebo) {
		this.id = id;
		this.placebo = placebo;
	}

	public String getId() {
		return this.id;
	}

	/* Whether the volunteer was given a placebo or the actual vaccine */
	public boolean isPlacebo() {
		return this.placebo;
	}

	/* Whether the volunteer got sick during the trial period, 
	 * the default value for this should be false */
	public boolean gotSick() {
		return this.gotSick;
	}

	/*
	 * Updates whether the participant got sick during the trial period
	 */
	public void setGotSick(boolean gotSick) {
		this.gotSick = gotSick;
	}

}

Oppgave b)

 Fyll ut klassen VaccineTrial, og alle metodene i denne klassen. Legg til egne nødvendige felt. VaccineTrial skal ha følgende metoder:

  • addVolunteer(String id, boolean placebo) - Legger til en deltaker i studien.
  • isMoreEffectiveThanLimit(double limit) - Hvorvidt vaksinen var mer effektiv enn den oppgitte grensen.
  • setSick(String id) - Oppdaterer deltakeren med den gitte ID-en til å ha blitt syk i løpet av studien.
  • VaccineTrialVolunteer getVolunteer(String id) - Returnerer deltakeren med den gitte ID-en.
import java.util.ArrayList;
import java.util.Collection;

public class VaccineTrial {

	// Add any needed fields here
	private Collection<VaccineTrialVolunteer> volunteers = new ArrayList<>();

	/**
	 * Adds a new VaccineTrialVolunteer to the trial
	 * 
	 * @param id      The id of the volunteer
	 * 
	 * @param placebo Whether the volunteer was given a placebo, or the actual
	 *                vaccine
	 */
	public void addVolunteer(String id, boolean placebo) {
		this.volunteers.add(new VaccineTrialVolunteer(id, placebo));

	}

	/**
	 * Returns whether the vaccine's effectiveness rate is higher than the provided
	 * limit. The effectiveness of the vaccine is calculated as follows: 
	 * 
	 * 1- (number of people that received the vaccine and got sick/
	 *         number of people that got sick)
	 * 
	 * If there is no sick people, the vaccine is not effective
	 * 
	 * @param limit A limit to compare against
	 * 
	 * @throws IllegalArgumentException If limit is not between (including) 0 and 1.
	 * 
	 * @return Whether the vaccine effectiveness rate is higher than the limit
	 */
	public boolean isMoreEffectiveThanLimit(double limit) {
		if (limit < 0 || limit > 1) {
			throw new IllegalArgumentException("Invalid limit");
		}
		double numberOfSick = 0;
		double numberOfSickWithVaccine = 0;
		for (VaccineTrialVolunteer volunteer: volunteers) {
			if (volunteer.gotSick()) {
				numberOfSick++;
				if (!volunteer.isPlacebo()) {
					numberOfSickWithVaccine++;
				}
			}
		}
		double ratio  = 1.0-(numberOfSickWithVaccine/numberOfSick);
		return ratio > limit;
	}

	/**
	 * Updates the sick state of a VaccineTrialVolunteer
	 * 
	 * @param id The id of the volunteer to set sick.
	 * @throws IllegalArgumentException if there is no volunteer with the given id
	 */
	public void setSick(String id) {
		VaccineTrialVolunteer volunteer = this.getVolunteer(id);
		if (volunteer == null) {
			throw new IllegalArgumentException("invalid ID");
		}
		volunteer.setGotSick(true);
	}

	/**
	 * Get's the volunteer with the given ID
	 * 
	 * @param id The id of the volunteer to set sick.
	 * 
	 * @return The vaccine trial volunteer with the given ID. If the ID is not valid
	 *         for any volunteer, return null
	 */
	public VaccineTrialVolunteer getVolunteer(String id) {
		for (VaccineTrialVolunteer volunteer: volunteers) {
			if (volunteer.getId().equals(id)) {
				return volunteer;
			}
		}
		return null;
	}
}


Fyll inn set og get-metodene i Person-klassen. Du skal gjøre dette uten å endre kode i Address-klassen.

// DO NOT MODIFY THIS CLASS
public class Address {

	private String streetName;
	private int streetNumber;

	public Address(String streetName, int streetNumber) {
		this.streetName = streetName;
		this.streetNumber = streetNumber;
	}

	public String getStreetName() {
		return streetName;
	}

	public int getStreetNumber() {
		return streetNumber;
	}

}


public class Person {

	// No other fields should be added to this class
	private Address address;

	
	// You do not need to consider the edge case of passing null into the constructor here
	public Person(Address address) {
		this.address = address;
	}
	
	/**
	 * 
	 * @return the street name of this person
	 */
	public String getStreetName() {
		...
	}

	/**
	 * Updates the street name of this person
	 * 
	 * @param streetName The street name to update
	 */
	public void setStreetName(String streetName) {
		...
	}
	
	
	public int getStreetNumber() {
		...
	}

	/**
	 * Updates the street number of this person
	 * 
	 * @param streetNumber A positive integer.
	 * 
	 * @throws IllegalArgumentException If number is not larger than 0.
	 */
	public void setStreetNumber(int streetNumber) {
		...
	}
}

public class Person {

	// No other fields should be added to this class
	private Address address;

	
	// You do not need to consider the edge case of passing null into the constructor here
	public Person(Address address) {
		this.address = address;
	}
	
	/**
	 * 
	 * @return the street name of this person
	 */
	public String getStreetName() {
		return this.address.getStreetName();
	}

	/**
	 * Updates the street name of this person
	 * 
	 * @param streetName The street name to update
	 */
	public void setStreetName(String streetName) {
		this.address = new Address(streetName, this.address.getStreetNumber());
	}
	
	
	public int getStreetNumber() {
		return this.address.getStreetNumber();
	}

	/**
	 * Updates the street number of this person
	 * 
	 * @param streetNumber A positive integer.
	 * 
	 * @throws IllegalArgumentException If number is not larger than 0.
	 */
	public void setStreetNumber(int streetNumber) {
		if (streetNumber <= 0) {
			throw new IllegalArgumentException();
		}
		this.address = new Address(this.address.getStreetName(), streetNumber);

	}
}

Følgende vedlagte klasser/interfaces brukes, men skal ikke endres i denne oppgaven. Du trenger ikke forstå hvordan metodene er implementert, bare benytte deg direkte av de.

  • SomeServiceImpl - Implementasjon av SomeService.
  • SomeService - Grensesnitt som implementers i både SomeServiceImpl og LoggingSomeService.
  • Logger - En hjelpeklasse for å logge resultater.

Du skal fylle ut LoggingSomeService og metodene/konstruktør i denne klassen. LoggingSomeService skal delegere videre til en delegat, som skal utføre arbeidet, og deretter logge resultatet før det returneres. Følgende metoder skal implementeres:

  • LoggingSomeService(SomeService delegate, Logger logger) - Oppretter et objekt av LoggingSomeService med en delegat og en logger.
  • getAMagicString() - Returnerer en magisk String. Det er den delegertes oppgave å hente ut Stringen, og den skal logges før det returneres.
  • getAMagicNumber() - Returnerer et magisk tall. Det er den delegertes oppgave å hente ut tallet, og det skal logges før det returneres.
public interface SomeService {

	public String getAMagicString();

	public int getAMagicNumber();
}


public class Logger {

	// This is only for testing
	Collection<String> hasLogged = new ArrayList<>();

	public void log(String log) {
		System.out.println(log);
		hasLogged.add(log);
	}
}
public class SomeServiceImpl implements SomeService {

	@Override
	public String getAMagicString() {
		return "magic";
	}

	@Override
	public int getAMagicNumber() {
		return 42;
	}

}


public class LoggingSomeService implements SomeService {

	// Add needed fields here

	/*
	 * Creates a LoggingSomeService object with the given delegate and logger
	 */
	public LoggingSomeService(SomeService delegate, Logger logger) {
		...
	}

	@Override
	/**
	 * Delegates the job of calculating a magic string to the delegate, and logs the
	 * result before returning it
	 * 
	 * @return A string
	 */
	public String getAMagicString() {
		...
	}

	/**
	 * Delegates the job of calculating a magic number to the delegate, and logs the
	 * result before returning it
	 * 
	 * @return An integer
	 */
	@Override
	public int getAMagicNumber() {
		...
	}
}


public interface SomeService {

	public String getAMagicString();

	public int getAMagicNumber();
}

import java.util.ArrayList;
import java.util.Collection;

public class Logger {

	// This is only for testing
	Collection<String> hasLogged = new ArrayList<>();

	public void log(String log) {
		System.out.println(log);
		hasLogged.add(log);
	}
}
public class SomeServiceImpl implements SomeService {

	@Override
	public String getAMagicString() {
		return "magic";
	}

	@Override
	public int getAMagicNumber() {
		return 42;
	}

}
public class LoggingSomeService implements SomeService {

	// Add needed fields here
	private SomeService delegate;
	private Logger logger;
	/*
	 * Creates a LoggingSomeService object with the given delegate and logger
	 */
	public LoggingSomeService(SomeService delegate, Logger logger) {
		this.delegate = delegate;
		this.logger = logger;
	
	}

	@Override
	/**
	 * Delegates the job of calculating a magic string to the delegate, and logs the
	 * result before returning it
	 * 
	 * @return A string
	 */
	public String getAMagicString() {
		String magic = delegate.getAMagicString();
		logger.log(magic);
		return magic;
	}

	/**
	 * Delegates the job of calculating a magic number to the delegate, and logs the
	 * result before returning it
	 * 
	 * @return An integer
	 */
	@Override
	public int getAMagicNumber() {
		int magicNumber = delegate.getAMagicNumber();
		logger.log(Integer.toString(magicNumber));
		return magicNumber;
	}
}


Fyll inn vedlagte AthleteComparators og de to metodene der. Du skal ta utgangspunkt i, men ikke trenge å endre Athlete og Medal som ligger vedlagt.

Det er tillatt å legge til metoder i disse klassene dersom du mener det er hjelpemetoder som vil være til hjelp. Ingen ekstra metoder du legger til bør endre tilstanden til objektene.

Følgende metoder skal implementeres:

  • getSimpleComparator() - Returner en comparator som skal brukes til å sammenlikne Athletes basert på navnet deres alfabetisk. Det vil si at Ane kommer før Berit, som igjen kommer før Daniel.
  • getAdvancedComparator Returner en comparator som skal brukes til å sammenlikne Athletes basert på antall medaljer de har. En atlet som har to gullmedaljer, vil komme før en atlet som har en gullmedalje og en sølvmedalje. Dersom de har likt antall medaljer av en type går man videre til neste medaljetype, og hvis de har likt antall medaljer av alle typer skal man sammenlikne basert på navnet som i getSimpleComparator.
import java.util.ArrayList;
import java.util.List;

public class Athlete {
	
	private List<Medal> medals = new ArrayList<Medal>();
	private String country;
	private String name;

	public Athlete(String country, String name, List<Medal> medals) {
		this.name = name;
		this.country = country;
		this.medals = new ArrayList<>(medals);
	}

	public List<Medal> getMedals() {
		return new ArrayList<>(medals);
	}

	public String getCountry() {
		return country;
	}

	public String getName() {
		return name;
	}

}
import java.util.Arrays;
import java.util.List;

public class Medal {
	
	private String metal;
	public static List<String> validMetals = Arrays.asList("Gold", "Silver", "Bronze");

	public Medal(String metal) {
		if (!validMetals.contains(metal)) {
			throw new IllegalArgumentException("Invalid medal");
		}
		this.metal = metal;
	}

	public String getMetal() {
		return metal;
	}
}


public class AthleteComparators {

	/**
	 * @return a comparator that compares athletes based on their name. Using this
	 *          comparator, Ane should come before Berit
	 */
	public static Comparator<Athlete> getSimpleComparator() {
		...
	}

	/**
	 * @return A comparator that compares athletes based on the number of medals of
	 *          different valour. The comparator will be used for sorting athletes
	 *          based on putting the athlete with the highest number of medals of the best valour
	 *          first.
	 * 
	 *          If one athlete has more "Gold" medals than the other athlete it
	 *          should come before that one. If they have equal number of "Gold"
	 *          medals they should be compared on the number of "Silver" medals, and
	 *          if that is equal on the number of "Bronze" medals. If they have the
	 *          same number of medals of all valour, they should be compared based
	 *          on the name similar to getSimpleComparator
	 *          
	 *          The spelling and order of the medals can be seen in the list validMetals in the Medal class. 
	 */
	public static Comparator<Athlete> getAdvancedComparator() {
		...
	}
}

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class AthleteComparators {

	/**
	 * @return a comparator that compares athletes based on their name. Using this
	 *          comparator, Ane should come before Berit
	 */
	public static Comparator<Athlete> getSimpleComparator() {
		return new Comparator<Athlete>() {
			public int compare(Athlete a, Athlete b) {
				return a.getName().compareTo(b.getName());
			}
		};
	}

	/**
	 * @return A comparator that compares athletes based on the number of medals of
	 *          different valour. The comparator will be used for sorting athletes
	 *          based on putting the athlete with the highest number of medals of the best valour
	 *          first.
	 * 
	 *          If one athlete has more "Gold" medals than the other athlete it
	 *          should come before that one. If they have equal number of "Gold"
	 *          medals they should be compared on the number of "Silver" medals, and
	 *          if that is equal on the number of "Bronze" medals. If they have the
	 *          same number of medals of all valour, they should be compared based
	 *          on the name similar to getSimpleComparator
	 *          
	 *          The spelling and order of the medals can be seen in the list validMetals in the Medal class. 
	 */
	public static Comparator<Athlete> getAdvancedComparator() {
		return new Comparator<Athlete>() {
			public int compare(Athlete a, Athlete b) {

				for (String metal : Medal.validMetals) {
					int numberOfMedalsA = (int) a.getMedals().stream().filter(medal -> medal.getMetal().equals(metal))
							.count();
					int numberOfMedalsB = (int) b.getMedals().stream().filter(medal -> medal.getMetal().equals(metal))
							.count();
					if (numberOfMedalsA != numberOfMedalsB) {
						return numberOfMedalsB - numberOfMedalsA;
					}
				}
				return a.getName().compareTo(b.getName());
			}
		};
	}
}









  • No labels