Python基础编程——实验室药品管理系统

简单介绍

主要涉及变量和数值类型、列表操作、字典操作、if语句、for、while循环、输入以及文件和异常,不包含装饰器等~

功能实现

  1. 文件导入和手工写入药品
  2. 查找信息和领用药品
  3. 显示所有信息——多种排序方式
  4. 显示库存不足的信息
  5. 显示领用后的登记信息

功能演示

小破站功能演示视频

代码如下_可直接运行

import time
import os
import random
import uuid

class Storage:

    def __init__(self):
        self.main()

    def main(self):
        # 定义主菜单
        exit_main = False

        while not exit_main:
            i = os.system('cls')
            self.menu_screen()
            cho = input("                    选择对应的功能(0-5):")
            if cho in "1,2,3,4,5,0":
                if cho == '1':
                    print("\n\n《《录入信息》》")
                    i = os.system('cls')
                    while True:

                        cho1 = input("""
                        ╔────  输入'q'or'Q'返回上一级
                        │   1.从文件导入
                        │   2.手动多个依次录入
                        │   3.手动单个依次录入
                        ╚───────────────────────
                                   选择对应的功能:""")
                        i = os.system('cls')
                        if cho1 == '1':
                            i = os.system('cls')
                            self.input_txt()
                        elif cho1 == '2':
                            i = os.system('cls')
                            self.insert_many_info()
                        elif cho1 == '3':
                            i = os.system('cls')
                            self.insert_si_info()
                        elif cho1.lower() == 'q':
                            i = os.system('cls')

                            break

                elif cho == '2':
                    i = os.system('cls')
                    print("\n\n《《查找药品》》")
                    self.search()

                elif cho == '3':
                    i = os.system('cls')
                    print("\n\n《《显示所有信息》》")
                    self.sort_info()
                elif cho == '4':
                    i = os.system('cls')
                    print("\n\n《《显示库存量较少的药品信息》》")
                    self.show_surp()
                elif cho == '5':
                    i = os.system('cls')
                    print("\n\n《《查看登记信息》》")
                    self.show_sign()


                elif cho == '0':
                    i = os.system('cls')
                    self.exit_sys()
                    exit_re = input("仔细看看这个顶,这是本系统的第一个彩蛋\n\n按enter退出")
                    if not exit_re:
                        exit_main = True
            else:
                print("选择错误,对应0-5!", end="")
                continue
    # 主菜单界面
    def menu_screen(self):
        print("""
                        ╔────  药品出入库本地管理系统
                        │   =================功能菜单=====
                        │                    1. 录入药品信息
                        │                    2. 查找领取药品
                        │                    3. 显示所有药品
                        │                    4. 显示需要增补的药品
                        │                    5. 查看登记表                 
                        │                    0. 退出                                                                    
                        │    v 1.0.0.0.0
                        │                                                
                        ╚───────────────    by:真礼箴a  2020-02-02

    """)

    # 导入的信息保存至文件
    def save(self,in_list, type="a"):
        with open("药品信息录入表.txt", type) as allfile:
            for info in in_list:
                allfile.write("\n" + str(info))
            print("导入成功")

    # 产生随机id定义录入药品信息函数
    def random_str(self,num=6):
        uln = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        rs = random.sample(uln, num)  # 生成一个 指定位数的随机字符串
        a = uuid.uuid1()  # 根据 时间戳生成 uuid , 保证全球唯一
        b = ''.join(rs + str(a).split("-"))  # 生成将随机字符串 与 uuid拼接
        return b  # 返回随机字符串

    # 单个信息录入
    def insert_si_info(self):
        in_list = []

        exit_insert = False
        while not exit_insert:
            dic = {}
            print("\n\n                    依次输入以下信息,不可后退更改,注意!!!")
            name = input("""
                        ╔────   输入'q'or'Q'返回上一级.\n\n                    名字:(氢氧化钠)""")
            if not name:
                print("                    输入不可为空,仔细看一看")
                continue
            if name.lower() != 'q':
                typ = input("\n                    类别:(有机/无机/醇/醚等)")
                try:
                    num = float(input("\n                    数量:(1、2、3)"))
                    num_unit = input("\n                    数量单位:(瓶/桶/箱)")
                    if not num_unit:
                        print("                    输入不可为空,仔细看一看")
                        continue
                    modle = float(input("\n                    规格:(250/500/1000)"))

                except ValueError:
                    print("                    输入类型错误,仔细看一看")
                    continue
                modle_unit = (input("\n                    规格单位:(ml/l/mg/g)"))
                if not modle_unit:
                    print("                    输入不可为空,仔细看一看")
                    continue
                time_insert = time.strftime("%Y-%m-%d", time.localtime(time.time()))
                locat = input("\n                    存放位置:")
                if not locat:
                    print("                    输入不可为空,仔细看一看")
                    continue
                total = num * modle
                surp = num * modle - 0
                sur_per = surp / total
                info_id = self.random_str()
                dic = {
                    "name": name, "typ": typ, "num": num, "num_unit": num_unit,
                    "modle": modle, "time_insert": time_insert, "locat": locat, "modle_unit": modle_unit,
                    "used": 0, "total": num * modle, "surp": num * modle - 0, "sur_per": sur_per, "id": info_id}
                in_list.append(dic)

                print(f"                    已加入“{dic['name']}”信息")

                exit_insert = True
                save_active = True

            else:
                exit_insert = True
                save_active = False
        if save_active:
            self.save(in_list)
        else:
            pass

    # 多个信息录入
    def insert_many_info(self):
        in_list = []
        in_name = []
        exit_insert = False
        while not exit_insert:
            dic = {}
            i = 1
            print(f"                    依次输入以下信息,不可后退更改,注意!!!\n\n                    第{i}条信息")
            name = input("""
                        ╔────   输入's'or'S'停止录入.\n                    名字:(氢氧化钠)""")
            if not name:
                print("                    输入不可为空,仔细看一看")
                continue
            if name.lower() == 's':
                break
            typ = input("                    类别:(有机/无机/醇/醚等)")
            try:
                num = float(input("                    数量:(1、2、3)"))
                num_unit = input("                    数量单位:(瓶/桶/箱)")
                if not num_unit:
                    print("                    输入不可为空,仔细看一看")
                    continue
                modle = float(input("                    规格:(250/500/1000)"))
            except ValueError:
                print("                    输入类型错误,仔细看一看")
                continue

            modle_unit = (input("                    规格单位:(ml/l/mg/g)"))
            if not modle_unit:
                print("                    输入不可为空,仔细看一看")
                continue
            time_insert = time.strftime("%Y-%m-%d", time.localtime(time.time()))
            locat = input("                    存放位置:")
            if not locat:
                print("                    输入不可为空,仔细看一看")
                continue
            total = num * modle
            surp = num * modle - 0
            sur_per = surp / total
            info_id = self.random_str()
            dic = {
                "name": name, "typ": typ, "num": num, "num_unit": num_unit,
                "modle": modle, "time_insert": time_insert, "locat": locat, "modle_unit": modle_unit,
                "used": 0, "total": num * modle, "surp": num * modle - 0, "sur_per": sur_per, "id": info_id}
            in_list.append(dic)
            in_name.append(dic['name'])
            i += 1

            print("已加入以下信息")
            print(*in_name, sep="\n")

        self.save(in_list)

    # 从文件中导入
    def input_txt(self):
        """批量将外部的一个文件导入为列表,再遍历列表,写入字典,添加到列表,转化为字符串写入文本"""
        in_list = []

        tet_name = input("""



                        ╔────   输入'q'or'Q'返回上一级.
                        输入当前路径下需导入的文件名字:""")
        if tet_name.lower() != 'q':
            tet_name1 = tet_name + ".txt"
            if os.path.exists(tet_name1):
                with open(tet_name1, "r") as allfile:
                    nefile = allfile.readlines()
                    count = 1
                    for info in nefile:
                        print("已成功加载")
                        print(info.strip().split("\t"))
                        info_list = (info.strip().split("\t"))
                        if info_list[0] != '类别':
                            name = info_list[1]
                            typ = info_list[0]
                            num = float(info_list[2])
                            num_unit = info_list[3]
                            modle = float(info_list[5])
                            modle_unit = info_list[6]
                            time_insert = time.strftime("%Y-%m-%d", time.localtime(time.time()))
                            locat = info_list[4]
                            total = num * modle
                            info_id = self.random_str()
                            used = 100
                            surp = total - used
                            sur_per = surp / total
                            count += 1
                            dic = {
                                "name": name, "typ": typ, "num": num, "num_unit": num_unit,
                                "modle": modle, "time_insert": time_insert, "locat": locat, "modle_unit": modle_unit,
                                "used": used, "total": total, "surp": surp, "sur_per": sur_per, "id": info_id}
                            in_list.append(dic)
                    print(f"\n\n                  ===================本次录入{count}条信息========================")

                self.save(in_list)

            else:
                print("名字输入有误,检查后重新输入", end="")
                self.input_txt()

        else:
            pass

    # 领用修改余量
    def motify_info(self,info_id, num1, name):
        sign_active = True
        try:

            num = float(num1)
            save_list = []
            nefile = []
            with open("药品信息录入表.txt", "r") as allfile:
                nefile = allfile.readlines()

            con = True
            for info in nefile:
                if info != '\n':
                    dic = dict(eval(info))
                    # 判断领用是否大于当前药品剩余量

                    if dic['id'] == info_id:
                        if dic['surp'] >= num:

                            print(f"                    已领用{num}{dic['modle_unit']}")

                            dic['surp'] = dic['surp'] - num
                            dic['used'] = dic['used'] + num
                            dic['num'] = dic['total'] / dic['modle']
                            dic['sur_per'] = dic['surp'] / dic['total']
                            modle = dic["modle_unit"]
                            print(f"                    当前余量{dic['surp']}{dic['modle_unit']}")
                            if dic["surp"] > 0:
                                save_list.append(dic)
                            else:
                                print("=" * 20)
                                print(f"                    “{dic['name']}”被领用完,及时补充")
                                print("=" * 20)
                                save_list.append(dic)
                        else:
                            print(f"\n\n                    {name}的领取量超出当前选择的药品的总量,请检查后重新输入")
                            sign_active = False
                            pass
                    else:
                        save_list.append(dic)


        except ValueError:
            print("\n\n                    输入的类型错误,请按照要求重新输入")

        if sign_active:
            sign = input("\n\n                    请输入领用者姓名:")
            time_insert = time.strftime("%Y-%m-%d", time.localtime(time.time()))
            print(f"""
            {sign}领用了“{name}”共{num}{modle}!
                            {time_insert}

            """)
            com_si = {}

            a = f"""{sign}\t“{name}”\t{num}{modle}\t{time_insert}"""

            self.save(save_list, "w")
            self.save_sign(a)
            ex = input(
                "\n\n                    ===========\n                    任意键退出\n                    ===========\n")

    # 保存签名
    def save_sign(self,a):
        if os.path.exists("登记表.txt"):
            with open("登记表.txt", "a") as alfile:
                alfile.write(a + "\n")
                print("登记成功")
        else:
            with open("登记表.txt", "a") as alfile:
                alfile.write("姓名\t领用药品\t领用量\t领用日期\n")
                alfile.write(a + "\n")
                print("登记成功")

    # 查询信息
    def search(self):
        with open("药品信息录入表.txt", "r") as allfile:
            nefile = allfile.readlines()
            sear_re = []
            while True:
                sear_name = input("\n                    输入'q'or'Q'退出\n                    输入要查询的名字:")
                if sear_name.lower() == 'q':
                    break

                for info in nefile:
                    if info != '\n':
                        dic = dict(eval(info))
                        if dic["name"] == sear_name:
                            sear_re.append(dic)

                print("                    ================================\n查找到%d条与“%s”相关的药品信息\n" % (
                len(sear_re), sear_name))

                ii = 0
                if len(sear_re) > 0:
                    print("序号\t类别\t药品名\t总量\t余量\t存放地\t数量\t规格\t入库时间")
                for i in sear_re:
                    ii += 1
                    print(f"{ii}.\t{i['typ']}\t{i['name']}\t{i['total']}\t{i['surp']}\t{i['locat']}\t{i['num']}{i['num_unit']}"
                          f"\t{i['modle']}{i['modle_unit']}\t\t{i['time_insert']}")
                con_sel = input("\n\n                    ================================是否继续查找其他药品('y'继续,其他按键取消)")
                if con_sel.lower() != 'y':
                    break

            fun_sel = input(
                "                    ╔────   输入'q'or'Q'返回上一级\n\n                    1.领用\n\n                    2.就看看\n")
            if fun_sel.lower() != 'q':
                if fun_sel == '1':
                    if len(sear_re) == 1:
                        sel_reu_str = input("                    输入需要领用药品的量:")
                        dic1 = sear_re[0]
                        dic_name = dic1["name"]
                        print(dic_name)

                        dic_num = float(sel_reu_str)
                        dic_id = dic1["id"]
                        print(dic_num)

                        print("                    领一个")

                        self.motify_info(dic_id, dic_num, dic_name)

                    else:

                        sel_reu_str = input(
                            "                    输入需要领用的药品序号及用量,逗号分隔》如:1,500,4,300\n                    ")

                        # 转换为列表
                        sel_reu_list = sel_reu_str.split(",")
                        if len(sel_reu_list) == 1:
                            sel_reu_list = sel_reu_str.split(",")

                        # 第一次从列表里取出来0 和1 的元素,0元素的内容作为上一次搜索出来的结果序号,取出结果列表的字典,并将字典里的id和name取出向下传递。
                        # 而1对应的元素则转换为float直接传递下去
                        i = 0
                        a = len(sel_reu_list) // 2
                        if len(sel_reu_list) // 2 == 1:
                            print("领一个")
                            b = int(sel_reu_list[0]) - 1
                            dic1 = sear_re[b]
                            dic_name = dic1["name"]
                            dic_id = dic1["id"]
                            dic_num = float(sel_reu_list[1])
                            self.motify_info(dic_id, dic_num, dic_name)
                        else:
                            for ti in range(0, a):
                                dic_name = int(sel_reu_list[i])
                                dic1 = sear_re[dic_name - 1]
                                dic_name = dic1["name"]
                                dic_id = dic1["id"]
                                print(dic_name)

                                dic_num = float(sel_reu_list[i + 1])
                                print(dic_num)

                                self.motify_info(dic_id, dic_num, dic_name)
                                i += 2
                elif fun_sel == '2':
                    print("就看看")
            else:
                pass

    # 所有信息排序
    def sort_info(self):
        if not os.path.exists("药品信息录入表.txt"):
            print(
                "\n\n                    ====================================\n                    当前没有录入任何药品信息\n                    ====================================")
        else:
            with open("药品信息录入表.txt", "r") as allfile:
                list1 = []
                nefile = allfile.readlines()
                print("                    当前共有%d条药品信息" % len(nefile))
                for info in nefile:
                    if info != '\n':
                        dic = dict(eval(info))
                        list1.append(dic)
                while True:
                    sort_select = input(
                        "\n\n                    ╔────   输入'q'or'Q'返回上一级\n\n                     选择排序类型(1类别,2名称,3余量,4总量,5入库时间):")
                    if sort_select == '1':
                        list1.sort(key=lambda x: x['typ'])
                    elif sort_select == '2':
                        list1.sort(key=lambda x: x['time_insert'])
                    elif sort_select == '3':
                        list1.sort(key=lambda x: x['surp'])
                    elif sort_select.lower() == 'q':
                        break
                    else:
                        print("                    输入有误,重新输入1-3")
                    self.show_info(list1)

    # 显示列表中的信息
    def show_info(self,info_list):
        if not info_list:
            print("                    无数据信息")
        print("=" * 95)

        # TODO 使其输出排列整齐
        print("序号\t类别", "\t" "名称", '\t\t' "存放位置", '\t\t' "余量", '\t\t' "总量", '\t\t' "入库时间")
        print("=" * 95)
        i = 1
        for info in info_list:
            print(
                f"{i}.\t{info.get('typ')}\t{info.get('name')}\t\t{info.get('locat')}\t\t{info.get('surp')}\t\t{info.get('total')}\t\t{info.get('time_insert')}")
            i += 1

    def show_surp(self):
        sp_li = []
        if not os.path.exists("药品信息录入表.txt"):
            print(
                "\n\n                    ====================================\n                    当前没有录入任何药品信息信息\n                    ====================================")
        else:
            with open("药品信息录入表.txt", "r") as allfile:
                nefile = allfile.readlines()
                for info in nefile:
                    if info != '\n':
                        dic = dict(eval(info))
                        if dic['sur_per'] < 0.2:
                            sp_li.append(dic)

            if len(sp_li) != 0:
                ii = 1
                print("\n                    ╔────   以下药品库存紧张,如果需要,请及时补充")
                print(
                    "\n                    │   ====================================\n                    │   名称\t\t余量\t\t余量百分比")
                for i in sp_li:
                    dic = dict(i)

                    print(f"                    │   {dic['name']}\t\t{dic['surp']}{dic['modle_unit']}\t\t{dic['sur_per'] * 100}%│")
                    ii += 1
            else:
                print("\n\n                    =================================\n                    当前没有需要补充的药品\n                    =================================\n\n\n")

            input("\n\n                    =================================\n                    任意键退出\n                    =================================\n\n\n")

    def exit_sys(self):
        print("""
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一一一一一一一一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一一一一一一一一一一一顶顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶一一一一顶一一一一一一一一一一一顶顶顶顶顶半顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一一一一顶一一一顶顶一一一一一顶顶顶顶顶顶顶顶顶顶顶 
                        顶顶顶一一一一一一一一一一一一顶顶顶顶顶顶一一一一顶顶顶顶顶顶顶顶顶顶顶顶 
                        顶一一一一一一一一一一一一一一顶顶顶顶顶顶一一一一顶顶顶顶顶顶顶顶顶顶顶顶 
                        顶一一一一一一一一一一一一顶顶顶顶顶顶顶一一一一一一一一一一一顶顶顶顶顶顶 
                        顶一一一一一一一一一一一一顶顶顶顶顶顶一一一一一一一一一一一一一一顶顶顶顶 
                        顶顶一一一一一一一一一一顶顶顶顶顶一一一一一一顶顶顶一一一一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶顶一一一一顶顶顶顶顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶顶一一顶顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶顶一一一一顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶顶一一一一顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶顶一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶顶一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶一一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶一一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶一一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一一顶一一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶一一一一顶顶顶顶一一一顶顶一一一一顶顶一一一一一顶顶顶顶顶 
                        顶顶一一顶顶顶一一一一一顶顶顶顶一一一顶顶一一一顶顶顶一一一一一顶顶顶顶顶 
                        顶顶一一一一一一一一一一顶顶顶顶顶一一顶顶一一顶顶顶顶一一一一一顶顶顶顶顶 
                        顶顶顶一一一一一一一一一顶顶顶顶顶顶顶顶一一一顶顶顶顶一一一一顶顶顶顶顶顶 
                        顶顶顶顶顶一一一一一一一顶顶顶顶顶顶顶顶一一一顶一一一一顶顶顶顶顶顶顶顶顶 
                        顶顶顶顶顶顶一一一一一一顶顶顶顶顶顶顶一一一一顶顶一一一一顶顶顶顶顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶一一一顶顶顶顶顶顶一一一一一顶顶顶一一一一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一一顶顶顶顶顶一一一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一一顶顶顶顶顶顶一一一一一一一顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一顶顶顶顶顶顶顶顶顶一一一一一一顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶顶一一一一一顶顶顶顶顶顶顶顶顶顶顶一一一一顶顶顶顶 
                        顶顶顶顶顶顶顶顶顶顶顶顶一一一顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶一一一顶顶顶顶
    """)

    def show_sign(self):
        if not os.path.exists("登记表.txt"):
            print(
                "\n\n                    ====================================\n                    当前没有任何登记信息\n                    ====================================")
        else:
            with open("登记表.txt", 'r') as allfile:
                nefile = allfile.readlines()
                ne_li = []
                for i in nefile:
                    i = str(i)
                    i = i.split("\t")
                    ne_li.append(i)

                ne_li.sort(key=lambda x: x[3])
                print(
                    "\n\n                    ====================================\n                    领用人\t药品名\t领取量\t领取日期\n                    ====================================")
                for i in ne_li:
                    print(f"                    {i[0]}\t{i[1]}\t{i[2]}\t{i[3]}", end="")

                input("enter键退出")

# 实例化对象
a = Storage()

致谢

感谢大家的阅读,里面还有过很多需要优化的地方,但是在我们实验室这些功能已经够用了,因此就不继续改了。 ^ _ ^

发布了5 篇原创文章 · 获赞 0 · 访问量 160

猜你喜欢

转载自blog.csdn.net/weixin_41655783/article/details/104433983