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

时间:2022-09-24 08:16:24

本次项目相当于对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.个人页面,电脑,手机等页面可以退回到主页 (类似前面的多级菜单同样的功能)

分析:

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

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

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

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

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

流程图:

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

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

这里说个知识点:

# 将当前py文件的上级文件夹目录的路径添加到模块索引列表内

import sys,os
path  = os.path.dirname(__file__)

sys.path.append(path)

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

代码:

项目包下载链接:传送门

需要的文件:

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

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

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("\033[36;1mplease enter amount or 'b' to back:\033[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('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance'])
        else:
            print('\033[31;1m[%s] not integer,only support integer\033[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("\033[36;1mplease enter amount or 'b' to back:\033[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('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance'])
        else:
            print('\033[31;1m[%s] not integer,only support integer\033[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("\033[36;1mplease enter amount or 'b' to back:\033[0m").strip()

        if transfer_amount == 'b':
            back_flag = True

        if len(transfer_amount) > 0 and transfer_amount.isdigit():
            transfer_user_id = input("\033[36;1mplease enter user id :\033[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('\033[46;1mtrade successfully!\033[0m')
                    print('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance'])
            except Exception as reason:
                    print('\033[31;1mtransaction failure!\033[0m')
                    print(reason)
        else:
            print('\033[31;1m[%s] not integer,only support integer\033[0m'%transfer_amount)

# 信用卡操作对象
def optionlist(data):
    '''

    :param data: user's data
    :return:
    '''
    menu = u'''\033[32;1m
    1.账户信息
    2.还款
    3.取款
    4.转账
    5.查询账单
    6.退出\033[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('\033[36;1mplease enter the option number:\033[32;1m')
        if user_option in option_dict:
            option_dict[user_option](data)
        else:
            print("\033[31;1m sorry,haven't option [%s]\033[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("\033[31;1m your card was out of date\033[0m")
                else:
                    return account_data
            else:
                print('\033[31;1m your id or password incorrect\033[0m')
    else:
        print('\033[31;1maccount [%s] does not exist\033[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("\033[36;1mplease enter your card's id:\033[0m").strip()
        password = input('\033[36;1menter your password:\033[0m').strip()
        userauth = auth(userid,password)
        if userauth:
            data['is_auth'] = True
            data['account_id'] = userid
            return userauth
        count +=1

    else:
        logobj.error('\033[31;1maccount [%s] too many login attempts\033[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("\033[31;1maccount [%s] balance is not sufficient to pay [%s]!\033[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('\033[31;1mTransaction type [%s] is not exist!\033[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('\033[36;1menter your user id:\033[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('\033[32;1m请登录\033[0m')
            username = input('\033[32;1musername:\033[0m')
            password = input('\033[32;1mpassword:\033[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('\033[31;1m用户名或密码错误,请重新登录\033[0m')
                    password = input('\033[32;1mpassword:\033[0m')
                else:
                    print('\033[34;1m登录成功!\n')
                    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('\033[31;1m不存在的用户名或者用户文件\033[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('\033[36;1m首页,js动态切换图片;精品促销;XX品牌日\033[0m')

#消费流水
@login
def consume():
    consume = temp-salary #消费金额
    if consume > 0:
        print('\033[36;1m您当前的消费流水详细账单:\033[0m')
        for i,j in dict(Counter(cart)).items():
            print('\033[36;1m%s 数量:%s\033[0m'%(i,j))
        print('\033[46;1m您总共消费了 %.2f 元,可用余额为 %.2f 元\033[0m\n'%(temp-salary,salary))
    else:
        print('\033[31;1m您还未购买任何物品\033[0m\n')

# 更新用户数据
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('\033[36;1m欢迎下次光临!您已退出!\033[0m')
        exit()

#购物车
def shopping_cart(string):
    global salary
    for page,goods_msg in product.items():
        if page == string:
            while True:
                print('\033[36;1m页面:%s\033[0m\n'%page)
                for ID,goods in goods_msg.items():
                    for name,price in goods.items():
                        print('\033[32;1m商品id:%s\t\t\t商品名:%s\t\t\t价格:%s\033[0m'%(ID,name,price))
                shopping = input('\033[32;1m请输入商品id(需要返回上一级菜单请输入“b”)>>>:\033[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('\033[31;1m您的余额不足\033[0m')
                    else:
                        salary -= gprice
                        print('\033[46;1m您已购买商品 %s -- 单价 %.2f,剩余余额:%.2f\033[0m\n'%(gname,gprice,salary))
                        cart.append('商品:%s 单价:%.2f'%(gname,gprice))
                        if not salary: #购买后再次检测信用卡剩余额度
                            print('\033[31;1m您的余额为0,不能再购买任何东西,程序已退出,欢迎下次光临\033[0m')
                            break
                elif shopping == 'b': #购买结束,到收银台结账
                    print('\033[32;1m已返回上一级\033[0m\n')
                    break
                else:
                    print('\033[31;1m您的输入有误,请查看是否有id为【%s】的商品\033[0m'%shopping)

#主函数
def man():
    mapper = {'1':home,'2':pc,'3':phone,'4':life,'5':consume,'6':logout} #映射函数
    print('\033[32;1m-------欢迎光临XXX商城-------\033[0m')
    while True:
        print('\033[32;1m1.主页\n2.电脑\n3.手机\n4.日用品\n5.打印流水凭条\n6.退出\033[0m')
        page = input('\033[32;1m请选择访问页面(输入前面的序号即可):\033[0m')
        if page in mapper:
            mapper[page]()
        else:
            print('\033[31;1m输入有误!!\033[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:

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

(部分截图)

详细结果:

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:

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

详细结果:

-------欢迎光临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文件验证:

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

表示同步成功

总结:

其实还有两个问题:

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

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

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

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

洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)的更多相关文章

  1. 老男孩Python高级全栈开发工程师三期完整无加密带课件&lpar;共104天&rpar;

    点击了解更多Python课程>>> 老男孩Python高级全栈开发工程师三期完整无加密带课件(共104天) 课程大纲 1.这一期比之前的Python培新课程增加了很多干货:Linux ...

  2. 老男孩Python高级全栈开发工程师【真正的全套完整无加密】

    点击了解更多Python课程>>> 老男孩Python高级全栈开发工程师[真正的全套完整无加密] 课程大纲 老男孩python全栈,Python 全栈,Python教程,Django ...

  3. 测开之Python自动化全栈工程师&plus;性能专项(送思维导图)

    测开之Python自动化全栈工程师+性能专项 功能测试基础 接口测试基础接口的通信原理与本质cookie.session.token详解接口测试的意义与测试方法接口测试用例的设计 app测试 app流 ...

  4. 全栈开发必备的10款Sublime Text 插件

    Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等.Sublime Text 更妙的是它的可扩展性.所以,这里挑选了全栈开发必备的10款 Sublime T ...

  5. 全栈开发必备的10款 Sublime Text 插件

    Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等.Sublime Text 更妙的是它的可扩展性.所以,这里挑选了全栈开发必备的10款 Sublime T ...

  6. &OpenCurlyDoubleQuote;全栈2019”22篇Java异常学习资料及总结

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"22篇Ja ...

  7. Asp&period;Net Core 2&period;0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录

    1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...

  8. Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享

    Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享 支付宝十年账单上的数字有点吓人,但它统计的项目太多,只是想看看到底单纯在淘宝上支出了多少,于是写了段脚本,统计任意时间段淘宝订单的消费情况,看 ...

  9. Python爬虫实战五之模拟登录淘宝并获取所有订单

    经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分享,希望大家支持. 温馨提示 更新时间,2016-02-01,现在淘宝换成了滑块验证了 ...

随机推荐

  1. Jsonp调用网易云音乐API搜索播放歌曲

    效果如下图: 基本就是正常的文件播放,暂停,停止,设置循环,随机播放,加速,减速,上一曲,下一曲,再多个选择本地文件加入到播放列表的功能.然后想着给加个能搜索网络歌曲并且播放的功能,今天研究了一下,成 ...

  2. 16、总经理要阅读的书籍 - IT软件人员书籍系列文章

    总经理是公司的一个领导角色.他主要负责公司级别的比如规划,战略等等内容.有些公司的总经理,比如软件公司的总经理,往往是一个大的业务员,将更多的大型的软件项目投取过来,让公司能够有钱赚,让公司员工能够跟 ...

  3. Xcode6与Xcode5中沙盒的变动以及偏好设置目录的变动

    1.Xcode6模拟器路径与Xcode5模拟器路径对比: (1)Xcode5中模拟器路径为:/Users/用户名/Library/Application Support/iPhone Simulato ...

  4. 我的权限系统设计实现MVC4 &plus; WebAPI &plus; EasyUI &plus; Knockout(二)菜单导航

    一.前言 上篇博客中已经总体的说了一下权限系统的思路和表结构设计,那接下来我们就要进入正文了,先从菜单导航这个功能开始. 二.实现 这个页面基本不用什么需求分析了,大家都很明白,不过在这个页面要多维护 ...

  5. hdu 4009 Transfer water(最小型树图)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)To ...

  6. 使用WebView视图显示网页-----迷你浏览器

    Android提供了WebView组件,表面上来看,这个组件与普通ImageView差不多,但实际上,这个组件的功能要强大得多,WebView组件本身就是一个浏览器实现,它的内核基于开源WebKit引 ...

  7. object C—类中函数的调用

    Object C-类中函数的调用 创建,三个类.然后,在代码中调用相同名字的函数.观察他们的调用次序. @interface test : NSObject - (void)print; @end @ ...

  8. Shell test命令

    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -gt 大于则为真 -ge 大于等于 ...

  9. C&num; 读取xml节点类容

    这是一个测试节点类容的获取 这是控制台代码部分 注意的应用文件 :using.system.Xml using System; using System.Collections.Generic; us ...

  10. nginx 日志格式

    log_format main '$http_host $server_addr $remote_addr [$time_local] "$request" ' '$request ...