Python中幼儿园级别电梯调度模拟实验

42 篇文章 1 订阅
14 篇文章 1 订阅

Python中幼儿园级别电梯调度模拟实验

一、前言

每天下班回家都能看到电梯,所以很想弄懂电梯是怎么实现自动调度的,由于本人python才疏学浅,本次博客偏新手向

PS:测试版本,以后会不断完善

二、版本说明

版本更新日期
1.0_beta2022-02-14
1.1_rc2022-02-15

三、1.0beta版本代码逻辑

  • 创建电梯A,电梯B两个线程
  • 获取去往的楼层,限制最大楼层为10
  • 根据电梯当前楼层与去往楼层的距离,选择调用电梯A,或者电梯B
  • 使用线程中的互斥锁,顺序调度

3.1、1.0beta版本代码

具体实现代码如下:

import logging, time
from threading import Lock, Thread

fomatter = logging.Formatter(' %(levelname)s %(asctime)s - %(funcName)s - %(thread)s [%(message)s]')
# 创建日志器对象
logger = logging.getLogger()
# 日志级别总开关
logger.setLevel("INFO")
# 创建控制台hander
console_hander = logging.StreamHandler()
# 创建控制台hander日志等级
console_hander.setLevel(level='INFO')
# 添加日志格式对象
console_hander.setFormatter(fomatter)
logger.addHandler(console_hander)

height_A = 0
height_B = 0


def diantiA(lock, select_height, staus):
    if staus:
        global height_A
        lock.acquire()
        logger.info('电梯A开始运行')
        while True:
            if select_height > height_A:
                logger.info(f'电梯A开始上升,当前电梯楼层为{height_A},去往{select_height}')
                height_A += 1
                time.sleep(0.25)
                if height_A == select_height:
                    logger.info('电梯A已到站')
                    lock.release()
                    break
            else:
                logger.info(f'电梯A开始下降,当前电梯楼层为{height_A},去往{select_height}')
                height_A -= 1
                time.sleep(0.25)
                if height_A == select_height:
                    logger.info('电梯A已到站')
                    lock.release()
                    break
    else:
        logger.info('电梯B以完成任务,电梯A不接受')


def diantiB(lock, select_height, staus):
    if staus:
        global height_B
        lock.acquire()
        logger.info('电梯B开始运行')
        while True:
            if select_height > height_B:
                logger.info(f'电梯B开始上升,当前电梯楼层为{height_B},去往{select_height}')
                height_B += 1
                time.sleep(0.25)
                if height_B == select_height:
                    logger.info('电梯B已到站')
                    lock.release()
                    break
            else:
                logger.info(f'电梯B开始下降,当前电梯楼层为{height_B},去往{select_height}')
                height_B -= 1
                time.sleep(0.25)
                if height_B == select_height:
                    logger.info('电梯B已到站')
                    lock.release()
                    break
    else:
        logger.info('电梯A以完成任务,电梯B不接受')


def main():
    lock = Lock()
    while True:
        staus = True
        try:
            print(f'电梯A当前高度{height_A},电梯B当前高度{height_B}')
            select_dianti = int(input('请输入楼层:'))
            if select_dianti > 10:
                logger.error('输入的电梯超过楼层高度,最高为10层,请重新输入')
                continue
            else:
                resultA = abs(select_dianti - height_A)
                resultB = abs(select_dianti - height_B)
                da = Thread(target=diantiA, args=(lock, select_dianti, staus))
                db = Thread(target=diantiB, args=(lock, select_dianti, staus))
                if resultA >= resultB:
                    staus = True
                    db.start()
                    db.join()
                    staus = False
                else:
                    staus = True
                    da.start()
                    da.join()
                    staus = False

        except Exception as e:
            logger.error(f'input wrong{e}')
            continue


if __name__ == '__main__':
    main()

四、1.1rc版本代码逻辑

  • 创建电梯A,电梯B两个线程
  • 获取用户当前所在的楼层,去往的楼层,限制两种楼层最大为10
  • 根据电梯当前楼层与去往楼层的距离,选择调用电梯A,或者电梯B,AB初始楼层一致时,默认会调度电梯B
  • 如果用户所在的楼层大于电梯当前的楼层,执行上升操作,反之则电梯下降
  • 使用线程中的互斥锁,顺序调度

4.1、1.1rc版本代码

全部代码如下:

import logging, time
from threading import Lock, Thread

fomatter = logging.Formatter(' %(levelname)s %(asctime)s - %(funcName)s - %(thread)s [%(message)s]')
# 创建日志器对象
logger = logging.getLogger()
# 日志级别总开关
logger.setLevel("INFO")
# 创建控制台hander
console_hander = logging.StreamHandler()
# 创建控制台hander日志等级
console_hander.setLevel(level='INFO')
# 添加日志格式对象
console_hander.setFormatter(fomatter)
logger.addHandler(console_hander)

height_A = 0
height_B = 0


def diantiA(lock, select_height, staus, target):
    if staus:
        global height_A
        lock.acquire()
        logger.info('电梯A开始运行')
        while True:
            # 如果用户所在的楼层大于电梯当前的楼层,执行上升操作
            if select_height > height_A:
                logger.info(f'电梯A开始上升,准备搭载乘客,当前电梯楼层为{height_A}')
                height_A += 1
                time.sleep(0.25)
                if height_A == select_height:
                    logger.info('电梯A已到站,开始搭载乘客')
                    logger.info(f'去往:{target}')
                    while True:
                        # 判断电梯当前楼层与目标楼层的大小,如果目标楼层大于当前楼层,执行上升操作,反之执行下降操作
                        if target > height_A:
                            height_A += 1
                            logger.info(f'电梯A搭载乘客中,当前电梯楼层为{height_A}')
                            time.sleep(0.25)
                            if height_A == target:
                                logger.info('电梯A成功到达目标楼层')
                                break
                        else:
                            height_A -= 1
                            logger.info(f'电梯A搭载乘客中,当前电梯楼层为{height_A}')
                            time.sleep(0.25)
                            if height_A == target:
                                logger.info("电梯A成功到达目标楼层")
                                break
                    lock.release()
                    break
            else:
                logger.info(f'电梯A开始下降,准备搭载乘客,当前电梯楼层为{height_A}')
                height_A -= 1
                time.sleep(0.25)
                if height_A == select_height:
                    logger.info(f'电梯A已到站,开始搭载乘客,目标楼层为{target}')
                    while True:
                        # 判断电梯当前楼层与目标楼层的大小,如果目标楼层大于当前楼层,执行上升操作,反之执行下降操作
                        if target > height_A:
                            height_A += 1
                            logger.info(f'电梯A搭载乘客中,当前电梯楼层为{height_A}')
                            time.sleep(0.25)
                            if height_A == target:
                                logger.info('电梯A成功到达目标楼层')
                                break
                        else:
                            height_A -= 1
                            logger.info(f'电梯A搭载乘客中,当前电梯楼层为{height_A}')
                            time.sleep(0.25)
                            if height_A == target:
                                logger.info("电梯A成功到达目标楼层")
                                break
                    lock.release()
                    break
    else:
        logger.info('电梯B以完成任务,电梯A不接受')


def diantiB(lock, select_height, staus, target):
    if staus:
        global height_B
        lock.acquire()
        logger.info('电梯B开始运行')
        while True:
            # 如果用户所在的楼层大于电梯当前的楼层,执行上升操作
            if select_height > height_B:
                logger.info(f'电梯B开始上升,准备搭载乘客')
                height_B += 1
                time.sleep(0.25)
                if height_B == select_height:
                    logger.info('电梯B已到站,开始搭载乘客,目标楼层为{target}')
                    while True:
                        # 判断电梯当前楼层与目标楼层的大小,如果目标楼层大于当前楼层,执行上升操作,反之执行下降操作
                        if target > height_B:
                            height_B += 1
                            logger.info(f'电梯B搭载乘客中,当前电梯楼层为{height_B}')
                            time.sleep(0.25)
                            if height_B == target:
                                logger.info('电梯B成功到达目标楼层')
                                break
                        else:
                            height_B -= 1
                            logger.info(f'电梯B搭载乘客中,当前电梯楼层为{height_B}')
                            time.sleep(0.25)
                            if height_B == target:
                                logger.info('电梯B成功到达目标楼层')
                                break
                    lock.release()
                    break
            else:
                logger.info(f'电梯B开始下降,当前电梯楼层为{height_B}')
                height_B -= 1
                time.sleep(0.25)
                if height_B == select_height:
                    logger.info('电梯B已到站')
                    logger.info(f'去往:{target}')
                    while True:
                        # 判断电梯当前楼层与目标楼层的大小,如果目标楼层大于当前楼层,执行上升操作,反之执行下降操作
                        if target > height_B:
                            height_B += 1
                            logger.info(f'电梯B搭载乘客中,当前电梯楼层为{height_B}')
                            time.sleep(0.25)
                            if height_B == target:
                                logger.info('电梯B成功到达目标楼层')
                                break
                        else:
                            height_B -= 1
                            logger.info(f'电梯B搭载乘客中,当前电梯楼层为{height_B}')
                            time.sleep(0.25)
                            if height_B == target:
                                logger.info('电梯B成功到达目标楼层')
                                break
                    lock.release()
                    break
    else:
        logger.info('电梯A以完成任务,电梯B不接受')


def main():
    lock = Lock()
    while True:
        staus = True
        try:
            print(f'电梯A当前高度{height_A},电梯B当前高度{height_B}')
            select_dianti = int(input('当前电梯楼层为:'))
            target = int(input('去往楼层为:'))
            if select_dianti > 10 or target > 10:
                logger.error('输入的电梯超过楼层高度,最高为10层,请重新输入')
                continue
            else:
                resultA = abs(select_dianti - height_A)
                resultB = abs(select_dianti - height_B)
                da = Thread(target=diantiA, args=(lock, select_dianti, staus, target))
                db = Thread(target=diantiB, args=(lock, select_dianti, staus, target))
                if resultA >= resultB:
                    staus = True
                    db.start()
                    db.join()
                    staus = False
                else:
                    staus = True
                    da.start()
                    da.join()
                    staus = False

        except Exception as e:
            logger.error(f'input wrong{e}')
            continue


if __name__ == '__main__':
    main()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈小c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值