You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

534 lines
21 KiB

6 months ago
from enum import Enum
import time
import re
import os
import logging
Model = Enum('Model', ("小汽车", "小卡", "中卡", "大卡"))
Color = Enum('Color', ("白色", "黑色", "灰色", "蓝色", "红色", "黄色"))
unit_price = 5 # 每小时单价为5元
class Car(object): # ParkManage
def __init__(self, parknum, carnum, model, color, intime=None):
# super(Car, self).__init__()
self.parknum = parknum
self.carnum = carnum
self.model = model
self.color = color
self.intime = intime
def __setitem__(self, key, value):
self.__dict__[key] = value
def __getitem__(self, key):
return self.__dict__[key]
def __str__(self):
return "%4s %-8s %-6s %-s %s" % \
(self.parknum, self.carnum, self.model.name, self.color.name, self.intime)
class ParkManage(object):
def __init__(self, max_car=150):
self.max_car = max_car
self.carlist = []
# self.carnum = len(self.carlist)
def check_empty(self, model=1):
"""
查找空闲车位model=1默认按小汽车查找
:return:{list}空闲车位号列表
"""
if model == 1:
# t_num = [parkedCar["parknum"] for parkedCar in self.carlist]
"""
t_list = []
for i in range(self.max_car):
if i not in t_num:
t_list.append(i)
return t_list
"""
# return [i for i in range(self.max_car) if i not in t_num]
return [i for i in range(self.max_car) if i not in
[parkedCar["parknum"] for parkedCar in self.carlist]]
def inquire_empty(self):
"""
查询空闲车位调用即可进行输出
:return: None
"""
t_i = 0
for t_empty in self.check_empty():
print("%3s " % t_empty, end='')
t_i += 1
if len(self.check_empty()) > 15 and t_i % 15 == 0: # 每15个一行
print('')
def check_car_num(self, carnum):
"""
基于正则表达式判断车牌号是否合法合法为True
:return:{bool}True/False
"""
# return True # TODO DEBUG
car_license = re.compile(u"^[\u4e00-\u9fa5][A-Z][A-Z0-9]{5}$") # e.g.: 苏BCD123
if car_license.match(carnum):
return True
else:
return False
def park(self, isAdmin):
"""
输入车辆信息停车管理员isAdmin==1时询问是否继续停车
:return:None
"""
if len(self.carlist) >= self.max_car:
print("对不起,当前车库已满!")
return None
while True:
print('当前空闲车位如下:')
self.inquire_empty()
print('')
# 变量初始化
flag_right_input = False
flag_error = 0 # 清除错误flag
temp_parknum = None
temp_carnum = None
temp_color = None
temp_model = None
try:
temp_parknum = int(input('请输入所停车位:'))
temp_carnum = input('请输入车牌号:')
temp_model = int(input('请输入车型序号1小汽车, 2小卡, 3中卡, 4大卡:'))
temp_color = int(input('请输入车辆颜色序号1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色:'))
# 以下为输入信息是否有效的判断
if 0 <= temp_parknum <= self.max_car: # 判断车位是否在合理范围内
if 1 <= temp_model <= 4:
temp_model = Model(temp_model) # 转化为Model枚举类型
if 1 <= temp_color <= 6:
temp_color = Color(temp_color) # 转化Color枚举类型
if self.check_car_num(temp_carnum): # 判断车牌号是否有效
for parkedCar in self.carlist:
if parkedCar.parknum == temp_parknum: # 判断车位是否已被占用
flag_error = 1
break
elif parkedCar.carnum == temp_carnum: # 判断车牌是否已重复
flag_error = 2
break
else:
flag_right_input = True # 以上判断均通过
"""
else:
error_input = 3
else:
error_input = 4
else:
error_input = 5
"""
except Exception as e:
# logging.exception(e) # for debug
flag_right_input = False # 输入类型错误
# error_input = 6
finally:
# if error_input != 0:
if not flag_right_input:
if flag_error == 1:
print('当前车位已被占用!')
elif flag_error == 2:
print('车牌号重复!')
else:
print("输入错误!")
retry_choice = input('按<F>键返回主菜单,按其他任意键重试')
if retry_choice == 'F' or retry_choice == 'f':
return None # 返回主菜单
else:
os.system('cls') # 清屏
else:
# 通过各项判断,下面新增车辆
temp_car = Car(temp_parknum, temp_carnum, temp_model, temp_color)
temp_car["intime"] = time.ctime() # 调用当前时间
self.carlist.append(temp_car)
print("%s 停车入库成功!" % temp_carnum)
if not isAdmin: # 用户返回主菜单
print('按任意键返回主菜单......')
os.system("pause")
return None
if isAdmin: # 管理员询问是否继续新增车辆
while True:
continue_choice = input("YN继续新增车辆")
if continue_choice == 'Y' or continue_choice == 'y':
os.system('cls') # 清屏
break
elif continue_choice == 'N' or continue_choice == 'n':
return None
else:
print('输入错误,请重试!')
"""
def add_car(self, car):
# 从car新增车辆到carlist中
# if self.check_car(car) is not None:
# print("车辆已存在,请重试!")
# else:
car["intime"] = time.ctime() # 调用当前时间
self.carlist.append(car)
print("%s 停车入库成功!" % car.carnum)
"""
def display(self, carlist=None):
"""
显示车辆信息
:param:{list}carlist, 默认为self.carlist
:return:None
"""
if carlist is None:
carlist = self.carlist
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
print("车位 车牌号 车型 颜色 入场时间 ")
i = 0
for parkedCar in carlist:
print(parkedCar)
i += 1
if len(carlist) > 10 and i % 10 == 0: # 超过10辆车则每10辆一页
print("按任意键查看下一页......")
os.system("pause")
print("车位 车牌号 车型 颜色 入场时间 ")
# os.system('pause')
def check_car(self, keyword, sort=1):
"""
用于查找车辆默认sort=1,按照车位查找若存在则返回满足条件的车辆信息
:param:keyword关键词sort查找方式
:return:{class Car}/{list}
"""
if sort == 1: # 按车位
for parkedCar in self.carlist:
if parkedCar.parknum == keyword:
return parkedCar
elif sort == 2: # 按车牌
for parkedCar in self.carlist:
if parkedCar.carnum == keyword:
return parkedCar
elif 3 <= sort <= 4:
if sort == 3: # 按车型
key = "model"
elif sort == 4: # 按颜色
key = "color"
else:
return None
t_list = []
for parkedCar in self.carlist:
if parkedCar[key] == keyword:
t_list.append(parkedCar)
return t_list
elif sort == 5: # TODO 按入场时间
# (developing)
pass
else:
return None
def inquire(self, choice=-1):
"""
查询信息
复用于取车的查找修改信息的查找
Developing:按照入场时间查询多少时间内
:param choice:查询方式选择默认为-1.
:return:None/{class Car}parkedCar
"""
# choice = -1 # DEBUG
while choice < 0 or choice > 6:
print("""
1)空闲车位查询
--车辆信息查询--
2)按车位查询车辆
3)按车牌查询车辆
4)按车型查询车辆
5)按颜色查询车辆
6)按入场时间查询(developing)
---------------------------
0)返回主菜单
""")
try:
choice = int(input("请输入操作码:"))
except Exception:
print("错误操作码,请重试!")
continue
if choice < 0 or choice > 6:
print("错误操作码,请重试!")
if choice == 0:
return None # 返回主菜单
# 空闲车位查询:
elif choice == 1:
if len(self.carlist) >= self.max_car:
print("对不起,当前车库已满!")
return None
else:
print('空闲车位如下:')
self.inquire_empty()
print('') # 多空一行
else:
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
try:
# 按车位查询车辆:
if choice == 2:
keyword = int(input("请输入车位号:"))
t_result = self.check_car(keyword, sort=1)
if t_result:
print("车位 车牌号 车型 颜色 入场时间 ")
print(t_result)
return t_result
else:
print("停车场中无此车辆。")
# 按车牌查询车辆:
elif choice == 3:
keyword = input("请输入车牌号:")
t_result = self.check_car(keyword, sort=2)
if t_result:
print("车位 车牌号 车型 颜色 入场时间 ")
print(t_result)
return t_result
else:
print("停车场中无此车辆。")
# 按车型查询车辆:
elif choice == 4:
keyword = Model(int(input("请输入车辆的车型1小汽车, 2小卡, 3中卡, 4大卡")))
t_result = self.check_car(keyword, sort=3)
if t_result:
self.display(t_result)
else:
print("停车场中无此车型车辆。")
# 按颜色查询车辆:
elif choice == 5:
keyword = Color(int(input("请输入车辆的颜色1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色")))
t_result = self.check_car(keyword, sort=4)
if t_result:
self.display(t_result)
else:
print("停车场中无此颜色车辆。")
# 按入场时间查询:
elif choice == 6:
# TODO (developing) 按入场时间查询
pass
"""
keyword = input("请输入入场时间:")
t_result = self.check_car(keyword, sort=5)
if t_result:
print(t_result)
else:
print("停车场中无此车辆。")
"""
else:
pass
except Exception as e: # 输入异常处理
# logging.exception(e) # DEBUG
print("输入错误,按任意键返回......")
return None
def pickup(self):
"""
取车
:return:None
"""
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
# 变量初始化
exit_car = None
inquire_choice = -1
while inquire_choice < 0 or inquire_choice > 2:
try:
print("-----------取车-----------")
inquire_choice = int(input("1)按车位查找\n2)按车牌号查找\n0)返回主菜单\n\n请输入操作码:"))
except:
continue
if inquire_choice == 0: # 返回主菜单
return None
elif inquire_choice == 1: # 按车位
exit_car = self.inquire(choice=2)
elif inquire_choice == 2: # 按车牌号
exit_car = self.inquire(choice=3)
if exit_car is None:
return None
exit_choice = input("确定请输入“Y”其他任意输入返回主菜单")
if exit_choice == 'Y' or exit_choice == 'y':
exit_time = time.ctime()
park_time = time.mktime(time.strptime(exit_time)) - time.mktime(time.strptime(exit_car.intime))
m, s = divmod(park_time, 60)
h, m = divmod(m, 60)
str_time = "%02d:%02d:%02d" % (h, m, s) # 得到时分秒字符串
global unit_price
price = h * unit_price
print("车牌号:%s \n停车时长:%s\n请交费%3d" % (exit_car.carnum, str_time, price))
self.carlist.remove(exit_car)
os.system("pause") # 预留之后完善计费功能
print("结算成功,欢迎您再次光临!")
else:
return None
def edit(self):
"""
编辑车辆信息
:return:None
"""
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
# 变量初始化
edit_car = None
inquire_choice = -1
while inquire_choice < 0 or inquire_choice > 2:
try:
print("-----车辆信息编辑-----")
inquire_choice = int(input("1)按车位查找\n2)按车牌号查找\n0)返回主菜单\n\n请输入操作码:"))
except:
continue
if inquire_choice == 0: # 返回主菜单
return None
elif inquire_choice == 1: # 按车位
edit_car = self.inquire(choice=2)
elif inquire_choice == 2: # 按车牌号
edit_car = self.inquire(choice=3)
if edit_car is None:
return None
edit_choice = input("确定请输入“Y”其他任意输入返回主菜单")
if edit_choice == 'Y' or edit_choice == 'y':
index = self.carlist.index(edit_car) # 获取索引
while True:
try:
flag_right = False # right flag
change_choice = input(
"\n1)车位号\n2)车牌号\n3)车型\n4)车颜色\n5)入场时间\n0)不修改返回主菜单\n\n请输入您要修改的信息序号:")
if change_choice == '0':
return None
elif change_choice == '1':
new_info = int(input("请输入新的车位号:"))
if 0 <= new_info <= self.max_car: # 在范围内
for parkedCar in self.carlist:
if parkedCar.parknum == new_info: # 判断车位是否已被占用
print(" %d号车位已被占用!" % new_info)
break
else:
self.carlist[index]["parknum"] = new_info
flag_right = True
print("车位号修改成功!")
# break
elif change_choice == '2':
new_info = input("请输入新的车牌号:")
if self.check_car_num(new_info): # 判断车牌号是否有效
for parkedCar in self.carlist:
if parkedCar.carnum == new_info: # 判断车牌是否已重复
print("车牌号重复!")
break
else:
self.carlist[index]["carnum"] = new_info
flag_right = True
print("车牌号修改成功!")
# break
elif change_choice == '3':
new_info = int(input("请输入新的车型1小汽车, 2小卡, 3中卡, 4大卡:"))
if 1 <= new_info <= 4:
new_info = Model(new_info) # 转化为Model枚举类型
self.carlist[index]["model"] = new_info
flag_right = True
print("车型修改成功!")
elif change_choice == '4':
new_info = int(input("请输入新的车颜色1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色"))
if 1 <= new_info <= 6:
new_info = Color(new_info) # 转化Color枚举类型
self.carlist[index]["color"] = new_info
flag_right = True
print("颜色修改成功!")
elif change_choice == '5':
new_info = input("请输入新的入场时间:(参考格式2019.3.4 12:00:00)")
print("DEVELOPING...")
# TODO 修改入场时间
pass
break
else:
pass
except:
print("输入错误,请重试!")
continue
if flag_right:
break
else:
print("请重试!")
continue
else:
return None
def statistics(self):
"""
统计车辆信息
:return:None
"""
print("""
本停车场总车位数{total:3d}
当前已驶入车辆数{exist:3d} 空闲车位数{empty:3d}
-----------------------------------------------
""".format(total=self.max_car, exist=len(self.carlist), empty=self.max_car - len(self.carlist)),
end='')
# 按车型、颜色统计车辆信息
cnt_model = [0, 0, 0, 0]
cnt_color = [0, 0, 0, 0, 0, 0]
if len(self.carlist) != 0:
for parkedCar in self.carlist:
cnt_model[parkedCar.model.value - 1] += 1
cnt_color[parkedCar.color.value - 1] += 1
print("""
* 按车型统计
小汽车 {:3d}, 小卡 {:3d}, 中卡 {:3d}, 大卡 {:3d}
* 按颜色统计
白色 {:3d}, 黑色 {:3d}, 灰色 {:3d}
蓝色 {:3d}, 红色 {:3d}, 黄色 {:3d}
""".format(cnt_model[0], cnt_model[1], cnt_model[2], cnt_model[3],
cnt_color[0], cnt_color[1], cnt_color[2],
cnt_color[3], cnt_color[4], cnt_color[5], ), end='')
if len(self.carlist) == 0:
print("""
-----------------------------------------------
""")
else:
# TODO 按入场时间统计
print("""
* 按入场时间统计
正在开发中 Developing...
-----------------------------------------------""")
# TODO 车辆信息按顺序输出
# choice = input("""
# 1)按车位排序 2)按入场时间排序
# 请输入操作码(其他任意输入返回主菜单):""")
# if choice == '1':
# pass
# temp_carlist = []
# for parkedCar in self.carlist:
# pass
#
# self.display(temp_carlist)
# elif choice == '2':
# pass
# else:
# return None
#