Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of the QuestionPriceArea class #45

Merged
merged 19 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package io.github.oliviercailloux.y2018.apartments.valuefunction.profile;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.collect.Range;
import io.github.oliviercailloux.y2018.apartments.valuefunction.Criterion;

public class QuestionPriceArea {
int price;
int surface;
av1m marked this conversation as resolved.
Show resolved Hide resolved
private final String question = "Would you pay %d€ more for %d m2 more?";
av1m marked this conversation as resolved.
Show resolved Hide resolved

/**
* Instantiates a new question price/area.
*
* @param price the price shown to the user according to his/her profile
* @param surface the surface shown to the user according to his/her profile
*/
private QuestionPriceArea(int price, int surface) {
this.price = price;
this.surface = surface;
}

/**
* Creates the object question.
*
* @param price the price
* @param surface the surface
* @return the question price area
*/
public static QuestionPriceArea create(int price, int surface) {
return new QuestionPriceArea(price, surface);
}

/**
* Getter for attribute price
av1m marked this conversation as resolved.
Show resolved Hide resolved
*
* @return the price : question parameter
*/
public int getPrice() {
return this.price;
}

/**
* Getter for attribute surface
av1m marked this conversation as resolved.
Show resolved Hide resolved
*
* @return the surface : question parameter
*/
public int getSurface() {
return this.surface;
}

/**
* Build the question according to parameters emitted during class creation
*
* @return the question constructed
*/
public String getQuestion() {
return String.format(this.question, this.getPrice(), this.getSurface());
}

/**
* Adapt the interval of weight contained in a profile depending on his response
*
* @param p the profile we need to modify
* @param response the response of the user
*/
public void resolve(Profile p, boolean response) {
av1m marked this conversation as resolved.
Show resolved Hide resolved
checkNotNull(p);
Criterion firstCriterion;
Criterion secondCriterion;
Range<Double> closedRange;

/**
* The code is very similar if the boolean response is true or false. The only factor that
* changes is the criteria. Thus, one seeks to know which criterion is given to which range. So
* we check this based on the boolean
*/
if (response) {
firstCriterion = Criterion.FLOOR_AREA;
secondCriterion = Criterion.PRICE_PER_NIGHT;
} else {
secondCriterion = Criterion.FLOOR_AREA;
firstCriterion = Criterion.PRICE_PER_NIGHT;
}

final Range<Double> firstRange = p.getWeightRange(firstCriterion);
final Range<Double> secondRange = p.getWeightRange(secondCriterion);

final double min = firstRange.lowerEndpoint() + p.getMiddleOfRange(firstCriterion) * 0.2;
if (min >= firstRange.upperEndpoint()) {
closedRange = Range.closed(firstRange.upperEndpoint(), firstRange.upperEndpoint());
} else {
closedRange = Range.closed(min, firstRange.upperEndpoint());
}
p.setWeightRange(firstCriterion, closedRange);

final double max = secondRange.upperEndpoint() - p.getMiddleOfRange(secondCriterion) * 0.1;
if (max <= secondRange.lowerEndpoint()) {
closedRange = Range.closed(secondRange.lowerEndpoint(), secondRange.lowerEndpoint());
} else {
closedRange = Range.closed(secondRange.lowerEndpoint(), max);
}
av1m marked this conversation as resolved.
Show resolved Hide resolved
p.setWeightRange(secondCriterion, closedRange);
av1m marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.github.oliviercailloux.y2018.apartments.valuefunction.profile;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.google.common.collect.Range;
import io.github.oliviercailloux.y2018.apartments.valuefunction.Criterion;
import java.util.Arrays;
import org.junit.jupiter.api.Test;

public class QuestionPriceAreaTests {

/** Verifying the initialization of the object QuestionPriceArea. */
@Test
void testInitialization() {
QuestionPriceArea q = QuestionPriceArea.create(100, 10);
assertEquals(100, q.getPrice());
assertEquals(10, q.getSurface());
assertEquals("Would you pay 100€ more for 10 m2 more?", q.getQuestion());
}

/**
* Test if the resolve method works well. The code in comment needs the class Profile first to be
* merge to work correctly
*/
@Test
void testResolve() {
QuestionPriceArea q = QuestionPriceArea.create(100, 10);
assertThrows(NullPointerException.class, () -> q.resolve(new Profile.Builder().build(), true));
// Profile construction
Range<Double> surface = Range.closed(100d, 300d);
Range<Double> price = Range.closed(500d, 1500d);
Profile.Builder profileBuilder = new Profile.Builder();
Arrays.stream(Criterion.values())
.forEach(c -> profileBuilder.setWeightRange(c, Range.closed(0d, 10d)));
profileBuilder
.setWeightRange(Criterion.FLOOR_AREA, surface.lowerEndpoint(), surface.upperEndpoint())
.setWeightRange(Criterion.PRICE_PER_NIGHT, price.lowerEndpoint(), price.upperEndpoint());
Profile p = profileBuilder.build();
q.resolve(p, false);
assertEquals(700d, p.getWeightRange(Criterion.PRICE_PER_NIGHT).lowerEndpoint());
assertEquals(280d, p.getWeightRange(Criterion.FLOOR_AREA).upperEndpoint());
q.resolve(p, true);
assertEquals(138d, p.getWeightRange(Criterion.FLOOR_AREA).lowerEndpoint());
assertEquals(1390d, p.getWeightRange(Criterion.PRICE_PER_NIGHT).upperEndpoint());
}
}