zoukankan      html  css  js  c++  java
  • 洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)

    本次项目相当于对python基础做总结,常用语法,数组类型,函数,文本操作等等

    本项目在博客园里其他开发者也做过,我是稍作修改来的,大体没变的

     

    项目需求:

    信用卡+商城:


    A、信用卡(类似白条/花呗)

    1.额度15000以上或者自定义
    2.可以提现,手续费5%
    3.账户信息,信用卡和购物车共用
    4.支持账户间转账
    5.支持购物结账功能
    6.有还款功能
    7.记录每月日常消费流水
    8.每个重要步骤都要记录到日志文件里(用logging模块)
    9.有管理员功能,添加账户,冻结账户,调整用户额度
    (可选)10.每月19号出帐,27号为最后还款日,逾期未还,按利息为欠款总额的万分之5每日计算

    B、在线购物商场

    1.与信用卡信息对接,支持信用卡结账
    2.登录验证用装饰器
    3.支持多账户登录
    4.有多个页面,个人主页,电脑,手机,日用品主页,具体多少个主页随意(结合前面学到的)
    5.每进入一个页面,分别打印页面下的产品
    6.个人页面,电脑,手机等页面可以退回到主页 (类似前面的多级菜单同样的功能)

    分析:

    本次项目由于项目比前面的难度有提升,并且涉及到贴合以后真正的开发,很多设置都是可修改,并不是前面的项目那样,单个文件就搞定的。要求不用多说,就和常识里使用到的类似京东的白条,支付宝的蚂蚁花呗,然后加上一个购物商场,功能也不用多说。但是文件很多,由此,画一个流程图解释:

    这个流程图我使用的百度脑图画的,分享链接:http://naotu.baidu.com/file/8ecc09fd00d5016349e4e7f72583ec48

    画得比较简单,每个文件都有备注是干嘛的。

    其实这个没什么难度,流程还是那些,登录验证,交易,更新数据,结束

    流程图:

    剩下的就是每个文件的编写,以及如何让这些文件联系起来了

    这里说个知识点:

    # 将当前py文件的上级文件夹目录的路径添加到模块索引列表内
    
    import sys,os
    path  = os.path.dirname(__file__)
    
    sys.path.append(path)
    

    以上的代码则可以把你的文件作为py文件导入并且不怕因为文件路径被修改而导致导入失败了

    代码:

    项目包下载链接:传送门

    需要的文件:

    card.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 21:41
    
    import os,sys
    
    base_dir = os.path.dirname(os.path.dirname(__file__))
    
    sys.path.append(base_dir)
    
    
    from libs import main
    
    if __name__ == '__main__':
        main.run()
    

    main.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 21:43
    
    import os,sys
    
    base_dir = os.path.dirname(os.path.dirname(__file__))
    sys.path.append(base_dir)
    
    from libs import auth
    from libs import logger
    from libs import transaction
    from libs import accounts
    from conf import settings
    
    
    # 用户数据,作为标志位以及缓存用户信用卡信息
    account_data = {
        'account_id':None,
        'is_auth':False,
        'data':None
    }
    
    
    
    # 用户日志
    account_log = logger.logger('account')
    
    # 交易日志
    transaction_log = logger.logger('transaction')
    
    # 账户信息
    def userinfo(data):
        '''
        print user of data
        :param data: user data
        :return:
        '''
        for k,v in data.items():
            print(k,':',v)
    
    # 查询账单
    def select(data):
        '''
        check transaction data
        :param data: user data
        :return:
        '''
        check_path = '%s/log/transaction.log'%settings.BASE_DIR
        with open(check_path) as f:
            for i in f.readlines():
                if str(data['id']) in i:
                    print(i)
    
    # 退出
    def logout(data):
        '''
        quit the programs func
        :param data: user data
        :return:
        '''
        print('account [%s] quit...'%data['id'])
        exit()
    
    # 还款
    def repay(data):
        '''
        user repay bill
        :param data: user data
        :return:
        '''
        corrent_accdata = accounts.corrent_accdata(data['id'])
    
        print('''---------- user %s bill ----------
        creadit:    %s
        balance:    %s
        '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance']))
    
        back_flag = False
        while  not back_flag:
            repay_amount = input("33[36;1mplease enter amount or 'b' to back:33[0m").strip()
    
            if repay_amount == 'b':
                back_flag = True
    
            print() #此处的打印空是为了换行美观,否则日志输出会和repay_amount在同一行
            if len(repay_amount) > 0 and repay_amount.isdigit():
                new_data = transaction.change(corrent_accdata,repay_amount,transaction_log,'repay')
                if new_data:
                    print('33[46;1mnew balance:[%s]33[0m'%new_data['balance'])
            else:
                print('33[31;1m[%s] not integer,only support integer33[0m'%repay_amount)
    
            if repay_amount == 'b':
                back_flag = True
    
    # 取款
    def draw(data):
        '''
        user repay bill
        :param data: user data
        :return:
        '''
        corrent_accdata = accounts.corrent_accdata(data['id'])
    
        print('''---------- user %s bill ----------
        creadit:    %s
        balance:    %s
        '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance']))
    
        back_flag = False
        while  not back_flag:
            draw_amount = input("33[36;1mplease enter amount or 'b' to back:33[0m").strip()
    
            if draw_amount == 'b':
                back_flag = True
    
            if len(draw_amount) > 0 and draw_amount.isdigit():
                new_data = transaction.change(corrent_accdata,draw_amount,transaction_log,'draw')
                if new_data:
                    print('33[46;1mnew balance:[%s]33[0m'%new_data['balance'])
            else:
                print('33[31;1m[%s] not integer,only support integer33[0m'%draw_amount)
    
    # 转账
    def transfer(data):
        '''
        user1 transfer money to user2
        :param data: user data
        :return:
        '''
        corrent_accdata = accounts.corrent_accdata(data['id'])
    
        print('''---------- user %s bill ----------
        creadit:    %s
        balance:    %s
        '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance']))
    
        back_flag = False
        while  not back_flag:
            transfer_amount = input("33[36;1mplease enter amount or 'b' to back:33[0m").strip()
    
            if transfer_amount == 'b':
                back_flag = True
    
            if len(transfer_amount) > 0 and transfer_amount.isdigit():
                transfer_user_id = input("33[36;1mplease enter user id :33[0m").strip()
                try:
                    transfer_userdata = accounts.corrent_accdata(transfer_user_id)
                    new_data = transaction.change(corrent_accdata,transfer_amount,transaction_log,'transfer')
                    if new_data:
                        transfer_userdata['balance'] += float(transfer_amount)
                        accounts.dump_accdata(transfer_userdata)
                        print('33[46;1mtrade successfully!33[0m')
                        print('33[46;1mnew balance:[%s]33[0m'%new_data['balance'])
                except Exception as reason:
                        print('33[31;1mtransaction failure!33[0m')
                        print(reason)
            else:
                print('33[31;1m[%s] not integer,only support integer33[0m'%transfer_amount)
    
    
    # 信用卡操作对象
    def optionlist(data):
        '''
    
        :param data: user's data
        :return:
        '''
        menu = u'''33[32;1m
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出33[0m'''
        option_dict = {
            '1':userinfo,
            '2':repay,
            '3':draw,
            '4':transfer,
            '5':select,
            '6':logout
        }
        exit_flag = False
        while  not exit_flag:
            print(menu)
            user_option  = input('33[36;1mplease enter the option number:33[32;1m')
            if user_option in option_dict:
                option_dict[user_option](data)
            else:
                print("33[31;1m sorry,haven't option [%s]33[0m"%user_option)
    
    # 运行
    def run():
        '''
        运行函数,将整个项目运行起来
        :return:
        '''
        userdata = auth.login(account_data,account_log)
        if account_data['is_auth'] == True:
            account_data['data'] = userdata
            optionlist(userdata)
    

    logger.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 21:54
    
    import logging
    from conf import settings
    
    def logger(log_type):
    
        # 创建一个文件型日志对象
        log_file = '%s/log/%s'%(settings.BASE_DIR,settings.LOG_TYPE[log_type])
        fh = logging.FileHandler(log_file)
        fh.setLevel(settings.LOG_LEVEL)
    
        # 创建一个输出到屏幕型日志对象
        sh = logging.StreamHandler()
        sh.setLevel(settings.LOG_LEVEL)
    
        # 设置日志格式
        formater = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
        # 添加格式到文件型和输出型日志对象中
        fh.setFormatter(formater)
        sh.setFormatter(formater)
    
        # 创建log对象,命名
        logger = logging.getLogger(log_type)
        logger.setLevel(settings.LOG_LEVEL)
    
        # 把文件型日志和输出型日志对象添加进logger
        logger.addHandler(fh)
        logger.addHandler(sh)
    
        return logger
    

    auth.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 21:53
    
    import json,os,time
    from conf import settings
    from libs import db
    
    def auth(userid,password):
        '''
        account libs func
        :param userid: user card id
        :param password: user pasword
        :return:
        '''
        userdbpath = db.db(settings.DATABASEINFO)
        account_file = '%s/%s.json'%(userdbpath,userid)
        # print(account_file)
        if os.path.isfile(account_file):
            with open(account_file) as f:
                account_data = json.load(f)
                if account_data['password'] == password:
                    indate = time.mktime(time.strptime(account_data['expire_date'],'%Y-%m-%d'))
                    if indate < time.time():
                        print("33[31;1m your card was out of date33[0m")
                    else:
                        return account_data
                else:
                    print('33[31;1m your id or password incorrect33[0m')
        else:
            print('33[31;1maccount [%s] does not exist33[0m'%userid)
    
    
    def login(data,logobj):
        '''
        account login func
        :param data: user's data
        :param logobj: account logger object
        :return:
        '''
        count = 0
        while data['is_auth'] is not True and count < 3:
            userid = input("33[36;1mplease enter your card's id:33[0m").strip()
            password = input('33[36;1menter your password:33[0m').strip()
            userauth = auth(userid,password)
            if userauth:
                data['is_auth'] = True
                data['account_id'] = userid
                return userauth
            count +=1
    
        else:
            logobj.error('33[31;1maccount [%s] too many login attempts33[0m' % userid)
            exit()
    

    accounts.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/20 0020 22:38
    
    
    from conf import settings
    from libs import db
    import json
    
    def corrent_accdata(userid):
        '''
    
        :param userid: user  card's id
        :return:
        '''
        accdata_path = db.db(settings.DATABASEINFO)
        acc_file = '%s/%s.json'%(accdata_path,userid)
        with open(acc_file) as f:
            corrent_accdata = json.load(f)
            return corrent_accdata
    
    def dump_accdata(data):
        '''
    
        :param data: user data
        :return:
        '''
        accdata_path = db.db(settings.DATABASEINFO)
        acc_file = '%s/%s.json'%(accdata_path,data['id'])
        with open(acc_file,'w') as f:
            json.dump(data,f)
    
        return True
    

    transaction.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/20 0020 17:50
    
    from conf import settings
    from libs import accounts
    
    
    def change(account_data,amount,logobj,trantype):
        '''
        :param account_data: user data
        :param amount: user entered amount
        :param logobj: transaction logging object
        :param trantype: transaction type
        :return:
        '''
        amount = float(amount)
        if trantype in settings.TRAN_TYPE:
            interest = amount * settings.TRAN_TYPE[trantype]['interest'] #利息
            old_balance = account_data['balance']
    
            if settings.TRAN_TYPE[trantype]['action'] == 'plus':
                new_balance = old_balance + amount +interest
    
            elif settings.TRAN_TYPE[trantype]['action'] == 'minus':
    
                new_balance = old_balance - amount - interest
                if new_balance < 0:
                    print("33[31;1maccount [%s] balance is not sufficient to pay [%s]!33[0m"
                          %(account_data['id'],amount +interest))
                    return
    
            account_data['balance'] = new_balance
            accounts.dump_accdata(account_data)
    
            logobj.info('account:%s - transaction:%s - amount:%s - interest:%s'
                        %(account_data['id'],trantype,amount,interest))
            return account_data
        else:
            print('33[31;1mTransaction type [%s] is not exist!33[0m'%trantype)
    

    settings.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 21:56
    
    import os,sys,logging
    
    # 项目根目录
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    
    # 设置日志等级
    LOG_LEVEL = logging.INFO
    
    # 存储日志类型
    LOG_TYPE = {
        'transaction':'transaction.log',
        'account':'account.log'
    
    }
    
    # 数据库信息
    DATABASEINFO = {
        'engine':'file',# 数据库类型,可以为文件,可以为数据库
        'dirname':'accounts',# 数据文件目录名
        'path':'%s/db'%BASE_DIR
    }
    
    # 交易类型
    TRAN_TYPE = {
        'repay':{'action':'plus','interest':0},
        'draw':{'action':'minus','interest':0.05},
        'transfer':{'action':'minus','interest':0.05}
    }
    

    db.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/19 0019 22:51
    
    
    def fl_db(parms):
        '''
    
        :param parms: malldb type
        :return: malldb path
        '''
        # print('file malldb:,parms')
        db_path = '%s/%s'%(parms['path'],parms['dirname'])
        # print(db_path)
        return db_path
    
    def ml_db(parms):
        pass
    
    def mo_db(parms):
        pass
    
    def oe_db(parms):
        pass
    
    def db(parms):
        '''
    
        :param parms: malldb information
        :return:
        '''
        db_dict = {
            'file':fl_db,
            'mysql':ml_db,
            'mongodb':mo_db,
            'orlcle':oe_db,
        }
        if parms['engine'] in db_dict:
            return db_dict[parms['engine']](parms)
    

    example.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/20 0020 15:43
    
    import json,sys,os,datetime
    
    base_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    sys.path.append(base_dir)
    
    from conf import settings
    from libs import db
    
    path = db.db(settings.DATABASEINFO)
    
    acc_dic = {
        'id': 123, #卡号
        'password': 'abc', #密码
        'credit': 15000, #额度
        'balance': 15000, #余额
        'enroll_date': '2016-01-02', #注册日期
        'expire_date': '2021-01-01', #失效日期
        'pay_day': 22, #还款日
        'status': 0 # 0 = normal, 1 = locked, 2 = disabled
    }
    
    id = int(input('33[36;1menter your user id:33[0m'))
    corrent_path = '%s/%s.json'%(path,id)
    
    acc_dic['id'] = id
    
    enroll_date = datetime.date.today()
    expire_date = enroll_date + datetime.timedelta(days=365*5)
    
    acc_dic['enroll_date'] = str(enroll_date)
    acc_dic['expire_date'] = str(expire_date)
    
    with open(corrent_path,'w') as f:
        json.dump(acc_dic,f)
    

     shopping.py:

     #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/1/21 0024 17:44
    
    import sys,json,os
    from collections import Counter
    
    base_dir = os.path.dirname(os.path.dirname(__file__))
    sys.path.append(base_dir)
    
    from card.conf import settings
    from card.libs import db
    
    
    # # 载入商城账号信息,商城和信用卡并不是等同的
    # user_path = '%s/mall/yang.json'%base_dir
    # with open(user_path) as f:
    #     userdata = json.load(f)
    
    # # 读取信用卡
    # path = db.db(settings.DATABASEINFO)
    # account_path = '%s/%s.json'%(path,userdata['id'])
    # with open(account_path) as f:
    #     accountdata = json.load(f)
    
    
    # # 账户可用余额
    # salary = accountdata['balance']
    # #缓存总额,用于后面总共消费多少作计算
    # temp = salary
    
    #购物车
    cart = []
    
    #商品总清单
    product ={
        '手机':{
            '1':{'IphoneX':8388.00},
            '2':{'Iphone8':5088.00},
            '3':{'一加5T':3270.00},
            '4':{'魅族pro7':1999.00},
            '5':{'小米MIX2':3299.00},
            '6':{'华为p10':3488.00}
        },
        '电脑':{
            '7':{'联想R720-15I':7399.00},
            '8':{'惠普战66ProG1':6499.00},
            '9':{'戴尔XPS13':6299.00},
            '10':{'MacBookAir':6988.00}
        },
        '日用品':{
            '11':{'高露洁牙刷':12.90},
            '12':{'三利纯棉浴巾':32.50},
            '13':{'半球电水壶':49.00}
        }
    }
    
    login_status = False  #登录状态标志位
    
    #登录验证
    def login(func):
        def inner():
            global login_status,accountdata,salary,temp,account_path
            while not login_status:
                print('33[32;1m请登录33[0m')
                username = input('33[32;1musername:33[0m')
                password = input('33[32;1mpassword:33[0m')
                user_path = '%s/mall/%s.json'%(base_dir,username)
                if os.path.isfile(user_path):
                    with open(user_path) as f:
                        userdata = json.load(f)
                    while password != userdata[username]: # 购物商场可以无限次登录
                        print('33[31;1m用户名或密码错误,请重新登录33[0m')
                        password = input('33[32;1mpassword:33[0m')
                    else:
                        print('33[34;1m登录成功!
    ')
                        login_status = True
                        path = db.db(settings.DATABASEINFO)
                        # 载入信用卡信息
                        account_path = '%s/%s.json'%(path,userdata['id'])
                        with open(account_path) as f:
                            accountdata = json.load(f)
                        # 账户可用余额
                        salary = accountdata['balance']
                        #缓存总额,用于后面总共消费多少作计算
                        temp = salary
                        return func()
                else:
                    print('33[31;1m不存在的用户名或者用户文件33[0m')
            else: #已登录状态
                return func()
        return inner
    
    #手机页面
    @login
    def phone(string='手机'):
        shopping_cart(string)
    
    #电脑页面
    @login
    def pc(string='电脑'):
        shopping_cart(string)
    
    #日用品页面
    @login
    def life(string='日用品'):
        shopping_cart(string)
    
    #主页
    @login
    def home():
        print('33[36;1m首页,js动态切换图片;精品促销;XX品牌日33[0m')
    
    #消费流水
    @login
    def consume():
        consume = temp-salary #消费金额
        if consume > 0:
            print('33[36;1m您当前的消费流水详细账单:33[0m')
            for i,j in dict(Counter(cart)).items():
                print('33[36;1m%s 数量:%s33[0m'%(i,j))
            print('33[46;1m您总共消费了 %.2f 元,可用余额为 %.2f 元33[0m
    '%(temp-salary,salary))
        else:
            print('33[31;1m您还未购买任何物品33[0m
    ')
    
    # 更新用户数据
    def dump():
        accountdata['balance'] = salary
        with open(account_path,'w') as f:
            json.dump(accountdata,f)
        return accountdata
    
    # 退出
    def logout():
        acc = dump()
        if acc:
            print('33[36;1m欢迎下次光临!您已退出!33[0m')
            exit()
    
    #购物车
    def shopping_cart(string):
        global salary
        for page,goods_msg in product.items():
            if page == string:
                while True:
                    print('33[36;1m页面:%s33[0m
    '%page)
                    for ID,goods in goods_msg.items():
                        for name,price in goods.items():
                            print('33[32;1m商品id:%s			商品名:%s			价格:%s33[0m'%(ID,name,price))
                    shopping = input('33[32;1m请输入商品id(需要返回上一级菜单请输入“b”)>>>:33[0m')
                    if shopping in goods_msg.keys():
                        gname = list(goods_msg[shopping].keys())[0]
                        gprice =list(goods_msg[shopping].values())[0]
                        if salary < gprice:
                            print('33[31;1m您的余额不足33[0m')
                        else:
                            salary -= gprice
                            print('33[46;1m您已购买商品 %s -- 单价 %.2f,剩余余额:%.2f33[0m
    '%(gname,gprice,salary))
                            cart.append('商品:%s 单价:%.2f'%(gname,gprice))
                            if not salary: #购买后再次检测信用卡剩余额度
                                print('33[31;1m您的余额为0,不能再购买任何东西,程序已退出,欢迎下次光临33[0m')
                                break
                    elif shopping == 'b': #购买结束,到收银台结账
                        print('33[32;1m已返回上一级33[0m
    ')
                        break
                    else:
                        print('33[31;1m您的输入有误,请查看是否有id为【%s】的商品33[0m'%shopping)
    
    #主函数
    def man():
        mapper = {'1':home,'2':pc,'3':phone,'4':life,'5':consume,'6':logout} #映射函数
        print('33[32;1m-------欢迎光临XXX商城-------33[0m')
        while True:
            print('33[32;1m1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出33[0m')
            page = input('33[32;1m请选择访问页面(输入前面的序号即可):33[0m')
            if page in mapper:
                mapper[page]()
            else:
                print('33[31;1m输入有误!!33[0m')
    
    if __name__ == '__main__':
        man()
    

    62285580.json:

    {"status": 0, "password": "123", "expire_date": "2020-07-26", "balance": 1500.75, "pay_day": 22, "id": 62285580, "enroll_date": "2015-07-25", "credit": 15000}
    

    62285589.json:

    {"status": 0, "password": "abc", "expire_date": "2021-01-01", "balance": 16022.05, "pay_day": 22, "id": 62285589, "enroll_date": "2016-01-02", "credit": 15000}
    

    以下两个文件是购物商场的账户数据文件,你也可以统一的放在一个json里

    yang.json:

    {"yang": "abc", "id": 62285589}
    

    ling.json:

    {"ling": "123", "id": 62285580}
    

     运行效果:

    运行card.py:

    (部分截图)

    详细结果:

    please enter your card's id:62285589
    enter your password:abc
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:2
    ---------- user 62285589 bill ----------
        creadit:    15000
        balance:    16022.05
        
    please enter amount or 'b' to back:500
    
    new balance:[16522.05]
    please enter amount or 'b' to back:2018-01-24 17:03:06,773 - transaction - INFO - account:62285589 - transaction:repay - amount:500.0 - interest:0.0
    b
    
    [b] not integer,only support integer
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:1
    status : 0
    password : abc
    expire_date : 2021-01-01
    balance : 16022.05
    pay_day : 22
    id : 62285589
    enroll_date : 2016-01-02
    credit : 15000
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:3
    ---------- user 62285589 bill ----------
        creadit:    15000
        balance:    16522.05
        
    please enter amount or 'b' to back:100
    2018-01-24 17:04:52,005 - transaction - INFO - account:62285589 - transaction:draw - amount:100.0 - interest:5.0
    new balance:[16417.05]
    please enter amount or 'b' to back:b
    [b] not integer,only support integer
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:4
    ---------- user 62285589 bill ----------
        creadit:    15000
        balance:    16417.05
        
    please enter amount or 'b' to back:200
    please enter user id :62285580
    2018-01-24 17:05:11,616 - transaction - INFO - account:62285589 - transaction:transfer - amount:200.0 - interest:10.0
    trade successfully!
    new balance:[16207.05]
    please enter amount or 'b' to back:b
    [b] not integer,only support integer
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:5
    2018-01-21 20:21:53,140 - transaction - INFO - account:62285589--transaction:repay--amount:400.0--interest:0.0
    
    2018-01-21 20:25:43,037 - transaction - INFO - account:62285589--transaction:draw--amount:400.0--interest:20.0
    
    2018-01-21 20:27:08,946 - transaction - INFO - account:62285589--transaction:draw--amount:400.0--interest:20.0
    
    2018-01-21 20:31:55,979 - transaction - INFO - account:62285589 - transaction:transfer - amount:100.0 - interest:5.0
    
    2018-01-24 17:03:06,773 - transaction - INFO - account:62285589 - transaction:repay - amount:500.0 - interest:0.0
    
    2018-01-24 17:04:52,005 - transaction - INFO - account:62285589 - transaction:draw - amount:100.0 - interest:5.0
    
    2018-01-24 17:05:11,616 - transaction - INFO - account:62285589 - transaction:transfer - amount:200.0 - interest:10.0
    
    
        1.账户信息
        2.还款
        3.取款
        4.转账
        5.查询账单
        6.退出
    please enter the option number:6
    account [62285589] quit...
    

    运行shopping.py:

    详细结果:

    -------欢迎光临XXX商城-------
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):2
    请登录
    username:yang
    password:abc
    登录成功!
    
    页面:电脑
    
    商品id:7			商品名:联想R720-15I			价格:7399.0
    商品id:8			商品名:惠普战66ProG1			价格:6499.0
    商品id:9			商品名:戴尔XPS13			价格:6299.0
    商品id:10			商品名:MacBookAir			价格:6988.0
    请输入商品id(需要返回上一级菜单请输入“b”)>>>:b
    已返回上一级
    
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):1
    首页,js动态切换图片;精品促销;XX品牌日
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):3
    页面:手机
    
    商品id:1			商品名:IphoneX			价格:8388.0
    商品id:2			商品名:Iphone8			价格:5088.0
    商品id:3			商品名:一加5T			价格:3270.0
    商品id:4			商品名:魅族pro7			价格:1999.0
    商品id:5			商品名:小米MIX2			价格:3299.0
    商品id:6			商品名:华为p10			价格:3488.0
    请输入商品id(需要返回上一级菜单请输入“b”)>>>:4
    您已购买商品 魅族pro7 -- 单价 1999.00,剩余余额:14208.05
    
    页面:手机
    
    商品id:1			商品名:IphoneX			价格:8388.0
    商品id:2			商品名:Iphone8			价格:5088.0
    商品id:3			商品名:一加5T			价格:3270.0
    商品id:4			商品名:魅族pro7			价格:1999.0
    商品id:5			商品名:小米MIX2			价格:3299.0
    商品id:6			商品名:华为p10			价格:3488.0
    请输入商品id(需要返回上一级菜单请输入“b”)>>>:b
    已返回上一级
    
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):4
    页面:日用品
    
    商品id:11			商品名:高露洁牙刷			价格:12.9
    商品id:12			商品名:三利纯棉浴巾			价格:32.5
    商品id:13			商品名:半球电水壶			价格:49.0
    请输入商品id(需要返回上一级菜单请输入“b”)>>>:11
    您已购买商品 高露洁牙刷 -- 单价 12.90,剩余余额:14195.15
    
    页面:日用品
    
    商品id:11			商品名:高露洁牙刷			价格:12.9
    商品id:12			商品名:三利纯棉浴巾			价格:32.5
    商品id:13			商品名:半球电水壶			价格:49.0
    请输入商品id(需要返回上一级菜单请输入“b”)>>>:b
    已返回上一级
    
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):5
    您当前的消费流水详细账单:
    商品:魅族pro7 单价:1999.00 数量:1
    商品:高露洁牙刷 单价:12.90 数量:1
    您总共消费了 2011.90 元,可用余额为 14195.15 元
    
    1.主页
    2.电脑
    3.手机
    4.日用品
    5.打印流水凭条
    6.退出
    请选择访问页面(输入前面的序号即可):6
    欢迎下次光临!您已退出!
    

    打开json文件验证:

    表示同步成功

    总结:

    其实还有两个问题:

    1.购物商场当多用户登录时,如果都是登录的同一个账号的话,会有意想不到的问题,由于还没学到socket编程以及IO阻塞,所以暂时不优化

    2.信用卡查询账单时,我是直接打印的日志文件里的,这样大体没问题,但不怎么好看

    以上问题,感兴趣的可以自己优化一下,其他方面基本上没啥问题,有问题还望指出

     

    细心的朋友你会发现,我的项目实战篇也是由易到难的,从零基础开始的,前面的项目很简单,不用函数都可以搞定,慢慢的开始使用到函数,下一篇项目实战也将从面向对象开始。然后前面基础篇漏掉的知识也会在实战篇中提出来,换句话就是利用项目实战,即把基础复习了,也把项目练好了,是不是想想就带劲,哈哈,唯一的不足就是,我知道我更博的时间太随意了,没办法啊,我也自学啊,还是那句,有时间就更新。不多说,大家都能把技术学好才是最终目的

  • 相关阅读:
    lintcode:previous permutation上一个排列
    lintcode : 二叉树的序列化和反序列化
    lintcode : find peak element 寻找峰值
    lintcode 中等题:搜索旋转排序数组II
    lintcode :搜索旋转排序数组
    lintcode: search for a range 搜索区间
    lintcode:最大子数组差
    lintcode:最大子数组II
    lintcode :最大子数组
    lintcode : 平衡二叉树
  • 原文地址:https://www.cnblogs.com/Eeyhan/p/8342662.html
Copyright © 2011-2022 走看看