DEV Community

Discussion on: Daily Challenge #4 - Checkbook Balancing

Collapse
 
rvictorino profile image
Robin Victorino

Here's my Groovy take on this:

class CheckBook {

    static final DecimalFormat DF = new DecimalFormat('#.00', DecimalFormatSymbols.getInstance(Locale.US))
    static final String LINE_SEPARATOR = '\n'
    static final String PROPERTY_SEPARATOR = ' '

    List<BookEntry> entries = []
    Float initialBalance = 0f

    CheckBook(String input) {
        parse(input)
        entries.sort{it.id}
    }

    void printOperations() {
        println "Original_Balance: ${DF.format(initialBalance)}"
        Float currentBalance = initialBalance
        List<Float> expenses = []
        entries.each { BookEntry b ->
            currentBalance -= b.amount
            expenses << b.amount
            println "$b Balance ${DF.format(currentBalance)}"
        }
        Float total = expenses.sum()
        println "Total expense ${DF.format(total)}"
        println "Average expense ${DF.format(total / expenses.size())}"
    }

    private void parse(String input) {
        List<String> lines = input.split(LINE_SEPARATOR)
        initialBalance = Float.valueOf(lines[0])
        parseEntries(lines.drop(1))
    }

    private void parseEntries(List<String> lines) {
        lines.each { String line ->
            parseEntry(line)
        }
    }

    private void parseEntry(String line) {
        List<String> properties = line.split(PROPERTY_SEPARATOR)
            .collect{sanitizeInput(it)}
        BookEntry newEntry = new BookEntry(
            id: properties[0].toInteger(),
            name: properties[1],
            amount: Float.valueOf(properties[2])
        )
        entries << newEntry
    }

    private String sanitizeInput(String toSanitize) {
        return toSanitize - ~ /[^\w\.]+/
    }

    class BookEntry {
        Integer id
        String name
        Float amount

        @Override
        String toString() {
            return "$id $name ${DF.format(amount)}"
        }
    }
}

Call is made like the following:

String checkBookInput = """
1233.00
125 Hardware;! 24.8?;
123 Flowers 93.5
127 Meat 120.90
120 Picture 34.00
124 Gasoline 11.00
123 Photos;! 71.4?;
122 Picture 93.5
132 Tires;! 19.00,?;
129 Stamps 13.6
129 Fruits{} 17.6
129 Market;! 128.00?;
121 Gasoline;! 13.6?;
""".trim().stripIndent()

CheckBook checkBook = new CheckBook(checkBookInput)
checkBook.printOperations()

Interesting points that are Groovy-related:

  • left shift operator to insert new element in a collection
  • regex evaluation operator
  • the good old Java DecimalFormat to format numbers at print time
  • triple quotes multiline Strings