I wrote a program to gradually lower the volume of my computer when I go to sleep so I can fall asleep with TV or music on. This was my first time using argparse and I feel like there should be a cleaner way to deal with default values of optional arguments. Any other feedback of course also welcomed.
import vol
from time import sleep
from subprocess import call, check_output
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--delay", help="time (in minutes) until volume begins to lower", type=int)
parser.add_argument("-m", "--minutes_until_mute", help="time (in minutes) to set the volume to mute", type=int)
a = parser.parse_args()
minutes_until_mute = a.minutes_until_mute if a.minutes_until_mute else 30
delay = a.delay if a.delay else 0
sleep(delay*60)
current_volume = check_output(['osascript', '-e', 'set ovol to output volume of (get volume settings)'])
for i in range(minutes_until_mute):
percent_of_volume = (-1.0/(minutes_until_mute**2))*(i**2) + 1 #quadratic function with maximum at (0, 100%) and crossing at (minutes_until_mute, 0)
new_volume = int(float(current_volume) * percent_of_volume)
call(["vol", "out", str(new_volume)])
call(["vol", "info"])
sleep(60)
call(["vol", "mute"]) #rounding errors mean we don't get exactly to 0
-
\$\begingroup\$ As you ask for any other comments, I will say: think to the planet and shutdown your computer at the end of the delay ! (this question caught my eye because I love to go to sleep with music and I used for years a python script to turn off my computer after a specified time or another to turn it off once my vlc playlist is completed) Well maybe it's not a computer that you shutdown anyway :) \$\endgroup\$mgc– mgc2016年02月07日 20:03:46 +00:00Commented Feb 7, 2016 at 20:03
2 Answers 2
"I feel like there should be a cleaner way to deal with default values of optional arguments"
Yes, there is. Per the documentation of ArgParse, you can specify a keyword argument default and give it the value you want.
parser.add_argument("-d", "--delay", help="Delay in minutes until starting mute", type=int, default=0)
-
\$\begingroup\$ Duh. I must've looked right at that a bunch of times. \$\endgroup\$thumbtackthief– thumbtackthief2016年02月05日 12:14:37 +00:00Commented Feb 5, 2016 at 12:14
Conversion
You could convert current_volume
to its relevant and usable type (float) at you get it instead of reconverting it everytime you use it.
current_volume = float(check_output(['osascript', '-e', 'set ovol to output volume of (get volume settings)']))
...
new_volume = int(current_volume * percent_of_volume)
Off-by-one error
This may or may not be an error depending on what you had in mind.
You've defined a function which is supposed to return 100% initially and 0% at the end.
Your function reaches 0 when (-1.0/(minutes_until_mute**2))*(i**2) + 1
which is when i == minutes_until_mute
. Unfortunately, this is not the last value of your loop : the last value of range(n)
is n-1
.
-
\$\begingroup\$ Eh. Technically an error, although not one that really affects anything. For best practices, though, best to just do
range(minutes+1)
? \$\endgroup\$thumbtackthief– thumbtackthief2016年02月05日 12:19:31 +00:00Commented Feb 5, 2016 at 12:19