DEV Community

Discussion on: Daily Challenge #4 - Checkbook Balancing

Collapse
 
valerionarcisi profile image
Valerio Narcisi

//TS
//TDD


import checkbookBalancing from './checkbook-balancing';

describe('tdd checkbook balancing', () => {
    const endOfLine = '\n';
    test('Example Checkbook', () => {
        const checkBook = `1000.00
        125 Market 125.45
        126 Hardware 34.95
        127 Video 7.45
        128 Book 14.32
        129 Gasoline 16.10`;

        const res = `Original_Balance: 1000.00${endOfLine}125 Market 125.45 Balance 874.55${endOfLine}126 Hardware 34.95 Balance 839.60${endOfLine}127 Video 7.45 Balance 832.15${endOfLine}128 Book 14.32 Balance 817.83${endOfLine}129 Gasoline 16.10 Balance 801.73${endOfLine}Total expense 198.27${endOfLine}Average expense 39.65`;
        expect(checkbookBalancing(checkBook)).toEqual(res);
    });

    test('Challenge Checkbook', () => {
        const checkBook = `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?;`;

        const res = `Original_Balance: 1233.00${endOfLine}125 Hardware 24.8 Balance 1208.20${endOfLine}123 Flowers 93.5 Balance 1114.70${endOfLine}127 Meat 120.90 Balance 993.80${endOfLine}120 Picture 34.00 Balance 959.80${endOfLine}124 Gasoline 11.00 Balance 948.80${endOfLine}123 Photos 71.4 Balance 877.40${endOfLine}122 Picture 93.5 Balance 783.90${endOfLine}132 Tires 19.00 Balance 764.90${endOfLine}129 Stamps 13.6 Balance 751.30${endOfLine}129 Fruits 17.6 Balance 733.70${endOfLine}129 Market 128.00 Balance 605.70${endOfLine}121 Gasoline 13.6 Balance 592.10${endOfLine}Total expense 640.90${endOfLine}Average expense 53.41`;
        expect(checkbookBalancing(checkBook)).toEqual(res);
    });
});

export default (str: string, endOfLine = '\n', separator = ' '): string | null => {
    if (str === '') {
        return null;
    }

    const initialState = {
        originalBalance: null,
        rows: '',
        totalExpense: 0,
        averageExpense: 0,
    };

    const round2 = num => Math.round(num * 100) / 100;

    const res = str
        .replace(/[^0-9A-Za-z\.\s]/g, '')
        .split(endOfLine)
        .map(val => val.trim().split(separator))
        .reduce((prev, curr, i) => {
            if (i === 0) {
                return { ...initialState, ...{ originalBalance: round2(curr[0]) } };
            }
            const totalExpense = round2(Number(prev.totalExpense + Number(curr[2])));
            const averageExpense = round2(totalExpense / i);
            return {
                ...prev,
                ...{
                    originalBalance: prev.originalBalance,
                    rows: `${prev.rows}${curr[0]} ${curr[1]} ${curr[2]} Balance ${round2(
                        prev.originalBalance - prev.totalExpense - Number(curr[2]),
                    ).toFixed(2)}${endOfLine}`,
                    totalExpense: totalExpense,
                    averageExpense: averageExpense,
                },
            };
        }, initialState);

    return `Original_Balance: ${res.originalBalance.toFixed(2)}${endOfLine}${
        res.rows
    }Total expense ${res.totalExpense.toFixed(2)}${endOfLine}Average expense ${res.averageExpense.toFixed(2)}`;
};