Thoughtworks公司代码题目:收银机

需求描述


商店里进行购物结算时会使用收银机系统,这台收银机会在结算时根据客户的购物车中的商品和商店正在进行的优惠活动进行结算和打印购物清单。

已知商品信息包含:名称,数量单位,单价,类别和条形码(伪)。 
已知我们可以对收银机进行设置,使之支持各种优惠。

我们需要实现一个名为打印购物清单的小模块,收银机会将输入的数据转换成一个JSON数据然后一次性传给我们这个小模块,我们将从控制台中输出结算清单的文本。

输入格式(样例):

[
    'ITEM000001',
    'ITEM000001',
    'ITEM000001',
    'ITEM000001',
    'ITEM000001',
    'ITEM000003-2',
    'ITEM000005',
    'ITEM000005',
    'ITEM000005'
]

其中对'ITEM000003-2'来说,"-"之前的是标准的条形码,"-"之后的是数量。 
当我们购买需要称量的物品的时候,由称量的机器生成此类条形码,收银机负责识别生成购物清单

该商店正在对部分商品进行“买二赠一”的优惠活动和对部分商品进行95折的优惠活动。其中:

  • “买二赠一”是指,每当买进两个商品,就可以免费再买一个相同商品。

  • “95折”是指,在计算小计的时候按单价的95%计算每个商品。

  • 每一种优惠都详细标记了哪些条形码对应的商品可以享受此优惠。

  • 店员设置,当“95折”和“买二赠一”发生冲突的时候,也就是一款商品既符合享受“买二赠一”优惠的条件,又符合享受“95折”优惠的条件时,只享受“买二赠一”优惠。


要求写代码支持上述的功能,并根据输入和设置的不同,输出下列购物清单

购物清单内容及格式(样例):

  • 当购买的商品中,有符合“买二赠一”优惠条件的商品时:

***<没钱赚商店>购物清单***
名称:可口可乐,数量:3瓶,单价:3.00(元),小计:6.00(元)
名称:羽毛球,数量:5个,单价:1.00(元),小计:4.00(元)
名称:苹果,数量:2斤,单价:5.50(元),小计:11.00(元)
----------------------
买二赠一商品:
名称:可口可乐,数量:1瓶
名称:羽毛球,数量:1个
----------------------
总计:21.00(元)
节省:4.00(元)
**********************

 

  • 当购买的商品中,没有符合“买二赠一”优惠条件的商品时:

***<没钱赚商店>购物清单***
名称:可口可乐,数量:3瓶,单价:3.00(元),小计:9.00(元)
名称:羽毛球,数量:5个,单价:1.00(元),小计:5.00(元)
名称:苹果,数量:2斤,单价:5.50(元),小计:11.00(元)
----------------------
总计:25.00(元)
**********************

 

  • 当购买的商品中,有符合“95折”优惠条件的商品时

***<没钱赚商店>购物清单***
名称:可口可乐,数量:3瓶,单价:3.00(元),小计:9.00(元)
名称:羽毛球,数量:5个,单价:1.00(元),小计:5.00(元)
名称:苹果,数量:2斤,单价:5.50(元),小计:10.45(元),节省0.55(元)
----------------------
总计:24.45(元)
节省:0.55(元)
**********************

 

  • 当购买的商品中,有符合“95折”优惠条件的商品,又有符合“买二赠一”优惠条件的商品时

***<没钱赚商店>购物清单***
名称:可口可乐,数量:3瓶,单价:3.00(元),小计:6.00(元)
名称:羽毛球,数量:6个,单价:1.00(元),小计:4.00(元)
名称:苹果,数量:2斤,单价:5.50(元),小计:10.45(元),节省0.55(元)
----------------------
买二赠一商品:
名称:可口可乐,数量:1瓶
名称:羽毛球,数量:2个
----------------------
总计:20.45(元)
节省:5.55(元)
**********************

 

作业要求

  1. 请根据需求自行设计商品信息和优惠信息的数据结构,并自己准备数据;

  2. 请完成全部需求,并输出样例格示的购物清单

  3. 请在保证代码可读性的前提下,尽可能用最小的圈复杂度完成作业;

  4. 移动开发请用Android/iOS,前端开发请用JavaScript。其他语言不限。

加分项

  1. 良好的设计

  2. 写测试

  3. 用github提交,并且有良好的提交习惯

直接失败的减分项

  1. 压缩包打不开

  2. 以txt文件,图片,word文档等非代码形式提交作业

  3. 只提交了二进制文件,没提交代码,比如exe和class文件

以上是原文的题目,下面附上我写的代码:


#coding=utf-8

#超市产品价格字典

products_dic = {"可口可乐":3.00,"羽毛球":1.00,"苹果":5.50,"西红柿":4.50,"篮球":80.00,"乒乓球":1.00,"菜花":5.80,"牛奶":3.50, 
              "百事可乐":3.00,"康师傅冰红茶":3.50,"芬达橙味饮料":3.50,"青菜":2.80,"白菜":1.50,"五花肉":15.80,"海捕大虾":40.00,
              "鲫鱼":9.50,"武昌鱼":12.60,"蛋黄派":6.50,"薯片":3.00,"泡椒凤爪":4.00,"白面馒头":1.00,"荞麦馒头":1.20,"玉米馒头":1.20,
              "千禾酱油500ml":6.80,"山西龙井口老陈醋600ml":8.80,"东北大米":3.50,"面粉":3.80,"糯米粉":7.50,"散装粉丝":10.00,
             "茅台飞天500ml":1688.00,"五粮液500ml":1288.00,"古井贡酒500ml":388.00,"二锅头500ml":25.00,"大蒜":5.00 }

#生成条码和产品名对应字典
item_dic = {}
list1 = [x[0] for x in products_dic.items()]
for i in xrange(34):
    item_dic["ITEM"+str(i).rjust(6,"0")] = list1[i]
''' 由于时间限制,条码字典就由商品字典快速按编码规则生成'''


#产品计量单位字典    

unit_dic={"武昌鱼":"斤","五花肉":"斤","糯米粉":"斤","大蒜":"斤","东北大米":"斤","散装粉丝":"斤","鲫鱼":"斤","西红柿":"斤","面粉":"斤",
          "菜花":"斤","海捕大虾":"斤","青菜":"斤","苹果":"斤","白菜":"斤","玉米馒头":"个","篮球":"个","乒乓球":"个","白面馒头":"个",
          "荞麦馒头":"个","羽毛球":"个","二锅头500ml":"瓶","可口可乐":"瓶","五粮液500ml":"瓶","千禾酱油500ml":"瓶","茅台飞天500ml":"瓶",
          "芬达橙味饮料":"瓶","山西龙井口老陈醋600ml":"瓶","百事可乐":"瓶","古井贡酒500ml":"瓶","康师傅冰红茶":"瓶","泡椒凤爪":"袋",
          "蛋黄派":"袋","薯片":"袋","牛奶":"盒"}

#discount1 为买二赠一活动商品集合,discount2 为95折活动商品集合

discount1 = {"二锅头500ml","五花肉","糯米粉","牛奶","可口可乐","泡椒凤爪","篮球","五粮液500ml","千禾酱油500ml",
         "茅台飞天500ml","芬达橙味饮料","大蒜","山西龙井口老陈醋600ml","东北大米","散装粉丝",}
discount2 = {"散装粉丝","乒乓球","鲫鱼","西红柿","面粉","菜花","百事可乐","海捕大虾","白面馒头","古井贡酒500ml","青菜","荞麦馒头",
             "蛋黄派","薯片","苹果","白菜","康师傅冰红茶","羽毛球"}

#增加条码,商品,单位字典的函数方法
def update_dic(item,name,price,unit):
    item_dic[item] = name
    products_dic[name] = price
    unit_dic[name] = unit
    

#格式化处理条形码函数,返回去重及计数后的条码字典

def format_items(items):
    new_items = {}
    for item in items:
        temp = item.split("-")
        try:
            if new_items.has_key(temp[0]):
                new_items[temp[0]] += float(temp[1])
            else:
                new_items[temp[0]] = float(temp[1])
        except IndexError:
                if new_items.has_key(temp[0]):
                    new_items[temp[0]] += 1
                else:
                
                    new_items[temp[0]] = 1
           
    return new_items
                
            
#条形码字典转换购物商品字典函数

def convert2shoppinglist(items):
    shoppinglist = {}
    for key,value in items.items():
        shoppinglist[item_dic[key]] = value
    return shoppinglist


#计算单项商品信息函数,返回元组用于格式化输出

def compute_product_information(product):
    name = product[0]
    number = product[1]
    price = products_dic[name]
    unit = unit_dic[name]
    if  name in discount1:  #按照商品优惠规则分类计算输出商品名称,数量,计量单位,单价,小计,节省
        return (name,number,unit,price,number%3*price+2*(number//3)*price)
    elif name in discount2:
        return (name,number,unit,price,number*price*0.95,number*price*0.05)
    else:
        return (name,number,unit,price,number*price)
    

#打印购物清单函数,将购物表中的商品格式化输出

def print_receipts(shoppinglist):
    total = 0  #初始化商品总价
    saved = 0  #初始化节省价格
    zengpin = {} #初始化买二赠一商品及赠送数量字典
    print "***<没钱赚商店>购物清单***"
    for product in shoppinglist.items():
        temp = compute_product_information(product)
        try:
            
            print "名称:%s,数量:%.3f %s,单价:%.3f(元),小计:%.3f(元)" % (temp)#普通商品和买二赠一商品输出格式
            if product[0] in discount1 and (product[1] // 3) > 0:  #将符合条件的商品增加到二赠一商品字典和节省价格自动增加
                zengpin[product[0]] = product[1] // 3            
                saved += zengpin[product[0]]*products_dic[product[0]]
        except:
            print "名称: %s,数量:%.3f %s,单价:%.3f(元),小计:%.3f(元),节省 %.3f(元)" % (temp)#95折商品输出格式
            saved += temp[5]
            
        total += temp[4]
    print "-"*22
    if len(zengpin) != 0:  # 若存在符合买二赠一的商品,输出商品及优惠数量
        print "买二赠一商品:"
        for key,value in zengpin.items():
            print "名称:%s,数量:%d %s" % (key,value,unit_dic[key])
        print "-"*22
    print "总计: % .3f (元)" % total
    if saved != 0:  #输出节省价格总量
        print "节省:%.3f (元)" % saved
    print "*"*18
    

#测试运行

if __name__ == '__main__':
    import random
    
    #随机生成15个测试集进行测试,每个测试集由随机15个商品字典内的条码,每个条码的商品数量(1-20)随机生成
    testlist = []
    for i in xrange(15):
        items = []
        for j in xrange(15):
            item = "ITEM" + str(random.randint(0, 33)).rjust(6,"0")+"-"+str(random.randint(1,20))
            items.append(item)
        testlist.append(items)
    for items in testlist:
        print_receipts(convert2shoppinglist(format_items(items)))



转载于:https://my.oschina.net/u/2440318/blog/631739

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值