## DEV Community is a community of 891,862 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

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!

## Discussion (7)

Davide Santangelo • Edited on
`````` 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

Michael Kohl

Some minor suggestions:

1. Move `ratings` out of the method, no need to recreate it.
2. You can try to retrieve the service and do a `nil` check instead of checking keys, which seems to be more common in Ruby code in the wild.
3. Floats are "viral", introducing one into the calculation makes all `to_f` calls redundant.
``````RATINGS = {
terrible: 0,
poor: 5,
good: 10,
great: 15,
excellent: 20
}.freeze

def calculate_tip(bill, service)
service = RATINGS[service.downcase.to_sym]
return 'Rating Not Recognized' unless service

(bill * service / 100.0).ceil
end
``````
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!

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)
``````
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
``````