美文网首页
(七)Python面向对象综合案例:控制台模拟红绿灯

(七)Python面向对象综合案例:控制台模拟红绿灯

作者: 小雨Coding | 来源:发表于2020-08-23 14:40 被阅读0次

    一、需求分析

    1. 需要实现的功能

    (1)通过控制台输入绿灯、黄灯、红灯的时间
    (2)输入完成后,按回车,先绿灯倒计时,然后黄灯倒计时,然后红灯倒计时,再到绿灯倒计时,周而复始。

    2. 对类的分析
    静态特征

    (1)三个数字:红灯、黄灯、绿灯
    (2)两个电子屏

    • 一个电子屏显示一个数字
    • 一个电子屏包含200个(20行*10列),控制200个灯的亮与不亮显示数字
    • 每个灯就两种状态:(亮与不亮)
    动态特征
    • 打印
    • 把数字构造在电子屏中
    • 用不同的颜色打印
    • 倒计时
    3. 如何实现时间的倒计时

    每次打印完成后--> 停止1秒 --> 清屏 --> 在数字减一后再打印 --> 停止1秒后 --> 清屏

    二、构建类的静态特征

    1. 构建一个Light类

    创建一个显示屏含有20行10列的小灯,每个小灯设置为布尔型值False;

    class Light:
        # 构造函数
        def __init__(self):
            self.light = []
            # 自动初始化
            self.prepare_light()
    
        def prepare_light(self):
            # 准备20行10列200个灯
            for row in range(20):
                temp = [] # 每行10个
                for col in range(10):
                    # 每一列的灯默认不亮
                    temp.append(False)
                # 把每行的10个插入到light集合中
                self.light.append(temp)
    
    2. 再构建一个TrafficLight

    接收红黄绿三种颜色灯要显示的时间:

    class TrafficLight:
        # 构造函数
        def __init__(self,green_time,yellow_time,red_time):
            self.green_time = green_time    # 绿灯的时间
            self.yellow_time = yellow_time  # 黄灯的时间
            self.red_time = red_time    # 红灯的时间
    
            self.number01 = Light() # 显示第一个数字的电子屏
            self.number02 = Light() # 显示第二个数字的电子屏
    

    三、实现红绿灯输入时间的校验

    在前面我们给红绿灯运行时间直接提供了数字,按照实际需求我们应当手动输入红绿灯运行的时间。
    我们定义一个方法可以根据提供的颜色,输入指定颜色灯光的时间。把这个方法定义成静态方法就可以不用通过对象来调用。
    之后我们再检验输入的值是否符合要求:

    • 输入的内容必须是数字
    • 输入的数字范围在1-99之间

    如果不符合要求,则提醒用户重新输入

    @staticmethod           # 静态方法,不需要实例化直接调用!!!
    def input_time(color:str):
        """
        根据提供的颜色,输入相应颜色的时间
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        :param color: 提供的颜色
        :return: 输入的时间
        """
        while True:
            time = ""    # 定义一个全局的time
            # 根据颜色提醒输入
            if color.lower() == "green":
                time = input("请输入绿灯的时间:")
            if color.lower() == "yellow":
                time = input("请输入黄灯的时间:")
            if color.lower() == "red":
                time = input("请输入红灯的时间:")
            # 校验输入的是否符合要求:数字、正数、1-99
            if not time.isdigit():
                print("输入的值不符合要求!【要求:1-99之间的数字】")
                continue    # 结束当前循环
            else:
                time_number = int(time)
                if time_number < 1 or time_number > 99:
                    print("输入的值不符合要求!【要求:1-99之间的数字】")
                    continue
                else:
                    # 符合要求
                    return time_number
    

    三、实现红绿灯的倒计时功能

    在控制台显示红绿灯效果的流程:清屏 --> 打印数字 --> 停止1秒 --> 打印减一后的数字

    def start(self):
        while True:
            # 默认一直循环下去
            # 绿灯
            for number in range(self.green_time,-1,-1):
                os.system("clear")  # 清屏(windows中换为cls)
                print("%02d"%number)    # 这里的2表示占用两个宽度,如果不够宽度,前面补零
                time.sleep(1)   # 停止1秒钟
    
            # 黄灯
            for number in range(self.yellow_time,-1,-1):
                os.system("clear")
                print("%02d"%number)
                time.sleep(1)
    
            # 红灯
            for number in range(self.red_time,-1,-1):
                os.system("clear")
                print("%02d"%number)
                time.sleep(1)
    

    四、实现不同的颜色输出

    为了让控制台实现不同的颜色输出,我们可以使用第三方库colorama,它支持window、macOS、Linux平台,设置控制台输出的文字颜色。

    1. 安装colorama
    pip install colorama
    

    导入colorama模块

    from colorama import init,Fore,Back,Style  
    init(autoreset=True)    # 初始化Colorama
    

    对于要指定输出颜色的字符串只需要在字符串前加上Fore.REDFore.GREENFore.YELLOW即可输出红绿黄的颜色。

    五、构建电子屏上的数字

    我们定义一个方法build_LED_number接收一个数字字符,来构建一个显示数字的矩阵,可以通过两次for循环来实现,这里以绘制数字6为例,其余的数字的绘制方法也以此类推;

    elif char == "6":
        for row in range(20):
            for col in range(10):
                if row < 2 or row > 17:
                    temp_LED.light[row][col] = True
                if row == 9 or row == 10:
                    temp_LED.light[row][col] = True
                if col < 2 :
                    temp_LED.light[row][col] = True
                if col >7 and row > 10 :
                    temp_LED.light[row][col] = True
    

    六、实现数字的显示屏打印

    我们怎么把倒计时的数字与要打印的数字做关联呢?
    在开始做红绿灯倒计时的函数start调用显示函数start_display,传入逐个减小的数字number,以及相应的参数color;

    def start(self):
        """
        开始红绿灯的倒计时
        """
        while True:
            # 默认一直循环下去
            # 绿灯
            for number in range(self.green_time,-1,-1):
                # 流程:清屏 --> 打印数字 --> 停止1秒 --> 清屏 --> 打印减一后的数字
                os.system("clear")  # 清屏(windows中换为cls)
                self.start_display(number,"green")  # 调用函数开始用特定的颜色打印
                # print(Fore.GREEN + "%02d" % number)    # 这里的2表示占用两个宽度,如果不够宽度,前面补零
                time.sleep(1)   # 停止1秒钟
    
            # 黄灯
            for number in range(self.yellow_time,-1,-1):
                os.system("clear")
                self.start_display(number, "yellow")
                # print(Fore.YELLOW +"%02d" % number)
                time.sleep(1)
    
            # 红灯
            for number in range(self.red_time,-1,-1):
                os.system("clear")
                self.start_display(number, "red")
                # print(Fore.RED + "%02d" % number)
                time.sleep(1)
    

    我们的设置显示函数start_display接收两个参数numbercolor,先把接收到的整型数值number格式化成字符串,第一个字符通过bulid_LED_number构建成number01,第一个构建成number02,然后通过函数print_LED再电子屏上显示出来:

    def print_LED(self,color:str):
        for row in range(20):
            # 打印第一个数字
            for col01 in range(10):
                if self.number01.light[row][col01] == True:
                    if color == "green":
                        print(Fore.GREEN + " ▉ ",end="")
                    elif color == "yellow":
                        print(Fore.YELLOW + " ▉ ", end="")
                    elif color == "red":
                        print(Fore.RED + " ▉ ", end="")
                else:
                    print(" □ ",end="")
            print("\t",end="")  # 两个数字之间的空格
            # 打印第二个数字
            for col02 in range(10):
                if self.number02.light[row][col02] == True:
                    if color == "green":
                        print(Fore.GREEN + " ▉ ", end="")
                    elif color == "yellow":
                        print(Fore.YELLOW + " ▉ ", end="")
                    elif color == "red":
                        print(Fore.RED + " ▉ ", end="")
                else:
                    print(" □ ", end="")
            # 换行
            print()
    

    七、效果演示

    1.gif

    附录

    全部源码

    
    import time # 让程序停止
    import os
    from colorama import init,Fore,Back,Style  # 导入颜色模块
    
    init(autoreset=True)    # 初始化Colorama
    
    class Light:
        # 构造函数
        def __init__(self):
            self.light = []
            # 自动初始化
            self.prepare_light()
    
        def prepare_light(self):
            # 准备20行10列200个灯
            for row in range(20):
                temp = [] # 每行10个
                for col in range(10):
                    # 每一列的灯默认不亮
                    temp.append(False)
                # 把每行的10个插入到light集合中
                self.light.append(temp)
    
    class TrafficLight:
        # 构造函数
        def __init__(self,green_time,yellow_time,red_time):
            self.green_time = green_time    # 绿灯的时间
            self.yellow_time = yellow_time  # 黄灯的时间
            self.red_time = red_time    # 红灯的时间
    
            self.number01 = Light() # 显示第一个数字的电子屏
            self.number02 = Light() # 显示第二个数字的电子屏
    
        def bulid_LED_number(self,char:str):
            """
            根据提供的数字来构建电子屏上的数字显示
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            :param char:提供的数字
            :return:返回构建的电子屏
            """
            temp_LED = Light()  # 新建一个电子屏屏幕,在修改这个电子屏
            if char == "0":
                for row in range(20):
                    for col in range(10):
                        if row < 2: # 最上面两行
                            temp_LED.light[row][col] = True
                        if row > 17: # 最下面两行
                            temp_LED.light[row][col] = True
                        if col < 2: # 左边两列
                            temp_LED.light[row][col] = True
                        if col > 7: # 最右边两列
                            temp_LED.light[row][col] = True
            elif char == "1":
                for row in range(20):
                    for col in range(10):
                        if col > 7:  # 最右边两列
                            temp_LED.light[row][col] = True
            elif char == "2":
                for row in range(20):
                    for col in range(10):
                        if row < 2:  # 最上面两行
                            temp_LED.light[row][col] = True
                        if row <9 and col >7:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if row > 10 and col < 2:
                            temp_LED.light[row][col] = True
                        if row > 17:
                            temp_LED.light[row][col] = True
            elif char == "3":
                for row in range(20):
                    for col in range(10):
                        if row < 2 or row > 17:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col > 7:
                            temp_LED.light[row][col] = True
            elif char == "4":
                for row in range(20):
                    for col in range(10):
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col < 2 and row < 9:
                            temp_LED.light[row][col] = True
                        if col > 7 :
                            temp_LED.light[row][col] = True
            elif char == "5":
                for row in range(20):
                    for col in range(10):
                        if row < 2 or row > 17:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col < 2 and row < 9:
                            temp_LED.light[row][col] = True
                        if col > 7 and row > 10:
                            temp_LED.light[row][col] = True
            elif char == "6":
                for row in range(20):
                    for col in range(10):
                        if row < 2 or row > 17:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col < 2 :
                            temp_LED.light[row][col] = True
                        if col >7 and row > 10 :
                            temp_LED.light[row][col] = True
    
            elif char == "7":
                for row in range(20):
                    for col in range(10):
                        if row < 2 :
                            temp_LED.light[row][col] = True
                        if col > 7:
                            temp_LED.light[row][col] = True
            elif char == "8":
                for row in range(20):
                    for col in range(10):
                        if row < 2 or row > 17:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col < 2 or col > 7:
                            temp_LED.light[row][col] = True
            elif char == "9":
                for row in range(20):
                    for col in range(10):
                        if row < 2 or row > 17:
                            temp_LED.light[row][col] = True
                        if row < 9 and col < 2:
                            temp_LED.light[row][col] = True
                        if row == 9 or row == 10:
                            temp_LED.light[row][col] = True
                        if col > 7:
                            temp_LED.light[row][col] = True
            # 返回这个LED
            return temp_LED
    
        def print_LED(self,color:str):
            for row in range(20):
                # 打印第一个数字
                for col01 in range(10):
                    if self.number01.light[row][col01] == True:
                        if color == "green":
                            print(Fore.GREEN + " ▉ ",end="")
                        elif color == "yellow":
                            print(Fore.YELLOW + " ▉ ", end="")
                        elif color == "red":
                            print(Fore.RED + " ▉ ", end="")
                    else:
                        print(" □ ",end="")
                print("\t",end="")  # 两个数字之间的空格
                # 打印第二个数字
                for col02 in range(10):
                    if self.number02.light[row][col02] == True:
                        if color == "green":
                            print(Fore.GREEN + " ▉ ", end="")
                        elif color == "yellow":
                            print(Fore.YELLOW + " ▉ ", end="")
                        elif color == "red":
                            print(Fore.RED + " ▉ ", end="")
                    else:
                        print(" □ ", end="")
                # 换行
                print()
    
        def start_display(self,number:int,color:str):
            """
            把传递过来的数字用指定的颜色打印
            :param number: 指定的数字
            :param color: 指定的颜色
            :return: 无返回值
            """
            # 把数字格式化
            number_str = "%02d" % number
            # 构建LED上显示的两个数字
            self.number01 = self.bulid_LED_number(number_str[0])
            self.number02 = self.bulid_LED_number(number_str[1])
            # 在电子屏上展示
            self.print_LED(color)
    
        def start(self):
            """
            开始红绿灯的倒计时
            """
            while True:
                # 默认一直循环下去
                # 绿灯
                for number in range(self.green_time,-1,-1):
                    # 流程:清屏 --> 打印数字 --> 停止1秒 --> 清屏 --> 打印减一后的数字
                    os.system("clear")  # 清屏(windows中换为cls)
                    self.start_display(number,"green")  # 调用函数开始用特定的颜色打印
                    # print(Fore.GREEN + "%02d" % number)    # 这里的2表示占用两个宽度,如果不够宽度,前面补零
                    time.sleep(1)   # 停止1秒钟
    
                # 黄灯
                for number in range(self.yellow_time,-1,-1):
                    os.system("clear")
                    self.start_display(number, "yellow")
                    # print(Fore.YELLOW +"%02d" % number)
                    time.sleep(1)
    
                # 红灯
                for number in range(self.red_time,-1,-1):
                    os.system("clear")
                    self.start_display(number, "red")
                    # print(Fore.RED + "%02d" % number)
                    time.sleep(1)
    
        @staticmethod           # 静态方法,不需要实例化直接调用!!!
        def input_time(color:str):
            """
            根据提供的颜色,输入相应颜色的时间
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            :param color: 提供的颜色
            :return: 输入的时间
            """
            while True:
                time = ""    # 定义一个全局的time
                # 根据颜色提醒输入
                if color.lower() == "green":
                    time = input(Fore.GREEN + "请输入绿灯的时间:")
                if color.lower() == "yellow":
                    time = input(Fore.YELLOW + "请输入黄灯的时间:")
                if color.lower() == "red":
                    time = input(Fore.RED + "请输入红灯的时间:")
                # 校验输入的是否符合要求:数字、正数、1-99
                # 如果不符合要求怎么处理:1. 出现异常,系统退出,报错;2.提醒重新输入
                if not time.isdigit():
                    print("输入的值不符合要求!【要求:1-99之间的数字】")
                    continue    # 结束当前循环
                else:
                    time_number = int(time)
                    if time_number < 1 or time_number > 99:
                        print("输入的值不符合要求!【要求:1-99之间的数字】")
                        continue
                    else:
                        # 符合要求
                        return time_number
    
    if __name__ == '__main__':
        # 输入红绿黄灯的时间
    
        green_time = TrafficLight.input_time("green")
        yellow_time = TrafficLight.input_time("yellow")
        red_time = TrafficLight.input_time("red")
        # 实例化
        traffic01 = TrafficLight(green_time, yellow_time, red_time)
        # 开始倒计时
        traffic01.start()
    

    相关文章

      网友评论

          本文标题:(七)Python面向对象综合案例:控制台模拟红绿灯

          本文链接:https://www.haomeiwen.com/subject/yxasjktx.html