felipe74590 / atx-events

App for Events in Austin Texas
0 stars 0 forks source link

Coding Interview Example #50

Open felipe74590 opened 3 days ago

felipe74590 commented 3 days ago
## Two parts

# Write a function that caluclates the final price of shopping cart after a coupon has been applied.
# Coupon can be applied to one category only
# If percent_discount and ammount_discount are missing, return an error
# Minimum num of items required for catergory with coupon can be None, apply to all of that category if None.
# Same thing for minimum price

# 1. First identify the category for which the coupon can be applied to. (Should always be there)
# 2. Make sure that the category is even in the cart, if not just return sum of all contents in the cart.
# 3. Gather the items in the cart that fall under the category, make sure that the meet the min amount required if any.
# 4. Apply the discount to these items.
# 5. Add this to the sum of the the other items in the cart.

# Example Cart
cart = [ {'price': 2.00, 'category': 'fruit'},
  {'price': 20.00, 'category': 'toy'},
  {'price': 5.00, 'category': 'clothing'},
  {'price': 8.00, 'category': 'fruit'}
]

# Example Coupon
#
# Exactly one of percent_discount and amount_discount will be non-null (error if not).
# The two 'minimum_...' values can each be null or non-null.
coupon = { 'category': 'electronics',
  'percent_discount': None,
  'amount_discount': 2,
  'minimum_num_items_required': 2,
  'minimum_amount_required': 11.00
}

def apply_coupon(total_of_category, coupon, amount_of_items_dis)->float:
    """Returns amount of the category items after coupon is applied"""

    if coupon["minimum_num_items_required"] is not None and coupon["minimum_num_items_required"] > amount_of_items_dis:
        print("Coupon can not be applied, minimum required items was not met.")
        return total_of_category

    if coupon["minimum_amount_required"] is not None and coupon["minimum_amount_required"] > total_of_category:
        print("Coupon can not be applied, minimum required total was not met.")
        return total_of_category

    if coupon['percent_discount'] is not None:
        discount = coupon["percent_discount"] / 100
        discount_amount = total_of_category * discount
    else:
        discount_amount = coupon["amount_discount"]

    return total_of_category-discount_amount

def cal_total(cart, coupon)->float:
    """Return final shopping cart amount"""

    category_discount = coupon['category']
    if coupon["percent_discount"] is None and coupon["amount_discount"] is None:
        raise Exception(f"Error this coupon for {category_discount} is not a valid coupon due to discount amount and percentage values.")
    elif coupon["percent_discount"] is not None and coupon["amount_discount"] is not None:
        raise Exception(f"Error, the coupon provided is invalid due to having both percent discount '{coupon["percent_discount"]}' and amount discount'{coupon["amount_discount"]}' ")

    items_discounted = [] #list of floats
    items_not_discounted = []
    for item in cart:
        if item["category"] == category_discount:
            items_discounted.append(item["price"])
        else:
            items_not_discounted.append(item["price"])

    sum_of_non_discounted = sum(items_not_discounted)
    amount_of_items_dis = len(items_discounted)
    if amount_of_items_dis == 0:
        return sum_of_non_discounted
    else:
        total_discount_items_sum = sum(items_discounted)
        final_amount_of_discounted_items = apply_coupon(total_discount_items_sum, coupon, amount_of_items_dis)

    final_amount = final_amount_of_discounted_items + sum_of_non_discounted

    return final_amount

print(cal_total(cart, coupon))
felipe74590 commented 3 days ago
# Routing numbers, unique to a bank but each bank can have many routing numbers, but also can only correspond to one bank. 
## Bank names, multiple names valid for bank
## Bank Ids, only one and its unique (integer)

new_rn_to_name = [
  {
    "123": "Wells Fargo",
    "456": "Chase",
  },
  {
    "123": "Wells",
    "789": "Capital One",
    "456": "Bank of America",
  },
  {
    "123": "Bank of America",
    "456": "Chase",
  },
]
# rn_to_name= {
#     "123": "Wells Fargo",
#     "456": "Chase",
#     "789": "Capital One",
#     "555": "First State Bank",
# }
name_to_bank_id = [
  # There are multiple common ways to write the name of this bank
  ("Wells Fargo", 1),
  ("Wells", 1),

  ("Chase", 2),
  ("Capital One", 3),
  ("Bank of America", 4),

  # These are two different banks with the same name
  ("First State Bank", 5),
  ("First State Bank", 6),
]

# Example output
# 123 -> 1
# 456 -> 2
# 789 -> 3
# 555 -> 5,6

from typing import Dict, List, Tuple
from collections import defaultdict

# create_routing_number_mapping combines a map from routing number to bank name with a list of relationships between
# bank names and bank IDs to create a single map with routing numbers as keys and a list of related bank IDs as values.

def create_routing_number_mapping(rn_to_name: Dict[str, str], name_to_bank_id: List[Tuple[str, int]]) -> Dict[str, List[int]]:
    """returning dict {"route_number": bank_ids(list)}"""
    # try to find the banks with the same ids
    # possible names {}, and bank name sharing id with another bank name will be added to this key = bank id, value list of bank names

    mapping_ids = defaultdict(list)
    final_result = {}
    for bank in name_to_bank_id:
        mapping_ids[bank[0]].append(bank[1])

    for key, name in rn_to_name.items():
        if name in mapping_ids:
            final_result[key] = mapping_ids[name]
        else:
            print("Bank name does not match any current banks listed.")

    return final_result

def check_each_source(new_rn_to_name):
    """return best mapping"""
    list_of_mappings = {}
    for db in new_rn_to_name:
        this_map = create_routing_number_mapping(db, name_to_bank_id)
        for key, value in this_map.items():
            for id in value:
                if key in list_of_mappings and id not in list_of_mappings[key]:
                    list_of_mappings[key][id] = 1
                elif key not in list_of_mappings:
                    list_of_mappings[key] = {id: 1}
                else:
                    new_count = list_of_mappings[key][id] + 1
                    list_of_mappings[key][id] = new_count

    print(list_of_mappings)
    for bank_ids, value in list_of_mappings.items():
        correct_route_num = max(value, key=value.get)
        print(correct_route_num)

print(check_each_source(new_rn_to_name))
felipe74590 commented 3 days ago

@bbelderbos

bbelderbos commented 1 day ago

Thanks, I will take a look this week.