使用Python构建个性化的智能闹钟


前言

读者们,您好,您通常会使用Python语言查看或构建闹钟,这将有助于您唤醒或提醒您重要的会议。

几乎所有这些都是简单的,没有任何智能,它们所做的只是播放您设置的警报音,或者选择随机播放的YouTube视频或歌曲。

因此,让我们进行升级,构建一些智能的东西,一些个性化的东西,这些东西可以帮助您理解并帮助您更快更好地醒来。

我们将在本文中构建的警报,将从过去的事件中学习并了解它们,以便在每个下一个警报中获得更好的性能。每次使用都会变得更好。它跟踪用户关闭闹钟所花费的时间(用户唤醒时间),并推荐闹钟音调,以帮助您更快地唤醒。

因此,事不宜迟,让我们开始构建警报。我们将在下面逐步构建它。

导入所需的软件包

第一步是将所需的程序包导入我们的Python代码中,以使用它们来构建警报。

如果尚未安装,则需要先使用pip install方法安装它们。完成安装步骤后,继续将它们导入代码中。

import datetime
import os
import time
import random
import csv
from pygame import mixer
import pandas as pd
import numpy as np

设置Tunes文件夹

下一步将是设置“警报音调”文件夹,用户将在其中存储他的首选警报音调。

您可以选择任何警报音调的路径,我更喜欢在与Python脚本相同的文件夹中创建该文件夹。我们只需要创建一次文件夹,因此我们需要检查文件夹是否存在。如果该文件夹不存在,我们将创建一个。

# Getting the current path of the script
path = os.getcwd()
# Setting up the alarm path
alarm_path = path + '\Alarm_Tunes'
# If no directory present, create one.
if not os.path.isdir(alarm_path):
    os.makedirs(alarm_path)

现在,在创建文件夹之后,当且仅当文件夹当前为空时,我们才会要求用户向该文件夹添加一些警报音。

# Ask user to add some alarm tunes to the folder.
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文件并定义一个辅助函数

现在,让我们在进入CSV文件创建部分之前定义一个辅助函数。

这个辅助函数可以帮助我们计算两个Python列表之间的差异。稍后将在我们的程序中使用。

def List_diff(list1, list2): 
    if len(list1)>=len(list2):
        return (list(set(list1) - set(list2)))
    else:
        return (list(set(list2) - set(list1)))

现在,由于我们已经编写了帮助函数来计算两个列表之间的差异,因此,如果它尚不存在,让我们继续创建一个CSV文件。

# If no csv file, create the lists with parameters as zero
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:它存储警报调谐的名称,从代码中可以明显看出,因为它存储存在于alarm_path中的文件列表。

tune_time:它存储用户关闭特定警报所花费的时间总和,即用户唤醒所花费的时间。

tune_counter:跟踪到现在为止播放每个警报音的次数。

tune_avg:找出用户为每个警报音调唤醒和关闭警报所花费的平均时间。

tune_prob_rev:它根据用户每次警报调谐所需的平均时间来计算一种反向概率。

tune_prob:每次播放警报音的可能性。它会根据以前的结果不断更新自身,并使用tune_rev_prob进行计算。

这里要注意的一件事是,我为所有这些列表设置了一些默认值,而不是零,因为它会对模型产生负面影响,因为从未玩过的那些游戏由于零概率而永远不会获得机会。

因此,我更倾向于假设每个游戏都播放了一次,平均时间为60秒。因此,这使我们的工作更加轻松。
现在,如果CSV文件已经存在,我们需要从CSV文件中加载数据。

另外,我们还需要注意"Alarm tunes"文件夹是否有任何更改。用户可能已经添加了新的乐曲或删除了一些当前的乐曲。因此,我们需要更新将新乐曲添加到列表中或删除已从文件夹中删除的乐曲。

因此,我们使用之前定义的辅助函数来找出文件夹获得的列表和CSV文件获得的列表之间的任何差异。并且,因此我们可以在代码上执行所需的操作,并使用它们各自的公式分别更新tune_prob_revtune_prob

# If csv file is present, read from csv file
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

设置闹钟并确认时间

现在,我们需要定义另一个帮助函数,以检查用户输入的时间是否正确。因此,我们已经定义了函数verify_alarm来做到这一点。

# Verify whether time entered is correct or not.
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

现在,我们已经准备好辅助功能。因此,我们需要询问用户闹钟时间。我们将使用一个循环来请求警报,并且一旦我们确认时间是合法的,我们就会爆发。如果无效,我们将再次询问用户,直到输入有效时间为止。

# Asking user to set alarm time and verifying whether true or not.
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代码休眠该秒数,以使警报仅在所需的时间响起。

# Converting the alarm time to seconds
alarm_sec = hour*3600 + minute*60 + seconds
# Getting current time and converting it to seconds
curr_time = datetime.datetime.now()
curr_sec = curr_time.hour*3600 + curr_time.minute*60 + curr_time.second
# Calculating the number of seconds left for alarm
time_diff = alarm_sec - curr_sec
#If time difference is negative, it means the alarm is for next day.
if time_diff < 0:
    time_diff += 86400
# Displaying the time left for alarm
print("Time left for alarm is %s" % datetime.timedelta(seconds=time_diff))
# Sleep until the time at which alarm rings
time.sleep(time_diff)

敲响警报

现在,我们将敲响警报,我们需要根据概率列表随机选择警报曲调。要播放警报音,我们将使用pygame.mixer.music库。我们将无限循环警报音,直到用户停止它为止。

print("Alarm time! Wake up! Wake up!")
# Choose a tune based on probability
tune_choice_np = np.random.choice(tune_list, 1, tune_prob)
tune_choice = tune_choice_np[0]
# Getting the index of chosen tune in list
tune_index = tune_list.index(tune_choice)
# Play the alarm tune
mixer.init()
mixer.music.load(alarm_path+"/"+tune_choice)
# Setting loops=-1 to ensure that alarm only stops when user stops it!
mixer.music.play(loops=-1)
# Asking user to stop the alarm
input("Press ENTER to stop alarm")
mixer.music.stop()

列表的计算和更新

现在,我们将根据用户停止警报所需的时间来更新列表的值。

我们将找到警报与当前停止警报之间的时间差。我们会将其转换为秒,然后进行相应的更新。

# Finding the time of stopping the alarm
time_stop = datetime.datetime.now()
stop_sec = time_stop.hour*3600 + time_stop.minute*60 + time_stop.second
# Calculating the time delay
time_delay = stop_sec - alarm_sec
# Updating the values
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文件。

#Create the merged list of all six quantities
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)
#Convert merged list to a pandas dataframe
df = pd.DataFrame(tune_rec, columns=['Tunes','Delay Times','Count','Average','Reverse Probability','Probability'],dtype=float)
#Save the dataframe as a csv (if already present, will overwrite the previous one)
df.to_csv('tune_parameters.csv',index=False)

我们终于完成了智能警报的构建。有关完整的代码,请访问我的Github,如果您有一些增强功能或新想法,请为该存储库做出贡献。

希望您能对本文有所了解。尝试构建您的版本,并在评论中分享您的想法。谢谢阅读!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值