Why can't I compare times?

Everything works great except for the commented out code at the bottom.

import pyinputplus as pyip
import subprocess
from datetime import datetime
from time import sleep

# INPUT:
print()
print('     Welcome to AutoProgramStart')
print('I start programs at the time specified')
print()

print('Select the items below by number')
program_to_start = pyip.inputMenu(['Audiobook', 'Word', 'Excel', 'Notepad',
                                   'Alarm'], numbered=True)
print('Use this format for time to start program: 14:58:16')
time_to_start_program = pyip.inputTime('Input time to start: ')
print(time_to_start_program)

now = datetime.now()
current_time = now.strftime("%H:%M:%S")  # Get current time
print("Current Time in twenty four hour format =", current_time)
print('Time to start program ', time_to_start_program)

# if current_time > time_to_start_program:
#     sleep(60)  # This give us the one-minute accuracy instead of 1 second
#     print('After sleep(60), This is where the alarm goes')

# OUTPUT:
subprocess.Popen(['start', 'alarm.wav'], shell=True)  # Start sound alarm

I get this when the commented is uncommented.

     Welcome to AutoProgramStart
I start programs at the time specified

Select the items below by number
Please select one of the following:
1. Audiobook
2. Word
3. Excel
4. Notepad
5. Alarm
1
Use this format for time to start program: 14:58:16
Input time to start: 17:30:00
17:30:00
Traceback (most recent call last):
  File "C:/Users/Leonard Dye/PycharmProjects/AutoStart2/input menu.py", line 21, in <module>
    print("Current Time in twenty four hour format =", current_time)
ValueError: invalid literal for int() with base 10: '17:25:49'``

I seems to me that on the concept of the “Black Box”, one whould assume you could compare the two time values.

According to the docs, pyip.inputTime returns a time, which is a time of day (from the datetime module).

You’re then getting the current datetime and converting it to a string:

    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")  # Get current time

and you’re trying to compare them:

    if current_time > time_to_start_program:

A time is a time, and a string is a string. You can’t ask whether one is greater than another because they’re completely different types.

Another point: time is a time of day (no date part), you have a datetime (date and time of day) in now, so you can’t ask whether one is greater than the other either because they’re different types (one includes a date part, the other doesn’t).

If you’re not bothered about midnight, you could just compare the time of day parts.

“Use the syntax print(int(“STR”)) to return the str as an int , or integer”. OK, we know its a string and we know that a string should be castable to int. I caught that it was different values.

Been reading and want to know if this is the way to do this. Use timedelta and compare two timedeltas.

Comparisons of timedelta objects are supported, with some caveats.

The comparisons == or != always return a bool, no matter the type of the compared object:

>>>
>>> from datetime import timedelta
>>> delta1 = timedelta(seconds=57)
>>> delta2 = timedelta(hours=25, seconds=2)
>>> delta2 != delta1
True
>>> delta2 == 5
False
For all other comparisons (such as < and >), when a timedelta object is compared to an object of a different type, TypeError is raised:

>>>
>>> delta2 > delta1
True
>>> delta2 > 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int'
In Boolean contexts, a timedelta object is considered to be true if and only if it isn’t equal to timedelta(0).

Something new to lean.

By Leonard Dye via Discussions on Python.org at 03Sep2022 04:12:

Been reading and want to know if this is the way to do this. Use
timedelta and compare two timedeltas.

Maybe Matthew was not clear. Broadly, you can only compare values of the
same type. There are some exceptions such at int vs float, where on
can be pretty naturally converted to the other.

So there are various ways to get the current time.

The most basic:

 >>> from time import time
 >>> t0 = time()
 >>> print(type(t0))
 <class 'float'>
 >>> t0
 1662178954.832384

This is a “UNIX time”, seconds since the UNIX epoch (start of 1 January
1970, UTC). No timezones, days of week, etc etc. Just elapsed seconds.
Getting the current time shortly later:

 >>> t1 = time()
 >>> t1
 1662178961.263362
 >>> t0 < t1
 True

They’re just floats, and can be compared.

A lot of people use datetime:

 >>> from datetime import datetime
 >>> dt0 = datetime.now()
 >>> type(dt0)
 <class 'datetime.datetime'>
 >>> dt0
 datetime.datetime(2022, 9, 3, 14, 22, 57, 453473)

datetimes are a bit complex. Aside from have a bunch of fields, they
also have a timezone. I like to avoid them if a plain UNIX time will do
me, which is often. Getting the current time a bit later:

 >>> dt1 = datetime.now()
 >>> type(dt1)
 <class 'datetime.datetime'>
 >>> dt0 < dt1
 True

They’re both datetimes, and can be compared.

I can obtain a str from a datetime:

 >>> str(dt0)
 '2022-09-03 14:22:57.453473'

That’s just a string, as was the result of your strftime() call
earlier. You can’t compare a string to a datetime or to a float;
they’re different types.

Cheers,
Cameron Simpson cs@cskk.id.au

By Leonard Dye via Discussions on Python.org at 03Sep2022 04:12:

In Boolean contexts, a timedelta object is considered to be true if and
only if it isn’t equal to timedelta(0).

Something new to lean.

This last bit isn’t specific to timedeltas. Most Python types try to
treat zero or empty values as “false”, and other values as “true”. An
empty string "" is falsey. An empty list is falsey. And so forth. the
statement above just details this for timedeltas. There’s nothing very
special to remember here if you know the general rule.

Because of this rule, you can often do things like this:

 s = input("enter a string")
 if s:
     print("an empty string")
 else:
     print("a nonempty string:", s)

where you might expect to go:

 s = input("enter a string")
 if len(s) > 0:
     print("an empty string")
 else:
     print("a nonempty string:", s)

Cheers,
Cameron Simpson cs@cskk.id.au

2 Likes

By Cameron Simpson via Discussions on Python.org at 03Sep2022 05:58:

Because of this rule, you can often do things like this:

s = input("enter a string")
if s:
    print("an empty string")
else:
    print("a nonempty string:", s)

And of course I have the messages upside down. Please swap the 2 print
messages. I blame being interrupted while composing that reply :slight_smile:

Cheers,
Cameron Simpson cs@cskk.id.au

This is what I have so far. I did not code the function “convert24”. I have more to do but the problem of the string conversion is solved, it works. Anything stand out at this piont that I should be aware of? Is code layout in correct order? Where would “classes” go in this code, not the calling of the class?

import pyinputplus as pyip
import subprocess
from datetime import datetime
from time import sleep   # Needed for timer rest


# Function to convert the time format from 12-hour to 24-hour
def convert24(str1):
    # Checking if last two elements of time
    # is AM and first two elements are 12
    if str1[-2:] == "AM" and str1[:2] == "12":
        return "00" + str1[2:-2]

    # remove the AM
    elif str1[-2:] == "AM":
        return str1[:-2]

    # Checking if last two elements of time
    # is PM and first two elements are 12
    elif str1[-2:] == "PM" and str1[:2] == "12":
        return str1[:-2]

    else:

        # add 12 to hours and remove PM
        return str(int(str1[:2]) + 12) + str1[2:8]


# INPUT:
print()
print('     Welcome to AutoProgramStart')
print('I start programs at the time specified')
print()
print('Select the items below by number')
program_to_start = pyip.inputMenu(['Audiobook', 'Word', 'Excel', 'Notepad',
                                   'Alarm'], numbered=True)
print(program_to_start)  # This is where menu code goes
print('Use 12 hour format for time to start program: 10:58:16 PM')
raw_time = input('Please, enter time to start program: ')
raw_time12 = convert24(raw_time)  # Convert to 24 hour time
raw_hour = int(raw_time12[0:2])
raw_minutes = int(raw_time12[3:5])
raw_seconds = int(raw_time12[6:8])
seconds_to_start_program = ((raw_hour * 60 * 60) + (raw_minutes * 60) +
                            raw_seconds)

now = datetime.now()
current_time = now.strftime("%H:%M:%S")  # Get current time
current_time_seconds = (now.hour * 60 * 60) + (now.minute * 60) + now.second 

while current_time_seconds <= seconds_to_start_program:
    current_time_seconds += 1
    sleep(1)  # This give us accuracy of 1 second
print('check current time is less than start program, After many sleep(1)'
                                ' cycles, this is where the alarm goes')

# OUTPUT:
subprocess.Popen(['start', 'alarm.wav'], shell=True)  # Start sound alarm

Thanks again for the great help.

The next part may get a little tricky, finding a certain program on any computer. Let’s start with just windows computers, LOL. As I see it, first is to search C:\ drive, the root, and each directory under the root, and each subfolder of each and find the file searched for. Then we know the absolute path for that program. Then we can load the program we need from a program we are writing. There has to be a better way. Every computer is different.
Thanks.