Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
Terry,

> Not really.  The resulting global objects do not normally take enough 
> space to worry about on normal modern desktops.

For some reason I still aim to keep my (running) programs as small as 
possible - even though the ammount of memory has grown more than a 
thousandfold since I started programming.  Old habits die hard.

> Standard for in-file test is
[snip]

Any reason to put the testcode in a procedure instead of just have it 
directly follow the "if __name__ == '__main__' " test ?

> The PEP 8 convention (except for basic builtin data structures like int, 
> str, list, tuple, set, and dict) is TitleCase.

Thanks.

> Follow or not as you wish.

:-) If I ever want/need to share my code with others (or post here as part 
of a question) it is a good idea to conform to certain standards to keep it 
easily readable.  It will take some getting acustomed to though, as every 
language seems to have its own way to do it  (I myself prefer single prefix 
chars to indicate the variables intended type).

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
DL,

> Some of this you will know. (Hopefully) some will be 'new':

Some of it is known to me, and indeed I do hope that there will be new stuff 
in there too.  Its why I took up Python. :-)

Thanks for the explanation (including the aliassing I wasn't aware of) and 
the links.

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
Greg,

>>> Are you sure there's a difference between classes and functions here?
>>
>> Yes, quite sure.
>
> And we're even more sure that there isn't. :-)

As it turned out "we're" are right, and I was thrown off by the error 
message. :-p

The problem is that I had no idea why I got that (rather explicit) error 
message, and took it by its face-value - sending me of in the wrong 
direction.

The actual caise ?  I made a mistake by, in the testcode (which I had not 
blocked off) in the imported file creating an instance with the exact same 
name as the class.   The deleting of that instance at the end of the 
testcode somehow caused the class to disappear as well, resulting in the 
"can't find it" error.

To be honest, I was not aware/did not assume that I could delete a class 
definition that way (I even find it a bit weird, but as I'm a newbie in 
regard to Python that does not say much).

Bottom line: I was caught by my own choice to give the instance the exact 
same name as the class. :-\

>You'll find that *any* form of import executes all the top-level code.

Thats certainly something I did not expect.

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread Greg Ewing

On 9/12/19 9:15 pm, R.Wieser wrote:

To be honest, I was not aware/did not assume that I could delete a class
definition that way (I even find it a bit weird, but as I'm a newbie in
regard to Python that does not say much).


Python is very dynamic. The class statement is actually an executable
statement that creates a class object and binds it to a name. There's
nothing stopping you from subsequently rebinding that name to some
other object, or deleting it altogether.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread Terry Reedy

On 12/9/2019 2:36 AM, R.Wieser wrote:

Terry,

Standard for in-file test is

[snip]

Any reason to put the testcode in a procedure instead of just have it
directly follow the "if __name__ == '__main__' " test ?


One can, for instance, interactively do

>>> import mod
>>> mod.test()

and explore the contents of mod, perhaps depending on the result of test()

def test(): ... also marks the code as test code rather than, for 
instance, command-line or setup code.  Putting such alternative code in 
function 'main' has the same effect.


For instance, 3.x has idlelib.__main__, which has something like

from idlelib.pyshell import main
main()

so than one can run 3.x IDLE from a command line with 'python -m idlelib'.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
Python,

> Child *depends* on Parent.

I'm sorry, but without any kind of underbuilding statements like that are of 
no value to me I'm afraid.

Also: if I can just copy-and-paste the class into the file which origionally 
included it and have the whole program run without a problem than that 
dependency upon its origional parent doesn't seem to mean all too much (if 
anything at all).

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
Greg,

> There's nothing stopping you from subsequently rebinding that name to some 
> other object, or deleting it altogether.

Which is something I did not expect.  But running into is what makes doing 
something new interesting. :-)

And I just realized something else: I just assumed that the "del instance" 
command did something more than it should, but there is a good chance that 
the mere action of creating an instance with the same name as the class made 
the classname disappear from the internal availability list, and not return 
after the instance (and I assume its name too) got deleted.

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


python 3 prefix to infix without too many parethesis

2019-12-09 Thread jezkator
Hi, I have got a problem.
I wrote a code for prefix to infix. It works, but I need improve it
so on input there will be only necessary parentheses. Can u help me?
Here is the code:

import re
a = input()

class Calculator:

def __init__ (self):
self.stack = []

def push (self, p):
if p in ['+', '-', '*', '/', "**"]:
op1 = self.stack.pop ()
op2 = self.stack.pop ()
self.stack.append ('(%s%s%s)' % (op1, p, op2))


print("op1 =", op1)
print("op2 =", op2)
print("p=", p)
print(self.stack)

else:
self.stack.append (p)


def convert (self, l):
l.reverse ()
for e in l:
self.push (e)
return self.stack.pop ()

c = Calculator ()

print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a)))


input is like /-*+*++**85 27 39 87 65 65 37 63 91

-- 
https://mail.python.org/mailman/listinfo/python-list


More efficient/elegant branching

2019-12-09 Thread Musbur

Hello,

I have a function with a long if/elif chain that sets a couple of 
variables according to a bunch of test expressions, similar to function 
branch1() below. I never liked that approach much because it is clumsy 
and repetetive, and pylint thinks so as well. I've come up with two 
alternatives which I believe are less efficient due to the reasons given 
in the respective docstrings. Does anybody have a better idea?


def branch1(a, b, z):
"""Inelegant, unwieldy, and pylint complains
about too many branches"""
if a > 4 and b == 0:
result = "first"
elif len(z) < 2:
result = "second"
elif b + a == 10:
result = "third"
return result

def branch2(a, b, z):
"""Elegant but inefficient because all expressions
are pre-computed althogh the first one is most likely
to hit"""
decision = [
(a > 4 and b == 0, "first"),
(len(z) < 2,   "second"),
(b + a == 10,  "third")]
for (test, result) in decision:
if test: return result

def branch3(a, b, z):
"""Elegant but inefficient because expressions
need to be parsed each time"""
decision = [
("a > 4 and b == 0", "first"),
("len(z) < 2",   "second"),
("b + a == 10",  "third")]
for (test, result) in decision:
if eval(test): return result
(env) [dh@deham01in015:~/python/rscl_fdc/devel]$

--
https://mail.python.org/mailman/listinfo/python-list


Re: More efficient/elegant branching

2019-12-09 Thread Chris Angelico
On Mon, Dec 9, 2019 at 10:36 PM Musbur  wrote:
>
> Hello,
>
> I have a function with a long if/elif chain that sets a couple of
> variables according to a bunch of test expressions, similar to function
> branch1() below. I never liked that approach much because it is clumsy
> and repetetive, and pylint thinks so as well. I've come up with two
> alternatives which I believe are less efficient due to the reasons given
> in the respective docstrings. Does anybody have a better idea?
>
> def branch1(a, b, z):
>  """Inelegant, unwieldy, and pylint complains
>  about too many branches"""
>  if a > 4 and b == 0:
>  result = "first"
>  elif len(z) < 2:
>  result = "second"
>  elif b + a == 10:
>  result = "third"
>  return result

If the branches are completely independent, there's not really a lot
you can do differently. I'd rewrite these as return statements rather
than assigning to a variable and returning it at the end (which also
allows you to make them 'if' rather than 'elif'), but that's a
marginal gain. This is the sort of thing that tends to fall into the
category of "inherent complexity" - the code is complex because the
problem it's solving is complex. Imagine trying to write a function
that tells you whether to hold or tap a button:

def button_action(color, word):
if color == "blue" and word == "Abort":
return "Hold"
if battery_count() > 1 and word == "Detonate":
return "Tap"
if color == "white" and "CAR" in indicators:
return "Hold"
if battery_count() > 2 and "FRK" in indicators:
return "Tap"
if color == "yellow":
return "Hold"
if color == "red" and word == "Hold":
return "Tap"
return "Hold"

You might be able to simplify this very slightly, but the conditions
are sufficiently varied that you can't really gain much, and they are
strictly ordered. The code here has as much complexity as the problem
it's solving, so you may as well just silence your linter's warnings
and carry on.

And yes, this sort of thing happens ALL THE TIME in real-world code.

https://thedailywtf.com/articles/The-Mythical-Business-Layer

IMO your code's fine. :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: More efficient/elegant branching

2019-12-09 Thread Peter Otten
Musbur wrote:

> Hello,
> 
> I have a function with a long if/elif chain that sets a couple of
> variables according to a bunch of test expressions, similar to function
> branch1() below. I never liked that approach much because it is clumsy
> and repetetive, and pylint thinks so as well. I've come up with two
> alternatives which I believe are less efficient due to the reasons given
> in the respective docstrings. Does anybody have a better idea?
> 
> def branch1(a, b, z):
>  """Inelegant, unwieldy, and pylint complains
>  about too many branches"""
>  if a > 4 and b == 0:
>  result = "first"
>  elif len(z) < 2:
>  result = "second"
>  elif b + a == 10:
>  result = "third"
>  return result

I agree with Chris that this is the way to go.
pylint be damned ;)

> 
> def branch2(a, b, z):
>  """Elegant but inefficient because all expressions
>  are pre-computed althogh the first one is most likely
>  to hit"""

Also, it doesn't work in the general case, like

decision = [
   (a == 0, "first"),
   (b/a > 1, "second"),
   ...

>  decision = [
>  (a > 4 and b == 0, "first"),
>  (len(z) < 2,   "second"),
>  (b + a == 10,  "third")]
>  for (test, result) in decision:
>  if test: return result
> 
> def branch3(a, b, z):
>  """Elegant but inefficient because expressions
>  need to be parsed each time"""
>  decision = [
>  ("a > 4 and b == 0", "first"),
>  ("len(z) < 2",   "second"),
>  ("b + a == 10",  "third")]
>  for (test, result) in decision:
>  if eval(test): return result

You can shave off most of the overhead by precompiling the expressions:

DECISIONS = [
("a > 4 and b == 0", "first"),
("len(z) < 2",   "second"),
("b + a == 10",  "third")
]

DECISIONS4 = [
(compile(expr, "", "eval"), result)
for expr, result in DECISIONS
]

def branch4(a, b, z):
for test, result in DECISIONS4:
if eval(test):
return result
raise ValueError

Using lambdas instead of precompiled expressions is a tad faster:

DECISIONS5 = [
(eval("lambda a, b, z: " + expr), result)
for expr, result in DECISIONS
]

def branch5(a, b, z):
for test, result in DECISIONS5:
if test(a, b, z):
return result
raise ValueError

This is is a slippery slope as you might now consider building branch1() 
from the DECISIONS list...

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Regarding problem in python 3.8.0 installation

2019-12-09 Thread Rhodri James

On 08/12/2019 18:08, alok singh wrote:

Sir,

My system is windows 7 SP1 32-bit . after installing python in my
system,when i try to launch it using command prompt then a message is
shown. I am attaching a screenshot of the following.
kindly look seriously into my problem and tell me the solution..


I'm afraid this is a text-only mailing list, so your screenshot has been 
stripped off before any of us could see it.  Please could you copy and 
paste the text of the error message you receive.


--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: More efficient/elegant branching

2019-12-09 Thread Tim Chase
On 2019-12-09 12:27, Musbur wrote:
> def branch1(a, b, z):
>  """Inelegant, unwieldy, and pylint complains
>  about too many branches"""
>  if a > 4 and b == 0:
>  result = "first"
>  elif len(z) < 2:
>  result = "second"
>  elif b + a == 10:
>  result = "third"
>  return result

Because of the diversity of test-types, I tend to agree with ChrisA
and be strongly tempted to ignore linting warning.  I have some ETL
code that has umpty-gazillion odd if-conditions like this and they
all update some global-to-the-if/local-to-the-loop state, and if I
split each out somehow, I'd either be passing an object around that I
mutate, or I would do a lot of copy-the-data-updating-one-field per
function.

Alternatively, ...

> def branch2(a, b, z):
>  """Elegant but inefficient because all expressions
>  are pre-computed althogh the first one is most likely
>  to hit"""
> def branch3(a, b, z):
>  """Elegant but inefficient because expressions
>  need to be parsed each time"""

If you really want to do lazy evaluation, you can create a
function for each, which might (or might not) make it easier to read:

  def something_descriptive(a, b, z):
return a > 4 and b == 0

  def z_is_short(a, b, z):
return len(z) < 2

  def proper_total(a, b, z)
 return b + a == 10

  def branch4(a, b, z):
for test, result in [
(something_descriptive, "first"),
(z_is_short, "second"),
(proper_total, "third"),
]:
  if test(a, b, z):
return result
return "some default"

or possibly

  def something_descriptive(a, b):
return a > 4 and b == 0

  def z_is_short(z):
return len(z) < 2

  def proper_total(a, b)
 return b + a == 10

  def branch5(a, b, z):
for test, params, result in [
(something_descriptive, (a, b), "first"),
(z_is_short, (z,), "second"),
(proper_total, (a, b), "third"),
]:
  if test(*params):
return result
return "some default"

I'm not sure either of those is necessarily *better*, but they're at
least options that you can try and see if it improves readability in
your particular case.

-tkc




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread Python

Le 09/12/2019 à 09:15, R.Wieser a écrit :
...

You'll find that *any* form of import executes all the top-level code.


Thats certainly something I did not expect.


How could it be otherwise? Consider a module defining two
classes: Parent and Child, Child inheriting from Parent.

if you do "from the_module import Child", how could it
not execute the code defining Parent as well? Child
*depends* on Parent.


--
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread songbird
Greg Ewing wrote:
> On 8/12/19 9:30 pm, songbird wrote:
>>wouldn't it make more sense to just go back and fix the
>> converter program than to have to manually convert all this
>> python2 code?
>
> Anything that isn't already fixed by 2to3 is probably
> somewhere between very difficult and impossible to fix
> using an automated process. It sounds like an interesting
> project, but be aware that it's probably an AI-complete
> problem.

  if the program already exists and is working then that
implies a parser already exists for it.

  this is not a general AI or CS issue.


  songbird
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread songbird
jf...@ms4.hinet.net wrote:
...
> Even string is hard to be handled by the AI:-)
>
> Quoted from https://portingguide.readthedocs.io/en/latest/strings.html
> " ... This means that you need to go through the entire codebase, and decide 
> which value is what type. Unfortunately, this process generally cannot be 
> automated."

  i don't agree.  if the language is already parsed then
you have the strings.  the contents of the strings will
have to be finite if they are fixed strings.  so to convert
a fixed string you can choose a type for the value and run
a test to see if it works.  if it does then you've picked 
the correct type, if it doesn't you pick the next type.
there are only a finite number of types.

  yes it is brute force but it would find something that
worked eventually if there was something to be found.

  for programs using indefinite strings via input you
can't predict what those would be doing, but then of
course you would be able to say the most general type could 
be tried first and then run tests to see if it worked.

  the overall patterns to try for a string could be 
driven by examining code which has already been converted
that contains similar patterns - eventually you would
have enough of an idea of which things to try first to
speed things up.

  yes, this is a generally hard issue if you are talking
random strings and not sure what is what, but in the
case of a computer language it is already specified and
parsers already exist.


  songbird
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread Chris Angelico
On Tue, Dec 10, 2019 at 5:05 AM songbird  wrote:
>
> jf...@ms4.hinet.net wrote:
> ...
> > Even string is hard to be handled by the AI:-)
> >
> > Quoted from https://portingguide.readthedocs.io/en/latest/strings.html
> > " ... This means that you need to go through the entire codebase, and 
> > decide which value is what type. Unfortunately, this process generally 
> > cannot be automated."
>
>   i don't agree.  if the language is already parsed then
> you have the strings.  the contents of the strings will
> have to be finite if they are fixed strings.  so to convert
> a fixed string you can choose a type for the value and run
> a test to see if it works.  if it does then you've picked
> the correct type, if it doesn't you pick the next type.
> there are only a finite number of types.
>

Here's an example piece of code.

sock = socket.socket(...)
name = input("Enter your username: ")
code = input("Enter the base64 code: ")
code = base64.b64decode(code)
sock.write("""GET /foo HTTP/1.0
Authentication: Demo %s/%s

""" % (name, code))
match = re.search(r"#[A-Za-z0-9]+#", sock.read())
if match: print("Response: " + match.group(0))

Your challenge: Figure out which of those strings should be a byte
string and which should be text. Or alternatively, prove that this is
a hard problem. There are only a finite number of types - two, to be
precise - so by your argument, this should be straightforward, right?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread Rob Gaddi

On 12/9/19 9:55 AM, songbird wrote:

jf...@ms4.hinet.net wrote:
...

Even string is hard to be handled by the AI:-)

Quoted from https://portingguide.readthedocs.io/en/latest/strings.html
" ... This means that you need to go through the entire codebase, and decide which 
value is what type. Unfortunately, this process generally cannot be automated."


   i don't agree.  if the language is already parsed then
you have the strings.  the contents of the strings will
have to be finite if they are fixed strings.  so to convert
a fixed string you can choose a type for the value and run
a test to see if it works.  if it does then you've picked
the correct type, if it doesn't you pick the next type.
there are only a finite number of types.



And how exactly do you propose to determine whether the constant I've enclosed 
in quotation marks in Python2 represents "text" or "binary data"?  Not all text 
is words; think of SQL queries.  And some words are binary data, think SCPI 
commands being sent to a serial port.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread R.Wieser
Dennis,

> "del instance" only deletes the NAME.
[snip]

Yep, I already assumed that that would happen.  Just wanted to keep it 
simple.

> "instance" xyz does not shadow "class" xyz... instead, the name "xyz"
> only exists in the binding to the instance.

That is what I tried to say: the name-binding to the class is removed.

> However, that instance has a binding to the class object,

And than when the instance is deleted the binding to the class is lost, and 
as a result it is garbage-collected.  Right ?

Regards,
Rudy Wieser


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 3 prefix to infix without too many parethesis

2019-12-09 Thread Terry Reedy

On 12/9/2019 6:21 AM, jezka...@gmail.com wrote:

Hi, I have got a problem.


Is this homework?


I wrote a code for prefix to infix. It works, but I need improve it
so on input there will be only necessary parentheses.


Define 'necessary'; give multiple input/output examples.
Put them in a test function.


Here is the code:

import re
a = input()

class Calculator:

 def __init__ (self):
 self.stack = []

 def push (self, p):
 if p in ['+', '-', '*', '/', "**"]:
 op1 = self.stack.pop ()
 op2 = self.stack.pop ()
 self.stack.append ('(%s%s%s)' % (op1, p, op2))

 
 print("op1 =", op1)

 print("op2 =", op2)
 print("p=", p)
 print(self.stack)

 else:
 self.stack.append (p)


 def convert (self, l):
 l.reverse ()
 for e in l:
 self.push (e)
 return self.stack.pop ()

c = Calculator ()

print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a)))


input is like /-*+*++**85 27 39 87 65 65 37 63 91


Since '*' and '**' are both allowed operators (see 'p in' above), spaces 
are needed between operators to disambiguate.  In any case, what output 
does your code produce now, and what do you want it to produce.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: python 3 prefix to infix without too many parethesis

2019-12-09 Thread DL Neil via Python-list

On 10/12/19 8:40 AM, Terry Reedy wrote:

On 12/9/2019 6:21 AM, jezka...@gmail.com wrote:

Hi, I have got a problem.


Is this homework?


Same question - that way we know that our task is to help you learn to 
code in Python, cf a problem with Python itself...


Similarly, you may like to  know that there is a separate Python-Tutor 
Discussion List.




I wrote a code for prefix to infix. It works, but I need improve it
so on input there will be only necessary parentheses.


The example code processes, like a calculator (um, yes, well...). What 
do you mean by "prefix to infix"?




Define 'necessary'; give multiple input/output examples.
Put them in a test function.


+1



Here is the code:


Question: with abbreviated variableNMs, eg "p", "a", even "op"; how 
easily will you comprehend the code in six month's time? How easy do you 
think it is for someone else to read the code now? NB the print 
functions are no help because the labels are equally-abbreviated, plus 
my aged-eyes start to strain when following lists of %s-es and regexps - 
mea culpa!




import re
a = input()

class Calculator:

 def __init__ (self):
 self.stack = []

 def push (self, p):
 if p in ['+', '-', '*', '/', "**"]:
 op1 = self.stack.pop ()
 op2 = self.stack.pop ()
 self.stack.append ('(%s%s%s)' % (op1, p, op2))

 print("op1 =", op1)
 print("op2 =", op2)
 print("p=", p)
 print(self.stack)

 else:
 self.stack.append (p)


 def convert (self, l):
 l.reverse ()
 for e in l:
 self.push (e)
 return self.stack.pop ()

c = Calculator ()

print (c.convert (re.findall(r'\d+|\*\*|[-+*/]', a)))


input is like /-*+*++**85 27 39 87 65 65 37 63 91


ALWAYS, ALWAYS, ALWAYS, document a RegExp with a comment!!!

After 'translating' the abbreviations according to my recollection of 
this form of a frequently-used ComSc course problem, I was then 
surprised by the format of the input - using an infix calculator we 
enter a value, then an operator, and then another value, etc; and using 
a postfix calculator one usually inputs a couple of values and then an 
operator, another value, and then an operator, and so on - rather than 
receiving it all at once. Is this 'all at once' a feature of an infix 
calculator or am I missing/forgetting something?


For which I am obviously not the only one with a confused expression on 
my face...



Since '*' and '**' are both allowed operators (see 'p in' above), spaces 
are needed between operators to disambiguate.  In any case, what output 
does your code produce now, and what do you want it to produce.


I hate RegExps because it is so easy to write a wrong 'un. However, 
because the "\*\*" selection precedes the "[-+*/]", it appears (rheumy 
eyes allowing) to enact arithmetic priority correctly. However, as 
mentioned before, most of us will have created a serial and algorithmic 
approach to this problem, back-when; so it does seem a little strange.



OK, let's address your actual question: the parentheses!

How do you plan to make them work? As elsewhere: please provide example 
input and expected output, so that we can be sure of the code's 
objective. Multiple examples can only help, especially if there are 
exceptions and "edge-cases". Also, if your progress in Python is ready 
for it, we can talk PyTest (or equivalent), plus such a plan enables you 
to practice Test-Driven Development...



These problems stretch one's mental acuities. It would seem that I am 
not the only one looking forward to hearing back from you...

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Python3 - How do I import a class from another file

2019-12-09 Thread DL Neil via Python-list
It might be becoming 'long', but this discussion contains much of profit 
to many people!



Us 'silver surfers' do need to periodically question those beliefs we 
hold as 'tenets' of ComSc. Amongst them is RAM (or "core"!) 
conservation. It remains a virtue somewhat, but at the same time, 
storage costs are considerably cheaper than they were four decades ago, 
whereas the relative-cost of your time (to think about such things) has 
increased!


That said, many of our more youthful (and in their own words "better in 
every way", harrumph!) colleagues should also review their own beliefs 
from time-to-time, eg working with IoT devices certainly requires a more 
conservative and considerate approach to resources!
(and in such applications, we tend to enjoy significant advantage 
because we've 'been there, done that'!)



Similarly, it is a serious fallacy to attempt to directly 'translate' a 
'command' from one language into an 'equivalent' in another/a new 
language. Whilst the syntax may appear similar, such superficiality 
doesn't allow for subtleties of meaning! In the same way, if you ask one 
person to translate the English word "preserve" into German, and then 
another person to translate that German word into English, what are the 
chances that the 'answer' will be "preserve"? Given that "preserve" 
could mean a jam/jelly/conserve (noun) or (verb) 'maintain the meaning', 
with a similar range of synonyms (etc) on the German side; the word 
"preserve" is unlikely to be preserved!

(with all due apologies for such terrible humor and word-play!)


On 9/12/19 11:32 PM, Terry Reedy wrote:

On 12/9/2019 2:36 AM, R.Wieser wrote:

Terry,

Standard for in-file test is

[snip]

Any reason to put the testcode in a procedure instead of just have it
directly follow the "if __name__ == '__main__' " test ?


One can, for instance, interactively do

 >>> import mod
 >>> mod.test()

...

I went through this cycle of thinking, first using if __name__... to 
'hide' testing, then adding test functions within the module, and now 
keep test code quite separate from 'the real thing'.


In fact, PyTest (for example) will auto-magically look for test-code in 
sub-directories of the project directory, eg "projectNM/tests". So, for 
every (Python) file in my projectDIR, you should be able to find at 
least one corresponding Python test-file in the tests sub-dir!


This fits with your philosophy of keeping (imported) modules small, 
perhaps to the point of separating each class into its own module - if 
'efficiency' is the goal, why would you want to include test-code within 
a 'production system'?



On which point, if we had a class Person(); and then decided that in 
certain cases we wanted specific methods that didn't apply to every 
(type of) Person, we would likely create a sub-class, eg class Man( 
Person ); - although some might dispute the accuracy of such an "is a" 
relationship...


That being the case, were you to put the Man class' code into (say) a 
module called "man.py" and Person()'s code into "person.py", then a 
point made earlier is that you can't merely import man.py;! You must 
also ensure that person.py is imported, somewhere along the line. Thus, 
because it names (and requires the logic of) the super-class, the 
sub-class cannot be imported 'alone'. (regardless of saving-space 
objectives, etc)



Expanding on 'names' and del(): the first point is that there is seldom 
much to be gained by using del(), ie becoming your own 'garbage 
collector'. That said, there are some very specific times when it 
becomes absolutely necessary (otherwise the Python 'gods' would not have 
given us the functionality!). Once again, RAM is (relatively) plentiful, 
and when you need to replicate many multiples of an object, it is likely 
within a loop and therefore the same instanceNM is being 're-used' and 
the garbage-collector takes care of 'recycling' the storage space 
auto-magically.



Regarding 'names', yes some languages are "strongly typed" and (mostly) 
for that reason include an indicator of "type" within the name. Python 
enables you to play fast-and-loose, eg


>>> x = 1
>>> x = "abc"
>>> x = 2.3
>>> x = [ 1, 2, 3 ]
>>> x = ( 1, 2, 3 )
>>> x = 1, 2, 3

constitutes a perfectly legal program (where "legal" != "useful").


There again, there are times when values are processed into a different 
data structure, eg we start with a list of values, but only want to use 
unique values/process each representative-member once.


A Python-list will handle the former (wow, that's a bit of 'rocket 
science'!?) whereas a Python-set will only contain unique values. So, 
rather than using a somewhat-bland varNM such as "letters", I would 
choose to be more explicit:


>>> letters_list = [ "a", "b", "a", "c", "a", "d", "a" ]
>>> len( letters_list )
7
>>> letters_set = set( letters_list )
>>> len( letters_set )
4
>>> letters_set
{'b', 'a', 'd', 'c'}

There is no question whether "letters" is a list, or a set, (or ...), 
because

Re: python 2 to 3 converter

2019-12-09 Thread songbird
Rob Gaddi wrote:
...
> And how exactly do you propose to determine whether the constant I've 
> enclosed 
> in quotation marks in Python2 represents "text" or "binary data"?  Not all 
> text 
> is words; think of SQL queries.  And some words are binary data, think SCPI 
> commands being sent to a serial port.

  why not assume one, see if it works and then if it doesn't you
know it is the other?  if those are the only two choices then 
that speeds things up.


  songbird
-- 
https://mail.python.org/mailman/listinfo/python-list


Randomizing Strings In A Microservices World

2019-12-09 Thread Tim Daneliuk
I ran across a kind of fun problem today that I wanted to run past you Gentle 
Geniuses (tm):

- Imagine an environment in which there may be multiple instances of a given
  microservice written in Python.

- Each of these services needs to produce a string of ten digits guaranteed to 
be unique
  on a per service instance basis AND to not collide for - oh, let's say - 
forever :)s

Can anyone suggest a randomization method that might achieve this efficiently?

My first thought was to something like nanonseconds since the epoch plus 
something
unique about the service instance - like it's IP?  (This is in a K8s cluster) - 
to
see the randomization and essentially eliminate the string being repeated.

Ideas welcome ..

P.S. I do not want to resort to a number generation service that each instance 
asks
 for a new number.  The network and service call overhead militates against 
this
 in my application.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread songbird
Chris Angelico wrote:
...
>
> Here's an example piece of code.
>
> sock = socket.socket(...)
> name = input("Enter your username: ")
> code = input("Enter the base64 code: ")
> code = base64.b64decode(code)
> sock.write("""GET /foo HTTP/1.0
> Authentication: Demo %s/%s
>
> """ % (name, code))
> match = re.search(r"#[A-Za-z0-9]+#", sock.read())
> if match: print("Response: " + match.group(0))
>
> Your challenge: Figure out which of those strings should be a byte
> string and which should be text. Or alternatively, prove that this is
> a hard problem. There are only a finite number of types - two, to be
> precise - so by your argument, this should be straightforward, right?

  this isn't a process of looking at isolated code.  this
is a process of looking at the code, but also the test cases
or working examples.  so the inputs are known and the code 
itself gives clues about what it is expecting.

  regular expressions can be matched in finite time as well
as a fixed length text of any type can be scanned as a match
or rejected.

  if you examined a thousand uses of match and found the
pattern used above and then examined what those programs did
with that match what would you select as the first type, the
one used the most first, if that doesn't work go with the 2nd,
etc.


  songbird
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread Chris Angelico
On Tue, Dec 10, 2019 at 12:11 PM songbird  wrote:
>
> Rob Gaddi wrote:
> ...
> > And how exactly do you propose to determine whether the constant I've 
> > enclosed
> > in quotation marks in Python2 represents "text" or "binary data"?  Not all 
> > text
> > is words; think of SQL queries.  And some words are binary data, think SCPI
> > commands being sent to a serial port.
>
>   why not assume one, see if it works and then if it doesn't you
> know it is the other?  if those are the only two choices then
> that speeds things up.
>

What if neither works, because there are assumptions that don't work?

I get the very strong impression that you've never tried this.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread Chris Angelico
On Tue, Dec 10, 2019 at 12:15 PM songbird  wrote:
>
> Chris Angelico wrote:
> ...
> >
> > Here's an example piece of code.
> >
> > sock = socket.socket(...)
> > name = input("Enter your username: ")
> > code = input("Enter the base64 code: ")
> > code = base64.b64decode(code)
> > sock.write("""GET /foo HTTP/1.0
> > Authentication: Demo %s/%s
> >
> > """ % (name, code))
> > match = re.search(r"#[A-Za-z0-9]+#", sock.read())
> > if match: print("Response: " + match.group(0))
> >
> > Your challenge: Figure out which of those strings should be a byte
> > string and which should be text. Or alternatively, prove that this is
> > a hard problem. There are only a finite number of types - two, to be
> > precise - so by your argument, this should be straightforward, right?
>
>   this isn't a process of looking at isolated code.  this
> is a process of looking at the code, but also the test cases
> or working examples.  so the inputs are known and the code
> itself gives clues about what it is expecting.

Okay. The test cases are also written in Python, and they use
unadorned string literals to provide mock values for input() and the
socket response. Now what?

What if the test cases are entirely ASCII characters?

What if the test cases are NOT entirely ASCII characters?

>   regular expressions can be matched in finite time as well
> as a fixed length text of any type can be scanned as a match
> or rejected.
>
>   if you examined a thousand uses of match and found the
> pattern used above and then examined what those programs did
> with that match what would you select as the first type, the
> one used the most first, if that doesn't work go with the 2nd,
> etc.
>

That's not really the point. Are your regular expressions working with
text or bytes? Does your socket return text or bytes?

I've deliberately chosen these examples because they are hard. And I
didn't even get into an extremely hard problem, with the inclusion of
text inside binary data inside of text inside of bytes. (It does
happen.)

These problems are fundamentally hard because there is insufficient
information in the source code alone to determine the programmer's
intent.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: More efficient/elegant branching

2019-12-09 Thread DL Neil via Python-list
I agree with you, so I'm going to ignore def branch2(a, b, z): and def 
branch3(a, b, z) because they appear too contrived - and I guess that's 
fair, in that you've contrived to satisfy pylint.


Question: are there other people/factors who/which should be regarded as 
more important than the linter's opinion?


The usual dictionary-controlled construct I've seen (and used) involves 
using functions as the dict's values:


def branch1( *args): pass
...
alternative[ x ] = branch1

and thus:

alternative[ choice ]( *args )


On 10/12/19 12:27 AM, Musbur wrote:
I have a function with a long if/elif chain that sets a couple of 
variables according to a bunch of test expressions, similar to function 
branch1() below. I never liked that approach much because it is clumsy 
and repetetive, and pylint thinks so as well. I've come up with two 
alternatives which I believe are less efficient due to the reasons given 
in the respective docstrings. Does anybody have a better idea?


def branch1(a, b, z):
     """Inelegant, unwieldy, and pylint complains
     about too many branches"""
     if a > 4 and b == 0:
     result = "first"
     elif len(z) < 2:
     result = "second"
     elif b + a == 10:
     result = "third"
     return result


Is it ironic that the language does not have a form of case/switch 
statement (despite many pleas and attempts to add it), yet the linter 
objects to an if-elif-else nesting???



One reason why this code looks a bit strange (and possibly why PyLint 
reacts?) is because it is trivial. When we look at the overall picture, 
the question becomes: what will the 'mainline' do with "result" (the 
returned value)? Immediately one suspects it will be fed into another 
decision, eg:


if result == "first": # do the first-thing...
if result == "second": # do the second-thing...

When found 'in real life', the above structure with such decisions is 
almost certainly followed by a second decision to select which 
'action(s)' will be carried-out. The original-code rarely stands-alone, 
because all we've achieved is a labelling of the circumstances according 
to the arguments provided.



Rather than using a variable for 'labelling', (all other things being 
equal) I'd prefer to go straight to a function which 'does the business' 
- and use the function's name as a documenting 'label'!



A quick reflection shows that I have vacillated between two approaches:

1 put the decision-making in the 'mainline' and call a variety of 
functions/methods to do 'the first thing' etc. ie more-or-less what you 
have here, except the cascade of decisions is not separated from 'what 
came before'.


def calculation( value, operator, operand):
if operator == "+":
add( value, operand)
elif operator == "-":
sub( value, operand)


2 arrange/call a series of functions each dealing with a single 
circumstance, eg (borrowing from @Chris) should I "tap"?. Thus each 
function will firstly check if the circumstances demand that action, ie 
the applicable one of the if-clauses above, and if they do, then 
implement that action: 'do the first thing' (etc).


value = handle_add( value, operator, operand )
value = handle_sub( value, operator, operand )

where:

def handle_add( value, operator, operand):
if operator == "+":
return value + operand
return value

Ugh - the example is no less contrived and grossly artificial...


The second of those appears somewhat 'cleaner' - in that we have 'hidden 
away' all those pesky if-constructs; BUT it is NOT immediately obvious 
exactly how many of the series of functions will actually result in any 
'action' (if not, all of them). So, perhaps that raises the 
(earlier/elsewhere) question of whether the various action-functions are 
dependent or independent/exclusive of each other? It also requires 
carefully choosing descriptive function names!

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Testing a TestPyPI package with dependencies

2019-12-09 Thread Akkana Peck
I'm a novice packager, trying to test a package I built and
uploaded to TestPyPI. It has dependencies and I want to make
sure my setup.py works before uploading to the real PyPI.

https://packaging.python.org/guides/using-testpypi/
says that if a package has dependencies, to use this command to get
the package from TestPyPI while getting dependencies from PyPI:

pip install --index-url https://test.pypi.org/simple/ --extra-index-url 
https://pypi.org/simple your-package

That doesn't seem to work, though. It seems like it never checks
pypi.org and looks for everything in test.pypi.org. Here's what I'm
doing, starting from a new virtualenv:

..
$ python3 -m venv /tmp/test3env

$ source /tmp/test3env/bin/activate

(test3env) $ pip install wheel
Collecting wheel
  Using cached 
https://files.pythonhosted.org/packages/00/83/b4a77d044e78ad1a45610eb88f745be2fd2c6d658f9798a15e384b7d57c9/wheel-0.33.6-py2.py3-none-any.whl
Installing collected packages: wheel
Successfully installed wheel-0.33.6

(test3env) $ pip install --index-url https://test.pypi.org/simple/ 
--extra-index-url https://pypi.org/simple pytopo==1.6.1
Looking in indexes: https://test.pypi.org/simple/, https://pypi.org/simple
Collecting pytopo
  Using cached 
https://test-files.pythonhosted.org/packages/1d/dd/f46722bed2296676053b333a97babf05cb31b20e4a621161d44399a3ed18/pytopo-1.6.1-py3-none-any.whl
Collecting simplejson (from pytopo)
Could not install packages due to an EnvironmentError: 404 Client Error: 
Not Found for url: https://test.pypi.org/simple/simplejson/
..

I can pip install simplejson without errors, so I know it's in PyPI.
(If I then try the install again, it fails on pycairo, same error.)

Am I misunderstanding that packaging.python.org guide, or making
some silly typo? Is there a trick it doesn't mention to getting pip
to use both PyPI and TestPyPI?

Thanks for any suggestions!

...Akkana
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Randomizing Strings In A Microservices World

2019-12-09 Thread Tim Delaney
On Tue, 10 Dec 2019 at 12:12, Tim Daneliuk  wrote:

> - Each of these services needs to produce a string of ten digits
> guaranteed to be unique
>   on a per service instance basis AND to not collide for - oh, let's say -
> forever :)s
>
> Can anyone suggest a randomization method that might achieve this
> efficiently?
>
> My first thought was to something like nanonseconds since the epoch plus
> something
> unique about the service instance - like it's IP?  (This is in a K8s
> cluster) - to
> see the randomization and essentially eliminate the string being repeated.
>

10 digits is only 9. That's not a very big number. Forget
nanoseconds since the epoch, that won't currently give you seconds since
the epoch - let alone combining with any other identifier.

$ date '+%s'
1575942612

Tim Delaney
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Randomizing Strings In A Microservices World

2019-12-09 Thread Tim Daneliuk
On 12/9/19 8:50 PM, Paul Rubin wrote:
> Tim Daneliuk  writes:
>> - Imagine an environment in which there may be multiple instances of a given
>>   microservice written in Python.
> 
> Decide the maximum number of microservice instances, say 1000.  Chop up
> the 10 digit range into 1000 pieces, so 0..99, 100-199, etc.
> Give one range to each microservice instance.  Then have the
> microservices give out the numbers sequentially, but treating them as 10
> digit numbers and encrypting each one under a 10 digit pseudorandom
> permutation shared by all the instances.  Look up "format preserving
> encryption" for how to do this.
> 
> Obvious variants of the above are obvious, and maybe you need some way
> to hand around chunks of range if some instance gives out more than a
> million numbers.
> 


The problem here is that the services are ephemeral and the number of said
services is not fixed.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Randomizing Strings In A Microservices World

2019-12-09 Thread Tim Daneliuk
On 12/9/19 8:54 PM, Dennis Lee Bieber wrote:
> On Mon, 9 Dec 2019 18:52:11 -0600, Tim Daneliuk 
> declaimed the following:
> 
>>
>> - Each of these services needs to produce a string of ten digits guaranteed 
>> to be unique
>>  on a per service instance basis AND to not collide for - oh, let's say - 
>> forever :)s
>>
>> Can anyone suggest a randomization method that might achieve this 
>> efficiently?
>>
>> My first thought was to something like nanonseconds since the epoch plus 
>> something
>> unique about the service instance - like it's IP?  (This is in a K8s 
>> cluster) - to
>> see the randomization and essentially eliminate the string being repeated.
>>
>> Ideas welcome ..
>>
> 
>   Well, 10 digits is rather short, but studying
> https://en.wikipedia.org/wiki/Universally_unique_identifier might provide
> some ideas.
> 
> 

For a variety of reasons the length of this string cannot exceed 10 digits.  It 
is believed
that - in this application - the consumption of values will be sparse over 
time.  All
I really need is a high entropy way to select from among the billion possible 
values to
minimize the possibility of collisions (which require retry and time we don't 
want to burn).

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread songbird
Chris Angelico wrote:
...
> What if neither works, because there are assumptions that don't work?

  then you get stuck doing it by hand, but you would have
been stuck doing it before for sure by hand so if you can
write something which might get some of the easy cases
done then at least you're saving your efforts for the 
harder stuff.


> I get the very strong impression that you've never tried this.

  of course not!  i don't have that kind of pipeline
or machine power and i'm several years away from being 
where i'd like to be in terms of understanding the
language itself.  i hope to have the time over the 
next few years to learn enough but i don't know how 
that will go.

  i'm glad in looking around more the past few evenings
that the conversion effort is making progress and 
things are not as dire as some have made it out to be.
i just hope the lessons have been learned going 
forwards.


  songbird
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2 to 3 converter

2019-12-09 Thread Chris Angelico
On Tue, Dec 10, 2019 at 4:41 PM songbird  wrote:
>
> Chris Angelico wrote:
> ...
> > What if neither works, because there are assumptions that don't work?
>
>   then you get stuck doing it by hand, but you would have
> been stuck doing it before for sure by hand so if you can
> write something which might get some of the easy cases
> done then at least you're saving your efforts for the
> harder stuff.

The easy cases are easy for anything, and don't need AI.

> > I get the very strong impression that you've never tried this.
>
>   of course not!  i don't have that kind of pipeline
> or machine power and i'm several years away from being
> where i'd like to be in terms of understanding the
> language itself.  i hope to have the time over the
> next few years to learn enough but i don't know how
> that will go.
>
>   i'm glad in looking around more the past few evenings
> that the conversion effort is making progress and
> things are not as dire as some have made it out to be.
> i just hope the lessons have been learned going
> forwards.

Never even done it manually, I mean. It's very difficult to try to
design an AI to do something that you can't do yourself and don't even
understand the problem.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list