dev.to staff

Posted on

# Daily Challenge #241 - Tip Calculator

Complete the function, which calculates how much you need to tip based on the total amount of the bill and the service.

You need to consider the following ratings:

`Terrible`: tip 0%
`Poor`: tip 5%
`Good`: tip 10%
`Great`: tip 15%
`Excellent`: tip 20%

The rating is case insensitive (so "great" = "GREAT"). If an unrecognized rating is received, then you need to return:
"Rating not recognized" in JavaScript, Python and Ruby...
...or null in Java
...or -1 in C#

Because you're a nice person, you always round up the tip, regardless of the service.

Examples
calculatetip(30, "poor") => 2
calculatetip(20, "hi")=> "Rating Not Recognized"
calculatetip(107.65, "great") => 17

Tests
calculatetip(78, "good") =>
calculatetip(50, "poor") =>
calculatetip(125, "excellent") =>

Good luck!

This challenge comes from Katbow 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!

Davide Santangelo • Edited
`````` RATINGS = {
terrible: 0,
poor: 5,
good: 10,
great: 15,
excellent: 20
}.freeze

def calculatetip(bill, service)
service = service.downcase.to_sym
service_percentage = RATINGS[service]

return 'Rating Not Recognized' unless service_percentage

tip = (bill.to_f * service_percentage.to_f / 100).ceil

tip
end
``````

calculatetip(78, "good") => 8
calculatetip(50, "poor") => 3
calculatetip(125, "excellent") => 25

peter279k

Here is the Python solution:

``````import math

def calculate_tip(amount, rating):
ratings = {
'terrible': 0,
'poor': 0.05,
'good': 0.1,
'great': 0.15,
'excellent': 0.2,
}

rating = rating.lower()

if rating not in ratings:
return 'Rating not recognised'

rating_number = ratings[rating]

return math.ceil(amount * rating_number)
``````

agtoever

Python 3

``````# Solution
import math
RATINGS = {
'terrible': .0,
'poor': 0.05,
'good': 0.1,
'great': 0.15,
'excellent': 0.2
}

tip = lambda p, s:  math.ceil(p * RATINGS[s.lower()]) if s.lower() in RATINGS else 'Rating not recognized'

# Test cases
cases = [
(30, "poor"),
(20, "hi"),
(107.65, "great"),
(78, "good"),
(50, "poor"),
(125, "excellent"),
]

for case in cases:
print(f'With score "{case[1]}" and amount {case[0]}, tip: {tip(*case)}')
``````

Try it online!

Amin

``````module Main (main) where

maybeTip :: Float -> String -> Maybe Int
maybeTip price "poor"       = Just \$ ceiling \$ price * 0.05
maybeTip price "good"       = Just \$ ceiling \$ price * 0.1
maybeTip price "great"      = Just \$ ceiling \$ price * 0.15
maybeTip price "excellent"  = Just \$ ceiling \$ price * 0.2
maybeTip _ _                = Nothing

main :: IO ()
main = do
print \$ maybeTip 30 "poor"          -- Just 2
print \$ maybeTip 20 "hi"            -- Nothing
print \$ maybeTip 107.65 "great"     -- Just 17
print \$ maybeTip 78 "good"          -- Just 8
print \$ maybeTip 50 "poor"          -- Just 3
print \$ maybeTip 125 "excellent"    -- Just 25
``````

mxb

Implementation in Frink

``````// Needs to be in a class as no concept of 'global' variables
class tipCalculator
{
class var rates = new dict[[["terrible", 0 percent],
["poor", 5 percent],
["good", 10 percent],
["great", 15 percent],
["excellent", 20 percent]]]

class calc[amount, rating] :=
{
r = lc[rating]
if not rates.containsKey[r]
return -1
return ceil[amount * rates@r]
}
}

println[tipCalculator.calc[30,"poor"]]          // 2
println[tipCalculator.calc[20, "hi"]]           // -1
println[tipCalculator.calc[107.65, "great"]]    // 17

println[tipCalculator.calc[78, "good"]]         // 8
println[tipCalculator.calc[50, "poor"]]         // 3
println[tipCalculator.calc[125, "excellent"]]   // 25
``````