Build a Personalized Smart Alarm with Python

栏目: IT技术 · 发布时间: 4年前

Build a Personalized Smart Alarm with Python

Let’s build a personalized smart alarm based on A.I. techniques which will set the best alarm tune for you to help you wake early.

Photo by Brandi Redd on Unsplash

Hello readers, you often would have seen or build alarm clocks using Python language which would help you wake up or remind you of an important meeting.

Almost all of those are simple with no intelligence in them and all they do is play an alarm tune set up by you or choose a random YouTube video or song to play.

So, let’s go a level up and build something smart, something more personalized which understands you and helps you wake up in a better and faster way.

Our alarm, which we will be building in this article, will learn from past events and understand them for better performance in each next alarm. It gets better each time it is used. It keeps a track of time taken by the user to put the alarm off (the time user took to wake up) and recommends the alarm tunes which help you wake faster.

So, without further ado, let’s begin building our alarm. We will build it step by step below.

Importing the Required Packages

The first step would be to import the required packages into our Python code to use them in building the alarm.

If they are not installed, you need to first install these using pip install method. After you are done with the installation step, proceed with importing them into the code.

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

Setting up the Tunes Folder

Next step would be to set up an Alarm tunes folder where the user would be storing his preferred alarm tunes.

You can choose any path for the alarm tunes, I preferred to create the folder in the same folder as the Python script. We need to create the folder only once, so we need to check whether the folder exists or not. If the folder does not exist, we will create one.

# 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)

Now, after our folder is created, we will ask users to add some alarm tunes to the folder, if and only if the folder is currently empty.

# 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

So, as seen above, we ask the user to add at least a single alarm tune. If there is no alarm tune, raise a warning and ask the user again.

Creating a CSV file and defining a helper function

Now, let’s define a helper function before jumping into CSV file creation part.

This helper function helps us to calculate the difference between two Python lists. This will be used later in our program.

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

Now, since we have now written our helper function to calculate the difference between two lists, let’s move forward to create a CSV file if it is not already present.

# 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)

So, the above code checks whether we have a CSV file present or not, if not we will create the lists as you can see above. We will save these in CSV file at end of the program.

Now, let’s explain the significance of each list present in the code. Let’s see them one by one.

  1. tune_list: It stores the name of the alarm tunes as is evident from the code as it stores the list of files present in the alarm_path.
  2. tune_time: It stores the sum of the amount of time a user takes to close that particular alarm i.e. the time taken by the user to wake up.
  3. tune_counter: It keeps track of the number of times each alarm tune is played till now.
  4. tune_avg: It finds out the average time taken by the user to wake up and close the alarm for every alarm tune.
  5. tune_prob_rev: It calculates a kind of reverse probability based on the average time a user requires for each alarm tune.
  6. tune_prob: It is the probability of an alarm tune to be played each time. It keeps updating itself based on previous results and is calculated using the tune_rev_prob .

One thing to note here is I have set some default values to all these lists instead of providing zero since it will affect the model negatively as the ones never played would never get a chance due to zero probability.

So, I preferred to assume that each of these has been played once and the average time is 60 seconds. Thus it makes our work easier.

Now, if the CSV file is already present, we need to load the data from the CSV file.

Also, we need to take care if there had been any changes to the Alarm tunes folder. The user might have added new tunes or removed some present tunes. So, we need to update the either add new tunes to our list or remove the ones which have been removed from the folder.

So, we use the helper function defined before to find out any differences between the list obtained by the folder and list obtained from the CSV file. And, thus we can perform the required things on our code and update the tune_prob_rev and tune_prob respectively using their respective formulas.

# 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

Setting the Alarm and Verifying the Time

Now, we need to define another helper function to check whether the time entered by the user is correct or not. So, we have defined the function verify_alarm to do so.

# 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

Now, we have the helper function ready. So, we need to ask the user for the alarm time. We will use a loop to ask for the alarm and we will break out once we verify the time is valid. If invalid, we will ask the user again until he enters a valid time.

# 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!")

Now, after taking input from the user, we will find out the current time and will convert both of these times to seconds and will find out the difference between the times. If the difference is negative, it will mean the alarm is for the next day.

We will then make the python code sleep for that amount of seconds so that alarm rings at the required time only.

# 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)

Ringing the Alarm

Now, we will ring our alarm and we will need to randomly choose the alarm tune based on the probability list. To play the alarm tune, we will be using the pygame.mixer.music library. We will loop the alarm tune infinitely until the user stops it.

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()

Calculations and Updatations of Lists

Now, we will update the values of the lists based on the time needed by the user to stop the alarm.

We will find the time difference between the alarm and the current time of stopping the alarm. We will convert it to seconds and then update accordingly.

# 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

Merging the Lists and saving as CSV file

Now, we will merge all the lists in a single multi-dimensional list and then we will convert it to a pandas data frame and then we will save it as a CSV file.

#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)

We have finally finished building our smart alarm. For complete code, visit my Github Repository and do contribute to the repository if you have some enhancements or new ideas.

Hope you find this article insightful. Try building your version and do share your thoughts in the comments. Thanks for reading!

More articles to read after this one:

Request for deletion

About

MC.AI – Aggregated news about artificial intelligence

MC.AI collects interesting articles and news about artificial intelligence and related areas. The contributions come from various open sources and are presented here in a collected form.

The copyrights are held by the original authors, the source is indicated with each contribution.

Contributions which should be deleted from this platform can be reported using the appropriate form (within the contribution).

MC.AI is open for direct submissions, we look forward to your contribution!

Search on MC.AI

mc.ai aggregates articles from different sources - copyright remains at original authors


以上所述就是小编给大家介绍的《Build a Personalized Smart Alarm with Python》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

新物种爆炸

新物种爆炸

吴声 / 中信出版社 / 2017-7-30 / 58.00元

宝马为什么要重点发展共享汽车 Airbnb正试图成为内容和社交平台 不排队、不结账、没有收银员的颠覆传统超市 茑屋书店要打造全新生活方式 基于新的商业环境与技术条件的变化,必须会产生新的品类和商业模式,这就是新物种! 大数据与人工智能等技术正在创建新的商业话语体系,创建新的权力架构,引领第四新物种爆炸。商业规则正在快速发生变化,新的模式与业态层出不穷。 要么成为......一起来看看 《新物种爆炸》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换