Groovy web console

subscribe to the feed Subscribe
to this
site

Groovy DB Homework

Published 2 months ago by Marcos Aurélio Brandão
Actions  ➤ Edit in console Back to console Show/hide line numbers View recent scripts
// ---------------------------//
// HOMEWORK
//
// Use Groovy to write a code under "YOUR CODE GOES BELOW THIS LINE" comment.
// Make sure the code is working in some of the web Groovy consoles, e.g. https://groovyconsole.appspot.com
// Do not over-engineer the solution.
//
// Assume you got some data from a customer and your task is to design a routine that will calculate the average Product price per Group.
//
// The Price of each Product is calculated as:
// Cost * (1 + Margin)
//
// Assume there can be a large number of products.
//
// Plus points:
// - use Groovy closures (wherever it makes sense)
// - make the category look-up performance effective
 
// contains information about [Product, Group, Cost]
def products = [
    ["A", "G1", 20.1],
    ["B", "G2", 98.4],
    ["C", "G1", 49.7],
    ["D", "G3", 35.8],
    ["E", "G3", 105.5],
    ["F", "G1", 55.2],
    ["G", "G1", 12.7],
    ["H", "G3", 88.6],
    ["I", "G1", 5.2],
    ["J", "G2", 72.4]]
 
// contains information about Category classification based on product Cost
// [Category, Cost range from (inclusive), Cost range to (exclusive)]
// i.e. if a Product has Cost between 0 and 25, it belongs to category C1
// ranges are mutually exclusive and the last range has a null as upper limit.
def category = [
    ["C3", 50, 75],
    ["C4", 75, 100],
    ["C2", 25, 50],
    ["C5", 100, null],
    ["C1", 0, 25]]
 
// contains information about margins for each product Category
// [Category, Margin (either percentage or absolute value)]
def margins = [
    "C1" : "20%",
    "C2" : "30%",
    "C3" : "0.4",
    "C4" : "50%",
    "C5" : "0.6"]
 
// ---------------------------
//
// YOUR CODE GOES BELOW THIS LINE
//
// Assign the 'result' variable so the assertion at the end validates
//
// ---------------------------
 

def grouped = getGroupedPrices(products, category, margins)
def result = getResult(grouped)

// ---------------------------
//
// IF YOUR CODE WORKS, YOU SHOULD GET "It works!" WRITTEN IN THE CONSOLE
//
// ---------------------------
assert result == [
    "G1" : 37.5,
    "G2" : 124.5,
    "G3" : 116.1
    ] : "It doesn't work"
 
println "It works!"

def getGroupedPrices(List products, List categories, Map margins) {
     def grouped = [:]
     products.each { prod ->
        def cost = new BigDecimal(prod[2])
        def group = prod[1]
        def cat =  findCategory(categories, cost)   
        def value = findMarginValue(margins, cat)
        def finalCost = cost * new BigDecimal(1 + value)
        def list = getGroupList(grouped, group)
        list.add(finalCost)
        grouped.put(prod[1], list)
    }
    return grouped;
}

def getGroupList(Map grouped, String group) {
     def list = grouped.getAt(group)
    if (list == null) {
        list = new ArrayList()        
    }
    return list;
}

def getResult(Map groupedPrices) {
     def result = [:]
     groupedPrices.each {
        def average= new BigDecimal(it.value.sum()).divide(it.value.size(), 1, java.math.RoundingMode.HALF_UP)
        result.put(it.key, average )
     }
     return result
}


def findCategory(Object category, BigDecimal cost) {
    return category.find { cat -> (cost > cat[1] && cost <= Optional.ofNullable(cat[2]).orElse(Integer.MAX_VALUE))}
}

def findMarginValue(Object margins, Object cat) {
    def margin = margins.find {margin -> margin.key == cat[0]}
    def value = margin.value

    if (value.endsWith("%")) {
        value = new BigDecimal(value.replace("%", "")).divide(100);
    } else {
        value = new BigDecimal(value)
    }
    return value
}