DEV Community

loading...

Daily Challenge #241 - Tip Calculator

thepracticaldev profile image dev.to staff ・1 min read

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

pic
Editor guide
Collapse
daviducolo profile image
Davide Santangelo
 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

Collapse
citizen428 profile image
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
Collapse
agtoever profile image
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!

Collapse
peter279k profile image
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)
Collapse
aminnairi profile image
Amin

Haskell

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
Collapse
mxb profile image
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
Enter fullscreen mode Exit fullscreen mode
Collapse
ansmtz profile image