6
\$\begingroup\$

Was too bored in holidays...here's a code which finds the day of the week using the algorithm in this video. Please give a logical date in the correct format cause I didn't account for improper inputs cause I'm too lazy. My code is short and sweet.

day=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]    #some database numbers and strings
mdoom=[3,28,14,4,9,6,11,8,5,10,7,12]
while True:
    entry=input('\nEnter a date in DD/MM/YYYY format:')         #Input date in a specified format
    date,month,year = map(int,entry.split('/'))                 #Get the date,month and year
    centdoom=[3,2,0,5]
    a=centdoom[((year//100)%4)-3]
    b=(year%100)//12
    c=(year%100)%12
    d=c//4                                                      #Random calculations for doomsday :)
    e=a+b+c+d

    if (year%4==0) and ((year%100!=0) or (year%400==0)):        #Checks for leap year
        mdoom[0],mdoom[1]=4,29

    ddoom=e%7                                                   #finds a date in the 1st week which has the same day as the doomsday    
    r=mdoom[month-1]                                            #Gives the doomsdate in the input month 
    r=r%7
    r=ddoom-r                                                   
    date=date%7                                                 #finds a date in the 1st week which has the same day as the input date
    print('\n',day[(r+date)%7])                                 #prints the output
    k=input('\nTry again?(y/n)')
    if k=='y':
        continue
    else:
        break

And any suggestions or improvements are welcome.

\$\endgroup\$
  • 1
    \$\begingroup\$ I would slightly improve on leap year (en.wikipedia.org/wiki/Leap_year#Algorithm). \$\endgroup\$ – dfhwze May 18 at 13:07
  • \$\begingroup\$ can you please send the edited part of the leap year condition...cause I can't plug in the 2 new conditions according to Wiki in my code.....I'm a complete noob :( ...thanks in advance \$\endgroup\$ – THE EPIC GUY May 18 at 17:48
3
\$\begingroup\$

Your code is hard to understand, even after watching the video.

  1. Make some functions. years_doomsday would help move some of the hard to understand information to be self-contained.
  2. If you need to floor divide and get the remainder use divmod.
  3. You can check the leap year using calendar.isleap.
  4. You have a bug, if you ever enter a leap year then the non-leap years will return incorrect values for January and February.
  5. You should make a function that calls years_doomsday, and returns the weekday.
  6. You should make centdoom a global constant.
  7. By rotating centdoom once you can remove the need for the -3.
import calendar

WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
MDOOMSDAY = [3, 28, 14, 4, 9, 6, 11, 8, 5, 10, 7, 12]
MDOOMSDAY_LEAP = list(MDOOMSDAY)
MDOOMSDAY_LEAP[:2] = [4, 29]
CDOOMSDAY = [2, 0, 5, 3]


def years_doomsday(year):
    a, b = divmod(year, 100)
    c, d = divmod(b, 12)
    e = d // 4
    return (CDOOMSDAY[a % 4] + c + d + e) % 7


def doomsday(year, month, day):
    y_doomsday = years_doomsday(year)
    mdoomsday = MDOOMSDAY_LEAP if calendar.isleap(year) else MDOOMSDAY
    return WEEKDAYS[(day - mdoomsday[month-1] + y_doomsday) % 7]


if __name__ == '__main__':
    tests = [
        (2305, 7, 13, 'Thursday'),
        (1776, 7, 4, 'Thursday'),
        (1969, 7, 20, 'Sunday'),
        (1984, 1, 6, 'Friday'),
        (1902, 10, 19, 'Sunday'),
    ]
    for test in tests:
        if doomsday(*test[:3]) != test[-1]:
            print('Broken for', test)

If you don't want any fun, you can replace your code with datetime.date.isoweekday.

import datetime

for test in tests:
    if WEEKDAYS[datetime.date(*test[:3]).isoweekday()%7] != test[-1]:
        print('Broken for', test)
\$\endgroup\$
  • \$\begingroup\$ Nice answer! +1 \$\endgroup\$ – Justin Jun 14 at 13:22
  • \$\begingroup\$ why not do tests = [(2705, 7, 13), "Thursday",...] or even making it a dict, and then for date, answer in tests:if doormsday(*date) != answer:print(...); and I find your way of assembling MDOOMSDAY_LEAP rather strange \$\endgroup\$ – Maarten Fabré Jun 14 at 13:25
  • 1
    \$\begingroup\$ @MaartenFabré Because I find ((1, 2, 3), 'd') is more annoying to type then (1, 2, 3, 'd'). \$\endgroup\$ – Peilonrayz Jun 14 at 13:28
  • \$\begingroup\$ it is 2 more brackets to type, yes, but a lot more clearer when using the test \$\endgroup\$ – Maarten Fabré Jun 14 at 13:29
  • 1
    \$\begingroup\$ @MaartenFabré And I was testing this in IDLE where I kept having to write the same stuff over and over. \$\endgroup\$ – Peilonrayz Jun 14 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.