Re: [Tutor] When you think to setup the __class__ of a module object to a subclass of ModuleType

2019-04-25 Thread Arup Rakshit

On 25/04/19 3:52 AM, Alan Gauld via Tutor wrote:

On 24/04/2019 12:22, Arup Rakshit wrote:

In the simple code like what are the advantages we get from?

I'm not really sure what you are asking about?
Ok. My question is that when people add such a class to the module? What 
is the goal/intention they met by setting such __class__ attribute of a 
module. The documentation I am reading just shown this technique but 
didn't dig into this. They didn't explain why/when should we use this 
technique, but the how.



Is this so that we can implement more special methods
than just __getattr__ and __dir__ in the module level?

Is it just the inheritance from ModuleType?

Or is it the assignment of the __class__ attribute?

Yes the reason of this assignment.


Or something else?


import sys
from types import ModuleType

class VerboseModule(ModuleType):
 def __repr__(self):
 return f'Verbose {self.__name__}'
 
 def __setattr__(self, attr, value):

 print(f'Setting {attr}...')
 super().__setattr__(attr, value)
sys.modules[__name__].__class__ = VerboseModule

There are many things in Python that are not generally used
by ordinary Python programmers. In many cases these are things
used by the core developers or are intended for advanced meta
programming type tasks. As a general rule of thumb any time
you see code that accesses dunder attributes (ie those with
leading and trailing __ markers) directly it's probably an
advanced technique you are unlikely to ever need...


That's a good catch. I am currently reading 
https://docs.python.org/3/reference/index.html source, and it seems like 
they touched everything possible in Python, without saying which is 
advance and which is basic part. Very often I get stuck, and coming here 
to ask and understand it. As the author didn't give the hints anything 
about what is advanced part, I am assuming these all a Python developer 
should know irrespective of their years of Python experience and keep 
readiing. But it feels like a lot in one go.





But if you want to increase your understanding carry on
asking but please be as specific as possible about what
it is you want the answer to.



--
Thanks,

Arup Rakshit

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


Re: [Tutor] When you think to setup the __class__ of a module object to a subclass of ModuleType

2019-04-25 Thread Steven D'Aprano
On Thu, Apr 25, 2019 at 11:30:28AM +0530, Arup Rakshit wrote:
> On 25/04/19 3:52 AM, Alan Gauld via Tutor wrote:
> >On 24/04/2019 12:22, Arup Rakshit wrote:
> >>In the simple code like what are the advantages we get from?
> >I'm not really sure what you are asking about?
>
> Ok. My question is that when people add such a class to the module? What 
> is the goal/intention they met by setting such __class__ attribute of a 
> module. The documentation I am reading just shown this technique but 
> didn't dig into this. They didn't explain why/when should we use this 
> technique, but the how.

Can to share which documentation you are reading? I've been using Python 
since version 1.5, and I've never heard of this technique.

Thanks.

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


Re: [Tutor] When you think to setup the __class__ of a module object to a subclass of ModuleType

2019-04-25 Thread Arup Rakshit

On 25/04/19 1:21 PM, Steven D'Aprano wrote:

On Thu, Apr 25, 2019 at 11:30:28AM +0530, Arup Rakshit wrote:

On 25/04/19 3:52 AM, Alan Gauld via Tutor wrote:

On 24/04/2019 12:22, Arup Rakshit wrote:

In the simple code like what are the advantages we get from?

I'm not really sure what you are asking about?

Ok. My question is that when people add such a class to the module? What
is the goal/intention they met by setting such __class__ attribute of a
module. The documentation I am reading just shown this technique but
didn't dig into this. They didn't explain why/when should we use this
technique, but the how.

Can to share which documentation you are reading? I've been using Python
since version 1.5, and I've never heard of this technique.

Thanks.


Hello Steven,

Here it is: *3.3.2.1. Customizing module attribute access* 
(https://docs.python.org/3/reference/datamodel.html#customizing-module-attribute-access)


--
Thanks,

Arup Rakshit

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


[Tutor] module import from a packager works inconsistent between REPL and command line

2019-04-25 Thread Arup Rakshit
I have a small app like this:

pizza-shop$ tree .
.
└── pizzapy
├── __init__.py
├── menu.py
└── pizza.py

1 directory, 3 files

# menu.py 

from typing import List
from pizza import Pizza

MENU: List[Pizza] = [
Pizza('Margherita', 30, 10.0),
Pizza('Carbonara', 45, 14.99),
Pizza('Marinara', 35, 16.99),
]

if __name__ == '__main__':
print(MENU)

# pizza.py 

import math

class Pizza:
name: str = ''
size: int = 0
price: float = 0

def __init__(self, name: str, size: int, price: float) -> None:
self.name = name
self.size = size
self.price = price

def area(self) -> float:
return math.pi * math.pow(self.size / 2, 2)

def awesomeness(self) -> int:
if self.name == 'Carbonara':
return 9000

return self.size // int(self.price) * 100

print('pizza.py module name is %s' % __name__)

if __name__ == '__main__':
print('Carbonara is the most awesome pizza.')


Now when I call the menu.py from command like it works as expected.

pizza-shop$ python3 pizzapy/menu.py 
pizza.py module name is pizza
[, , 
]

But it fails in REPL:

pizza-shop$ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:15) 
[Clang 10.0.1 (clang-1001.0.46.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from  pizzapy import menu
Traceback (most recent call last):
  File "", line 1, in 
  File "/Users/aruprakshit/python_playground/pizza-shop/pizzapy/menu.py", line 
2, in 
from pizza import Pizza
ModuleNotFoundError: No module named 'pizza'
>>> 


What is the reason of this inconsistency ?


Thanks,

Arup Rakshit
a...@zeit.io



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


[Tutor] help with colormode

2019-04-25 Thread Mark Alderson
hi

Ihave a very small program.  I want to cycle colours.  I cant set the colormode 
from 1 to 255

tried screen.colormode(255)

tells me screen is not defined.  the program works without the colormode, but i 
want to use it.

I just change the a and b variable values to generate new art.

-code-
from turtle import Turtle
t = Turtle()
t.speed(0)

b = 180

a = 35

colormode(255)

t.color((55,55,55))
for i in range(200):
t.circle(i,a)
t.right(b)
t.circle(i,a)


#input('Press any key to continue...')

-

===error===
Traceback (most recent call last):
  File "H:\python\snowflake.py", line 9, in 
screen.colormode(255)
NameError: name 'screen' is not defined
===

any help would be appreciated,
thanks

Mark

City of Glasgow College | Scottish Charity Number SCO36198 | VAT Number 
59677128 DISCLAIMER :- This email, together with any attachments, may be 
confidential and the subject of legal privilege. If you are not the intended 
recipient, please notify the sender of this email immediately, delete this 
message and note that you are not permitted to print, copy, disclose or use the 
content in any way. City of Glasgow College does not accept any legal 
responsibility of liability (including in negligence) for the contents of this 
communication, nor does it endorse or accept any personal views represented 
herein. Email communications may be subject to interception by third parties or 
possible data corruption and City of Glasgow College accepts no responsibility 
whatsoever for the content of communications altered after transmission from 
the college network.


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


Re: [Tutor] help with colormode

2019-04-25 Thread Peter Otten
Mark Alderson wrote:

> hi
> 
> Ihave a very small program.  I want to cycle colours.  I cant set the
> colormode from 1 to 255
> 
> tried screen.colormode(255)
> 
> tells me screen is not defined.  the program works without the colormode,
> but i want to use it.
> 
> I just change the a and b variable values to generate new art.
> 
> -code-
> from turtle import Turtle
> t = Turtle()
> t.speed(0)
> 
> b = 180
> 
> a = 35
> 
> colormode(255)
> 
> t.color((55,55,55))
> for i in range(200):
> t.circle(i,a)
> t.right(b)
> t.circle(i,a)
> 
> 
> #input('Press any key to continue...')
> 
> -
> 
> ===error===
> Traceback (most recent call last):
>   File "H:\python\snowflake.py", line 9, in 
> screen.colormode(255)
> NameError: name 'screen' is not defined
> ===

The only name you import is Turtle, so you only have that (and the built-
ins). Fortunately you can get the screen from the Turtle, so:

from turtle import Turtle

ninja = Turtle()
ninja.speed(0)

screen = ninja.screen
screen.colormode(255)

b = 180
a = 35

for i in range(200):
ninja.color((i + 55, 55, 55))
ninja.circle(i, a)
ninja.right(b)
ninja.circle(i, a)

screen.exitonclick()


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


[Tutor] str.replace error

2019-04-25 Thread Roger Lea Scherer
I'm working wtih python 3.7 on Windows 10.
I'm trying to write some code in order to clean up the data in the csv file.
Using spreadsheet language, I want to replace part of a cell ("Basic P1")
with an empty string and write it in the comments cell.
I thought assigning a variable and replacing the string would be a good
idea.

Here is my code:

import csv

with open('somefile') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in range(100):
a = "Basic P1"
str.replace(a, "")
print(next(csvReader))

I get an error:

Traceback (most recent call last):
  File "somefile", line 7, in 
str.replace(a, "")
TypeError: replace() takes at least 2 arguments (1 given)

But I think I have 2 arguments: a being the "old" argument as per the
documentation, "" being the "new" argument as per the documentation.

What am I missing?

-- 
Roger Lea Scherer
623.255.7719

  *Strengths:*
   Input, Strategic,
Responsibility,

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


Re: [Tutor] help with colormode

2019-04-25 Thread Alan Gauld via Tutor
On 25/04/2019 11:54, Mark Alderson wrote:

> tried screen.colormode(255)

Peter has shown you how to make that work but
there is a wee issue below I need to point out.

> -code-
> from turtle import Turtle
> t = Turtle()
> t.speed(0)
> 
> b = 180
> a = 35
> 
> colormode(255)
> 
> t.color((55,55,55))
> for i in range(200):
> t.circle(i,a)
> t.right(b)
> t.circle(i,a)
> 
> 
> #input('Press any key to continue...')
> 
> -
> 
> ===error===
> Traceback (most recent call last):
>   File "H:\python\snowflake.py", line 9, in 
> screen.colormode(255)
> NameError: name 'screen' is not defined
> ===

The error message clearly does not reflect the code above.
In this case its not too bad but in more complex questions
it is very important that you send the actual code that
generates the error. Otherwise we wind up just guessing
at what might be the problem.

Just something for future reference.

Regards from Stirling,
-- 
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] str.replace error

2019-04-25 Thread Alan Gauld via Tutor
On 25/04/2019 18:46, Roger Lea Scherer wrote:

> Here is my code:
> 
> import csv
> 
> with open('somefile') as csvDataFile:
> csvReader = csv.reader(csvDataFile)
> for row in range(100):

what happens if there are more rows in the file than 100?
Or even if there are less!?

> a = "Basic P1"
> str.replace(a, "")

where does str come from? You haven't assigned anything
to str, this is the first mention.

did you mean to do something like

for str in csvreader:

?


> print(next(csvReader))
> 
> I get an error:
> 
> Traceback (most recent call last):
>   File "somefile", line 7, in 
> str.replace(a, "")
> TypeError: replace() takes at least 2 arguments (1 given)

I would expect a name error. So I think the code you
sent is not the code that generated the error. But
without the original code we have no idea what str
actually is.

If it is some kind of string remember that Python strings
are immutable so to get the changed string you need
to store the result. Possibly something like:

str = str.replace(...)

> But I think I have 2 arguments: a being the "old" argument as per the
> documentation, "" being the "new" argument as per the documentation.
> 
> What am I missing?

We can't say because we can't see the code that produced the error.

-- 
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] str.replace error

2019-04-25 Thread Steven D'Aprano
On Thu, Apr 25, 2019 at 10:46:31AM -0700, Roger Lea Scherer wrote:

> with open('somefile') as csvDataFile:
> csvReader = csv.reader(csvDataFile)
> for row in range(100):
> a = "Basic P1"
> str.replace(a, "")
> print(next(csvReader))


I'm not quite sure what you expected this to do, but you've 
(deliberately? accidently?) run into one of the slightly advanced 
corners of Python: unbound methods. Apologies in advance, but this may 
be a bit technical. For a suggestion on how to fix the problem, see 
right at the end.

Normally when you call a string method, you do something like this:

mystring = "Something here"
newstring = mystring.replace("here", "there")

The technical name for the mystring.replace call is a "bound method", as 
the method is "bound" to a string instance (mystring). The method 
actually takes *three* arguments: the string to operate on, the 
substring to be replaced, and the replacement string:

   (string to operate on) . replace ( substring to be replaced, replacement )

But under the hood, what that turns into is an "unbound method" that 
calls the method attached to the *class* "str":

str.replace(string to operate on, substring to replace, replacement)

Alas, when you call an *unbound* method like this:

str.replace(a, "")

the interpreter may get a bit confused and report a slightly inaccurate 
error message:

> TypeError: replace() takes at least 2 arguments (1 given)

For technical reasons, all the counts are off by one. The error message 
should say:

TypeError: replace() takes at least 3 arguments (2 given)

but because the same error message gets used for both bound and unbound 
methods, the counts are off for unbound methods. This is an annoyance, 
but given that unbound methods are relatively rare, not a large one.

So how do you fix your code?

(1) First of all, you need a string to operate on. I'm not sure which 
string that should be -- do you want to check *every* cell? Just the 
first cell in each row? Every second row? That's up to you to decide.

(2) Secondly, strings in Python are "immutable" -- that is to say, they 
cannot be changed in place. Unlike languages like (say) Pascal, if you 
want to change the value of a string, you need to re-assign a new 
string:

a = "Hello World!"
a.upper()  # Doesn't work!!!
print(a)  # Still gives "Hello World!"

Instead you need to say a = a.upper().

(3) Unbound methods are a slightly advanced technique which you don't 
need here, so you should just use normal method call.



Putting those three changes together gives something like this:


with open('somefile') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in range(100):  # How do you know there are only 100 rows?
mystring = "Something here? ~Basic P1~ but I don't know what"
print("Before:", mystring)
mystring = mystring.replace("Basic P1", "")
print("After:", mystring)
print(next(csvReader))



Hopefully that's enough to set you on the right track. If not, please 
feel free to write back to the list and ask more questions!




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


Re: [Tutor] module import from a packager works inconsistent between REPL and command line

2019-04-25 Thread Steven D'Aprano
On Thu, Apr 25, 2019 at 05:40:18PM +0530, Arup Rakshit wrote:

> I have a small app like this:

Please simplify your code to the minimum needed to demonstrate the 
problem you are asking about. This bit is excellent:

> pizza-shop$ tree .
> .
> └── pizzapy
> ├── __init__.py
> ├── menu.py
> └── pizza.py
> 
> 1 directory, 3 files

Nicely shown!

But we don't need to see all the gory details of menu.py and especially 
not of pizza.py, all those methods in pizza.Pizza are irrelevant to the 
problem. Please read this:

http://www.sscce.org/

for a guide. It is written for Java programmers, but it applies to any 
language.

All we need in menu.py is a single line:

# menu.py 
from pizza import Pizza

because that's the line that fails.

And for pizza.py, all we need is:

# pizza.py 
Pizza = None


> Now when I call the menu.py from command like it works as expected.

When you ask Python to import a module, it doesn't search the entire 
hard drive, that could take hours if the drive is big enough. It only 
looks in the search-path. At runtime, you can see the paths searched 
like this:

import sys
print(sys.path)

which will show you where Python is looking for modules.

When you directly call a module:

python path/to/menu.py

the directory holding that module is included in the search path, so if 
you also have path/to/pizza.py the "import pizza" will work.

But in the REPL, only the default search path is used. 

In your case, the fix is, I think, to change menu.py to do this:

# was: from pizza import Pizza
from pizzapy.pizza import Pizza

which I *think* will solve the problem, but I haven't tested it.

For what it is worth, importing problems are sometimes annoying to 
solve. What works as a good design for importing libraries doesn't 
always make a good design for scripts that you call directly from the 
command line, and visa versa, so the import system is a bit of a 
compromise between the two.



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


Re: [Tutor] When you think to setup the __class__ of a module object to a subclass of ModuleType

2019-04-25 Thread Steven D'Aprano
On Thu, Apr 25, 2019 at 02:52:07PM +0530, Arup Rakshit wrote:

> Here it is: *3.3.2.1. Customizing module attribute access* 
> (https://docs.python.org/3/reference/datamodel.html#customizing-module-attribute-access)

Oh! That's brand new in 3.7, no wonder I didn't know about it.

I did see the core developers talking about adding this feature, but I 
didn't know that they had done so.

Your original question was:

> In the simple code like what are the advantages we get from? Is this 
> so that we can implement more special methods than just __getattr__ 
> and __dir__ in the module level?

Yes, that's what the documentation says. I don't see any reason not to 
believe it.

Oh, this is cool! I'm going to enjoy playing with this...


py> from types import ModuleType
py> class Magic(ModuleType):
... count = 0
... @property
... def spam(self):
... self.count += 1
... return ' '.join(['spam']*self.count)
...
py> import sys
py> sys.modules['__main__'].__class__ = Magic
py> import __main__
py> __main__.spam
'spam'
py> __main__.spam
'spam spam'
py> __main__.spam
'spam spam spam'



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