一、需求分析
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.RED
、Fore.GREEN
、Fore.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ù)number
和color
,先把接收到的整型數(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()
七、效果演示
附錄
全部源碼
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()