Python調(diào)用終端模擬紅綠燈

一、需求分析

1. 需要實現(xiàn)的功能

(1)通過控制臺輸入綠燈、黃燈、紅燈的時間
(2)輸入完成后,按回車,先綠燈倒計時,然后黃燈倒計時,然后紅燈倒計時,再到綠燈倒計時,周而復始。

2. 對類的分析
靜態(tài)特征

(1)三個數(shù)字:紅燈、黃燈、綠燈
(2)兩個電子屏

  • 一個電子屏顯示一個數(shù)字
  • 一個電子屏包含200個(20行*10列),控制200個燈的亮與不亮顯示數(shù)字
  • 每個燈就兩種狀態(tài):(亮與不亮)
動態(tài)特征
  • 打印
  • 把數(shù)字構(gòu)造在電子屏中
  • 用不同的顏色打印
  • 倒計時
3. 如何實現(xiàn)時間的倒計時

每次打印完成后--> 停止1秒 --> 清屏 --> 在數(shù)字減一后再打印 --> 停止1秒后 --> 清屏

二、構(gòu)建類的靜態(tài)特征

1. 構(gòu)建一個Light類

創(chuàng)建一個顯示屏含有20行10列的小燈,每個小燈設(shè)置為布爾型值False;

class Light:
    # 構(gòu)造函數(shù)
    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. 再構(gòu)建一個TrafficLight

接收紅黃綠三種顏色燈要顯示的時間:

class TrafficLight:
    # 構(gòu)造函數(shù)
    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() # 顯示第一個數(shù)字的電子屏
        self.number02 = Light() # 顯示第二個數(shù)字的電子屏

三、實現(xiàn)紅綠燈輸入時間的校驗

在前面我們給紅綠燈運行時間直接提供了數(shù)字,按照實際需求我們應當手動輸入紅綠燈運行的時間。
我們定義一個方法可以根據(jù)提供的顏色,輸入指定顏色燈光的時間。把這個方法定義成靜態(tài)方法就可以不用通過對象來調(diào)用。
之后我們再檢驗輸入的值是否符合要求:

  • 輸入的內(nèi)容必須是數(shù)字
  • 輸入的數(shù)字范圍在1-99之間

如果不符合要求,則提醒用戶重新輸入

@staticmethod           # 靜態(tài)方法,不需要實例化直接調(diào)用!!!
def input_time(color:str):
    """
    根據(jù)提供的顏色,輸入相應顏色的時間
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    :param color: 提供的顏色
    :return: 輸入的時間
    """
    while True:
        time = ""    # 定義一個全局的time
        # 根據(jù)顏色提醒輸入
        if color.lower() == "green":
            time = input("請輸入綠燈的時間:")
        if color.lower() == "yellow":
            time = input("請輸入黃燈的時間:")
        if color.lower() == "red":
            time = input("請輸入紅燈的時間:")
        # 校驗輸入的是否符合要求:數(shù)字、正數(shù)、1-99
        if not time.isdigit():
            print("輸入的值不符合要求!【要求:1-99之間的數(shù)字】")
            continue    # 結(jié)束當前循環(huán)
        else:
            time_number = int(time)
            if time_number < 1 or time_number > 99:
                print("輸入的值不符合要求!【要求:1-99之間的數(shù)字】")
                continue
            else:
                # 符合要求
                return time_number

三、實現(xiàn)紅綠燈的倒計時功能

在控制臺顯示紅綠燈效果的流程:清屏 --> 打印數(shù)字 --> 停止1秒 --> 打印減一后的數(shù)字

def start(self):
    while True:
        # 默認一直循環(huán)下去
        # 綠燈
        for number in range(self.green_time,-1,-1):
            os.system("clear")  # 清屏(windows中換為cls)
            print("%02d"%number)    # 這里的2表示占用兩個寬度,如果不夠?qū)挾龋懊嫜a零
            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)

四、實現(xiàn)不同的顏色輸出

為了讓控制臺實現(xiàn)不同的顏色輸出,我們可以使用第三方庫colorama,它支持window、macOS、Linux平臺,設(shè)置控制臺輸出的文字顏色。

1. 安裝colorama
pip install colorama

導入colorama模塊

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

對于要指定輸出顏色的字符串只需要在字符串前加上Fore.REDFore.GREENFore.YELLOW即可輸出紅綠黃的顏色。

五、構(gòu)建電子屏上的數(shù)字

我們定義一個方法build_LED_number接收一個數(shù)字字符,來構(gòu)建一個顯示數(shù)字的矩陣,可以通過兩次for循環(huán)來實現(xiàn),這里以繪制數(shù)字6為例,其余的數(shù)字的繪制方法也以此類推;

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

六、實現(xiàn)數(shù)字的顯示屏打印

我們怎么把倒計時的數(shù)字與要打印的數(shù)字做關(guān)聯(lián)呢?
在開始做紅綠燈倒計時的函數(shù)start調(diào)用顯示函數(shù)start_display,傳入逐個減小的數(shù)字number,以及相應的參數(shù)color;

def start(self):
    """
    開始紅綠燈的倒計時
    """
    while True:
        # 默認一直循環(huán)下去
        # 綠燈
        for number in range(self.green_time,-1,-1):
            # 流程:清屏 --> 打印數(shù)字 --> 停止1秒 --> 清屏 --> 打印減一后的數(shù)字
            os.system("clear")  # 清屏(windows中換為cls)
            self.start_display(number,"green")  # 調(diào)用函數(shù)開始用特定的顏色打印
            # print(Fore.GREEN + "%02d" % number)    # 這里的2表示占用兩個寬度,如果不夠?qū)挾龋懊嫜a零
            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)

注意這里的清屏函數(shù),在Mac系統(tǒng)下使用clear,在windows系統(tǒng)下使用參數(shù)cls

我們的設(shè)置顯示函數(shù)start_display接收兩個參數(shù)numbercolor,先把接收到的整型數(shù)值number格式化成字符串,第一個字符通過bulid_LED_number構(gòu)建成number01,第一個構(gòu)建成number02,然后通過函數(shù)print_LED再電子屏上顯示出來:

def print_LED(self,color:str):
    for row in range(20):
        # 打印第一個數(shù)字
        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="")  # 兩個數(shù)字之間的空格
        # 打印第二個數(shù)字
        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:
    # 構(gòu)造函數(shù)
    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:
    # 構(gòu)造函數(shù)
    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() # 顯示第一個數(shù)字的電子屏
        self.number02 = Light() # 顯示第二個數(shù)字的電子屏

    def bulid_LED_number(self,char:str):
        """
        根據(jù)提供的數(shù)字來構(gòu)建電子屏上的數(shù)字顯示
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        :param char:提供的數(shù)字
        :return:返回構(gòu)建的電子屏
        """
        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):
            # 打印第一個數(shù)字
            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="")  # 兩個數(shù)字之間的空格
            # 打印第二個數(shù)字
            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):
        """
        把傳遞過來的數(shù)字用指定的顏色打印
        :param number: 指定的數(shù)字
        :param color: 指定的顏色
        :return: 無返回值
        """
        # 把數(shù)字格式化
        number_str = "%02d" % number
        # 構(gòu)建LED上顯示的兩個數(shù)字
        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:
            # 默認一直循環(huán)下去
            # 綠燈
            for number in range(self.green_time,-1,-1):
                # 流程:清屏 --> 打印數(shù)字 --> 停止1秒 --> 清屏 --> 打印減一后的數(shù)字
                os.system("clear")  # 清屏(windows中換為cls)
                self.start_display(number,"green")  # 調(diào)用函數(shù)開始用特定的顏色打印
                # print(Fore.GREEN + "%02d" % number)    # 這里的2表示占用兩個寬度,如果不夠?qū)挾龋懊嫜a零
                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           # 靜態(tài)方法,不需要實例化直接調(diào)用!!!
    def input_time(color:str):
        """
        根據(jù)提供的顏色,輸入相應顏色的時間
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        :param color: 提供的顏色
        :return: 輸入的時間
        """
        while True:
            time = ""    # 定義一個全局的time
            # 根據(jù)顏色提醒輸入
            if color.lower() == "green":
                time = input(Fore.GREEN + "請輸入綠燈的時間:")
            if color.lower() == "yellow":
                time = input(Fore.YELLOW + "請輸入黃燈的時間:")
            if color.lower() == "red":
                time = input(Fore.RED + "請輸入紅燈的時間:")
            # 校驗輸入的是否符合要求:數(shù)字、正數(shù)、1-99
            # 如果不符合要求怎么處理:1. 出現(xiàn)異常,系統(tǒng)退出,報錯;2.提醒重新輸入
            if not time.isdigit():
                print("輸入的值不符合要求!【要求:1-99之間的數(shù)字】")
                continue    # 結(jié)束當前循環(huán)
            else:
                time_number = int(time)
                if time_number < 1 or time_number > 99:
                    print("輸入的值不符合要求!【要求:1-99之間的數(shù)字】")
                    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()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。