loading...
Cover image for Daily Challenge #276 - Unwanted Dollar Signs

Daily Challenge #276 - Unwanted Dollar Signs

thepracticaldev profile image dev.to staff ・1 min read

If you're faced with an input box, like this:

                                           +--------------+
  Enter the price of the item, in dollars: |              |
                                           +--------------+

Do you put the $ sign in, or not? Inevitably, some people will type a $ sign and others will leave it out. The instructions could be made clearer - but that won't help those people who never read instructions anyway.

A better solution is to write code that can handle the input whether it includes a $ sign or not.

So, write a simple function that converts a string representing a number into the number itself. Your function should be able to handle negatives!

Examples:

money_value("12.34") => 12.34
money_value("-0.89") => -0.89
money_value(" .11") => 0.11
money_value("007") => 7

Tests:
money_value("-$ 0.1")
money_value("12.34")
money_value("$-2.3456")
money_value("$.2")

Good luck!


This challenge comes from geoffp on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

markdown guide
 

This is my solution in Python3

def remove_dollar(string: str) -> float:
  remove_char = string.replace('$', '' ).replace(' ', '')
  return float(remove_char)

EDIT: Removed space, thanks for correcting me guys

 

This was great, but failed (Python 3.8) the first test due to the added space - added an additional replace and passed all tests.

def remove_dollar(string:str) -> float:
  remove_char = string.replace('$', '').replace(' ', '')
  return float(remove_char)
 

You could also use the method strip

return float(string.strip("$"))

strip doc:

S.strip([chars]) -> str

Return a copy of the string S with leading and trailing
whitespace removed.
If chars is given and not None, remove characters in chars instead.

This doesn't work with string = "-$ 0.1" isn't it? I'd rather prefer the replace way :P

 
 

you alse need to remove space from the string to avoid the exception

 

This is my solution in javascript:

const money_value = (str) => parseFloat(str.replace('$','').replace(' ',''));

A more readable version:

const money_value = (str) => {
    let result = str.replace('$',''); 
    result = result.replace(' ','');
    return parseFloat(result);
};
 

My solution in Typescript

const remove_dollar = (input: string) => Number(input.replace(/\$|\s/g, ""));
 

I like this but I will do it without /g as you will encounter this replacement at the most once. Also space after $ maybe present or may not be so /\$?\s?/ would do I guess. What do you think?

 

In C with O(1):

#include <stdio.h>
#include <stdlib.h>

float money_value(char const * s)
{
    if(*s == '$')
        return atof(s+1);
    else if(*s=='-' && *(s+1)=='$')
        return -1*atof(s+2);
    else    
        return atof(s);
}

int main(void)
{
    printf("%f\n",money_value("$-.38"));
    printf("%f\n",money_value("-$ 0.1"));
    printf("%f\n",money_value("12.34"));
    printf("%f\n",money_value("$-2.3456"));
    printf("%f\n",money_value("$.2"));
}
 
 

Well, technically atof is O(n), but while specifing the big O notation, I just abstracted all the library calls to O(1). And I think that doing this is the most stupid thing but it just helps me to analyse what could be the worst case scenario of my implementation. Hope it doesn't mislead any wrong information.

 

Here's Kotlin with a String extension function:

fun String.toMoneyValue() =
    this.filter { it.isDigit() || it in listOf('-', '.') }
        .toBigDecimal()

// Examples
"12.34".toMoneyValue()
"-0.89".toMoneyValue()
".11".toMoneyValue()
"007".toMoneyValue()
 

Ruby

def money_value(money)
  money_str = money.tr("$", "").tr(" ", "")
  # This is to remove trailing zeros
  if money_str.to_f == money_str.to_i
    return money_str.to_i
  end
  return money_str.to_f
end
 

APL (using Dyalog APL):

      MoneyValue←{⍎⍵~'$ '}  ⍝ ⍵: dollar string
      MoneyValue '12.34'
12.34
      MoneyValue '-0.89'
¯0.89
      MoneyValue '.11'
0.11
      MoneyValue '007'
7
      MoneyValue '-$ 0.1'
¯0.1
      MoneyValue '$-2.3456'
¯2.3456
      MoneyValue '$.2'
0.2

(Use the bookmarklet on this post to see the code with APL font and syntax highlighting.)

Removes the characters $ and space using "set difference" ~, and evaluates the resulting string as APL expression. The preceding - gets evaluated as the "negate" function, and APL's numeric notation uses ¯ (read "high minus") for the negative sign.

 

This was my solution typescript/javascript

 const arr: Array<string> = ['12.34', '-0.89', '-$ 0.1','007','$-2.3456','$.2','$. 7'];

    console.log(`array: ${arr}`);

    const solve = xs => {

      xs.forEach(x => {

        const num = +x.replace(/[\$,' ']/g, '');
        console.log(`num: ${num}`);

      })
    }

    let me = solve(arr);

  }
 

Here is the simple solution with Python:

Using the while loop and if...else conditions to check specific string pattern and replace unwanted character.

Then return s with casting to float value finally.

def money_value(s):
    s = s.replace(' ', '')
    s = s.replace('$' , '')

    if s == '':
        return 0.0

    if s[0] == '.':
        s = '0' + s

    if s[0] == '0' and s[1] == '0':
        s = s.replace('0', '')

    if len(s) < 4:
        if '.' not in s:
            s += '.'
        start_length = 0
        zero_len = 4 - len(s)

        while start_length < zero_len:
            s += '0'
            start_length += 1    

    return float(s)
 

solution in js

function money_value(input){
  return parseFloat(input.replace(/\$/g,'').replace(/\s/g,''));
}
 

Javascript

const convert = string => parseFloat(string.replace(/[^0-9.]/g, ''))
 

fails on negative values, due to replacing the '-'