Insurance Premium Quote Challenge











up vote
1
down vote

favorite












I was failed at coding challenge for my interview with the following reasons given by the interviewer: deep use of mutation and a not that well thought up internal API.



I understand that my code and design have so many flaws and I genuinely want to get your opinion so I could improve my code.



The challenge is about asking me to build a quote processor to calculate a premium for different products, based on different rule sets.



Since the requirements are very lengthy, I try to summarize it below:



Data model




  • A user (with an id, an address, and a risk value)

  • An address (with an id and a location risk value)

  • A product (with an id and a price value)


(Risk values are in our patented Universal Risk Value Scale [tm])



For products we have modelled in our system the following types:
- Houses (with address and size in square meters)
- Bananas (with number of black spots)
- Bicycles (with number of gears)



Asides from above, the premium quote would need to take in rules, base surcharge, universal risk value for each product and each user to quote a premium for user.



Rules



We want to build a quote processor that will receive a user and a set of products, and return whether we reject the user or not, and if not, for how much premium will we insure the products in euros per year.



To ensure this, we have a set of rules to follow.



Each product will have a base premium value, that multiplied by the product value will give a subtotal for the product's premium. To this subtotal, we must add a surcharge that depends on the product type and maybe on other rules. Each surcharge is multiplied to the base value.



Then, for all the products, if for one the rules say that it is un-insurable, then the final result given is that we won't offer an insurance. If no product is un-insurable, then we add all the premiums and that is the quote we return to the user.



Below are my classes, I am putting here one or two model classes just to present my design.



It is my first time using SO so I do not know how to put code in a good way yet, please understand.




  1. Interfaces:



public interface Product {
BigDecimal getProductValue();
BigDecimal getBasePremium();
BigDecimal getSubTotalPremium();
}

public interface Risk {

void setRiskValue(int riskValue);
BigDecimal getRiskSurcharge();

static BigDecimal getUnIdentifiedRiskSurcharge()
{
return new BigDecimal(-1);
}

static BigDecimal getDefaultRiskSurcharge()
{
return new BigDecimal(0);
}

static boolean isWithinRange(int riskValue, int minValue, int maxValue)
{
return riskValue >= minValue && riskValue <= maxValue;
}
}




  1. Model classes:


    • Base class InsuredProduct implements above interfaces.





public abstract class InsuredProduct implements Product, Risk {
private int id;
private BigDecimal productValue;
private int riskValue;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

public InsuredProduct(int id, BigDecimal productValue)
{
this.id = id;
this.productValue =productValue;
}

public BigDecimal getProductValue() {
return productValue;
}

public void setProductValue(BigDecimal productValue) {
this.productValue = productValue;
}

@Override
public BigDecimal getSubTotalPremium()
{
return getProductValue().multiply(getBasePremium());
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

public int getRiskValue() {
return this.riskValue;
}

}




  • Then Banana class as insured product extends from base class:



public class Banana extends InsuredProduct {
private static BigDecimal BASE_PREMIUM = new BigDecimal(1.15);

private int noOfBlackSpots;
private int userRiskValue;

public Banana(int id, BigDecimal productValue) {
super(id, productValue);
}

public int getNoOfBlackSpots() {
return noOfBlackSpots;
}

public void setNoOfBlackSpots(int noOfBlackSpots) {
this.noOfBlackSpots = noOfBlackSpots;
}

@Override
public BigDecimal getBasePremium() {
return BASE_PREMIUM;
}

@Override
public BigDecimal getRiskSurcharge() {
if(this.userRiskValue > 200)
return Risk.getUnIdentifiedRiskSurcharge();

final int minAcceptableBlackSpots = 3;
final int maxAcceptableBlackSpots = 12;

if(Risk.isWithinRange(this.noOfBlackSpots, minAcceptableBlackSpots, maxAcceptableBlackSpots))
return Risk.getDefaultRiskSurcharge();

return Risk.getUnIdentifiedRiskSurcharge();
}

@Override
public void setRiskValue(int riskValue) {
this.userRiskValue = riskValue;
}
}




  • A User class (with Address) as an insured person. User's address is also part of risk surcharge to determine the quote calculation.



public class User implements Risk {
private static final BigDecimal MAXIMUM_USER_RISK_SURCHARGE = new BigDecimal(3.0);
private static final BigDecimal MEDIUM_USER_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_USER_RISK_SURCHARGE = new BigDecimal(0.3);

private int id;
private Address address;
private int riskValue;

public User(int id, Address address)
{
this.setId(id);
this.setAddress(address);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public int getRiskValue() {
return riskValue;
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedRiskValue = 501;
final int startMinimumRiskValue = 20;
final int endMinimumRangeRiskValue = 200;
final int startMaximumRiskValue = 201;
final int endMaximumRangeRiskValue = 500;

if(this.getRiskValue() >= unsupportedRiskValue)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumRiskValue)
return MINIMUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumRiskValue, endMinimumRangeRiskValue))
return MEDIUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumRiskValue, endMaximumRangeRiskValue))
return MAXIMUM_USER_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}

}

public class Address implements Risk{
private static final BigDecimal MAXIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(2.5);
private static final BigDecimal MEDIUM_LOCATION_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(0.7);

private int id;
private int locationRisk;

public Address(int id)
{
this.id = id;
}

public int getRiskValue() {
return locationRisk;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public void setRiskValue(int riskValue) {
this.locationRisk = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedLocationRisk = 502;
final int startMinimumLocationRisk = 100;
final int endMinimumRangeLocationRisk = 299;
final int startMaximumLocationRisk = 300;
final int endMaximumRangeLocationRisk = 501;

if(this.getRiskValue() >= unsupportedLocationRisk)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumLocationRisk)
return MINIMUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumLocationRisk, endMinimumRangeLocationRisk))
return MEDIUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumLocationRisk, endMaximumRangeLocationRisk))
return MAXIMUM_LOCATION_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}
}




  1. Processor: To calculate the premium quote or to determine if it's is insurable.



public class UserPremiumBuilder<T extends InsuredProduct> {

private User user;
T product;

private UserPremiumBuilder(User user){
this.user = user;
}

public static <T extends InsuredProduct> UserPremiumBuilder<T> createProfile(User user){
UserPremiumBuilder<T> builder = new UserPremiumBuilder<T>(user);
return builder;
}

public UserPremiumBuilder <T> setProduct(T product) {
this.product = product;
return this;
}

public BigDecimal calculateSingleProductPremiumForUser() {
BigDecimal userRiskSurcharge = user.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(userRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

this.product.setRiskValue(this.user.getRiskValue());
BigDecimal productRiskSurcharge =this.product.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(productRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

if(Risk.getDefaultRiskSurcharge().compareTo(productRiskSurcharge)==0)
return this.product.getSubTotalPremium();

BigDecimal totalPremium = this.product.getSubTotalPremium().multiply(this.product.getRiskSurcharge()).multiply(user.getRiskSurcharge());
return totalPremium;
}

}




  1. A sample unit test class:



public class UserPremiumBuilderBananaTest {
Banana banana;

@Before
public void initBanana()
{
banana = new Banana(1, new BigDecimal(10));
}

@Test
public void testUnInsurableBananaRiskSurchargeWithUserRiskValueLargerThan200() {
User user = initUser(10);
user.setRiskValue(201);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(4);

BigDecimal totalPremium = createProfile(user).setProduct(banana).calculateSingleProductPremiumForUser();
assertEquals(Risk.getUnIdentifiedRiskSurcharge(), totalPremium);
}

@Test
public void testInsurableBananaRiskSurchargeWithUserRiskNotGreaterThan200() {
User user = initUser(10);
user.setRiskValue(200);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(3);

UserPremiumBuilder<Banana> builder = createProfile(user);
BigDecimal totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
BigDecimal productPremium = banana.getSubTotalPremium().setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

user.setRiskValue(199);
totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

}

private static UserPremiumBuilder<Banana> createProfile(User user)
{
return UserPremiumBuilder.createProfile(user);
}

private User initUser(int addressRiskValue)
{
Address address = new Address(1);
address.setRiskValue(addressRiskValue);
User user = new User(1, address);
return user;
}
}










share|improve this question







New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
    – Tom
    12 hours ago










  • @Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
    – Anna
    11 hours ago










  • I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
    – Tom
    11 hours ago















up vote
1
down vote

favorite












I was failed at coding challenge for my interview with the following reasons given by the interviewer: deep use of mutation and a not that well thought up internal API.



I understand that my code and design have so many flaws and I genuinely want to get your opinion so I could improve my code.



The challenge is about asking me to build a quote processor to calculate a premium for different products, based on different rule sets.



Since the requirements are very lengthy, I try to summarize it below:



Data model




  • A user (with an id, an address, and a risk value)

  • An address (with an id and a location risk value)

  • A product (with an id and a price value)


(Risk values are in our patented Universal Risk Value Scale [tm])



For products we have modelled in our system the following types:
- Houses (with address and size in square meters)
- Bananas (with number of black spots)
- Bicycles (with number of gears)



Asides from above, the premium quote would need to take in rules, base surcharge, universal risk value for each product and each user to quote a premium for user.



Rules



We want to build a quote processor that will receive a user and a set of products, and return whether we reject the user or not, and if not, for how much premium will we insure the products in euros per year.



To ensure this, we have a set of rules to follow.



Each product will have a base premium value, that multiplied by the product value will give a subtotal for the product's premium. To this subtotal, we must add a surcharge that depends on the product type and maybe on other rules. Each surcharge is multiplied to the base value.



Then, for all the products, if for one the rules say that it is un-insurable, then the final result given is that we won't offer an insurance. If no product is un-insurable, then we add all the premiums and that is the quote we return to the user.



Below are my classes, I am putting here one or two model classes just to present my design.



It is my first time using SO so I do not know how to put code in a good way yet, please understand.




  1. Interfaces:



public interface Product {
BigDecimal getProductValue();
BigDecimal getBasePremium();
BigDecimal getSubTotalPremium();
}

public interface Risk {

void setRiskValue(int riskValue);
BigDecimal getRiskSurcharge();

static BigDecimal getUnIdentifiedRiskSurcharge()
{
return new BigDecimal(-1);
}

static BigDecimal getDefaultRiskSurcharge()
{
return new BigDecimal(0);
}

static boolean isWithinRange(int riskValue, int minValue, int maxValue)
{
return riskValue >= minValue && riskValue <= maxValue;
}
}




  1. Model classes:


    • Base class InsuredProduct implements above interfaces.





public abstract class InsuredProduct implements Product, Risk {
private int id;
private BigDecimal productValue;
private int riskValue;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

public InsuredProduct(int id, BigDecimal productValue)
{
this.id = id;
this.productValue =productValue;
}

public BigDecimal getProductValue() {
return productValue;
}

public void setProductValue(BigDecimal productValue) {
this.productValue = productValue;
}

@Override
public BigDecimal getSubTotalPremium()
{
return getProductValue().multiply(getBasePremium());
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

public int getRiskValue() {
return this.riskValue;
}

}




  • Then Banana class as insured product extends from base class:



public class Banana extends InsuredProduct {
private static BigDecimal BASE_PREMIUM = new BigDecimal(1.15);

private int noOfBlackSpots;
private int userRiskValue;

public Banana(int id, BigDecimal productValue) {
super(id, productValue);
}

public int getNoOfBlackSpots() {
return noOfBlackSpots;
}

public void setNoOfBlackSpots(int noOfBlackSpots) {
this.noOfBlackSpots = noOfBlackSpots;
}

@Override
public BigDecimal getBasePremium() {
return BASE_PREMIUM;
}

@Override
public BigDecimal getRiskSurcharge() {
if(this.userRiskValue > 200)
return Risk.getUnIdentifiedRiskSurcharge();

final int minAcceptableBlackSpots = 3;
final int maxAcceptableBlackSpots = 12;

if(Risk.isWithinRange(this.noOfBlackSpots, minAcceptableBlackSpots, maxAcceptableBlackSpots))
return Risk.getDefaultRiskSurcharge();

return Risk.getUnIdentifiedRiskSurcharge();
}

@Override
public void setRiskValue(int riskValue) {
this.userRiskValue = riskValue;
}
}




  • A User class (with Address) as an insured person. User's address is also part of risk surcharge to determine the quote calculation.



public class User implements Risk {
private static final BigDecimal MAXIMUM_USER_RISK_SURCHARGE = new BigDecimal(3.0);
private static final BigDecimal MEDIUM_USER_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_USER_RISK_SURCHARGE = new BigDecimal(0.3);

private int id;
private Address address;
private int riskValue;

public User(int id, Address address)
{
this.setId(id);
this.setAddress(address);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public int getRiskValue() {
return riskValue;
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedRiskValue = 501;
final int startMinimumRiskValue = 20;
final int endMinimumRangeRiskValue = 200;
final int startMaximumRiskValue = 201;
final int endMaximumRangeRiskValue = 500;

if(this.getRiskValue() >= unsupportedRiskValue)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumRiskValue)
return MINIMUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumRiskValue, endMinimumRangeRiskValue))
return MEDIUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumRiskValue, endMaximumRangeRiskValue))
return MAXIMUM_USER_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}

}

public class Address implements Risk{
private static final BigDecimal MAXIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(2.5);
private static final BigDecimal MEDIUM_LOCATION_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(0.7);

private int id;
private int locationRisk;

public Address(int id)
{
this.id = id;
}

public int getRiskValue() {
return locationRisk;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public void setRiskValue(int riskValue) {
this.locationRisk = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedLocationRisk = 502;
final int startMinimumLocationRisk = 100;
final int endMinimumRangeLocationRisk = 299;
final int startMaximumLocationRisk = 300;
final int endMaximumRangeLocationRisk = 501;

if(this.getRiskValue() >= unsupportedLocationRisk)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumLocationRisk)
return MINIMUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumLocationRisk, endMinimumRangeLocationRisk))
return MEDIUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumLocationRisk, endMaximumRangeLocationRisk))
return MAXIMUM_LOCATION_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}
}




  1. Processor: To calculate the premium quote or to determine if it's is insurable.



public class UserPremiumBuilder<T extends InsuredProduct> {

private User user;
T product;

private UserPremiumBuilder(User user){
this.user = user;
}

public static <T extends InsuredProduct> UserPremiumBuilder<T> createProfile(User user){
UserPremiumBuilder<T> builder = new UserPremiumBuilder<T>(user);
return builder;
}

public UserPremiumBuilder <T> setProduct(T product) {
this.product = product;
return this;
}

public BigDecimal calculateSingleProductPremiumForUser() {
BigDecimal userRiskSurcharge = user.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(userRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

this.product.setRiskValue(this.user.getRiskValue());
BigDecimal productRiskSurcharge =this.product.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(productRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

if(Risk.getDefaultRiskSurcharge().compareTo(productRiskSurcharge)==0)
return this.product.getSubTotalPremium();

BigDecimal totalPremium = this.product.getSubTotalPremium().multiply(this.product.getRiskSurcharge()).multiply(user.getRiskSurcharge());
return totalPremium;
}

}




  1. A sample unit test class:



public class UserPremiumBuilderBananaTest {
Banana banana;

@Before
public void initBanana()
{
banana = new Banana(1, new BigDecimal(10));
}

@Test
public void testUnInsurableBananaRiskSurchargeWithUserRiskValueLargerThan200() {
User user = initUser(10);
user.setRiskValue(201);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(4);

BigDecimal totalPremium = createProfile(user).setProduct(banana).calculateSingleProductPremiumForUser();
assertEquals(Risk.getUnIdentifiedRiskSurcharge(), totalPremium);
}

@Test
public void testInsurableBananaRiskSurchargeWithUserRiskNotGreaterThan200() {
User user = initUser(10);
user.setRiskValue(200);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(3);

UserPremiumBuilder<Banana> builder = createProfile(user);
BigDecimal totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
BigDecimal productPremium = banana.getSubTotalPremium().setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

user.setRiskValue(199);
totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

}

private static UserPremiumBuilder<Banana> createProfile(User user)
{
return UserPremiumBuilder.createProfile(user);
}

private User initUser(int addressRiskValue)
{
Address address = new Address(1);
address.setRiskValue(addressRiskValue);
User user = new User(1, address);
return user;
}
}










share|improve this question







New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
    – Tom
    12 hours ago










  • @Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
    – Anna
    11 hours ago










  • I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
    – Tom
    11 hours ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I was failed at coding challenge for my interview with the following reasons given by the interviewer: deep use of mutation and a not that well thought up internal API.



I understand that my code and design have so many flaws and I genuinely want to get your opinion so I could improve my code.



The challenge is about asking me to build a quote processor to calculate a premium for different products, based on different rule sets.



Since the requirements are very lengthy, I try to summarize it below:



Data model




  • A user (with an id, an address, and a risk value)

  • An address (with an id and a location risk value)

  • A product (with an id and a price value)


(Risk values are in our patented Universal Risk Value Scale [tm])



For products we have modelled in our system the following types:
- Houses (with address and size in square meters)
- Bananas (with number of black spots)
- Bicycles (with number of gears)



Asides from above, the premium quote would need to take in rules, base surcharge, universal risk value for each product and each user to quote a premium for user.



Rules



We want to build a quote processor that will receive a user and a set of products, and return whether we reject the user or not, and if not, for how much premium will we insure the products in euros per year.



To ensure this, we have a set of rules to follow.



Each product will have a base premium value, that multiplied by the product value will give a subtotal for the product's premium. To this subtotal, we must add a surcharge that depends on the product type and maybe on other rules. Each surcharge is multiplied to the base value.



Then, for all the products, if for one the rules say that it is un-insurable, then the final result given is that we won't offer an insurance. If no product is un-insurable, then we add all the premiums and that is the quote we return to the user.



Below are my classes, I am putting here one or two model classes just to present my design.



It is my first time using SO so I do not know how to put code in a good way yet, please understand.




  1. Interfaces:



public interface Product {
BigDecimal getProductValue();
BigDecimal getBasePremium();
BigDecimal getSubTotalPremium();
}

public interface Risk {

void setRiskValue(int riskValue);
BigDecimal getRiskSurcharge();

static BigDecimal getUnIdentifiedRiskSurcharge()
{
return new BigDecimal(-1);
}

static BigDecimal getDefaultRiskSurcharge()
{
return new BigDecimal(0);
}

static boolean isWithinRange(int riskValue, int minValue, int maxValue)
{
return riskValue >= minValue && riskValue <= maxValue;
}
}




  1. Model classes:


    • Base class InsuredProduct implements above interfaces.





public abstract class InsuredProduct implements Product, Risk {
private int id;
private BigDecimal productValue;
private int riskValue;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

public InsuredProduct(int id, BigDecimal productValue)
{
this.id = id;
this.productValue =productValue;
}

public BigDecimal getProductValue() {
return productValue;
}

public void setProductValue(BigDecimal productValue) {
this.productValue = productValue;
}

@Override
public BigDecimal getSubTotalPremium()
{
return getProductValue().multiply(getBasePremium());
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

public int getRiskValue() {
return this.riskValue;
}

}




  • Then Banana class as insured product extends from base class:



public class Banana extends InsuredProduct {
private static BigDecimal BASE_PREMIUM = new BigDecimal(1.15);

private int noOfBlackSpots;
private int userRiskValue;

public Banana(int id, BigDecimal productValue) {
super(id, productValue);
}

public int getNoOfBlackSpots() {
return noOfBlackSpots;
}

public void setNoOfBlackSpots(int noOfBlackSpots) {
this.noOfBlackSpots = noOfBlackSpots;
}

@Override
public BigDecimal getBasePremium() {
return BASE_PREMIUM;
}

@Override
public BigDecimal getRiskSurcharge() {
if(this.userRiskValue > 200)
return Risk.getUnIdentifiedRiskSurcharge();

final int minAcceptableBlackSpots = 3;
final int maxAcceptableBlackSpots = 12;

if(Risk.isWithinRange(this.noOfBlackSpots, minAcceptableBlackSpots, maxAcceptableBlackSpots))
return Risk.getDefaultRiskSurcharge();

return Risk.getUnIdentifiedRiskSurcharge();
}

@Override
public void setRiskValue(int riskValue) {
this.userRiskValue = riskValue;
}
}




  • A User class (with Address) as an insured person. User's address is also part of risk surcharge to determine the quote calculation.



public class User implements Risk {
private static final BigDecimal MAXIMUM_USER_RISK_SURCHARGE = new BigDecimal(3.0);
private static final BigDecimal MEDIUM_USER_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_USER_RISK_SURCHARGE = new BigDecimal(0.3);

private int id;
private Address address;
private int riskValue;

public User(int id, Address address)
{
this.setId(id);
this.setAddress(address);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public int getRiskValue() {
return riskValue;
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedRiskValue = 501;
final int startMinimumRiskValue = 20;
final int endMinimumRangeRiskValue = 200;
final int startMaximumRiskValue = 201;
final int endMaximumRangeRiskValue = 500;

if(this.getRiskValue() >= unsupportedRiskValue)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumRiskValue)
return MINIMUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumRiskValue, endMinimumRangeRiskValue))
return MEDIUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumRiskValue, endMaximumRangeRiskValue))
return MAXIMUM_USER_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}

}

public class Address implements Risk{
private static final BigDecimal MAXIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(2.5);
private static final BigDecimal MEDIUM_LOCATION_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(0.7);

private int id;
private int locationRisk;

public Address(int id)
{
this.id = id;
}

public int getRiskValue() {
return locationRisk;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public void setRiskValue(int riskValue) {
this.locationRisk = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedLocationRisk = 502;
final int startMinimumLocationRisk = 100;
final int endMinimumRangeLocationRisk = 299;
final int startMaximumLocationRisk = 300;
final int endMaximumRangeLocationRisk = 501;

if(this.getRiskValue() >= unsupportedLocationRisk)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumLocationRisk)
return MINIMUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumLocationRisk, endMinimumRangeLocationRisk))
return MEDIUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumLocationRisk, endMaximumRangeLocationRisk))
return MAXIMUM_LOCATION_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}
}




  1. Processor: To calculate the premium quote or to determine if it's is insurable.



public class UserPremiumBuilder<T extends InsuredProduct> {

private User user;
T product;

private UserPremiumBuilder(User user){
this.user = user;
}

public static <T extends InsuredProduct> UserPremiumBuilder<T> createProfile(User user){
UserPremiumBuilder<T> builder = new UserPremiumBuilder<T>(user);
return builder;
}

public UserPremiumBuilder <T> setProduct(T product) {
this.product = product;
return this;
}

public BigDecimal calculateSingleProductPremiumForUser() {
BigDecimal userRiskSurcharge = user.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(userRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

this.product.setRiskValue(this.user.getRiskValue());
BigDecimal productRiskSurcharge =this.product.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(productRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

if(Risk.getDefaultRiskSurcharge().compareTo(productRiskSurcharge)==0)
return this.product.getSubTotalPremium();

BigDecimal totalPremium = this.product.getSubTotalPremium().multiply(this.product.getRiskSurcharge()).multiply(user.getRiskSurcharge());
return totalPremium;
}

}




  1. A sample unit test class:



public class UserPremiumBuilderBananaTest {
Banana banana;

@Before
public void initBanana()
{
banana = new Banana(1, new BigDecimal(10));
}

@Test
public void testUnInsurableBananaRiskSurchargeWithUserRiskValueLargerThan200() {
User user = initUser(10);
user.setRiskValue(201);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(4);

BigDecimal totalPremium = createProfile(user).setProduct(banana).calculateSingleProductPremiumForUser();
assertEquals(Risk.getUnIdentifiedRiskSurcharge(), totalPremium);
}

@Test
public void testInsurableBananaRiskSurchargeWithUserRiskNotGreaterThan200() {
User user = initUser(10);
user.setRiskValue(200);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(3);

UserPremiumBuilder<Banana> builder = createProfile(user);
BigDecimal totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
BigDecimal productPremium = banana.getSubTotalPremium().setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

user.setRiskValue(199);
totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

}

private static UserPremiumBuilder<Banana> createProfile(User user)
{
return UserPremiumBuilder.createProfile(user);
}

private User initUser(int addressRiskValue)
{
Address address = new Address(1);
address.setRiskValue(addressRiskValue);
User user = new User(1, address);
return user;
}
}










share|improve this question







New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I was failed at coding challenge for my interview with the following reasons given by the interviewer: deep use of mutation and a not that well thought up internal API.



I understand that my code and design have so many flaws and I genuinely want to get your opinion so I could improve my code.



The challenge is about asking me to build a quote processor to calculate a premium for different products, based on different rule sets.



Since the requirements are very lengthy, I try to summarize it below:



Data model




  • A user (with an id, an address, and a risk value)

  • An address (with an id and a location risk value)

  • A product (with an id and a price value)


(Risk values are in our patented Universal Risk Value Scale [tm])



For products we have modelled in our system the following types:
- Houses (with address and size in square meters)
- Bananas (with number of black spots)
- Bicycles (with number of gears)



Asides from above, the premium quote would need to take in rules, base surcharge, universal risk value for each product and each user to quote a premium for user.



Rules



We want to build a quote processor that will receive a user and a set of products, and return whether we reject the user or not, and if not, for how much premium will we insure the products in euros per year.



To ensure this, we have a set of rules to follow.



Each product will have a base premium value, that multiplied by the product value will give a subtotal for the product's premium. To this subtotal, we must add a surcharge that depends on the product type and maybe on other rules. Each surcharge is multiplied to the base value.



Then, for all the products, if for one the rules say that it is un-insurable, then the final result given is that we won't offer an insurance. If no product is un-insurable, then we add all the premiums and that is the quote we return to the user.



Below are my classes, I am putting here one or two model classes just to present my design.



It is my first time using SO so I do not know how to put code in a good way yet, please understand.




  1. Interfaces:



public interface Product {
BigDecimal getProductValue();
BigDecimal getBasePremium();
BigDecimal getSubTotalPremium();
}

public interface Risk {

void setRiskValue(int riskValue);
BigDecimal getRiskSurcharge();

static BigDecimal getUnIdentifiedRiskSurcharge()
{
return new BigDecimal(-1);
}

static BigDecimal getDefaultRiskSurcharge()
{
return new BigDecimal(0);
}

static boolean isWithinRange(int riskValue, int minValue, int maxValue)
{
return riskValue >= minValue && riskValue <= maxValue;
}
}




  1. Model classes:


    • Base class InsuredProduct implements above interfaces.





public abstract class InsuredProduct implements Product, Risk {
private int id;
private BigDecimal productValue;
private int riskValue;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

public InsuredProduct(int id, BigDecimal productValue)
{
this.id = id;
this.productValue =productValue;
}

public BigDecimal getProductValue() {
return productValue;
}

public void setProductValue(BigDecimal productValue) {
this.productValue = productValue;
}

@Override
public BigDecimal getSubTotalPremium()
{
return getProductValue().multiply(getBasePremium());
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

public int getRiskValue() {
return this.riskValue;
}

}




  • Then Banana class as insured product extends from base class:



public class Banana extends InsuredProduct {
private static BigDecimal BASE_PREMIUM = new BigDecimal(1.15);

private int noOfBlackSpots;
private int userRiskValue;

public Banana(int id, BigDecimal productValue) {
super(id, productValue);
}

public int getNoOfBlackSpots() {
return noOfBlackSpots;
}

public void setNoOfBlackSpots(int noOfBlackSpots) {
this.noOfBlackSpots = noOfBlackSpots;
}

@Override
public BigDecimal getBasePremium() {
return BASE_PREMIUM;
}

@Override
public BigDecimal getRiskSurcharge() {
if(this.userRiskValue > 200)
return Risk.getUnIdentifiedRiskSurcharge();

final int minAcceptableBlackSpots = 3;
final int maxAcceptableBlackSpots = 12;

if(Risk.isWithinRange(this.noOfBlackSpots, minAcceptableBlackSpots, maxAcceptableBlackSpots))
return Risk.getDefaultRiskSurcharge();

return Risk.getUnIdentifiedRiskSurcharge();
}

@Override
public void setRiskValue(int riskValue) {
this.userRiskValue = riskValue;
}
}




  • A User class (with Address) as an insured person. User's address is also part of risk surcharge to determine the quote calculation.



public class User implements Risk {
private static final BigDecimal MAXIMUM_USER_RISK_SURCHARGE = new BigDecimal(3.0);
private static final BigDecimal MEDIUM_USER_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_USER_RISK_SURCHARGE = new BigDecimal(0.3);

private int id;
private Address address;
private int riskValue;

public User(int id, Address address)
{
this.setId(id);
this.setAddress(address);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public int getRiskValue() {
return riskValue;
}

@Override
public void setRiskValue(int riskValue) {
this.riskValue = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedRiskValue = 501;
final int startMinimumRiskValue = 20;
final int endMinimumRangeRiskValue = 200;
final int startMaximumRiskValue = 201;
final int endMaximumRangeRiskValue = 500;

if(this.getRiskValue() >= unsupportedRiskValue)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumRiskValue)
return MINIMUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumRiskValue, endMinimumRangeRiskValue))
return MEDIUM_USER_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumRiskValue, endMaximumRangeRiskValue))
return MAXIMUM_USER_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}

}

public class Address implements Risk{
private static final BigDecimal MAXIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(2.5);
private static final BigDecimal MEDIUM_LOCATION_RISK_SURCHARGE = new BigDecimal(1.0);
private static final BigDecimal MINIMUM_LOCATION_RISK_SURCHARGE = new BigDecimal(0.7);

private int id;
private int locationRisk;

public Address(int id)
{
this.id = id;
}

public int getRiskValue() {
return locationRisk;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public void setRiskValue(int riskValue) {
this.locationRisk = riskValue;
}

@Override
public BigDecimal getRiskSurcharge() {
final int unsupportedLocationRisk = 502;
final int startMinimumLocationRisk = 100;
final int endMinimumRangeLocationRisk = 299;
final int startMaximumLocationRisk = 300;
final int endMaximumRangeLocationRisk = 501;

if(this.getRiskValue() >= unsupportedLocationRisk)
return Risk.getUnIdentifiedRiskSurcharge();

if(this.getRiskValue() < startMinimumLocationRisk)
return MINIMUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMinimumLocationRisk, endMinimumRangeLocationRisk))
return MEDIUM_LOCATION_RISK_SURCHARGE;
if(Risk.isWithinRange(this.getRiskValue(), startMaximumLocationRisk, endMaximumRangeLocationRisk))
return MAXIMUM_LOCATION_RISK_SURCHARGE;

return Risk.getDefaultRiskSurcharge();
}
}




  1. Processor: To calculate the premium quote or to determine if it's is insurable.



public class UserPremiumBuilder<T extends InsuredProduct> {

private User user;
T product;

private UserPremiumBuilder(User user){
this.user = user;
}

public static <T extends InsuredProduct> UserPremiumBuilder<T> createProfile(User user){
UserPremiumBuilder<T> builder = new UserPremiumBuilder<T>(user);
return builder;
}

public UserPremiumBuilder <T> setProduct(T product) {
this.product = product;
return this;
}

public BigDecimal calculateSingleProductPremiumForUser() {
BigDecimal userRiskSurcharge = user.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(userRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

this.product.setRiskValue(this.user.getRiskValue());
BigDecimal productRiskSurcharge =this.product.getRiskSurcharge();
if(Risk.getUnIdentifiedRiskSurcharge().compareTo(productRiskSurcharge)==0)
return Risk.getUnIdentifiedRiskSurcharge();

if(Risk.getDefaultRiskSurcharge().compareTo(productRiskSurcharge)==0)
return this.product.getSubTotalPremium();

BigDecimal totalPremium = this.product.getSubTotalPremium().multiply(this.product.getRiskSurcharge()).multiply(user.getRiskSurcharge());
return totalPremium;
}

}




  1. A sample unit test class:



public class UserPremiumBuilderBananaTest {
Banana banana;

@Before
public void initBanana()
{
banana = new Banana(1, new BigDecimal(10));
}

@Test
public void testUnInsurableBananaRiskSurchargeWithUserRiskValueLargerThan200() {
User user = initUser(10);
user.setRiskValue(201);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(4);

BigDecimal totalPremium = createProfile(user).setProduct(banana).calculateSingleProductPremiumForUser();
assertEquals(Risk.getUnIdentifiedRiskSurcharge(), totalPremium);
}

@Test
public void testInsurableBananaRiskSurchargeWithUserRiskNotGreaterThan200() {
User user = initUser(10);
user.setRiskValue(200);

banana.setRiskValue(user.getRiskValue());
banana.setNoOfBlackSpots(3);

UserPremiumBuilder<Banana> builder = createProfile(user);
BigDecimal totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
BigDecimal productPremium = banana.getSubTotalPremium().setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

user.setRiskValue(199);
totalPremium = builder.setProduct(banana).calculateSingleProductPremiumForUser();
totalPremium = totalPremium.setScale(2, BigDecimal.ROUND_HALF_EVEN);
assertEquals(productPremium, totalPremium);

}

private static UserPremiumBuilder<Banana> createProfile(User user)
{
return UserPremiumBuilder.createProfile(user);
}

private User initUser(int addressRiskValue)
{
Address address = new Address(1);
address.setRiskValue(addressRiskValue);
User user = new User(1, address);
return user;
}
}







java






share|improve this question







New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 14 hours ago









Anna

61




61




New contributor




Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Anna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
    – Tom
    12 hours ago










  • @Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
    – Anna
    11 hours ago










  • I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
    – Tom
    11 hours ago


















  • At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
    – Tom
    12 hours ago










  • @Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
    – Anna
    11 hours ago










  • I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
    – Tom
    11 hours ago
















At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
– Tom
12 hours ago




At a first glance, try to avoid instantiating BigDecimals when you can reuse existing instances. Thus, instead of new BigDecimal(0) use BigDecimal.ZERO. Similar instances exists for ONE and TEN as well. Also, don't use the double constructor of BigDecimal, because double can be imprecise and your 3.0 could become 3.0000000001. Use either new BigDecimal("3.0") or BigDecimal.valueOf(3.0).
– Tom
12 hours ago












@Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
– Anna
11 hours ago




@Tom: Thank you, definitely very useful advice! If you could also shed some light on the interviewer's feedback to my code: "deep use of mutation and a not that well thought up internal API.", I really appreciate that!
– Anna
11 hours ago












I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
– Tom
11 hours ago




I'm sorry, I don't have the time for further inspections of the code, but I'm sure someone else will gladly help you.
– Tom
11 hours ago















active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Anna is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209439%2finsurance-premium-quote-challenge%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes








Anna is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Anna is a new contributor. Be nice, and check out our Code of Conduct.













Anna is a new contributor. Be nice, and check out our Code of Conduct.












Anna is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209439%2finsurance-premium-quote-challenge%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Quarter-circle Tiles

build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

Mont Emei