Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleDel 1 - Småplukk (25%)

Denne delen består av mindre, uavhengige oppgaver som tester spesifikke ferdigheter.

Expand
titleString-håndtering

Denne klassen hjelper til med formattering av oppramsinger av typen, "en, to og tre". Poenget er at en har to måter å skille elementer på, én som brukes mellom alle elementene utenom de to siste og én som brukes mellom de to siste. Separatorene (mainSeparator og lastSeparator) kan være like, som i eksempelet "en, to, tre, fire".

  • Skriv metodene som mangler i Joiner-klassen.
Code Block
languagejava
package stuff;

import java.util.Arrays;
import java.util.Iterator;

public class Joiner {

    private final String mainSeparator;
    private final String lastSeparator;

    
    /**
     * Joins the strings together, where all elements but the two last are separated by mainSeparator, and
     * the two last are separated by lastSeparator. If lastSeparator is null, mainSeparator is used between all elements.
     * E.g. if you join the strings "one", "two", "three" with mainSeparator as ", " and lastSeparator as " and ",
     * you should get "one, to and three".
     * If strings contains only one element, that element is returned, if it contains no elements, the empty string is returned.
     * @param strings the strings to join
     * @param mainSeparator the separator used between all but the two last elements
     * @param lastSeparator the separator used between the last two elements
     * @return strings joined with the provided separators
     */
    public static String join(final Iterator<String> strings, final String mainSeparator, final String lastSeparator) {
        final StringBuilder builder = new StringBuilder();
        while (strings.hasNext()) {
            final String item = strings.next();
            if (builder.length() > 0) {
                final String sep = (strings.hasNext() || lastSeparator == null ? mainSeparator : lastSeparator);
                builder.append(sep);
            }
            builder.append(item);
        }
        return builder.toString();
    }
    /**
     * Initialises this Joiner with the provided separators.
     * @param mainSeparator the separator to use between all but the last two elements
     * @param lastSeparator the separator to use between the last two elements
     */
    public Joiner(final String mainSeparator, final String lastSeparator) {
        this.mainSeparator = mainSeparator;
        this.lastSeparator = lastSeparator;
    }

    /**
     * Initialises this Joiner with the provided separator.
     * @param separator the separator to use between all elements
     */
    public Joiner(final String separator) {
        this(separator, null);
    }

    /**
     * Joins strings with the provided mainSeparator and lastSeparator
     * @param strings the strings to join
     * @return the joined strings
     */
    public String join(final Iterator<String> strings) {
        return Joiner.join(strings, mainSeparator, lastSeparator);
    }

    /**
     * Joins strings with the provided mainSeparator and lastSeparator
     * @param strings the strings to join
     * @return the joined strings
     */
    public String join(final Iterable<String> strings) {
        return join(strings.iterator());
    }

    /**
     * Joins strings with the provided mainSeparator and lastSeparator
     * @param strings the strings to join
     * @return the joined strings
     */
    public String join(final String... strings) {
        return join(Arrays.asList(strings));
    }
}

Her skulle kandidatene vise kunnskap i manipulering av strenger, iteratorer og iterables. De ulike metodene skal samtidig vise ulike former for iterering – over Iterable, String… og Iterator. Dersom kandidaten kan alle disse (og starter øverst) er de knyttet tett sammen og en slipper å gjøre mye på nummer to og utover.

Typiske feil: Mange har ikke sett at en ved å løse første oppgave kan løse resten med enlinjerskall. De har dermed løst omtrent samme oppgave flere ganger, med gjentakende kode. En del hadde også løst at en tar inn en iterator ved å fylle opp en liste. Det er en liten omvei, men hvis all kode fungerte ga det allikevel full skår.


Expand
titleTesting - MedianComputerTest

Summer-klassen inneholder tre metoder med kode som virker i noen tilfeller (bl.a. de som testes av eksisterende testmetoder i SummerTest), men feiler i andre. Oppgaven går ut på å utvide SummerTest-klassen med ekstra testmetoder som avdekker disse feilene på en hensiktsmessig måte. Du skal altså ikke fikse på koden, bare lage testene.

  • Skriv nødvendige metoder i SummerTest-klassen.

MedianComputer og MedianComputerTest

Følgende figur fra Wikipedia beskriver beregning av median-verdien til en samling tall.

  • Deklarer en compute-metode i MedianComputer-klassen som passer for formålet å beregne median.

  • Skriv en eller flere testmetoder i MedianComputerTest-klassen som tester at compute-metoden virker som den skal, og på en måte som avdekker det du anser som mulige feil.

Du trenger deklarasjonen av compute for å kunne skrive testene, men du trenger ikke implementere den, bare skrive nok kode til at den kompilerer. Om du velger å implementere den, f.eks. for å kunne kjøre testen-klassen, så vil vi ikke vurdere implementasjonen, kun deklarasjonen og test-logikken. Legg merke til behovet for avrunding i AssetEquals, eksempel på toppen av koden.

Et eksempel på implementasjon av MedianComputer:

Code Block
languagejava
package stuff;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class MedianComputer {

    public static double compute(final Collection<Double> nums) throws IllegalArgumentException {
        if (nums.size() < 1) {
            throw new IllegalArgumentException("Cannot compute median of no values");
        }
        final List<Double> sorted = new ArrayList<>(nums);
        Collections.sort(sorted);
        final int size = sorted.size();
        if (size % 2 == 0) {
            return (sorted.get(size / 2 - 1) + sorted.get(size / 2)) / 2;
        } else {
            return sorted.get(size / 2);
        }
    }
}

Eksempel på tester for flere ulike typer feil:

Code Block
languagejava
    package stuff;

import static org.junit.Assert.fail;

import java.util.List;

import org.junit.Assert;
import org.junit.Test;

public class MedianComputerTest {

    // use as third argument to assertEquals method for handling round-off errors
    double roundErrorDelta = 0.00000001;

    @Test
    public void testComputeEvenSize() {
        Assert.assertEquals(6.0, MedianComputer.compute(List.of(1.0, 3.0, 3.0, 6.0, 7.0, 8.0, 9.0)), roundErrorDelta);
    }

    @Test
    public void testComputeOddSize() {
        Assert.assertEquals(4.5, MedianComputer.compute(List.of(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 9.0)), roundErrorDelta);
    }

    @Test
    public void testComputeSize1() {
        Assert.assertEquals(4.5, MedianComputer.compute(List.of(4.5)), roundErrorDelta);
    }

    @Test
    public void testComputeSize2() {
        Assert.assertEquals(4.5, MedianComputer.compute(List.of(4.0, 5.0)), roundErrorDelta);
    }

    @Test
    public void testComputeSize0() {
        try {
            MedianComputer.compute(List.of());
            fail();
        } catch (final Exception e) {
            Assert.assertTrue(e instanceof IllegalArgumentException);
        }
    }
}


Her kunne de (hvis de ønsket) implementere MedianComputer, men målet var egentlig å skrive tester som viser at de kan dekke krav til en metode, spesielt grensetilfeller. Beregner den korrekt null elementer, ett, to, odde eller like antall elementer. Poeng gis etter hvor stor del av disse en tester for. Det var ikke behov for å lage en fullstendig kode for MedianComputer her – oppgaveteksten sier at en bare må ha noe som kompilerer.


Expand
titleTesting - SummerTest

Summer-klassen inneholder tre metoder med kode som virker i noen tilfeller (bl.a. de som testes av eksisterende testmetoder i SummerTest), men feiler i andre. Oppgaven går ut på å utvide SummerTest-klassen med ekstra testmetoder som avdekker disse feilene på en hensiktsmessig måte. Du skal altså ikke fikse på koden, bare lage testene.

  • Skriv nødvendige metoder i SummerTest-klassen.

Code Block
languagejava
package stuff;

import java.util.List;

import org.junit.Assert;
import org.junit.Test;

public class SummerTest {

    @Test
    public void testSum1() {
        Assert.assertEquals(6, Summer.sum(List.of(1, 2, 3)));
    }

    @Test
    public void testSumMistake() {
        Assert.assertEquals(0, Summer.sum(List.of()));
    }

    @Test
    public void testDifference1() {
        Assert.assertEquals(0, Summer.difference(List.of(6, 1, 2, 3)));
    }

    @Test
    public void testDifferenceMistake() {
        try {
            Summer.difference(List.of());
            Assert.fail("Empty list should throw IllegalArgumentException");
        } catch (final Exception e) {
            Assert.assertTrue("Empty list should throw IllegalArgumentException", e instanceof IllegalArgumentException);
        }
    }
}

Her er det altså SummerTest.java som skrives av kandidaten, ikke Summer.java. Målet er at de skal forstå koden til Summer.java, og klarer å skrive to tester som feiler (suksess her er gjerne 1 error og en failure, hvis testene gjør det de skal.)

-        testSumMistake() skal forvente at Summer.sum() med en tom liste blir 0. Det blir den jo ikke..

-        testDifferenceMistake() skal teste at difference.of() med en tom liste ikke utløser en IllegalArgumentException, slik  javadoc beskriver.


...