3
\$\begingroup\$

I created this script because the Spotify desktop app doesn't have a built in sleep timer, and I needed one. I made it as easy to use as possible, and it can close other programs because it asks for the package name at the beginning of the script.

import time
import sys
import subprocess

pkgname = input("Please set the package name: ")
tillclose = float(input("\nPlease choose the amount of time before it closes:\n\n[1.] 10 Minutes\n[2.] 30 Minutes\n[3.] 1 Hour\n[4.] 2 Hours\n[5.] 3 Hours\n[6.] 4 Hours\n[7.] 5 Hours\n"))

if tillclose == 1:
    print("Confirmed. Set to close in 10 Minutes.")
    tillclose = 600

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 2:
    print("Confirmed. Set to close in 30 Minutes.")
    tillclose = 1800

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 3:
    print("Confirmed. Set to close in 1 Hour.")
    tillclose = 3600

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 4:
    print("Confirmed. Set to close in 2 Hours.")
    tillclose = 7200

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 5:
    print("Confirmed. Set to close in 3 Hours")
    tillclose = 10800

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 6:
    print("Confirmed. Set to close in 4 Hours")
    tillclose = 14400

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

elif tillclose == 7:
    print("Confirmed. Set to close in 5 Hours")
    tillclose = 18000

    for remaining in range(int(tillclose), 0, -1):
        sys.stdout.write("\r")
        sys.stdout.write("{:2d} seconds remaining.".format(remaining))
        sys.stdout.flush()
        time.sleep(1)

    subprocess.call(["taskkill", "/F", "/IM", pkgname])

else:
    print("Invalid option, please run again.")

It works flawlessly, but I'm wondering if there's a shorter way to make it.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Create one function with tillclose as the parameter and then call it. \$\endgroup\$
    – PM 77-1
    Feb 6, 2023 at 21:49
  • \$\begingroup\$ in for remaining in range(int(tillclose), 0, -1): casting tillclose to an int seems to be redundant as it is already an int. I see you originally cast this to a float instead of an integer, there doesn't seem to be much point in that either so you might want to cast it originally to an int as int(input("\nPlease choose the amount of time before it closes:\n\n[1.] 10 Minutes\n[2.] 30 Minutes\n[3.] 1 Hour\n[4.] 2 Hours\n[5.] 3 Hours\n[6.] 4 Hours\n[7.] 5 Hours\n")). \$\endgroup\$
    – xihtyM
    Feb 6, 2023 at 21:49
  • \$\begingroup\$ The first obvious thing on cursory examination is the repetition of code in all you elif statements. Surely all that can be put into a single function that is called in each elif. \$\endgroup\$
    – Galo do Leste
    Feb 6, 2023 at 21:50
  • 1
    \$\begingroup\$ As tillclose gets changed, you might aswell have a dictionary that maps each number to the new value for tillclose. e.g. options = {1: 600, 2: 1800, ...} etc, using dict.get() you can rewrite this code to be really clean. \$\endgroup\$
    – xihtyM
    Feb 6, 2023 at 21:55

1 Answer 1

1
\$\begingroup\$
import time
import sys
import subprocess

pkgname = input("Please set the package name: ")
choice = float(input("\nPlease choose the amount of time before it closes:\n\n[1.] 10 Minutes\n[2.] 30 Minutes\n[3.] 1 Hour\n[4.] 2 Hours\n[5.] 3 Hours\n[6.] 4 Hours\n[7.] 5 Hours\n"))

secs_in_hour = 60 * 60
hour_intervals = [1/6, 1/2, 1, 2, 3, 4, 5]
# choice - 1 for options {1, 2, 3, 4, 5, 6, 7} to index transition
tillclose = hour_intervals[int(choice) - 1] * secs_in_hour
for remaining in range(int(tillclose), 0, -1):
    sys.stdout.write("\r")
    sys.stdout.write("{:2d} seconds remaining.".format(remaining))
    sys.stdout.flush()
    time.sleep(1)

subprocess.call(["taskkill", "/F", "/IM", pkgname])
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Bearing in mind that the OP asked "if there's a shorter way to make it." and it has since been migrated from Stack Overflow, can you please add a summary of the changes and benefits of this solution? It would likely be helpful to read (possibly first) The help center page How do I write a good answer?. \$\endgroup\$ Feb 6, 2023 at 23:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.