Разделение строки для математических вычислений дает странный результат в Python - PullRequest
4 голосов
/ 13 февраля 2012

Итак, я признаю, что это домашнее задание, но я не прошу всех вас сделать это для меня, я просто ищу руководство.Нам нужно сделать так, чтобы программа на Python принимала время в формате Hours: Minutes (2:30) в одной строке и выводила количество времени в минутах.(т.е. 2 часа и 30 минут = 150 минут)

Мне все еще нужно выработать некоторые ограничения для ввода строки:

  1. Убедитесь, что используются только цифры и двоеточие
  2. Убедитесь, что он может принимать только пять символов (##: ##)
  3. Убедитесь, что средний символ является двоеточием (т. Е. Числа в правильном порядке)
  4. и введитеуверен, что если введено время, подобное 4:35, то ноль будет добавлен вперед автоматически

Я над этим поработаю позже - сейчас я решил поработать над математикой, которую получуиз ввода.

Для меня имело смысл разделить строку на две части: часы и минуты.Затем я умножил количество часов на 60 и добавил их к уже существующим минутам, чтобы получить общее количество минут.Тем не менее, прямо сейчас, введя время как 02:45 выводит мельчайшее количество 02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020245.

1018 * Любая идея, что может идти здесь не так?Просто чтобы прояснить, это домашнее задание, и я хочу самостоятельно решить ограничения ввода, мне просто нужна помощь, чтобы пройти мимо этого математического вопроса.
#Henry Quinn - Python Advanced 4.0 Hours and Minutes
import re
print "This program takes an input of time in hours and minutes and outputs the amount    of minutes."
count = 0

#I still need to work out while loop
#Supposed to make sure that a time is entered correctly, or error out
while (count <1):
    time = raw_input("Please enter the duration of time (ex: 2:15 or 12:30): ")
    if not re.match("^[0-9, :]*$", time):
        print "Sorry, you're only allowed to use the numbers 0-9."
    elif len(time) > 5:
        print "Sorry, only five characters max allowed."
#MAKE THIS CHECK FOR A COLON
#elif
#elif
    else:
        count = count + 1

#If time = 12:45, hours should be equal to 12, and minutes should be equal to 45
hours = time[:2]
minutes = time[3:]

#Should convert hours to minutes
newhours = hours * 60

#Should make total amount of minutes
totalminutes = newhours + minutes

print "The total amount of elapsed minutes is %s" % (totalminutes)

raw_input("Please press Enter to terminate the program.")

Ответы [ 4 ]

5 голосов
/ 13 февраля 2012

Сейчас часы и минуты являются строковыми переменными, а не целыми числами. Таким образом, вы не можете умножить их, как число.

Измените строки 20 и 21 на

hours = int(time[:2])
minutes = int(time[3:])

И вставка 02:45 должна работать. Тем не менее, вы все равно столкнетесь с проблемами, если у вас нет этого начального 0 (например, если вы вставите 2:45), поэтому я мог бы предложить вам вместо этого разделить его на ":", например так:

hours = int(time.split(":")[0])
minutes = int(time.split(":")[1])
3 голосов
/ 13 февраля 2012

Вы умножаете строку на целое число.

>>> st = '20'
>>> st*3
'202020'
>>> int(st)*3
60
>>>

Тип приведи его к int.

Итак, измените это

minutes = time[3:]
newhours = hours * 60

до

 minutes = int(time[3:])
 newhours = int(hours) * 60
1 голос
/ 13 февраля 2012

2-е и 4-е требования противоречат друг другу.Либо вы принимаете только строки из 5 символов, либо вы также разрешаете #:## (форма из 4 символов).

import re

def minutes(timestr):
    """Return number of minutes in timestr that must be either ##:## or #:##."""
    m = re.match(r"(\d?\d):(\d\d)$", timestr)
    if m is None:
       raise ValueError("Invalid timestr: %r" % (timestr,))
    h, m = map(int, m.groups())
    return 60*h + m

Если вы разрешаете пробелы внутри форм timestr и ##:#, #:# и т. Д.,:

def minutes2(timestr):
    h, m = map(int, timestr.partition(':')[::2])
    return 60*h + m

Если вы хотите ограничить часы до 0..23, а минуты до 0..59, тогда:

import time

def minutes3(timestr):
    t = time.strptime(timestr, "%H:%M")
    return 60*t.tm_hour + t.tm_min

Пример

minutes ('12:11') -> 731
minutes2('12:11') -> 731
minutes3('12:11') -> 731
minutes ('  12:11') -> error: Invalid timestr: '  12:11'
minutes2('  12:11') -> 731
minutes3('  12:11') -> error: time data '  12:11' does not match format '%H:%M'
minutes ('12:11  ') -> error: Invalid timestr: '12:11  '
minutes2('12:11  ') -> 731
minutes3('12:11  ') -> error: unconverted data remains:   
minutes ('3:45') -> 225
minutes2('3:45') -> 225
minutes3('3:45') -> 225
minutes ('03:45') -> 225
minutes2('03:45') -> 225
minutes3('03:45') -> 225
minutes ('13:4') -> error: Invalid timestr: '13:4'
minutes2('13:4') -> 784
minutes3('13:4') -> 784
minutes ('13:04') -> 784
minutes2('13:04') -> 784
minutes3('13:04') -> 784
minutes ('24:00') -> 1440
minutes2('24:00') -> 1440
minutes3('24:00') -> error: time data '24:00' does not match format '%H:%M'
minutes ('11:60') -> 720
minutes2('11:60') -> 720
minutes3('11:60') -> error: unconverted data remains: 0
1 голос
/ 13 февраля 2012

Так как это домашняя работа, вот решение - если вы выясните, как это работает, я гарантирую, что вы узнаете что-то новое;)

tre = re.compile("([0-2]?[0-9]):([0-5][0-9])")
h,m = ((int(_) for _ in tre.match("2:30").groups())
td = timedelta(hours=h, minutes=m)
print(td.total_seconds() / 60)
...