Re: [Tutor] Help with range of months spanning across years

2011-02-02 Thread Steven D'Aprano

ian douglas wrote:
It bugs me that so many people are quick to jump on the we wont' do 
your homework bandwagon -- I was accused of the same thing when I 
posted a question to the list myself. I've been programming 
professionally for many years but learning Python in my spare time... I 
sent this reply to Sean privately, but frankly I'm so annoyed at the 
'homework' replies, I figured I'd just post it here.


It's a fine line. Most people consider homework questions to be 
cheating, and don't want to either condone or assist cheaters in any 
way. The cost, though, is occasionally offending people who aren't 
cheating, but merely asking a question poorly, or happen to be asking 
something that *sounds* like homework, or just unlucky.


Generally, if you want an answer to a question, you should demonstrate 
that you've tried to solve it yourself. Code, even broken code that 
doesn't work, and a clear description of the problem, go a long way to 
assuring people that *even if it is homework*, you've made a good 
attempt at the problem and are looking for *help* rather than somebody 
to do it for you.


At which point somebody will almost certainly jump in an do it for you :)


I'm still very junior to Python, but this seems to work for me using 
recursion. I'm sure there's a much more elegant way of doing this, but 
like I said, I'm still pretty new to the language.


def makelist(startmonth,startyear,endmonth,endyear):
mylist = []
if (startyear == endyear):
for month in range (startmonth,endmonth+1):
mylist += [(startyear,month)]
else:
for month in range (startmonth,13):
mylist += [(startyear,month)]
mylist += makelist(1,startyear+1, endmonth, endyear)
return mylist ;

print makelist(8,2009,1,2010)

I'd love to hear any replies from the experts on the list on how to make 
this more efficient in Python 'cause I'm still learning myself.


Generally, you don't use recursion because it's efficient, 'cos it 
ain't. At least not in Python, which has a fairly naive recursion model. 
Some other languages can spot a particular kind of recursion, and 
optimise the bejeezus out of it. So leave recursion for the problems 
where (1) it makes solving the problem easy, and (2) the inefficiency 
doesn't matter.


The *general* way of making recursion efficient is by converting it to 
iteration, if possible. In your case, recursion doesn't seem to really 
make the problem any easier to solve, but it probably doesn't hurt much.



--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Help with range of months spanning across years

2011-02-01 Thread Sean Carolan
I have a function that accepts four arguments, namely startmonth,
startyear, endmonth, and endyear.  For example:

startmonth = 8
startyear = 2009
endmonth = 1
endyear = 2010

What would be the most straightforward way to create a list of
year/month pairs from start to end?  I want to end up with a list of
tuples like this:

mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11), (2009, 12), (2010, 1)]
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Hugo Arts
On Wed, Feb 2, 2011 at 12:19 AM, Sean Carolan scaro...@gmail.com wrote:
 I have a function that accepts four arguments, namely startmonth,
 startyear, endmonth, and endyear.  For example:

 startmonth = 8
 startyear = 2009
 endmonth = 1
 endyear = 2010

 What would be the most straightforward way to create a list of
 year/month pairs from start to end?  I want to end up with a list of
 tuples like this:

 mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11), (2009, 12), (2010, 1)]


This sounds somewhat like homework. If it is, that's fine, mention it,
and we will help you. But we won't do your homework for you, so keep
that in mind.

That said, you can do this rather straightforwardly with two nested
for loops and the range() or xrange(), one for the year and one for
the month. The only problem here is that endmonth  startmonth in some
cases, like the example you gave above. In that case, you can adjust
endmonth so the range function will give the right amount of months,
then correct in the final output to get the right numbers.

Go and code something up, try stuff out, and come back and post what
you get. We'll give you tips on how to improve on it.

Hugo

P.S.: There is also a solution using the itertools package that is
possibly more succinct, but also less clear. You can investigate if
you'd like, see the documentation of the itertools.product function.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Alan Gauld


Hugo Arts hugo.yo...@gmail.com wrote


What would be the most straightforward way to create a list of
year/month pairs from start to end? I want to end up with a list of
tuples like this:

mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11), (2009, 12), 
(2010, 1)]



That said, you can do this rather straightforwardly with two nested
for loops and the range() or xrange(), one for the year and one for
the month.


Or if you want to be able to use it across historic times
(taking account of calendar irregularities etc) then you
can get the data from the datetime module... It just
depends how open ended your lists need to be. For
months and years you are probably ok with a simple
loop approach as Hugo suggests, but if you ever need
to go to days or weeks then datetime would be safer..

HTH,

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Elwin Estle
--- On Tue, 2/1/11, Sean Carolan scaro...@gmail.com wrote:

 From: Sean Carolan scaro...@gmail.com
 Subject: [Tutor] Help with range of months spanning across years
 To: Tutor@python.org
 Date: Tuesday, February 1, 2011, 6:19 PM
 I have a function that accepts four
 arguments, namely startmonth,
 startyear, endmonth, and endyear.  For example:
 
 startmonth = 8
 startyear = 2009
 endmonth = 1
 endyear = 2010
 
 What would be the most straightforward way to create a list
 of
 year/month pairs from start to end?  I want to end up
 with a list of
 tuples like this:
 
 mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11),
 (2009, 12), (2010, 1)]


--- On Tue, 2/1/11, Sean Carolan scaro...@gmail.com wrote:

 From: Sean Carolan scaro...@gmail.com
 Subject: [Tutor] Help with range of months spanning across years
 To: Tutor@python.org
 Date: Tuesday, February 1, 2011, 6:19 PM
 I have a function that accepts four
 arguments, namely startmonth,
 startyear, endmonth, and endyear.  For example:
 
 startmonth = 8
 startyear = 2009
 endmonth = 1
 endyear = 2010
 
 What would be the most straightforward way to create a list
 of
 year/month pairs from start to end?  I want to end up
 with a list of
 tuples like this:
 
 mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11),
 (2009, 12), (2010, 1)]


Well, I noticed someone else's reply to this, about it potentially being 
homework, so I won't post any code.

I tinkered with your problem and have a solution, but I didn't use nested for 
loops as someone else suggested.  My solution works, so long as the end year 
isn't the same as the start year, tho with a bit of fiddling, one could add 
some conditional code to take care of that.

I would suggest thinking about the situation with the first year/month pair in 
the date range, and the last year/date...vs any years in the middle.  What is 
different?  What is the same?


  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread ian douglas
It bugs me that so many people are quick to jump on the we wont' do 
your homework bandwagon -- I was accused of the same thing when I 
posted a question to the list myself. I've been programming 
professionally for many years but learning Python in my spare time... I 
sent this reply to Sean privately, but frankly I'm so annoyed at the 
'homework' replies, I figured I'd just post it here.


I'm still very junior to Python, but this seems to work for me using 
recursion. I'm sure there's a much more elegant way of doing this, but 
like I said, I'm still pretty new to the language.


def makelist(startmonth,startyear,endmonth,endyear):
mylist = []
if (startyear == endyear):
for month in range (startmonth,endmonth+1):
mylist += [(startyear,month)]
else:
for month in range (startmonth,13):
mylist += [(startyear,month)]
mylist += makelist(1,startyear+1, endmonth, endyear)
return mylist ;

print makelist(8,2009,1,2010)

I'd love to hear any replies from the experts on the list on how to make 
this more efficient in Python 'cause I'm still learning myself.



On 02/01/2011 05:14 PM, Elwin Estle wrote:

--- On Tue, 2/1/11, Sean Carolanscaro...@gmail.com  wrote:


What would be the most straightforward way to create a list
of
year/month pairs from start to end?  I want to end up
with a list of
tuples like this:

mylist = [(2009, 8), (2009, 9), (2009, 10), (2009, 11),
(2009, 12), (2010, 1)]
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Sean Carolan
 This sounds somewhat like homework. If it is, that's fine, mention it,
 and we will help you. But we won't do your homework for you, so keep
 that in mind.

A reasonable assumption but this is actually going in a cgi tool that
I'm using at work.  The input comes from pull-down menus on a web
page.

Here's what I came up with, feel free to give suggestions on how this
might be made more efficient:

if startyear  endyear or (startyear == endyear and startmonth  endmonth):
print 'Your start date must be earlier than the end date.'
else:
datelist = []
month = startmonth
year = startyear
while month != endmonth or year != endyear:
datelist.append((year, month))
if month == 12:
month = 1
year += 1
else:
month += 1
datelist.append((year, month))
print datelist

I was hoping there was some whiz-bang function that would just iterate
through months if it was fed a start and end date.  Can datetime or
calendar do this?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Hugo Arts
On Wed, Feb 2, 2011 at 2:30 AM, ian douglas ian.doug...@iandouglas.com wrote:
 It bugs me that so many people are quick to jump on the we wont' do your
 homework bandwagon -- I was accused of the same thing when I posted a
 question to the list myself. I've been programming professionally for many
 years but learning Python in my spare time... I sent this reply to Sean
 privately, but frankly I'm so annoyed at the 'homework' replies, I figured
 I'd just post it here.


Okay, this has gotten rather long, but I'll post it anyway because I
think the we won't do your homework response is valid and there's
good reasoning behind it.

It's not just homework. The thing is, the point of this list is to
teach people how to program (in general, but in python specifically).
When someone posts a question, responding with a lump of code and a
crisp This is how you do it just isn't a very effective teaching
method. More of the equivalent of giving a man a fish, as in the old
saying.

Another point, mentioned in Eric Raymond's How to ask questions the
smart way[1], is that I generally dislike answering questions for
people who don't appear to have put in any work in solving the problem
themselves. It leaves us with little options to give pointers, and
we're stuck with the lump of code mentioned above, or a few vague
hints as to how to approach the problem.

This isn't a place that solves your coding problems for free. But I'm
happy to help you learn python. For those reasons, I *never* give out
a straight answer, especially not to someone who doesn't show their
own attempts. In those cases, I will tell them that I won't and why,
give them some hints, and encourage them to try some things on their
own and get back here, at which point we can help them further. That's
what tutoring is all about after all.

So, in short, we're not accusing you of trying to make us do your
homework, and we're certainly not dismissing your questions. We're
simply saying show us what you have, and we'll give you tips. if
you're totally at a loss, try doing so-and-so, or look at this and
that documentation.

[1]: http://www.catb.org/~esr/faqs/smart-questions.html, everybody
should read this before posting to a mailing list, imho.

 I'm still very junior to Python, but this seems to work for me using
 recursion. I'm sure there's a much more elegant way of doing this, but like
 I said, I'm still pretty new to the language.

 def makelist(startmonth,startyear,endmonth,endyear):
     mylist = []
     if (startyear == endyear):
         for month in range (startmonth,endmonth+1):
             mylist += [(startyear,month)]
     else:
         for month in range (startmonth,13):
             mylist += [(startyear,month)]
         mylist += makelist(1,startyear+1, endmonth, endyear)
     return mylist ;

 print makelist(8,2009,1,2010)

 I'd love to hear any replies from the experts on the list on how to make
 this more efficient in Python 'cause I'm still learning myself.


Your solution feels rather lispy to me. I really like that. I actually
had a simple iterative solution in mind when I wrote that first post,
but while trying to write it now I'm running into some complications I
hadn't considered before, mea culpa (I'm such a good armchair
programmer /sarcasm)

In any case, you can replace the for loops with a list comprehensions,
and factor them out into a single one since they're so similar. Let me
write it out:

def datelist(startyear, startmonth, endyear, endmonth):
em = endmonth + 1 if startyear == endyear else 13
dates = [(startyear, m) for m in range(startmonth, em)]
if startyear  endyear:
dates += datelist(startyear + 1, 1, endyear, endmonth)
return dates

 print(datelist(2008, 8, 2009, 1))
[(2008, 8), (2008, 9), (2008, 10), (2008, 11), (2008, 12), (2009, 1)]

Hugo
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Hugo Arts
On Wed, Feb 2, 2011 at 2:55 AM, Sean Carolan scaro...@gmail.com wrote:
 This sounds somewhat like homework. If it is, that's fine, mention it,
 and we will help you. But we won't do your homework for you, so keep
 that in mind.

 A reasonable assumption but this is actually going in a cgi tool that
 I'm using at work.  The input comes from pull-down menus on a web
 page.

I apologize for assuming homework. It's the tutor list, and I try to
focus on effective teaching more than anything. No offense was meant.

 Here's what I came up with, feel free to give suggestions on how this
 might be made more efficient:

 [snip code]

 I was hoping there was some whiz-bang function that would just iterate
 through months if it was fed a start and end date.  Can datetime or
 calendar do this?

As far as I can tell from quickly going through documentation, no. At
least, not with a quick and easy function. datetime can represent the
dates just fine, and you can add days to that until you hit your end
date, but adding months is harder. timedelta can't represent a month,
which makes sense since they're not of constant length anyway. So
using datetime is not really your best option. Calendar is more about
displaying than doing calculations, making it even less useful.

You can use your code or ian's (or my modification of ian's code) to
your taste, I don't expect any measurable difference in efficiency. If
it's really important, *measure*. But I suspect it isn't, unless
you'll run it either on time spans of thousands of years or if it will
be used by thousands of people at a time.

Hugo
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with range of months spanning across years

2011-02-01 Thread Sean Carolan
 As far as I can tell from quickly going through documentation, no. At
 least, not with a quick and easy function. datetime can represent the
 dates just fine, and you can add days to that until you hit your end
 date, but adding months is harder. timedelta can't represent a month,
 which makes sense since they're not of constant length anyway. So
 using datetime is not really your best option. Calendar is more about
 displaying than doing calculations, making it even less useful.

Thank you, this is useful information.


 You can use your code or ian's (or my modification of ian's code) to
 your taste, I don't expect any measurable difference in efficiency. If
 it's really important, *measure*. But I suspect it isn't, unless
 you'll run it either on time spans of thousands of years or if it will
 be used by thousands of people at a time.

Yes, the code runs quickly enough for our needs.  Thanks again for the
helpful suggestions.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor