Re: [Tutor] HELP PLEASE

2019-08-13 Thread David L Neil

On 13/08/19 7:11 AM, Marissa Russo wrote:

This is my code:

import math

def get_numbers():
 print("This program will compute the mean and standard deviation")
 file1 = input("Please enter the first filename: ")
 file2 = input("Please enter the second filename: ")
 x = open(file1, "r")
 y = open(file2, "r")
 nums = x.readlines()
 nums2 = y.readlines()

 return nums, nums2



Do you understand the concept of a "loop" - Code which is repeated as 
many times as necessary?


How many files must be opened, read, and then averaged?



def to_ints(strings):
 num_copy = []
 for num in nums:
 num_copy.append(float(num))
 return num_copy

 return to_ints(nums), to_ints(nums2)


What is the purpose of this line, given that the previous line has 
returned to the calling code?


Have I missed something? When is to_ints() used?



def mean(nums):
 _sum = 0
 return(sum(nums)/len(nums))

def main():
 data = get_numbers()
 m = mean(data[0])


Do you know what data[ 0 ] (or [ 1 ]) contains?
Might this knowledge be helpful?



 m2 = mean(data[1])
 print("The mean of the first file is: ", m)
 print("The mean of the second file is: ", m2)
main()


This is the output of my updated code:

Traceback (most recent call last):
   File "/Applications/Python 3.7/exercises .py", line 37, in 
 main()
   File "/Applications/Python 3.7/exercises .py", line 33, in main
 m = mean(data[0])
   File "/Applications/Python 3.7/exercises .py", line 29, in mean
 return(sum(nums)/len(nums))
TypeError: unsupported operand type(s) for +: 'int' and 'str'


What do you think "TypeError" means? Do you know the difference between 
an "int" and a "str[ing]"?


Given that both sum() and len() return numbers, what do you think is the 
"str"? Might this refer back to the earlier suggestion that you need to 
'see' the data being read?


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


Re: [Tutor] HELP PLEASE

2019-08-13 Thread Cameron Simpson

On 12Aug2019 15:11, Marissa Russo  wrote:

This is my code:


Thank you.


This is the output of my updated code:
Traceback (most recent call last):
 File "/Applications/Python 3.7/exercises .py", line 37, in 
   main()
 File "/Applications/Python 3.7/exercises .py", line 33, in main
   m = mean(data[0])
 File "/Applications/Python 3.7/exercises .py", line 29, in mean
   return(sum(nums)/len(nums))
TypeError: unsupported operand type(s) for +: 'int' and 'str'


Thank you for this as well, it makes things much clearer.

So, to your code:


import math


Just a remark: you're not using anything from this module. I presume you 
intend to later.



def get_numbers():
   print("This program will compute the mean and standard deviation")
   file1 = input("Please enter the first filename: ")
   file2 = input("Please enter the second filename: ")
   x = open(file1, "r")
   y = open(file2, "r")
   nums = x.readlines()
   nums2 = y.readlines()


As has been mentioned in another reply, readlines() returns a list of 
strings, one for each line of text in the file.


In order to treat these as numbers you need to convert them.


   return nums, nums2

def to_ints(strings):
   num_copy = []
   for num in nums:
   num_copy.append(float(num))
   return num_copy


This returns a list of floats. You might want to rename this function to 
"to_floats". Just for clarity.



   return to_ints(nums), to_ints(nums2)


This isn't reached. I _think_ you need to put this line at the bottom of 
the get_numbers function in order to return two lists of numbers. But it 
is down here, not up there.



def mean(nums):
   _sum = 0
   return(sum(nums)/len(nums))


This is the line raising your exception. The reference to "+" is because 
sum() does addition. It starts with 0 and adds the values you give it, 
but you're handing it "nums".


Presently "nums" is a list of strings, thus the addition of the initial 
0 to a str in the exception message.


If you move your misplaced "return to_ints(nums), to_ints(nums2)" 
statement up into the get_numbers function you should be better off, 
because then it will return a list of numbers, not strings.


Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] HELP PLEASE

2019-08-13 Thread Sithembewena L. Dube
Hi Marissa,

I really think that you could consider doing an introductory Python
tutorial and then venture back into solving this problem.

Understanding concepts like data types, function syntax and loops makes all
the difference in approaching programming challenges.

Here is a decent and free online Python tutorial to get you going:
https://www.learnpython.org/


Kind regards,
Sithembewena Dube


*Sent with Shift
*

On Tue, Aug 13, 2019 at 12:47 PM Cameron Simpson  wrote:

> On 12Aug2019 15:11, Marissa Russo  wrote:
> >This is my code:
>
> Thank you.
>
> >This is the output of my updated code:
> >Traceback (most recent call last):
> >  File "/Applications/Python 3.7/exercises .py", line 37, in 
> >main()
> >  File "/Applications/Python 3.7/exercises .py", line 33, in main
> >m = mean(data[0])
> >  File "/Applications/Python 3.7/exercises .py", line 29, in mean
> >return(sum(nums)/len(nums))
> >TypeError: unsupported operand type(s) for +: 'int' and 'str'
>
> Thank you for this as well, it makes things much clearer.
>
> So, to your code:
>
> >import math
>
> Just a remark: you're not using anything from this module. I presume you
> intend to later.
>
> >def get_numbers():
> >print("This program will compute the mean and standard deviation")
> >file1 = input("Please enter the first filename: ")
> >file2 = input("Please enter the second filename: ")
> >x = open(file1, "r")
> >y = open(file2, "r")
> >nums = x.readlines()
> >nums2 = y.readlines()
>
> As has been mentioned in another reply, readlines() returns a list of
> strings, one for each line of text in the file.
>
> In order to treat these as numbers you need to convert them.
>
> >return nums, nums2
> >
> >def to_ints(strings):
> >num_copy = []
> >for num in nums:
> >num_copy.append(float(num))
> >return num_copy
>
> This returns a list of floats. You might want to rename this function to
> "to_floats". Just for clarity.
>
> >return to_ints(nums), to_ints(nums2)
>
> This isn't reached. I _think_ you need to put this line at the bottom of
> the get_numbers function in order to return two lists of numbers. But it
> is down here, not up there.
>
> >def mean(nums):
> >_sum = 0
> >return(sum(nums)/len(nums))
>
> This is the line raising your exception. The reference to "+" is because
> sum() does addition. It starts with 0 and adds the values you give it,
> but you're handing it "nums".
>
> Presently "nums" is a list of strings, thus the addition of the initial
> 0 to a str in the exception message.
>
> If you move your misplaced "return to_ints(nums), to_ints(nums2)"
> statement up into the get_numbers function you should be better off,
> because then it will return a list of numbers, not strings.
>
> Cheers,
> Cameron Simpson 
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] HELP PLEASE

2019-08-13 Thread Alan Gauld via Tutor
On 13/08/2019 12:09, Sithembewena L. Dube wrote:
> Hi Marissa,
> 
> I really think that you could consider doing an introductory Python
> tutorial and then venture back into solving this problem.

>>> This is the output of my updated code:
>>> Traceback (most recent call last):
>>>  File "/Applications/Python 3.7/exercises .py", line 37, in 
>>>main()

Based on the file name I suspect she is already doing some kind of
tutorial. However, you are right about needing to review some of the
basic concepts.

As a plug I'll just mention my own tutorial linked in my .sig below :-)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] cgi module help

2019-08-13 Thread Peter Otten
rmli...@riseup.net wrote:

> I have a question about the cgi module.
> 
> I'm trying to retrieve post data as a nested dictionary from client
> code.
> 
> For instance:
> 
> 
> 
> """client code"""
> from requests import sessions
> from datetime import datetime
> 
> session = sessions.Session()
> date = str(datetime.now())
> msg_id = 0001
> message = {"metadata": {"date": date, "id": msg_id}}
> session.post(data=message)

I made the above post to the server I found here

https://gist.github.com/mdonkers/63e115cc0c79b4f6b8b3a6b797e485c7

and got the following output:


$ python3 server.py 8080
INFO:root:Starting httpd...

INFO:root:POST request,
Path: /
Headers:
Host: localhost:8080
Content-Length: 25
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/2.2.1 CPython/2.7.6 Linux/3.13.0-170-generic



Body:
metadata=date&metadata=id

127.0.0.1 - - [13/Aug/2019 17:45:35] "POST / HTTP/1.1" 200 -

It looks like the data doesn't even get through.


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


Re: [Tutor] class functions/staticmethod?

2019-08-13 Thread Cameron Simpson

On 11Aug2019 22:58, James Hartley  wrote:

I am lacking in understanding of the @staticmethod property.
Explanation(s)/links might be helpful.  I have not found the descriptions
found in the Internet wild to be particularly instructive.


You have received some answers; to me they seem detailed enough to be 
confusing.


I think of things this way: what context does a method require?  Not 
everything needs the calling instance.


Here endeth the lesson.



All this stuff below is examples based on that criterion:

Here's a trite example class:

 class Rectangle:
   def __init__(self, width, height):
 self.width=width
 self.height = height

Most methods do things with self, and are thus "instance methods", the 
default. They automatically receive the instance used to call them as 
the first "self" argument.


 def area(self):
   return self.width * self.height

They need "self" as their context to do their work.

Some methods might not need an instance as context: perhaps they return 
information that is just based on the class, or they are factory methods 
intended to return a new instance of the class. Then you might use a 
@classmethod decorator to have the calling instance's class as the 
context.


 @classmethod
 def from_str(cls, s):
   width, height = parse_an_XxY_string(s)
   return cls(width, height)

And some methods do not need the class or the instance to do something 
useful:


 @staticmethod
 def compute_area(width, height):
   return width * height

and so we don't give them the instance or the class as context.

Now, _why_?

Instance methods are obvious enough - they exist to return values 
without the caller needing to know about the object internals.


Class methods are less obvious.

Consider that Python is a duck typed language: we try to arrange that 
provided an object has the right methods we can use various different 
types of objects with the same functions. For example:


 def total_area(flat_things):
   return sum(flat_thing.area() for flat_thing in flat_things)

That will work for Rectangles and also other things with .area() 
methods. Area, though, is an instance method.


Class methods tend to come into their own with subclassing: I 
particularly use them for factory methods.


Supposing we have Rectangles and Ellipses, both subclasses of a 
FlatThing:


 class FlatThing:
   def __init__(self, width, height):
 self.width=width
 self.height = height
 @classmethod
 def from_str(cls, s):
   width, height = parse_an_XxY_string(s)
   return cls(width, height)

 class Rectangle(FlatThing):
   def area(self):
 return self.width * self.height

 class Ellipse(FlatThing):
   def area(self):
 return self.width * self.height * math.PI / 4

See that from_str? It is common to all the classes because they can all 
be characterised by their width and height. But I require the class for 
context in order to make a new object of the _correct_ class. Examples:


 rect = Rectangle.from_str("5x9")
 ellipse = Ellipse.from_str("5x9")
 ellispe2 = ellipse.from_str("6x7")

Here we make a Rectangle, and "cls" is Rectangle when you call it this 
way. Then we make an Ellipse, and "cls" is Ellipse when called this way.  
And then we make another Ellipse from the first ellipse, so "cls" is 
again "Ellipse" (because "ellipse" is an Ellipse).


You can see that regardless of how we call the factory function, the 
only context passed is the relevant class.


And in the last example (an Ellipse from an existing Ellipse), the class 
comes from the instance used to make the call. So we can write some 
function which DOES NOT KNOW whether it gets Ellipses or Rectangles:


 def bigger_things(flat_things):
   return [ flat_thing.from_str(
  "%sx%s" % (flat_thing.width*2, flat_thing.height*2))
for flat_thing in flat_things
  ]

Here we could pass in a mix if Rectangles or Ellipses (or anything else 
with a suitable from_str method) and get out a new list with a matching 
mix of bigger things.


Finally, the static method.

As Peter remarked, because a static method does not have the instance or 
class for context, it _could_ be written as an ordinary top level 
function.


Usually we use a static method in order to group top level functions 
_related_ to a specific class together. It also helps with imports 
elsewhere.


So consider the earlier:

 @staticmethod
 def compute_area(width, height):
   return width * height

in the Rectangle class. We _could_ just write this as a top level 
function outside the class:


 def compute_rectangular_area(width, height):
   return width * height

Now think about using that elsewhere:

 from flat_things_module import Rectangle, Ellipse, compute_rectangular_area

 area1 = compute_rectangular_area(5, 9)
 area2 = Rectangle.compute_area(5, 9)
 area3 = Ellipse.compute_area(5, 9)

I would rather use the forms of "area2" and "area3" because it is clear 
that I'm getting an area function from a nicely named class. (Also

Re: [Tutor] class functions/staticmethod?

2019-08-13 Thread Steven D'Aprano
On Wed, Aug 14, 2019 at 09:58:35AM +1000, Cameron Simpson wrote:
> On 11Aug2019 22:58, James Hartley  wrote:
> >I am lacking in understanding of the @staticmethod property.
> >Explanation(s)/links might be helpful.  I have not found the descriptions
> >found in the Internet wild to be particularly instructive.
> 
> You have received some answers; to me they seem detailed enough to be 
> confusing.

Its only confusing if you don't work your way through it carefully and 
systematically. There's a lot to understand, but if you don't understand 
it, Python's behaviour in this case seems counter-intuitive and hard to 
follow.

Python makes the behaviour of regular instance methods so simple and 
intuitive, it can be quite a blow when you try to do something that 
isn't.


> I think of things this way: what context does a method require?  Not 
> everything needs the calling instance.
> 
> Here endeth the lesson.

Given that you go on to write almost another 150 lines of explanation, I 
think a better description would be "Here *begins* the lesson" *wink*


Your lesson, I think, assumes that it is obvious that staticmethods 
don't have access to the calling instance, or its class. But if you look 
at James' code, I think you will agree that he's assuming that 
staticmethods *do* have access to the calling class, and is perplexed by 
the fact that the look-up of class variables (class attributes) fails.

If James comes from a Java background, he's probably assuming that 
static methods do have access to the class variables, using undotted 
names:

class K(object):
attr = 1
@staticmethod
def foo():
return attr

In Java, K.foo() would return 1.

Your lesson gives us no clue why James' first method, "dimensions()", 
which he describes as a "class method", isn't a class method and doesn't 
actually work correctly, even though it appears to at first glance.


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


Re: [Tutor] class functions/staticmethod?

2019-08-13 Thread Cameron Simpson

On 14Aug2019 11:15, Steven D'Aprano  wrote:

On Wed, Aug 14, 2019 at 09:58:35AM +1000, Cameron Simpson wrote:

On 11Aug2019 22:58, James Hartley  wrote:
>I am lacking in understanding of the @staticmethod property.
>Explanation(s)/links might be helpful.  I have not found the descriptions
>found in the Internet wild to be particularly instructive.

You have received some answers; to me they seem detailed enough to be
confusing.


Its only confusing if you don't work your way through it carefully and
systematically. There's a lot to understand, but if you don't understand
it, Python's behaviour in this case seems counter-intuitive and hard to
follow.


Yeah, but it helps to understand the objective: function context.

A deep dive into the mechanisms used to achieve that is a load to 
ingest. High levels of detail tend to swamp one's view of the larger 
picture, particularly when learning.


[...]

I think of things this way: what context does a method require?  Not
everything needs the calling instance.

Here endeth the lesson.


Given that you go on to write almost another 150 lines of explanation, I
think a better description would be "Here *begins* the lesson" *wink*


Well, maybe, but I really wanted to highlight the objective: 
@classmethod and @staticmethod dictate the context provided to the 
method.


All the examples that follow aim, however vaguely, to show those 
contexts in action.



Your lesson, I think, assumes that it is obvious that staticmethods
don't have access to the calling instance, or its class.


No, it aims to make that point clear. EVerything else is example or 
mechanism.



But if you look
at James' code, I think you will agree that he's assuming that
staticmethods *do* have access to the calling class, and is perplexed by
the fact that the look-up of class variables (class attributes) fails.


Because nobody had said that @staticmethod and @classmethod _define_ the 
provided context.



Your lesson gives us no clue why James' first method, "dimensions()",
which he describes as a "class method", isn't a class method and doesn't
actually work correctly, even though it appears to at first glance.


I didn't try to tackle his code. I think it is better to get the 
intended use of @classmethod and @staticmethod clear. Digging into 
whatever weird consequences there might be to his slightly wrong code 
just brings confusion.


Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor