Подскажите путь к решению задачки на Питоне

Начал учить Python и застрял на этой задачке (уже больше недели). Пожалуйста, подскажите путь к решению, у меня идей нет…

Задача

Вам необходимо создать программу, которая выводит состояние магазина Open или Closed в зависимости от времени и дня недели.

Магазин открыт ежедневно с 10 до 21, кроме субботы и воскресенья. В четверг магазин открыт с 15 часов.

Вам необходимо добавить час и день недели в качестве ввода. День недели представлен в виде целого числа (1 для понедельника, 2 для вторника и т. д.)

Пример ввода: 15 4

Пример вывода: Open

Мой код

    hour = int(input())
    day = int(input())
    if day == 6 or day == 7:
        print('Closed')
    if (hour < 15 or hour > 21) and (day == 4):
        print('Closed')
    if (hour < 10 or hour > 21) and (day == 1 or day == 2 or day == 3 or day == 5):
        print('Closed')
    else:
        print('Open')

Проблема

Если вводить субботу или воскресенье (6 или 7 день) идет двойной вывод: сначала прога возвращает, как и должно быть, Closed и следом за ним почему-то еще и Open.

Тот же результат, если вводить нерабочие часы четверга.

С остальными днями недели все равботает как должно.


Ответы (4 шт):

Автор решения: Jack_oS

У вас четыре взаимоисключаемые условия:

СБ, ВС - закрыт (однозначно, и дальше нечего проверять)

ЧТ - закрыт, если время меньше 15 или больше 21

остальные дни - закрыт, если время меньше 10 или больше 21

иначе (если ничего из вышеперечисленного не сработало) - открыт

Вот для такого взаимоисключения elif и нужен (из документации):

if_stmt ::=  "if" assignment_expression ":" suite
         ("elif" assignment_expression ":" suite)*
         ["else" ":" suite]

Код:

hour = int(input())
day = int(input())

if day == 6 or day == 7:
    print('Closed')
elif day == 4 and 15 > hour > 21:
    print('Closed')
elif 10 > hour > 21:
    print('Closed')
else:
    print('Open')
→ Ссылка
Автор решения: Zhihar

судя по примеру ввода - данные надо вводить в 1 строке, тогда

hour, day = map(int, input().split())

а дальше можно отталкивать только от времени работы магазина:

if 1 <= day < 4 and 10 <= hour <= 21:
    print("open")
elif day == 4 and 15 <= hour <= 21:
    print("open")
else:
    print("closed")

можно подсвернуть:

if (1 <= day < 4 and 10 <= hour <= 21) or (day == 4 and 15 <= hour <= 21):
    print("open")
else:
    print("closed")

или еще подсвернуть:

print("open" if (1 <= day < 4 and 10 <= hour <= 21) or (day == 4 and 15 <= hour <= 21) else "closed")

или еще подсвернуть:

print(("closed", "open")[(1 <= day < 4 and 10 <= hour <= 21) or (day == 4 and 15 <= hour <= 21)])
→ Ссылка
Автор решения: Cowboyserg

else привязывается к ближайшему elif, если такого нет, то к ближайшему if.

Что это значит? Вы вводите day как 6. Пробуем попасть в первое условие. Тут говорится, если день равен 6, то выводится Closed, отлично, вроде все как надо, идем дальше.

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

7 строчка тоже не срабатывает, так как у нас ни один из тех дней, что на этой строчке перечислены.

9 строчка. Она привязана к ближайшему if, то есть к 7 строке. 7 строка уже выдала false, она не сработала, а раз она не сработала то как раз данный else сработает в любом случае. То есть у вас выполнится и условие на 3 строке и else.

Если же вы хотите, чтобы else сработал не из-за последнего if, то их надо связать.

    hour = int(input())
    day = int(input())
    if day == 6 or day == 7:
        print('Closed')
    elif (hour < 15 or hour > 21) and (day == 4):
        print('Closed')
    elif (hour < 10 or hour > 21) and (day == 1 or day == 2 or day == 3 or day == 5):
        print('Closed')
    else:
        print('Open')

Теперь условие elif (hour < 15 or hour > 21) and (day == 4): может выполниться только если не сработает if day == 6 or day == 7:.

Условие elif (hour < 10 or hour > 21) and (day == 1 or day == 2 or day == 3 or day == 5): только если не сработают два предыдущих.

И в результате else сработает только если не сработают все предыдущие. А у вас оно бы сработало, только если не выполнится elif (hour < 10 or hour > 21) and (day == 1 or day == 2 or day == 3 or day == 5):.

А вообще рекомендую свой код запустить [здесь][1], чтобы вы смогли построчно пройтись по вашему коду, чтобы лучше понять, как это работает

P.S. другие комментаторы уже приложили такой код, так что мой комментарий имеет смысл только в подробном описании вашего примера. [1]: http://www.pythontutor.com/visualize.html#mode=edit

→ Ссылка
Автор решения: binar

я тоже решал эту задачу, при чем здорово так споткнулся о неё. У меня концепция решения вся True (вначале указываем основное условие) if, а затем баним ненужные нам ветвления в elif. По-моему довольно изящно.

введите сюда описание изображения

→ Ссылка