patternpythonMinor
Spotify puzzle problem in python
Viewed 0 times
problemspotifypuzzlepython
Problem
I'm a complete beginner in Python and programming in general. I made a program for Spotify's Best Before puzzle. It was accepted. I have looked a litle around on internet and looked at other solutions to the problem, and everyone I have seen have importet several modules, inclusive the Calendar module. I understand this is probably a good solution, but I wanted to make everything myself as a practice.
I would really appreciate all tips and hint, but mainly without haveing to import code. It's primarily the
```
normYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
leapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
answerList = []
u''' Check if any of the integers are years '''
def yearCheck():
for x in xrange(0, 3):
a = dataList[x]
if len(a) > 2:
if not len(a) == 4 and int(a) in xrange(2000,3000):
if int(a) in xrange(100,1000):
dataList[x] = int(a) + 2000
else:
print data + u" is illegal"
u''' Make integers and sort '''
def integer():
for x in xrange(0, 3):
dataList[x] = int(dataList[x])
dataList.sort()
u''' Check for possible leap years '''
def leapYears():
global leapList
leapList = []
for x in xrange(0, 3):
if dataList[x] % 4 == 0:
if dataList[x] % 100 == 0:
if dataList[x] % 400 == 0:
leapList.append(x)
else:
leapList.append(x)
u''' Changes year type '''
def defYear(a):
global xYear
if a in leapList:
xYear = leapYear
else:
xYear = normYear
u''' Printer '''
def printer(a):
if dataList[a] < 2000:
dataList[a] += 2000
year = dataList[a]
del dataList[a]
if not dataList[0] == 0:
month = dataList.pop(0)
day = dataList.pop(0)
answerList.append(unicode(year))
answerList.append(unicode(u'%02d' %
I would really appreciate all tips and hint, but mainly without haveing to import code. It's primarily the
printer(a) and det dataMaker() that needs modification.```
normYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
leapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
answerList = []
u''' Check if any of the integers are years '''
def yearCheck():
for x in xrange(0, 3):
a = dataList[x]
if len(a) > 2:
if not len(a) == 4 and int(a) in xrange(2000,3000):
if int(a) in xrange(100,1000):
dataList[x] = int(a) + 2000
else:
print data + u" is illegal"
u''' Make integers and sort '''
def integer():
for x in xrange(0, 3):
dataList[x] = int(dataList[x])
dataList.sort()
u''' Check for possible leap years '''
def leapYears():
global leapList
leapList = []
for x in xrange(0, 3):
if dataList[x] % 4 == 0:
if dataList[x] % 100 == 0:
if dataList[x] % 400 == 0:
leapList.append(x)
else:
leapList.append(x)
u''' Changes year type '''
def defYear(a):
global xYear
if a in leapList:
xYear = leapYear
else:
xYear = normYear
u''' Printer '''
def printer(a):
if dataList[a] < 2000:
dataList[a] += 2000
year = dataList[a]
del dataList[a]
if not dataList[0] == 0:
month = dataList.pop(0)
day = dataList.pop(0)
answerList.append(unicode(year))
answerList.append(unicode(u'%02d' %
Solution
- You have unicode strings as comments. Just use comments.
- You rely on manipulating global state, not a good idea. Instead,
have function return things. You don't use any return statements
anywhere in your code.
- You use
not a == binstead ofa != bin several places
- You use
a in xrange(b,c)whereb
- All of your for loops use xrange, usually you want to iterate over the container directly
- Your yearCheck function doesn't do anything. The if` condition is impossible to satisfy. It looks like you discovered this, because you've implemented the logic down in the printer function.
- You delay converting the data components to integer, this only serves to complexicate your code.
- You generate a list of leap years, but you only ever check the years 0, 1, 2 and 3.
- You keep the data inside the list the whole time. Code is easier to follow if you don't do that. Pull the data out of lists into local variables rather then indexing into the list.
Here is a reworking of your approach:
NORMAL_MONTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def get_month_lengths(year):
"""
Returns appropriate months for a particular year
"""
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return LEAP_MONTHS
else:
return LEAP_MONTHS
return NORMAL_MONTHS
def print_date(year, month, day):
"""
Print the given date
"""
if year < 2000:
year += 2000
print u'%04d-%02d-%02d' % (year, month, day)
# Looks for legal dates, first [Y<M<D] then [M<Y<D] then [M,D,Y]
def dateMaker(data):
"""
Try different ways of interpretating the date
"""
a, b, c = data
for year, month, day in [(c,b,a), (c,a,a), (b,a,c)]:
month_lengths = get_month_lengths(year)
if month <= 12 and day <= month_lengths[month - 1]:
print_date(year, month, day)
return
print unicode(data) + u" is illegal"
data = sorted(map(int, raw_input().split(u"/")))
dateMaker(data)Code Snippets
NORMAL_MONTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def get_month_lengths(year):
"""
Returns appropriate months for a particular year
"""
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return LEAP_MONTHS
else:
return LEAP_MONTHS
return NORMAL_MONTHS
def print_date(year, month, day):
"""
Print the given date
"""
if year < 2000:
year += 2000
print u'%04d-%02d-%02d' % (year, month, day)
# Looks for legal dates, first [Y<M<D] then [M<Y<D] then [M,D,Y]
def dateMaker(data):
"""
Try different ways of interpretating the date
"""
a, b, c = data
for year, month, day in [(c,b,a), (c,a,a), (b,a,c)]:
month_lengths = get_month_lengths(year)
if month <= 12 and day <= month_lengths[month - 1]:
print_date(year, month, day)
return
print unicode(data) + u" is illegal"
data = sorted(map(int, raw_input().split(u"/")))
dateMaker(data)Context
StackExchange Code Review Q#8263, answer score: 4
Revisions (0)
No revisions yet.