作者|Kumar Shubham
編譯|VK
來源|Towards Data Science
你可能之前有見過有人使用Python語言構建鬧鐘,幫助他喚醒或提醒他一個重要的會議,
這些都是很簡單,沒有任何智能,他們所做的只是播放你設定的鬧鐘音樂,或者隨機選擇一個YouTube視頻或歌曲來播放,
所以,讓我們更上一層樓,做一些更聰明,更個性化的東西,它能理解你,幫助你更快更好地醒來,
我們將在本文中構建的個性化鬧鐘系統將從過去的事件中學習并理解它們,以便在下一個鬧鐘中獲得更好的性能,每次使用它都會變得更好,
它會記錄用戶關閉鬧鐘所花的時間(用戶醒來所用的時間),并推薦有助于你更快醒來的鬧鈴調音,
所以,讓我們開始制造鬧鐘系統,我們將在下面一步一步地建造它,
匯入所需的包
第一步是將所需的包匯入到Python代碼中,以便在構建鬧鐘時使用它們,
如果沒有安裝它們,你需要首先使用pip安裝方法安裝它們,完成安裝步驟后,繼續將它們匯入代碼中,
import datetime
import os
import time
import random
import csv
from pygame import mixer
import pandas as pd
import numpy as np
設定Tunes檔案夾
下一步是設定一個AlarmTunes檔案夾,用戶將在其中存盤他選的鬧鈴,
你可以設定鬧鈴的路徑,我更喜歡Python腳本所在的檔案夾創建一個新檔案夾,
我們只需要創建一次檔案夾,所以我們需要檢查該檔案夾是否存在,如果檔案夾不存在,我們將創建一個,
# 獲取腳本的當前路徑
path = os.getcwd()
# 設定鬧鈴路徑
alarm_path = path + '\Alarm_Tunes'
# 如果沒有,創建一個,
if not os.path.isdir(alarm_path):
os.makedirs(alarm_path)
現在,在我們的檔案夾被創建后,如果并且僅當檔案夾當前是空的,我們將要求用戶添加一些鬧鈴到檔案夾,
# 要求用戶在檔案夾中添加一些鬧鈴,
while len(os.listdir(alarm_path))==0:
print("No Alarm Tunes Present. Please add some tunes to the folder before proceeding.")
confirm = input("Have you added songs? Press Y or N:\t")
if(confirm=="Y"):
print("Good! Let's continue!")
continue
else:
continue
因此,如上所述,我們要求用戶至少添加一個鬧鈴,如果沒有鬧鈴,發出警告并再次詢問用戶,
創建CSV檔案并定義helper函式
現在,讓我們在跳轉到CSV檔案創建部分之前定義一個helper函式,
這個helper函式幫助我們計算兩個Python串列之間的差異,這將在以后的程式中使用,
def List_diff(list1, list2):
if len(list1)>=len(list2):
return (list(set(list1) - set(list2)))
else:
return (list(set(list2) - set(list1)))
現在,我們已經撰寫了helper函式來計算兩個串列之間的差異,
如果csv檔案還不存在的話,我們繼續創建一個CSV檔案,csv檔案代表鬧鐘的引數,
# 如果沒有csv檔案,則創建引數為零的串列
if not os.path.isfile("tune_parameters.csv"):
tune_list = os.listdir(alarm_path)
tune_time = [60]*len(tune_list)
tune_counter = [1]*len(tune_list)
tune_avg = [60]*len(tune_list)
tune_prob_rev = [1/len(tune_list)]*len(tune_list)
tune_prob = [1/len(tune_list)]*len(tune_list)
所以,上面的代碼檢查我們是否有一個CSV檔案存在,如果沒有,我們將創建,正如你在上面看到的那樣,我們將在程式結束時將這些保存在CSV檔案中,
現在,讓我們解釋一下代碼中每個串列的重要性,讓我們一個接一個地看,
-
tune_list:它存盤鬧鈴的名稱,它存盤的是鬧鐘路徑中存在的檔案串列,從代碼中可以看出,
-
tune_time:它存盤用戶關閉特定鬧鐘所用的時間總和,即用戶喚醒所用的時間,
-
tune_counter:它會記錄到現在為止每個鬧鈴的播放次數,
-
tune_avg:它計算用戶在每次鬧鈴時喚醒和關閉鬧鐘所用的平均時間,
-
tune_prob_rev:它根據用戶每次鬧鈴所需的平均時間計算一種反向概率,
-
tune_prob:這是每次播放鬧鈴的概率,它會根據先前的結果不斷更新,并使用tune_rev_prob計算,
這里需要注意的一點是,我已經為所有這些串列設定了一些默認值,而不是提供零,因為提供零這將對模型產生負面影響,因為從未播放過的串列由于概率為零而永遠不會有概率,
所以,我更傾向于假設這些鬧鈴都運行過一次,平均時間是60秒,這樣我們的作業就容易多了,
現在,如果CSV檔案已經存在,我們需要從CSV檔案加載資料,
此外,我們需要注意鬧鈴檔案夾是否有任何變化,用戶可能添加了新的音樂或洗掉了一些現有的音樂,因此,我們要么需要更新到我們的串列,要么從檔案夾中洗掉,
因此,我們使用前面定義的helper函式來找出由檔案夾獲得的串列和從CSV檔案獲得的串列之間的任何差異,
因此,我們可以對代碼執行所需的操作,并分別使用它們各自的公式更新tune_prob_rev和tune_prob,
# 如果存在csv檔案,則從csv檔案讀取
else:
tune_df = pd.read_csv("tune_parameters.csv")
tune_list_os = os.listdir(alarm_path)
tune_list = list(tune_df['Tunes'])
tune_diff = List_diff(tune_list_os, tune_list)
tune_time = list(tune_df['Delay Times'])
tune_counter = list(tune_df['Count'])
tune_avg = list(tune_df['Average'])
tune_prob_rev = list(tune_df['Reverse Probability'])
tune_prob = list(tune_df['Probability'])
if len(tune_list_os)>=len(tune_list):
for i in range(0,len(tune_diff)):
tune_list.append(tune_diff[i])
tune_time.append(60)
tune_counter.append(1)
tune_avg.append(60)
tune_prob_rev.append(0.1)
tune_prob.append(0.1)
else:
for i in range(0,len(tune_diff)):
tune_diff_index = tune_list.index(tune_diff[i])
tune_list.pop(tune_diff_index)
tune_time.pop(tune_diff_index)
tune_counter.pop(tune_diff_index)
tune_avg.pop(tune_diff_index)
tune_prob_rev.pop(tune_diff_index)
tune_prob.pop(tune_diff_index)
avg_sum = sum(tune_avg)
for i in range(0,len(tune_prob_rev)):
tune_prob_rev[i] = 1 - tune_avg[i]/avg_sum
avg_prob = sum(tune_prob_rev)
for i in range(0,len(tune_prob)):
tune_prob[i] = tune_prob_rev[i]/avg_prob
設定鬧鐘并驗證時間
現在,我們需要定義另一個helper函式來檢查用戶輸入的時間是否正確,因此,我們定義了verify_alarm函式來執行此操作,
# 驗證輸入的時間是否正確,
def verify_alarm(hour,minute,seconds):
if((hour>=0 and hour<=23) and (minute>=0 and minute<=59) and (seconds>=0 and seconds<=59)):
return True
else:
return False
現在,我們準備好了helper函式,所以,我們需要詢問用戶報警時間,我們將使用一個回圈來請求鬧鐘,一旦我們確認時間有效,我們就會中斷,如果無效,我們將再次詢問用戶,直到他輸入有效時間,
# 要求用戶設定報警時間并驗證是否正確,
while(True):
hour = int(input("Enter the hour in 24 Hour Format (0-23):\t"))
minute = int(input("Enter the minutes (0-59):\t"))
seconds = int(input("Enter the seconds (0-59):\t"))
if verify_alarm(hour,minute,seconds):
break
else:
print("Error: Wrong Time Entered! Please enter again!")
現在,在接受用戶的輸入后,我們將找出當前時間,并將這兩個時間轉換為秒,并找出時間之間的差異,如果差值為負,則意味著鬧鐘將在第二天發出,
然后,我們將使python代碼休眠這幾秒鐘,以便只在需要的時間發出鬧鈴,
# 將報警時間轉換為秒
alarm_sec = hour*3600 + minute*60 + seconds
# 獲取當前時間并將其轉換為秒
curr_time = datetime.datetime.now()
curr_sec = curr_time.hour*3600 + curr_time.minute*60 + curr_time.second
# 計算剩余報警秒數
time_diff = alarm_sec - curr_sec
# 如果時差為負,則表示鬧鐘為第二天,
if time_diff < 0:
time_diff += 86400
# 顯示剩余時間
print("Time left for alarm is %s" % datetime.timedelta(seconds=time_diff))
# 睡到鬧鐘響的時候
time.sleep(time_diff)
播放鬧鈴
現在,我們將播放鬧鈴,我們需要根據概率串列隨機選擇鬧鈴,要播放鬧音,我們將使用pygame.mixer.music庫,我們將無限回圈鬧鈴,直到用戶停止,
print("Alarm time! Wake up! Wake up!")
# 根據概率選擇鬧鈴
tune_choice_np = np.random.choice(tune_list, 1, tune_prob)
tune_choice = tune_choice_np[0]
# 獲取索引
tune_index = tune_list.index(tune_choice)
# 播放鬧鈴
mixer.init()
mixer.music.load(alarm_path+"/"+tune_choice)
# 設定loops=-1以確保報警僅在用戶停止時停止!
mixer.music.play(loops=-1)
# 要求用戶停止鬧鐘
input("Press ENTER to stop alarm")
mixer.music.stop()
計算和更新
現在,我們將根據用戶停止報警所需的時間更新串列的值,
我們將找到報警與當前停止報警時間之間的時差,我們將其轉換為秒,然后相應地更新,
# 找到停止鬧鐘的時間
time_stop = datetime.datetime.now()
stop_sec = time_stop.hour*3600 + time_stop.minute*60 + time_stop.second
# 計算時間延遲
time_delay = stop_sec - alarm_sec
# 更新值
tune_time[tune_index] += time_delay
tune_counter[tune_index] += 1
tune_avg[tune_index] = tune_time[tune_index] / tune_counter[tune_index]
new_avg_sum = sum(tune_avg)
for i in range(0,len(tune_list)):
tune_prob_rev[i] = 1 - tune_avg[i] / new_avg_sum
new_avg_prob = sum(tune_prob_rev)
for i in range(0,len(tune_list)):
tune_prob[i] = tune_prob_rev[i] / new_avg_prob
合并串列并另存為CSV檔案
現在,我們將所有的串列合并到一個多維串列中,然后將其轉換為pandas資料幀,然后將其保存為CSV檔案,
# 創建串列
tune_rec = [[[[[[]]]]]]
for i in range (0,len(tune_list)):
temp=[]
temp.append(tune_list[i])
temp.append(tune_time[i])
temp.append(tune_counter[i])
temp.append(tune_avg[i])
temp.append(tune_prob_rev[i])
temp.append(tune_prob[i])
tune_rec.append(temp)
tune_rec.pop(0)
# 將合并串列轉換為資料幀
df = pd.DataFrame(tune_rec, columns=['Tunes','Delay Times','Count','Average','Reverse Probability','Probability'],dtype=float)
# 將資料幀保存為csv
df.to_csv('tune_parameters.csv',index=False)
我們終于完成了智能鬧鐘的制造,要獲得完整的代碼,請訪問我的Github存盤庫
鏈接:https://github.com/shubham1710/Personalised-Alarm-using-Python
原文鏈接:https://towardsdatascience.com/build-a-personalized-smart-alarm-with-python-ceae3682a761
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/173541.html
標籤:其他
下一篇:20個Pandas函式詳解
