Re: [Tutor] What would be good use cases for the enum module?

2017-04-08 Thread Steven D'Aprano
On Sat, Apr 08, 2017 at 10:00:21PM -0500, boB Stepp wrote:
> After reading some discussion on the Python main list about the enum
> module and some suggested changes, I thought I would read the docs on
> it at
> https://docs.python.org/3/library/enum.html?highlight=enum#module-enum
[...]
> And I am having an even harder time imagining what I would want to use
> Enum for if I don't care about the values assigned to the names and
> use auto to automatically assign values.  I am having a real crisis of
> imagination here!  Anyone with some commonplace and practical
> applications of the enum module?

Have you read the PEP for the enum module? There's also an earlier, 
rejected PEP:

https://www.python.org/dev/peps/pep-0354/

https://www.python.org/dev/peps/pep-0435/

There are a few uses for enums where they have to behave like ints for 
compatibility with code following C conventions, but basically an enum 
is an abstract symbol with a pretty representation to make debugging 
easier.

For example, suppose I have a function that justifies a paragraph of 
text:

def justify(paragraph, where):
...

where the `where` argument specifies whether to justify the text on the 
left, on the right, in the centre, or fully justified on both sides. One 
way to specify that is to use numeric constants:

if where == 1:
# justify on the left
elif where == 2:
# justify on the right
elif where == 3:
# justify in the centre
elif where == 4:
# fully justify at both ends

but there's no connection between the numbers I choose and the type of 
justification. I could just have sensibly used -3, 87, 4 and 32.5 as 1, 
2, 3 and 4.

A bit better is to use strings:

if where == 'LEFT':
# justify on the left
elif where == 'RIGHT':
# etc

which at least now is self-documenting, but it suggests that the `where` 
argument might take any string at all, which is not correct. There are 
only four fixed values it can take. And besides, having to use the 
quotation marks is tiresome.

So let's invent four (or even five, for Americans) named constants:

LEFT = 'LEFT'
RIGHT = 'RIGHT'
CENTRE = CENTER = 'CENTRE'
FULL = 'FULLY JUSTIFIED'


Now we're getting closer. The caller can say:

text = justify(some_text, CENTRE)

which is nice, and the justify() function can include:

if where == LEFT:
...

without quotation marks, which is also nice. That solves about 95% of 
the problem.

The last niggly 5% is a subtle thing. Because the constants are strings, 
we might be tempted to do string things to them, either deliberately or 
by mistake:


justification_mode = CENTRE.lower() + LEFT[1:]  # Oops!
# much later
justify(some_text, justification_mode)


which of course will fail, but it will fail *when the string is used*, 
not when you do the string-stuff to those constants. It would be nice if 
it failed straight away, at the "justification_mode" line.

To fix that, we need something which looks like a string when you print 
it, for debugging, but actually isn't a string, so it doesn't accept all 
the usual string methods. That's effectively just an abstract symbol, 
and the way to get this in Python is with an enum.

Enums have a few other nice properties, which you may or may not care 
about, but the primary use is to act as set of related named symbols.



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


[Tutor] What would be good use cases for the enum module?

2017-04-08 Thread boB Stepp
After reading some discussion on the Python main list about the enum
module and some suggested changes, I thought I would read the docs on
it at
https://docs.python.org/3/library/enum.html?highlight=enum#module-enum

Most of the mechanics of using it, Enum in particular, seem
understandable to me, but I am having difficulty imagining where I
might want to use these features.

I did some searching and read the first few results, mostly from Stack
Overflow.  So far only a couple of situations occur to me:

1)  Seems I could have a Constants class, like:

class Constants(Enum):
PI = 3.1415
E = 2.718
etc.

2)  Or if I had a GUI, I could give names to things like radio
buttons, checklist boxes, etc., though I don't see why I would not
just use the normal indices (Which start from the usual zero, unlike
how the examples seem to be written in the enum docs.).

And I am having an even harder time imagining what I would want to use
Enum for if I don't care about the values assigned to the names and
use auto to automatically assign values.  I am having a real crisis of
imagination here!  Anyone with some commonplace and practical
applications of the enum module?

TIA!

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


Re: [Tutor] Count for loops

2017-04-08 Thread Alex Kleider

On 2017-04-08 05:49, Rafael Knuth wrote:

Dear Sama,

thank you so much for your explanation and sorry to bother you on the
same subject again.
I learn the most by taking code apart line by line, putting it
together, taking apart again, modifying it slightly ... which is
exactly what I did with your code.

On Tue, Apr 4, 2017 at 3:20 PM, D.V.N.Sarma డి.వి.ఎన్.శర్మ
 wrote:
b = "3"+b[2:]  #Removing the decimal point so that there are digits 
only in


my_number = 3.14159
my_number = "3"+my_number[2:]
print(my_number)

This is the error code I got:

== RESTART: C:/Users/Rafael/Documents/01 - BIZ/CODING/Python 
Code/PPC_56.py ==

Traceback (most recent call last):
  File "C:/Users/Rafael/Documents/01 - BIZ/CODING/Python
Code/PPC_56.py", line 2, in 
my_number = "1"+my_number[2:]
TypeError: 'float' object is not subscriptable




I am really trying to understand how to modify strings, floats and
variables from different sources.
In case of a text file, your code works, but if I apply the same to a
float assigned to a variable, it does not work.
What am I doing wrong here? Thank you so much for your patience.


The error message is telling you exactly what is wrong:
"not subscriptable"
You've tried to use string functionality on a float.
Specifically: my_number is a float.
"""my_number[2:]""" would only make sense to the interpreter if 
it("my_number", not the interpretery:-) were a string (or some other 
sequence.)

try changing your code to:
  my_number_as_a_string = "3.14159"
  my_new_number_still_a_string = "3" + my_number_as_a_string[2:]  # 
spaces added for clarity

  print(my_new_number_still_a_string)
  my_float = float(my_new_number_still_a_string)
  print(my_float)
HTH
ps warning: not tested
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Count for loops

2017-04-08 Thread Alan Gauld via Tutor
On 08/04/17 13:49, Rafael Knuth wrote:

>> b = "3"+b[2:]  #Removing the decimal point so that there are digits only in
> 
> my_number = 3.14159

Here you assign a floating point number to mmy_number but
the code Sama wrote was for working with strings read
from a text file.

You would need to convert it first:

my_number = str(3.14159)

> my_number = "3"+my_number[2:]
> print(my_number)
> 
> This is the error code I got:
> 
> == RESTART: C:/Users/Rafael/Documents/01 - BIZ/CODING/Python Code/PPC_56.py ==
> Traceback (most recent call last):
>   File "C:/Users/Rafael/Documents/01 - BIZ/CODING/Python
> Code/PPC_56.py", line 2, in 
> my_number = "1"+my_number[2:]
> TypeError: 'float' object is not subscriptable

And that is what the error tells you, that you are trying
to index a float but it should be a string.

> In case of a text file, your code works, but if I apply the same to a
> float assigned to a variable, it does not work.

That's right, the set of operations applicable to numbers is
completely different to those applicable to strings, you cannot
mix 'n match. You need to convert between the types.

-- 
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] Count for loops

2017-04-08 Thread Rafael Knuth
Dear Sama,

thank you so much for your explanation and sorry to bother you on the
same subject again.
I learn the most by taking code apart line by line, putting it
together, taking apart again, modifying it slightly ... which is
exactly what I did with your code.

On Tue, Apr 4, 2017 at 3:20 PM, D.V.N.Sarma డి.వి.ఎన్.శర్మ
 wrote:
> b = "3"+b[2:]  #Removing the decimal point so that there are digits only in

my_number = 3.14159
my_number = "3"+my_number[2:]
print(my_number)

This is the error code I got:

== RESTART: C:/Users/Rafael/Documents/01 - BIZ/CODING/Python Code/PPC_56.py ==
Traceback (most recent call last):
  File "C:/Users/Rafael/Documents/01 - BIZ/CODING/Python
Code/PPC_56.py", line 2, in 
my_number = "1"+my_number[2:]
TypeError: 'float' object is not subscriptable
>>>

I am really trying to understand how to modify strings, floats and
variables from different sources.
In case of a text file, your code works, but if I apply the same to a
float assigned to a variable, it does not work.
What am I doing wrong here? Thank you so much for your patience.



> the file
> n = len(b)
> for i in range(n-3):
> if b[i:i+4] == get_year:  # Taking 4 digit long chunks from successive
> positions in b and seeing whether they are equal to get_year
> count += 1  # If they are equal increase the count by 1
>
> regards,
> Sarma.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] want to set IDLE setting to default.

2017-04-08 Thread Peter Otten
Tianjiao Cui wrote:

> Hi, all. I have met a very annoying issue that i messed up with IDlL
> configuration. I changed "run" key in settings but i found it does not
> work and then i tried to reset it to default but i failed. Pls help me get
> rid of this problem because it has been bothering me for a while.
> Thanks.

If things are seriously messed up you can close idle, rename the 
configuration directory ~/.idlerc (the ~ is the placeholder for your user 
directory) and then start idle again. This should create a new ~/.idlerc 
directory with all defaults restored.

If everything works to your satisfaction you can delete the renamed 
directory.

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


Re: [Tutor] Tkinter class question - solved

2017-04-08 Thread Alan Gauld via Tutor
On 07/04/17 20:21, Phil wrote:

> After a bit more thought I now realise that I just 
> need to use self to reference e[][] in my check function.

You need to use self any time you access any member of your
class. So in your case:

class TestGUI:
def __init__(self, master):
self.master = master
...
self.e = [[None] * num_cols for _ in range(num_rows)]
...
self.check_button = Button(master,text="Check",
   command=self.check)
...

def check(self,array): ...

The following attributes all need to be prefixed with self
any time you access them:

self.master
self.e
self.check_button
self.check

In this specific case you only need to use self.e

HTH

-- 
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] Tkinter class question

2017-04-08 Thread Peter Otten
Phil wrote:

> On Sat, 08 Apr 2017 09:12:17 +0200
> Peter Otten <__pete...@web.de> wrote:
> 
> Thank you yet again Peter.
> 
> I realised what the answer is after taking a break for a couple of hours,
> however, I didn't know about:
> 
>> ...
>> self.check_button = Button(
>> master,
>> text="Check",
>> command=self.check_2_2  # note there's no () -- the bound
>> method # is not invoked
>> )
>> ...
>> 
> 
> My working method uses the () 

This is unlikely unless you have found out about factory methods (functions 
that return functions).

> but I will remove them and see what
> difference it makes.

Make sure you understand the difference between calling a function and 
passing around a function as a value.

def f(): return 42

a = f
b = f()

You have understood the difference if you can predict the outcome of 
all four lines below:

print(a)
print(b)
print(a())
print(b())

Once you think you know the answer try it in the interactive interpreter.

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


Re: [Tutor] Tkinter class question - solved

2017-04-08 Thread Peter Otten
Phil wrote:

> On Sat, 8 Apr 2017 02:00:38 +1000
> 
> This is one of those times where I wish I could delete a sent message.
> 
> After a bit more thought I now realise that I just need to use self to
> reference e[][] in my check function.

Relax ;) We all had to go through a learning process. 


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


Re: [Tutor] Tkinter class question

2017-04-08 Thread Phil
On Sat, 08 Apr 2017 09:12:17 +0200
Peter Otten <__pete...@web.de> wrote:

Thank you yet again Peter.

I realised what the answer is after taking a break for a couple of hours, 
however, I didn't know about:

> ...
> self.check_button = Button(
> master,
> text="Check",
> command=self.check_2_2  # note there's no () -- the bound
> method # is not invoked
> )
> ...
> 

My working method uses the () but I will remove them and see what difference it 
makes.

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


Re: [Tutor] Tkinter class question - solved

2017-04-08 Thread Phil
On Sat, 8 Apr 2017 02:00:38 +1000

This is one of those times where I wish I could delete a sent message.

After a bit more thought I now realise that I just need to use self to 
reference e[][] in my check function.

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


Re: [Tutor] Tkinter class question

2017-04-08 Thread Alan Gauld via Tutor
On 07/04/17 17:00, Phil wrote:

> ...I'm now having a problem knowing when to use the "self" reference.

self is needed every time you use an instance attribute or method.
It is equivalent to 'this' in C++(or Java), but in Python it is
never implicit you always have to explicitly specify self when accessing
a member of the class.

>  ...the function "ckeck" is called without the need to press 

Peter has addressed this.

-- 
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] Tkinter class question

2017-04-08 Thread Peter Otten
Phil wrote:

> I've progressed a little further but I'm now having a problem knowing when
> to use the "self" reference. In the following code, the function "ckeck"
> is called without the need to press the "check" button. This didn't occur
> before I sprinkled "selfs" into the code and added "array" to the "ckeck"
> function. I found that I needed "self" to point "array" to my list array
> "e" and I think that is where the fault is.
> 
> from tkinter import *
> 
> class TestGUI:
> def __init__(self, master):
<...>

> self.check_button = Button(master, text="Check",
> command=self.check(self.e))

Think hard about what the expression

command=self.check(self.e)

does. Spoiler:

The check() method is invoked, and the result is passed as the command 
argument. But what is that result?

> def check(self, array):
> print("checked")
> array[2][2].insert(0, "4")

No explicit return means the return value is None. Your above code is 
equivalent to

# print "checked" and insert "4"
self.check(self.e)
# create a button with no command
self.check_button = Button(master, text="Check", command=None)

To set a command you must define a function or method that takes no 
arguments:

class TestGUI:
def check_2_2(self):
print("checked"
self.e[2][2].insert(0, "4")

def __init__(self, master):
...
self.check_button = Button(
master,
text="Check",
command=self.check_2_2  # note there's no () -- the bound method
# is not invoked
)
...


> root = Tk()
> my_gui = TestGUI(root)
> root.mainloop()

If there are a lot of similar commands the command is often constructed by 
wrapping a method in a lambda with default arguments. Simple example:

import tkinter as tk

class TestGUI:
def __init__(self, master):
for i in range(5):
button = tk.Button(
master, 
text="Button {}".format(i),
command=lambda n=i: self.button_pressed(n)
)
button.grid(row=i, column=0)

def button_pressed(self, n):
print("You pressed button {}".format(n))

root = tk.Tk()
test = TestGUI(root)
root.mainloop()

There's also functools.partial() which can be used to the same effect

command=functools.partial(self.button_pressed, i)

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