Re: [Tutor] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Alan Gauld

On 06/08/13 08:16, Jim Mooney wrote:


class IterableFraction(Fraction):
   def __iter__(self):
   yield self.numerator
   yield self.denominator



Seriously, though, I thought yield was like return - one and you're
done - how are you getting two yields in there?


yield acts like a return but also a freeze frame.
So the first time you call the function it runs till it hits yield. The 
next time you call the function it picks up at the yield and continues 
from that point. In this case to the next yield.


The usual paradigm is to have the yield inside a loop such that every 
call returns the next result of a loop. You could do that here too but 
its shorter to use 2 yields:


def __iter__(self):
  for value in [self.numerator, self.denominator]
yield value


hth

--
Alan G
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] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Steven D'Aprano
On Tue, Aug 06, 2013 at 08:58:31AM +0100, Alan Gauld wrote:
> On 06/08/13 08:16, Jim Mooney wrote:
> 
> >>class IterableFraction(Fraction):
> >>   def __iter__(self):
> >>   yield self.numerator
> >>   yield self.denominator
> 
> >Seriously, though, I thought yield was like return - one and you're
> >done - how are you getting two yields in there?
> 
> yield acts like a return but also a freeze frame.
> So the first time you call the function it runs till it hits yield. The 
> next time you call the function it picks up at the yield and continues 
> from that point. In this case to the next yield.

All this is correct, but yield is more powerful than that. Not only does 
yield get used to return values from a function, it also gets used to 
send values *into* a running function.


py> def cr():  # Co-Routine.
... x = yield()
... while True:
... x = yield(x + 1)
... 
py> magic = cr()
py> magic.send(None)
()
py> magic.send(1)
2
py> magic.send(2)
3
py> magic.send(99)
100
py> magic.send(3)
4


Prepare to have your mind expanded, possibly until it leaks out your 
ears :-)


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


Re: [Tutor] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Alan Gauld

On 06/08/13 09:26, Steven D'Aprano wrote:


All this is correct, but yield is more powerful than that. Not only does
yield get used to return values from a function, it also gets used to
send values *into* a running function.


Yikes. This is new to me too.
When did that happen? Has yield always had these two way powers?


py> def cr():  # Co-Routine.
... x = yield()
... while True:
... x = yield(x + 1)
...
py> magic = cr()
py> magic.send(None)
()
py> magic.send(1)
2

Prepare to have your mind expanded


I have some reading to do...

--
Alan G
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] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Walter Prins
Hi Steven, Alan,

On 6 August 2013 09:44, Alan Gauld  wrote:

> On 06/08/13 09:26, Steven D'Aprano wrote:
>
>  All this is correct, but yield is more powerful than that. Not only does
>> yield get used to return values from a function, it also gets used to
>> send values *into* a running function.
>>
>
> Yikes. This is new to me too.
> When did that happen? Has yield always had these two way powers?
>

No, but having done a search myself about this just now, apparently since
about 2005:
http://www.python.org/dev/peps/pep-0342/



>
>  py> def cr():  # Co-Routine.
>> ... x = yield()
>> ... while True:
>> ... x = yield(x + 1)
>> ...
>> py> magic = cr()
>> py> magic.send(None)
>> ()
>> py> magic.send(1)
>> 2
>>
>> Prepare to have your mind expanded
>>
>
Wow, I like you Alan was aware of the basics of yield but not send etc...,
this is rather neat.  So you can also simplistically think of "send" and
yield as akin to threaded execution, where cr() is like a thread that
blocks at the yield call after creation, and then when you call on
magic.send() the "thread" wakes up and continues and eventually returns
another value to the "calling thread" and itself blocks again at the
yield?  All without using real threads anywhere?  Very very cool

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


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Saad Javed
> It looks like you're using Python 2, but you didn't specify.
>
> I'd probably do something like this:
>
> #!/usr/bin/env python
>
> MAX_LENGTH = 140
>
> users = [
> "saad", "asad", "sherry", "danny", "ali", "hasan", "adil",
> "yousaf",
> "maria", "bilal", "owais",
> ]
>
> def populate():
> message = raw_input("Enter string: ")
> while users:
> new_message = " ".join([message, "@" + users.pop(0)])
> if len(new_message) > MAX_LENGTH:
> break
> message = new_message
> return message
>
> if __name__ == "__main__":
> print(populate())
>

It will add max no. of  users to one tweet until limit is reached. I want
all users added to the tweet. E.g. if 4 users can be added to the tweet
before reaching the limit, return three tweets...first two with 4 users
attached and the last one with three. Think of it as sending the same tweet
with all the users in the list mentioned. The code I posted does that but
can only add 3 users at a time. I want it to be able to calculate maximum
no of users it can attach to the tweet and then keep doing it until the
list runs out. Hope i've explained my problem. And yes, i'm using python 2.

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


Re: [Tutor] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Alan Gauld

On 06/08/13 10:01, Walter Prins wrote:


py> def cr():  # Co-Routine.
... x = yield()
... while True:
... x = yield(x + 1)
...



"send" and yield as akin to threaded execution, where cr() is like a
thread that blocks at the yield call after creation, and then when you
call on magic.send() the "thread" wakes up and continues and eventually
returns another value


It's clever but I'm not keen on it overloading yield to do it.
yield as a word conveys (to me at least) the idea of returning a value 
but not quite completely ending. This usage sounds like a different 
concept and I'd have preferred a more explicit name - although I can't 
think what!! Also I'm not keen on the argument/parameter mechanism
here either. Arguments are sent but not explicitly declared in the 
receiver, that all feels rather un-pythonic to me. But I've only

skimmed it so far, I need to do some hands-on playing I think.

I am getting concerned that python is developing a lot of these
non-intuitive type features, almost because it can(*). A lot of it no 
doubt scratches somebody's itch but its at the expense of making what 
was a very easy to use language ever more complex. I'm not sure if i 
would choose Python for my Learn to Program tutorial if I was starting 
it  these days - although I'm not sure what else is any better...


(*)The same thing happened with C++ between v2 and ISO
standardization - a lot of bells n' whistles were added which made C++ 
much more complex than was good for it (or for me as a programmer!). 
Eventually you had to be a guru level coder to use it successfully. 
Python hasn't got that far yet but it seems to be in danger of it.


--
Alan G
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] adding users to tweets on a list

2013-08-06 Thread Saad Javed
> Ah, I see. Sorry, I misread your requirements. Something like this should
> work.
>
> #!/usr/bin/env python
>
> MAX_LENGTH = 140
>
>
> class TweetTooLongError(Exception):
> """
> Raised when a user would be too long to add to the tweet, even
> alone.
> """
> pass
>
>
> def generate_tweets(message, users):
> """
> Generate tweets based around a message, with users
> appended to each tweet.
>
> :param message: the base message
> :param users: a group of users to append
> :returns: tweets based around the message to the users
> """
>
> add = ""
> longest_in_list = " @" + max(users, key=len)
>
> if len(longest_in_list) + len(message) > MAX_LENGTH:
> raise TweetTooLongError(
> "At least one user would make the tweet too long."
> )
>
> while users:
> new_message = message
> while len(new_message) + len(add) <= MAX_LENGTH:
> new_message += add
> if not users:
> break
> add = " @" + users.pop(0)
> yield new_message
>
>
> if __name__ == "__main__":
> users = [
> "saad", "asad", "sherry", "danny", "ali", "hasan", "adil",
> "yousaf", "maria", "bilal", "owais",
> ]
> message = raw_input("Enter string: ")
> print("\n".join(generate_tweets(message, users)))
>

Thank you for your response. This code has a bug.

If there is one user left in the user list, it doesn't print a tweet with
just that one user added. For example use this string: "These are my
friends living in the same city as i am. I have known them for years. They
are good people in general. They are:"...you will see that "owais" is still
in the list and is not added to a new tweet and printed.

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


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Saad Javed
> ...or, better, remove the if...break and just do:
>
> while users and len(new_message) + len(add) <= MAX_LENGTH:
>

That causes:

Enter string: These are my friends living in the same city as i am. I have
known them for years. They are good people in general. They are:
Traceback (most recent call last):
  File "chris_tweet_len.py", line 44, in 
print("\n".join(generate_tweets(message, users)))
  File "chris_tweet_len.py", line 31, in generate_tweets
while users and len(new_message) + len(add) <= MAX_LENGTH:
UnboundLocalError: local variable 'new_message' referenced before assignment

And the earlier fix now adds two users to a tweet, then one user, then two
user, then one... :(
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Saad Javed
>
> And the earlier fix now adds two users to a tweet, then one user, then two
> user, then one... :(
>

Enter string: These are my friends living in the same city as i am. I have
known them for years. They are good people in general. They are:
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @saad @asad
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @sherry
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @danny @ali
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @hasan @adil
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @yousaf
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @maria @bilal
These are my friends living in the same city as i am. I have known them for
years. They are good people in general. They are: @owais
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Saad Javed
> I don't see how that differs from your expected output...?
>
> > I want all users added to the tweet. E.g. if 4 users can be added to the
> > tweet before reaching the limit, return three tweets...first two with 4
> users
> > attached and the last one with three.
>
> You hit the 140 character limit if another user is added, so it resets to
> the
> base message and adds the next user(s) as possible.
>
> What is your expected output for that sample input?
>

Oops! My bad. The fix worked as expected. The output fooled me into
thinking it was skipping a user every second line. Actually MAX_LENGTH was
being reached in each case. I'll check the tweet.py you posted.

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


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Saad Javed
I added *len(new_message) + len(add) <= MAX_LENGTH *to the outer while loop
instead of inner which threw an error. Your code works as expected. Thanks
a lot!

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


Re: [Tutor] adding users to tweets on a list

2013-08-06 Thread Dave Angel
Saad Javed wrote:

> I want to add users to the tweet from the list, the no. of users added
> based on the length of the tweet.
>
This version should be a bit cleaner than what I've seen on this thread.

#!/usr/bin/env python

LIMIT = 140
#(I use uppercase there to show it's a constant)

def send(message, users):
output = message
while users:
while users and 1+len(output+users[0]) < LIMIT:
output += " " + users.pop(0)
if output == message:
print "message too long for user", user[0]
raise userError
print output
output = message

lst = ['@saad', '@asad', '@sherry', '@danny', '@ali', '@hasan',
'@adil', '@yousaf', '@maria', '@bilal', '@owais']


#string = raw_input('enter string: ')
#example string
string = ("These are my friends living in the same city as i am."
" I have known them for years. They are "
"good people in general. They are:")

send(string, lst)

BTW, you have a bunch of other messages on the thread which are replying
to the invisible man, posts that aren't (yet?) visible.  Since you quote
him without attribution, we have no clue who you're commenting about.

-- 
DaveA


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


Re: [Tutor] How to extract numerator and denominator from fractions.Fraction(4, 32)?

2013-08-06 Thread Alan Gauld

On 06/08/13 18:56, Oscar Benjamin wrote:


 py> def cr():  # Co-Routine.
 ... x = yield()
 ... while True:
 ... x = yield(x + 1)
 ...


I'm not keen on the argument/parameter mechanism
here either. Arguments are sent but not explicitly declared in the receiver,
that all feels rather un-pythonic to me.


I'm not really sure what you mean here.


I simply meant that the syntax for send is like a normal function call:

foo.send(someValue)

But its not obvious from the code for cr() that someValue will get 
assigned to x. (It's not even obvious that the cr() code would be 
invoked at all!)


And in the last line I'm still not sure (I've not had time to play yet) 
but I think it's saying:


"return someValue+1 and assign that result to x ready for the next 
iteration of the cr() function."


At least, that's what I read it to mean. So x which looks like a regular 
local variable assigned the result of yield() suddenly acquires the 
value of the argument to send(). That's not intuitive and it's not 
explicit (It breaks with the Python credo - explicit is better than 
implicit).


It all seems a bit like too much magic going on for most beginners to 
understand. And while it's true they don't have to use it, it's easy for 
beginners to hit that kind of thing by accident, have their code "work" 
(no errors) but actually do something very different to what they 
expect. Now, in this case they have to call send(), which in itself is 
not an intuitive thing to do accidentally but I shudder to think how I 
would explain all that to a newbie who did stumble upon it! (Maybe by 
cut n' pasting code from a forum/thread somewhere?)



--
Alan G
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