用Python构建个性化智能闹钟

做者|Kumar Shubham 编译|VK 来源|Towards Data Sciencepython

你可能以前有见过有人使用Python语言构建闹钟,帮助他唤醒或提醒他一个重要的会议。git

这些都是很简单,没有任何智能,他们所作的只是播放你设置的闹钟音乐,或者随机选择一个YouTube视频或歌曲来播放。github

因此,让咱们更上一层楼,作一些更聪明,更个性化的东西,它能理解你,帮助你更快更好地醒来。app

咱们将在本文中构建的个性化闹钟系统将从过去的事件中学习并理解它们,以便在下一个闹钟中得到更好的性能。每次使用它都会变得更好。dom

它会记录用户关闭闹钟所花的时间(用户醒来所用的时间),并推荐有助于你更快醒来的闹铃调音。机器学习

因此,让咱们开始制造闹钟系统。咱们将在下面一步一步地建造它。函数

导入所需的包

第一步是将所需的包导入到Python代码中,以便在构建闹钟时使用它们。oop

若是没有安装它们,你须要首先使用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文件中。

如今,让咱们解释一下代码中每一个列表的重要性。让咱们一个接一个地看。

  1. tune_list:它存储闹铃的名称,它存储的是闹钟路径中存在的文件列表,从代码中能够看出。

  2. tune_time:它存储用户关闭特定闹钟所用的时间总和,即用户唤醒所用的时间。

  3. tune_counter:它会记录到如今为止每一个闹铃的播放次数。

  4. tune_avg:它计算用户在每次闹铃时唤醒和关闭闹钟所用的平均时间。

  5. tune_prob_rev:它根据用户每次闹铃所需的平均时间计算一种反向几率。

  6. 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/

相关文章
相关标签/搜索