I'll preface this by saying that I'm fairly new to Python (after having 2-3 years of C++ under my belt), but for some reason I can't figure out the reasoning behind global variables and when/how I should be using them.

For instance, there is a project for school that we've been working on for the past week. Basically we need to compute the number of days between a birthday and the next birthday (mind you, WITHOUT using the built-in Python modules for date/time).

I'm perfectly fine with figuring out the ordinal date (how many days into a year a specific date is), leap years, as well as getting the inputs from the user. However, when I try and tie it all together.....it falls apart quick.

For instance, here is what I've got so far:

Jan = 0
Feb = 31
Mar = 59
Apr = 90
May = 120
Jun = 151
Jul = 181
Aug = 212
Sep = 243
Oct = 276
Nov = 305
Dec = 334

dTilBday = 0
curCount = 0
birCount = 0 

curMonth = input('Enter the current month in the Mmm (ex Jan) format:')
curDay = input('Enter the current day in the DD format:')
curYear = input('Enter the current year:')
birMonth = input('Enter your birth month in the Mmm (ex Jan) format:')
birDay = input('Enter your birth day in the DD format:')



def isLeapYear(curYear):
        if (curYear % 4 == 0 and curYear % 100 != 0) or (curYear % 400 == 0):
                return 1
        
                
        else:
               
                global Mar
                Mar = 60
                global Apr
                Apr = 91
                global May
                May = 121
                global Jun
                Jun = 152
                global Jul
                Jul = 182
                global Aug
                Aug = 213
                global Sep
                Sep = 244
                global Oct
                Oct = 277
                global Nov
                Nov = 305
                global Dec
                Dec = 335
        return 0

def daysTilBday():
        if birCount > curCount:
                global dTilBday
                dTilBday = birCount - curCount
        else:
                dTilBday = (birCount + 365) - curCount
        return 0

def BirthdayPrintout():
        if birCount == curCount:
                print 'Congrats, today is your birthday!'
        else:
                print 'There are', dTilBday(), 'days til your next birthday'
        return 0

curCount = curMonth + curDay
birCount = birMonth + birDay

What I'm trying to do is:
A) assign starting values for days in a month
B) read user input
C) determine if the year is a leap year
C)ii modify the original days in a month values if it is a leapyear
D) calculate the ordinal date
E) calculate the days between the current date and the birthdate using the ordinal dates for each
F) simple printout saying the total days til birthday, or saying "Happy Birthday" if they are the same date

I've tried going to office hours, but I'm still INCREDIBLY confused by the global values :(
Any help is GREATLY appreciated!

Instead of 1 or 0 why don't you return True or False...? Also, even though it's a bad habit of mine, it's considered ugly to use globals when not necessary in a function, you could simply return what you need to, try putting all these things in an array or hash "list or dictionary" and having them returned along with True or False.

>>> def is_good(word):
	word.capitalize()
	if word == 'Python':
		return True
	else:
		return False

	
>>> wrd='C'
>>> is_good(wrd)
False

also for changing global variables:

>>> lis=[0,1,2,3]
>>> 
>>> def plus1(that):
	new=[]
	for i in that:
		i+=1
		new.append(i)
	return new

>>> lis
[0, 1, 2, 3]
>>> lis=plus1(lis)
>>> lis
[1, 2, 3, 4]

Edited 5 Years Ago by pyguy62: n/a

Comments
Thank you for the input

Ahhhh I see now. The list/dictionary idea will work much better when I need to change the values for leapyears.

Thank you for the input, I'll give it a shot and let you know how it works out.

Here is something to get you started:

# imports (None)
# global data
days_in_months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
               'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
days_before = dict((m, sum(days_in_months[:ind])) for ind, m in enumerate(month_names))

# functions
def is_leap_year(year):
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)

def before_with_leap(year, month, day):
    return days_before[month] + day + (1 if month > 2 and is_leap_year(year) else 0) - 1

# main routine, do not run on import. Testing routine
if __name__ == '__main__':
    # import in middle makes it clear that module datetime is only used for testing in main routine 
    # Exception to rule to put imports in beginning
    import datetime
    for y in range(2000, 2012):
        print('')
        print('%i %s leap year' % (y, ('is' if is_leap_year(y) else 'is not')))
        print('Days before Oct 5, %i: %i' % (y, before_with_leap(y, 'Oct', 5)))
        print('Check with datetime: %i ' % (datetime.date(y, 10, 5) - datetime.date(y, 1, 1)).days)

    # check first of Jan as corner case
    print('\nBefore Jan 1 is %i days' % (before_with_leap(2011, 'Jan', 1)))

You can use unchanging values from global values, but do not change those, you can use function instead. Eval is dangerous, use your own dictionary instead.

Edited 5 Years Ago by pyTony: n/a

Alrighty, I gave those a shot and I've got it working almost 100% now. However, I'm still having one issue with the dictionary.

Basically I'm trying to use the dictionary within the if statement for Leap Years (in order to modify the # of days per month based upon the if check); however, when I do this, Python gives me an error saying I need to initialize the dictionary (monthDict). So when I do that above...it overwrites ALL of if dictionary changes....

monthDict = {01: 0, 02: 31, 03: 59, 04: 90, 05: 120, 06: 151, 07: 181, 8: 212, 9: 243, 10: 273, 11: 304, 12: 334}

#Leap Year Function
def isLeap(year):
    if not year % 4 and (year % 100 or not year % 400):
        monthDict = {01: 0, 02: 31, 03: 60, 04: 91, 05: 121, 06: 152, 07: 182, 8: 213, 9: 244, 10: 274, 11: 305, 12: 335}
        return 1
    monthDict = {01: 0, 02: 31, 03: 59, 04: 90, 05: 120, 06: 151, 07: 181, 8: 212, 9: 243, 10: 273, 11: 304, 12: 334}
    return 0

Is there a way to do this?

This article has been dead for over six months. Start a new discussion instead.