Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread Greg Ewing

On 17/12/20 8:31 am, Grant Edwards wrote:

On 2020-12-16, Dennis Lee Bieber  wrote:

https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name


I vaguely recall some other old
language I ran across in a survey course when in college that used it.
IIRC it was Algol.


Algol 60.

Also, Lisp macros effectively let you do something similar.

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


Re: Function returns old value

2020-12-17 Thread Peter J. Holzer
On 2020-12-17 03:06:32 -, Bischoop wrote:
> pasting from my IDE to vim/slrn was messing syntax,

You can 

:set paste

in vim to prevent it from messing with pasted content (don't forget to
set nopaste afterwards).

With newer vims that's rarely necessary though since they can distinguish
between input that was pasted and input that was typed.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python 2 to Python 3 .so library incompatibility - need help

2020-12-17 Thread Chris Green
Cameron Simpson  wrote:
> >> Guessing from the library name, have you looked on the OKI.com site 
> >> for current software? Maybe here? What's your printer model?
> >> 
> >> https://www.oki.com/au/printing/support/drivers-and-utilities/index.html
> >>
> >>
> >It comes from OKI with the Linux utilities for the printer, it's an
> >MC342N.
> 
> From here?
> 
> https://www.oki.com/uk/printing/support/drivers-and-utilities/colour-multifunction/01331401/?os=ab33&lang=ac2
>  
> 
> 
> This driver?
> 
> https://www.oki.com/uk/printing/support/drivers-and-utilities/?id=46252701FZ01&tab=drivers-and-utilities&productCategory=colour-multifunction&sku=01331401&os=ab33&lang=ac2
>  
> 
> 
> I've just installed the .deb above on my Ubuntu 20.04.1 LTS system.  
> Aside from whinging about systemd it installed ok. How do I reproduce 
> your problems? (I've got no printer of course, but...)
> 
Try running scantool.py, that should pop up a little GUI.

It uses GTK which of course in itself makes migration tricky because
one has to move from the native Python 2 code to the 'introspection'
code on Python 3.  However I can do those code changes, the killer is
that several of the scripts import pyscand and that's the Python 2
library.

The issue basically is that you can't run Python 2 GTK in a modern
system that's mostly Python 3 because the GTK libraries conflict. Thus
I need to convert the code to Python 3 but I can't because of the
library.

I've extracted all the calls/uses of pyscand from the Python code:-

pyscand.ADF:
pyscand.BEGIN:
pyscand.EVENT_PUSHSCAN:
pyscand.EVENT_PUSHSCANCCL:
pyscand.E_BUSY
pyscand.E_BUSY:
pyscand.E_CANCELED:
pyscand.E_CONNECTION_REFUSED:
pyscand.E_ERROR
pyscand.E_IOERROR:
pyscand.E_NODATA:
pyscand.E_SUCCESS
pyscand.E_SUCCESS:
pyscand.FINISHED:
pyscand.O_HEIGHT
pyscand.O_PAPER_HEIGHT
pyscand.O_PAPER_WIDTH
pyscand.O_WIDTH
pyscand.PRM_ACTION
pyscand.PRM_DEVICE
pyscand.PRM_DEVICE
pyscand.PRM_PAGE
pyscand.PRM_PATH
pyscand.PRM_PROGRESS
pyscand.PRM_PUSHSCAN_ID
pyscand.PRM_SOURCE
pyscand.PRM_STATUS
pyscand.PROGRESS:
pyscand.TO_APPLICATION:
pyscand.TO_FOLDER:
pyscand.cancel_register_client()
pyscand.cancel_scan(device)
pyscand.exit_client()
pyscand.get_device_list(devicelist)
pyscand.is_registered()
pyscand.recv_client_event()
pyscand.register_client()
pyscand.scan(self._device, self._cfg, outpath, self._scan_callback,
self._pushscanid)
pyscand.strstatus(rc)))
pyscand.strstatus(status)
pyscandsupp.to_device_name_list(devicelist)

As you can see it's mostly constants but there's that pyscand.scan()
at the bottom which I suspect is the fundamental scanning software.

-- 
Chris Green
·
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python 2 to Python 3 .so library incompatibility - need help

2020-12-17 Thread Michał Jaworski
I've looked into the details of the deb package that Cameron mentioned. It
may be the one that you Chris uss because it does indeed include a
pyscand.so file. Quick question to you Chris: the utilities
you've mentioned are the code that you've written yourself or utilities
from /usr/libexec/okimfputl that are shipped with the "driver package". In
the deb package I've found following files:
/usr/libexec/okimfputl/imgfilecv.py
/usr/libexec/okimfputl/pushconfig.py
/usr/libexec/okimfputl/pushass.py
/usr/libexec/okimfputl/mfpcfgfile.py
...

If that's the latter, I wouldn't even try to port that to Python 3. First,
it would be clearly against the licence agreement. Second, that would
probably result in total mess and take more time that it takes to earn for
a new printer. If you really want to keep the printer (I wouldn't) I would
do the following: upgrade your system, install Python 2.7 straight from
sources in a separate location (e.g. /opt/oki-python?) and modify all
shebang lines of the OKI python utilities from utilities to use that python
location instead of "/usr/bin/env python" or "/usr/bin/python". That would
make it totally independent of your system installation. The last thing
would be probably installing pygtk in that "isolated" python installation
as OKI utilities clearly rely on this. You could use venv for that or just
simply make sure that gtk for python2 is in that python's library path.
Whatever more convenient: you won't be using that python installation for
anything else than supporting the driver.

To be honest, what I would really do is to buy a new printer from a vendor
that is known to be supporting their hardware for long term on the system
you use. Printer vendors sucks. In the end, they always stop producing
printing supplies you need and render your hardware useless. I have a combo
that I can't refill with toner anymore which has used photoconductor drum
that I can't replace anymore. I keep it around because it has a working
scanner and haven't buyed a new printer because this one "almost works".

Cheers,
Michał

śr., 16 gru 2020 o 23:48 Cameron Simpson  napisał(a):

> On 16Dec2020 21:59, Chris Green  wrote:
> >Cameron Simpson  wrote:
> >> On 16Dec2020 18:51, Chris Green  wrote:
> >> >The specific problem that finally prevented me from managing to get it
> >> >to work was a (Linux) .so file that had been built for Python 2 and,
> >> >as I don't have the source, I can't build for Python 3.
> >>
> >> ChrisA I think suggested keeping a Python 2.7 install around for this.
> >>
> >Not possible really as there are other python conflicts that start
> >appearing if one tries to retain the libraries needed.
>
> Runtime python issues like you missing symbol error, or package conflict
> issues?
>
> i.e. can you keep the OKI stuff sitting around along with Python 2
> install without having trouble with the PPA?
>
> >> >I need to have another go at fixing this as otherwise the code that
> >> >I need to manage my printer will stop working as I update my Ubuntu
> >> >systems.
>
> I'm leaning towards ChrisA's JSON suggestion at this point (absent newer
> driver software). Keep a small Python 2 programme around which uses the
> printer driver in whatever _basic_ ways you need, and _invoke that_ from
> your modern Python 3 code as an external command, passing/receiving the
> necessary information in JSON form as input.output, or on its command
> line if that is more convenient.
>
> >> Have you considered keeping a legacy VM around as well? I have a few VMs
> >> sitting here I use for some legacy software.
> >>
> >That's not a lot of use.  The programs that I want to run (by
> >converting to Python 3) are utility programs for my printer, they
> >install with a handy 'app' in my toolbar.  Having them in a VM
> >wouldn't really do much good! :-)
>
> Fair enough. It seemed cumbersome to me too, but it is a viable way to
> keep something legacy around, particularly if that legacy thing requires
> a legacy OS.
>
> >I still have python 2.  The issue is that the programs need modules
> >which come from a PPA to support Python GTK, these conflict with
> >ongoing updates to Python.  The PPA works OK in Ubuntu 20.04 but
> >prevents some updates in 20.10.  I expect it will get worse as time
> >goes on.
> [...]
> >> Guessing from the library name, have you looked on the OKI.com site
> >> for current software? Maybe here? What's your printer model?
> >>
> https://www.oki.com/au/printing/support/drivers-and-utilities/index.html
> >>
> >>
> >It comes from OKI with the Linux utilities for the printer, it's an
> >MC342N.
>
> From here?
>
>
> https://www.oki.com/uk/printing/support/drivers-and-utilities/colour-multifunction/01331401/?os=ab33&lang=ac2
>
> This driver?
>
>
> https://www.oki.com/uk/printing/support/drivers-and-utilities/?id=46252701FZ01&tab=drivers-and-utilities&productCategory=colour-multifunction&sku=01331401&os=ab33&lang=ac2
>
> I've just installed the .deb above on my Ubuntu 20.04.1 LTS system.
> Aside

sudo python PermissionError [Errno 13] Permission denied

2020-12-17 Thread Pascal
hi,

here, I have this simple script that tests if the /tmp/test file can be
opened in write mode :

$ cat /tmp/append
#!/usr/bin/python
with open('/tmp/test', 'a'): pass

the file does not exist yet :

$ chmod +x /tmp/append
$ ls -l /tmp/test
ls: cannot access '/tmp/test': No such file or directory

the script is launched as a simple user :

$ /tmp/append
$ ls -l /tmp/test
-rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test

everything is ok.
now, the script fails if it is replayed as root user with the sudo command :

$ sudo /tmp/append
[sudo] password for user:
Traceback (most recent call last):
  File "/tmp/append", line 2, in 
with open('/tmp/test', 'a'):
PermissionError: [Errno 13] Permission denied: '/tmp/test'

the problem is the same if the opening mode is 'w' or if "sudo -i" or "su -"
are used.

why can't root user under python manipulate the simple user file ?

regards, lacsaP.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread jak

Il 15/12/2020 18:07, Mark Polesky ha scritto:

Hi.

# Running this script

D = {'a':1}
def get_default():
     print('Nobody expects this')
     return 0
print(D.get('a', get_default()))

# ...generates this output:

Nobody expects this
1

###

Since I'm brand new to this community, I thought I'd ask here first... Is this 
worthy of a bug report?  This behavior is definitely unexpected to me, and I 
accidentally coded an endless loop in a mutual recursion situation because of 
it.  Calling dict.get.__doc__ only gives this short sentence: Return the value 
for key if key is in the dictionary, else default.  Nothing in that docstring 
suggests that the default value is evaluated even if the key exists, and I 
can't think of any good reason to do so.

Am I missing something?

Thanks,
Mark



print(_ if d.get('a', None) is not None else get_default())



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


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread jak

Il 17/12/2020 12:16, jak ha scritto:

Il 15/12/2020 18:07, Mark Polesky ha scritto:

Hi.

# Running this script

D = {'a':1}
def get_default():
 print('Nobody expects this')
 return 0
print(D.get('a', get_default()))

# ...generates this output:

Nobody expects this
1

###

Since I'm brand new to this community, I thought I'd ask here first... 
Is this worthy of a bug report?  This behavior is definitely 
unexpected to me, and I accidentally coded an endless loop in a mutual 
recursion situation because of it.  Calling dict.get.__doc__ only 
gives this short sentence: Return the value for key if key is in the 
dictionary, else default.  Nothing in that docstring suggests that the 
default value is evaluated even if the key exists, and I can't think 
of any good reason to do so.


Am I missing something?

Thanks,
Mark



print(_ if d.get('a', None) is not None else get_default())




ops...

print((_ if d.get('a', None) is not None else get_default()))

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


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread Peter J. Holzer
On 2020-12-17 12:16:29 +0100, jak wrote:
> print(_ if d.get('a', None) is not None else get_default())

That doesn't work:

>>> print(_ if d.get('a', None) is not None else get_default())
Traceback (most recent call last):
  File "", line 1, in 
NameError: name '_' is not defined

But this works:

>>> print(_ if (_ := d.get('a', None)) is not None else get_default())
1

(I would prefer ChrisA's solution, though.)

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Review, suggestion etc?

2020-12-17 Thread Michał Jaworski
I've made a quick look at the code and even executed it. It looks pretty
clear and is easy to understand, although it has some structural problems.
I won't do a thorough review but highlight the most important problems.

First, the recursive user input pattern you use:
  def marriage():
maritals = input('Married: Yes/No ?: ').title()
while maritals != 'Yes' and maritals != 'No':
return marriage()
return maritals

It may look really convenient but you should really avoid that. In small
amounts it can be harmless, but it is kind of a resource leak. Aslo this
pattern is omnipresent so can quickly get out of hand and exceed maximum
recursion depth:

   ...
   You can choose only numbers.
   What you wanna do?:
   You can choose only numbers.
   What you wanna do?:
   You can choose only numbers.
   What you wanna do?:
   You can choose only numbers.
   What you wanna do?:
   You can choose only numbers.
   What you wanna do?:
   You can choose only numbers.
   Fatal Python error: Cannot recover from stack overflow.

   Current thread 0x000112836dc0 (most recent call first):
 ...
 File "vimart.py", line 52 in menu_choice
 File "vimart.py", line 52 in menu_choice
 ...
   Abort trap: 6

Also, this choice-prompt pattern could be moved to a separate general
function so you don't have to repeat it all over the code. Take a look at
the prompt() function from click.termui module to get a better
understanding on how to build such things (
https://github.com/pallets/click/blob/master/src/click/termui.py). I would
also recommend creating helper functions for common things like displaying
results because right now it's hard to figure out which parts of
application constitute its presentation layer and which are part of "core
logic". Try to keep these two concepts separate and you will get better
results.

Second major structural "problem" are inline function definitions:

def add_people():
def how_old():
...

def p_sex():
...

def marriage():
...

You shouldn't be doing that unless you need a closure with nonlocal
variables to read from. Otherwise it really harms the readability. I
understand the urge to keep relevant code close to the usage but you would
have better results with modules. If you really want to keep everything in
a single module, keep functions close together in the file but don't nest
them. Use relevant naming conventions instead. Simply think of how you
would write that in C. You could use some object-oriented approach too, but
I would recommend polishing structural programming first.

There are also other issues like not always closing files, and not
validating the user input in specific places. Still, these will be more
evident as you improve the structure of application and do thorough
testing. Anyway, the code doesn't look bad. It of course needs improvement
but I've also seen worse specimens from people being actually paid for
writing the code.

Remember that "how to make things better" is a function of few parameters:
- what you want to achieve
- what are you able to do
- how much time do you have

If your sole goal is to learn and improve skills, I would recommend
polishing this in current procedural fashion to some extent, but not trying
to make it perfect. Then I would start from scratch and experiment with
different paradigms (OOP for instance). Then I would try to make a smaller
project that has some actual utility.

czw., 17 gru 2020 o 04:17 Bischoop  napisał(a):

> On 2020-12-17, Bischoop  wrote:
>
>
> Accidently removed the paste, https://bpa.st/E3FQ
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: sudo python PermissionError [Errno 13] Permission denied

2020-12-17 Thread 2QdxY4RzWzUUiLuE
On 2020-12-17 at 11:17:37 +0100,
Pascal  wrote:

> hi,
> 
> here, I have this simple script that tests if the /tmp/test file can be
> opened in write mode :
> 
> $ cat /tmp/append
> #!/usr/bin/python
> with open('/tmp/test', 'a'): pass
> 
> the file does not exist yet :
> 
> $ chmod +x /tmp/append
> $ ls -l /tmp/test
> ls: cannot access '/tmp/test': No such file or directory
> 
> the script is launched as a simple user :
> 
> $ /tmp/append
> $ ls -l /tmp/test
> -rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test
> 
> everything is ok.
> now, the script fails if it is replayed as root user with the sudo command :
> 
> $ sudo /tmp/append
> [sudo] password for user:
> Traceback (most recent call last):
>   File "/tmp/append", line 2, in 
> with open('/tmp/test', 'a'):
> PermissionError: [Errno 13] Permission denied: '/tmp/test'
> 
> the problem is the same if the opening mode is 'w' or if "sudo -i" or "su -"
> are used.
> 
> why can't root user under python manipulate the simple user file ?

This has to do with the idiosyncratic permissions of the /tmp directory
and not your code.  In my shell on my Linux box:

$ rm -f /tmp/x
$ echo x >/tmp/x
$ echo x | sudo tee /tmp/x
tee: /tmp/x: Permission denied
x

$ ls -ld /tmp
drwxrwxrwt 13 root root 380 Dec 17 06:03 /tmp

Try your experiment in a different directory, one without the sticky bit
set.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread jak

Il 17/12/2020 12:40, Peter J. Holzer ha scritto:

On 2020-12-17 12:16:29 +0100, jak wrote:

print(_ if d.get('a', None) is not None else get_default())


That doesn't work:


print(_ if d.get('a', None) is not None else get_default())

Traceback (most recent call last):
   File "", line 1, in 
NameError: name '_' is not defined

But this works:


print(_ if (_ := d.get('a', None)) is not None else get_default())

1

(I would prefer ChrisA's solution, though.)

 hp


this one?



D['a'] if 'a' in D else get_default()

ChrisA



This solution search two times same key.
--
https://mail.python.org/mailman/listinfo/python-list


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread Chris Angelico
On Thu, Dec 17, 2020 at 11:16 PM jak  wrote:
>
> Il 17/12/2020 12:40, Peter J. Holzer ha scritto:
> > On 2020-12-17 12:16:29 +0100, jak wrote:
> >> print(_ if d.get('a', None) is not None else get_default())
> >
> > That doesn't work:
> >
>  print(_ if d.get('a', None) is not None else get_default())
> > Traceback (most recent call last):
> >File "", line 1, in 
> > NameError: name '_' is not defined
> >
> > But this works:
> >
>  print(_ if (_ := d.get('a', None)) is not None else get_default())
> > 1
> >
> > (I would prefer ChrisA's solution, though.)
> >
> >  hp
> >
> this one?
>
> 
>
> D['a'] if 'a' in D else get_default()
>
> ChrisA
>
> 
>
> This solution search two times same key.

Yes, it does, but hash lookups are pretty fast. Unless your key is
some sort of custom object with a very expensive __hash__ function,
the double lookup isn't going to be too costly. But if that does
bother you, you can write it as a try/except instead.

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


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread jak

Il 17/12/2020 12:40, Peter J. Holzer ha scritto:

On 2020-12-17 12:16:29 +0100, jak wrote:

print(_ if d.get('a', None) is not None else get_default())


That doesn't work:


print(_ if d.get('a', None) is not None else get_default())

Traceback (most recent call last):
   File "", line 1, in 
NameError: name '_' is not defined

But this works:


print(_ if (_ := d.get('a', None)) is not None else get_default())

1

(I would prefer ChrisA's solution, though.)

 hp



I had already corrected my oversight (jak 12:32):

> print((_ if d.get('a', None) is not None else get_default()))

while your fix works but not correctly because in that way does not 
collect the return code of the function get_default().

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


Re: sudo python PermissionError [Errno 13] Permission denied

2020-12-17 Thread Pascal
you are right !

the "sticky bit" set to /tmp/ prevents the root user from altering the file
belonging to the simple user !

$ ls -ld /tmp/
drwxrwxrwt 13 root root 320 Dec 17 13:22 /tmp/

$ ls -l /tmp/test
-rw-r--r-- 1 user 0 Dec 17 13:24 /tmp/test

$ echo test | sudo tee -a /tmp/test
tee: /tmp/test: Permission denied
test

but it does not prevent its deletion !

$ sudo rm -v /tmp/test
removed '/tmp/test'.

which misled me : sorry for the waste of time.

happy end of year 2020, lacsaP.

Le jeu. 17 déc. 2020 à 13:09, <2qdxy4rzwzuui...@potatochowder.com> a écrit :

> On 2020-12-17 at 11:17:37 +0100,
> Pascal  wrote:
>
> > hi,
> >
> > here, I have this simple script that tests if the /tmp/test file can be
> > opened in write mode :
> >
> > $ cat /tmp/append
> > #!/usr/bin/python
> > with open('/tmp/test', 'a'): pass
> >
> > the file does not exist yet :
> >
> > $ chmod +x /tmp/append
> > $ ls -l /tmp/test
> > ls: cannot access '/tmp/test': No such file or directory
> >
> > the script is launched as a simple user :
> >
> > $ /tmp/append
> > $ ls -l /tmp/test
> > -rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test
> >
> > everything is ok.
> > now, the script fails if it is replayed as root user with the sudo
> command :
> >
> > $ sudo /tmp/append
> > [sudo] password for user:
> > Traceback (most recent call last):
> >   File "/tmp/append", line 2, in 
> > with open('/tmp/test', 'a'):
> > PermissionError: [Errno 13] Permission denied: '/tmp/test'
> >
> > the problem is the same if the opening mode is 'w' or if "sudo -i" or
> "su -"
> > are used.
> >
> > why can't root user under python manipulate the simple user file ?
>
> This has to do with the idiosyncratic permissions of the /tmp directory
> and not your code.  In my shell on my Linux box:
>
> $ rm -f /tmp/x
> $ echo x >/tmp/x
> $ echo x | sudo tee /tmp/x
> tee: /tmp/x: Permission denied
> x
>
> $ ls -ld /tmp
> drwxrwxrwt 13 root root 380 Dec 17 06:03 /tmp
>
> Try your experiment in a different directory, one without the sticky bit
> set.
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: dict.get(key, default) evaluates default even if key exists

2020-12-17 Thread jak

Il 17/12/2020 13:33, Chris Angelico ha scritto:

On Thu, Dec 17, 2020 at 11:16 PM jak  wrote:


Il 17/12/2020 12:40, Peter J. Holzer ha scritto:

On 2020-12-17 12:16:29 +0100, jak wrote:

print(_ if d.get('a', None) is not None else get_default())


That doesn't work:


print(_ if d.get('a', None) is not None else get_default())

Traceback (most recent call last):
File "", line 1, in 
NameError: name '_' is not defined

But this works:


print(_ if (_ := d.get('a', None)) is not None else get_default())

1

(I would prefer ChrisA's solution, though.)

  hp


this one?



D['a'] if 'a' in D else get_default()

ChrisA



This solution search two times same key.


Yes, it does, but hash lookups are pretty fast. Unless your key is
some sort of custom object with a very expensive __hash__ function,
the double lookup isn't going to be too costly. But if that does
bother you, you can write it as a try/except instead.

ChrisA



try/except is a very expensive time. if we have a small dictionary in 
which you do little research, you definitely have reason. I would be 
curious to see the differences by taking times with 50 / 60K records by 
repeating the search 1 or 2 million times with and without try/except 
and also searching 1 or 2 times too.


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


Re: Review, suggestion etc?

2020-12-17 Thread Bischoop
On 2020-12-17, Michał Jaworski  wrote:

Thanks for feedback and useful tips. 
I couldn't use any OOP here because have not a clue about it, just going
to go toward it.


> I've made a quick look at the code and even executed it. It looks pretty
> clear and is easy to understand, although it has some structural problems.
> I won't do a thorough review but highlight the most important problems.
>
> First, the recursive user input pattern you use:
>   def marriage():
> maritals = input('Married: Yes/No ?: ').title()
> while maritals != 'Yes' and maritals != 'No':
> return marriage()
> return maritals
>
>
> def marriage():
> ...
>

Could you expand here, I rather don't know how I could do it different
way apart from if maritals == 'Yes' or maritals == 'No' or is it what
you meant?


> You shouldn't be doing that unless you need a closure with nonlocal
> variables to read from. Otherwise it really harms the readability. I
> understand the urge to keep relevant code close to the usage but you would
> have better results with modules. If you really want to keep everything in
> a single module, keep functions close together in the file but don't nest
> them. Use relevant naming conventions instead. Simply think of how you
> would write that in C. You could use some object-oriented approach too, but
> I would recommend polishing structural programming first.
>

Well I don't know C, the only other language I was learning it was basic
for Atari :-) So in other words I shoudn't nest functions like in
changes(), add_people() etc but keep
everything in one functions. 

> There are also other issues like not always closing files, and not
> validating the user input in specific places. Still, these will be more
> evident as you improve the structure of application and do thorough
> testing. Anyway, the code doesn't look bad. It of course needs improvement
> but I've also seen worse specimens from people being actually paid for
> writing the code.
>
> Remember that "how to make things better" is a function of few parameters:
> - what you want to achieve
> - what are you able to do
> - how much time do you have
>
> If your sole goal is to learn and improve skills, I would recommend
> polishing this in current procedural fashion to some extent, but not trying
> to make it perfect. Then I would start from scratch and experiment with
> different paradigms (OOP for instance). Then I would try to make a smaller
> project that has some actual utility.
>

Yes, I was pretty much interested in Python at the end 90s however life
made me putting this hobby away and now life changed again so I've more
free time and I'm happy be back with Python so after couple months
learning it again and writing few liners this is first thing that got me
to use what I've learnt so far and gave opportunity to solve moany
problems I had to deal with (had few nights without sleep ) :-)
Now I'll learn OOP as you said and then try to made this program again
with OOP from scratch.

--
Thanks

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


Messed up syntax in Vim when pasting python code to post to the groups.

2020-12-17 Thread Bischoop


I've being asked not to use external links for code sharing to the
groups but when I paste the code in to my vim editor I do use with slrn
client the code is just messed up. 
How dear people people using vim solved this?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Messed up syntax in Vim when pasting python code to post to the groups.

2020-12-17 Thread 2QdxY4RzWzUUiLuE
On 2020-12-17 at 16:20:16 -,
Bischoop  wrote:

> I've being asked not to use external links for code sharing to the
> groups but when I paste the code in to my vim editor I do use with
> slrn client the code is just messed up.

> How dear people people using vim solved this?

I'm not a vim user, but it just came up to look into the paste and
nopaste commands.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Review, suggestion etc?

2020-12-17 Thread Michael Torrie
On 12/17/20 9:10 AM, Bischoop wrote:
> Could you expand here, I rather don't know how I could do it different
> way apart from if maritals == 'Yes' or maritals == 'No' or is it what
> you meant?

I think he's hinting at using a loop instead.

while maritals != 'Yes' and maritals != 'No':
maritals = input('Married: Yes/No ?: ').title()

I think I got the logical condition right. Sometimes those are tricky!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Messed up syntax in Vim when pasting python code to post to the groups.

2020-12-17 Thread Bischoop
On 2020-12-17, Bischoop  wrote:
>
> I've being asked not to use external links for code sharing to the
> groups but when I paste the code in to my vim editor I do use with slrn
> client the code is just messed up. 
> How dear people people using vim solved this?

Solved, partialy. Paste mode F2, however after pasting clicking F2 again
supposed to go to paste option OFF but in my case it's still pasting
without messing syntax, but yes I can paste with correct syntax.

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


Re: Messed up syntax in Vim when pasting python code to post to the groups.

2020-12-17 Thread Bischoop
On 2020-12-17, 2qdxy4rzwzuui...@potatochowder.com 
<2qdxy4rzwzuui...@potatochowder.com> wrote:
>
> I'm not a vim user, but it just came up to look into the paste and
> nopaste commands.

I've googled the matter and found pressing F2 toogles 'paste' mode and
then after pasting F2 again to switch off paste mode or manually 
:set paste
:set nopaste

https://vim.fandom.com/wiki/Toggle_auto-indenting_for_code_paste

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


Re: Review, suggestion etc?

2020-12-17 Thread Bischoop
On 2020-12-17, Michael Torrie  wrote:
> On 12/17/20 9:10 AM, Bischoop wrote:
>> Could you expand here, I rather don't know how I could do it different
>> way apart from if maritals == 'Yes' or maritals == 'No' or is it what
>> you meant?
>
> I think he's hinting at using a loop instead.
>
> while maritals != 'Yes' and maritals != 'No':
> maritals = input('Married: Yes/No ?: ').title()
>
> I think I got the logical condition right. Sometimes those are tricky!

I think you're right.
Yes those are tricky sometimes :-)

Look how I had it previously:

def marriage():
maritals = input('Married: Yes/No ?: ').title()
while maritals != 'Yes' and maritals != 'No':
return marriage()
return maritals
marital = marriage()


When looking at it now I couldn't find the dumbest way for it.


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


Re: Review, suggestion etc?

2020-12-17 Thread Michał Jaworski
> I think he's hinting at using a loop instead.
>
> while maritals != 'Yes' and maritals != 'No':
>maritals = input('Married: Yes/No ?: ').title()

Exactly. I would go even further and make it a reusable function. Eg.

def prompt_choices(prompt, choices):
choices = set(c.lower() for c in choices)
while value := input(f"{prompt} {choices}:").lower() not in choices:
pass
return value

Or without := operator:

def prompt_choices(prompt, choices):
value = None
choices = set(c.lower() for c in choices)
while value not in choices:
input(f"{prompt} {choices}:").lower()
return value

That way you can use it as follows:

marital = prompt_choices("Married", ["yes", "no"])

> So in other words I shoudn't nest functions like in
> changes(), add_people() etc but keep
> everything in one functions.

Simply move those functions outside of their "hosting" functions and
call them as they are. Also, many of them won't be needed anymore as you
introduce some generic helper functions (e.g. prompt_choices).

> Now I'll learn OOP as you said and then try to made this program again
> with OOP from scratch.

Recommend polishing the procedural approach a bit more too, though. Like
reducing code repetition. Looking into how data is stored, eg. can fields
be stored in CSV columns instead of JSON? OOP can be overwhelming at the
very beginning. For instance it can take some time learning what should be
an object and what shouldn't. You definitely can start adding e.g.
dataclasses because they are more like structures (e.g. struct in C
mentioned earlier).

czw., 17 gru 2020 o 17:38 Michael Torrie  napisał(a):

> On 12/17/20 9:10 AM, Bischoop wrote:
> > Could you expand here, I rather don't know how I could do it different
> > way apart from if maritals == 'Yes' or maritals == 'No' or is it what
> > you meant?
>
> I think he's hinting at using a loop instead.
>
> while maritals != 'Yes' and maritals != 'No':
> maritals = input('Married: Yes/No ?: ').title()
>
> I think I got the logical condition right. Sometimes those are tricky!
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Review, suggestion etc?

2020-12-17 Thread Bischoop
On 2020-12-17, Michał Jaworski  wrote:
>
> Exactly. I would go even further and make it a reusable function. Eg.
>
> def prompt_choices(prompt, choices):
> choices = set(c.lower() for c in choices)
> while value := input(f"{prompt} {choices}:").lower() not in choices:
> pass
> return value
>
> Or without := operator:
>
> def prompt_choices(prompt, choices):
> value = None
> choices = set(c.lower() for c in choices)
> while value not in choices:
> input(f"{prompt} {choices}:").lower()
> return value
>
> That way you can use it as follows:
>
> marital = prompt_choices("Married", ["yes", "no"])
>

Oh man that really not like they teach in tutorials.
These are the examples at which you look and think: moment, I need a few sec
to follow :-)


>> So in other words I shoudn't nest functions like in
>> changes(), add_people() etc but keep
>> everything in one functions.
>
> Simply move those functions outside of their "hosting" functions and
> call them as they are. Also, many of them won't be needed anymore as you
> introduce some generic helper functions (e.g. prompt_choices).
>


Honestly I've done it like that because I thought that would be more elegant
way to have how_old(), marriage() etc hosted in add_people() but I'm glad I've 
done this time because learn a bit, I had quite a problem to keep people
argument storing and returning in every function, I see it was unecessary
as I know now but another experience.

>> Now I'll learn OOP as you said and then try to made this program again
>> with OOP from scratch.
>
> Recommend polishing the procedural approach a bit more too, though. Like
> reducing code repetition. Looking into how data is stored, eg. can fields
> be stored in CSV columns instead of JSON? OOP can be overwhelming at the
> very beginning. For instance it can take some time learning what should be
> an object and what shouldn't. You definitely can start adding e.g.
> dataclasses because they are more like structures (e.g. struct in C
> mentioned earlier).
>

Right I keep it in mind. Yes, the storing you mention I'll have to
improve, even the json I've done sucks because I've noticed it storing
everything in one column lol I thought that json library handles it
itself but apparently I have to tell him about it to insert key,values
into different columns.

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


Re: Function returns old value

2020-12-17 Thread Bischoop
On 2020-12-17, dn  wrote:
>> After expiry, any posts 'here' with links to 'there', will be useless.
>> 
>> I do mind that however I thoght it better if paste a whole code to see
>> and pasting from my IDE to vim/slrn was messing syntax, I'll do better
>> next time.
>
>
> Yes, it can be difficult to know how much code to include and how much 
> can be left-out. Don't worry about that - replies can always trim any 
> excess.
>

I solved the pasting problem but about triming the excess, well
some people don't give a fuck and don't cut unecessary lines.
I'm pretty sure that if I post a 100 line code, some will reply without
cutting it just to point what's wrong in line 50 lol.




> Also, don't be concerned about such comments. Rather than complaints, 
> please regard them as advice from folk who have been 'here' and/or using 
> Python for some time.

I'm not concerned at all :-) 
I'm using newsgroups,irc for good over 20 years so I don't bother.

--
Thanks

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


Re: Function returns old value

2020-12-17 Thread Bischoop
On 2020-12-17, Peter J. Holzer  wrote:
>
> --EVF5PPMfhYS0aIcm
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> Content-Transfer-Encoding: quoted-printable
>
> On 2020-12-17 03:06:32 -, Bischoop wrote:
>> pasting from my IDE to vim/slrn was messing syntax,
>
> You can=20
>
>:set paste

Indeed, thanks I just didn't come to conclusion that it has to be special
paste mode to paste without breaking the lines. 
Also  adding in * set pastetoggle= * in vimrc activates paste
mode when pressing F2, I find it more convenient.
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Lambda in parameters

2020-12-17 Thread Abdur-Rahmaan Janhangeer
Greetings list,

Here is a famous question's solution

def cons(a, b):
def pair(f):
return f(a, b)
return pair

def car(c):
return c(lambda a, b: a)

print(cons(1, 2)(lambda a, b: a))
print(car(cons(1, 2)))

The aim of car is to return 1


but i don't understand how lambda achieves this

Kind Regards,


Abdur-Rahmaan Janhangeer

https://www.github.com/Abdur-RahmaanJ

Mauritius

sent from gmail client on Android, that's why the signature is so ugly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function returns old value

2020-12-17 Thread Michael F. Stemper

On 17/12/2020 03.57, Peter J. Holzer wrote:

On 2020-12-17 03:06:32 -, Bischoop wrote:

pasting from my IDE to vim/slrn was messing syntax,


You can

:set paste

in vim to prevent it from messing with pasted content (don't forget to
set nopaste afterwards).


What's the difference between that and
:set ai
and
:set noai


With newer vims that's rarely necessary though since they can distinguish
between input that was pasted and input that was typed.


I thought that I was going nuts when I encountered that. Any idea how to
defeat such a so-called 'feature"?


--
Michael F. Stemper
The name of the story is "A Sound of Thunder".
It was written by Ray Bradbury. You're welcome.
--
https://mail.python.org/mailman/listinfo/python-list


setuptools issue

2020-12-17 Thread Rich Shepard

I want to use tkcalendar and dateentry in my application but have problems
with tkcalendar's dependency on babel and setuptools.

When I try to build babel it fails:
Traceback (most recent call last):
  File "/tmp/SBo/babel-2.8.1/setup.py", line 7, in 
from setuptools import setup
ModuleNotFoundError: No module named 'setuptools'

Installed on this Slackware-14.2/x86_64 workstation with python-3.9.1 are:
python-setuptools-22.0.5-x86_64-1
setuptools-git-1.1-x86_64-1_SBo
setuptools-scm-3.3.3-x86_64-1_SBo

Please advise me how I diagnose the reason babel's setup.py cannot find a
suitable setuptools.

TIA,

Rich

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


Re: Review, suggestion etc?

2020-12-17 Thread Bischoop
On 2020-12-17, Dennis Lee Bieber  wrote:
>>
>
>   The main concern is that you are using a RECURSIVE call. It is much
> better for such input checking to use an ITERATIVE (loop) scheme.
>
>   def marriage():
>   #loop forever
>   while True:
>   #get response from user
>   maritals = input("Married: Yes/No ?").title()
>   #if response is good, exit (break) the loop
>   if maritals in ["Yes", "No"]: break
>   #otherwise display error message and repeat loop
>   print("Try again. Please respond with Yes or No")
>   #return valid response
>   return maritals
>   
>
It makes sense for me now, better logic used here than mine. 
I've never met that way used in * if maritals in ['Yes', No']: * ,
it makes code elegant. 
So it's not good to use calling function itself (recursive call), I get it now.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Review, suggestion etc?

2020-12-17 Thread Bischoop
On 2020-12-17, Bischoop  wrote:
> On 2020-12-17, Dennis Lee Bieber  wrote:
>>>
>>
>>  The main concern is that you are using a RECURSIVE call. It is much
>> better for such input checking to use an ITERATIVE (loop) scheme.
>>
>>  def marriage():
>>  #loop forever
>>  while True:
>>  #get response from user
>>  maritals = input("Married: Yes/No ?").title()
>>  #if response is good, exit (break) the loop
>>  if maritals in ["Yes", "No"]: break
>>  #otherwise display error message and repeat loop
>>  print("Try again. Please respond with Yes or No")
>>  #return valid response
>>  return maritals
>>  
>>
> It makes sense for me now, better logic used here than mine. 
> I've never met that way used in * if maritals in ['Yes', No']: * ,
> it makes code elegant. 
> So it's not good to use calling function itself (recursive call), I get it 
> now.

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


RE: setuptools issue

2020-12-17 Thread Joseph L. Casale
> Installed on this Slackware-14.2/x86_64 workstation with python-3.9.1 are:
> python-setuptools-22.0.5-x86_64-1

I just ran into this recently, I don't recall the actual source but it was the 
version
of setuptools having been so old. Your version is from Jun 3, 2016...

Update it, that was what worked for me.

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


Re: Review, suggestion etc?

2020-12-17 Thread Joe Pfeiffer
Bischoop  writes:

> On 2020-12-17, Dennis Lee Bieber  wrote:
>>>
>>
>>  The main concern is that you are using a RECURSIVE call. It is much
>> better for such input checking to use an ITERATIVE (loop) scheme.
>>
>>  def marriage():
>>  #loop forever
>>  while True:
>>  #get response from user
>>  maritals = input("Married: Yes/No ?").title()
>>  #if response is good, exit (break) the loop
>>  if maritals in ["Yes", "No"]: break
>>  #otherwise display error message and repeat loop
>>  print("Try again. Please respond with Yes or No")
>>  #return valid response
>>  return maritals
>>  
>>
> It makes sense for me now, better logic used here than mine. 
> I've never met that way used in * if maritals in ['Yes', No']: * ,
> it makes code elegant. 
> So it's not good to use calling function itself (recursive call), I get it 
> now.

Recursion has very limited application, but where it's the right tool
it's invaluable (top-down parsers, some graph algorithms...).  We teach
it primarily because by the time a student has a good handle on how to
write a recursive function they understand functions in general really well.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Review, suggestion etc?

2020-12-17 Thread Grant Edwards
On 2020-12-18, Joe Pfeiffer  wrote:

> Recursion has very limited application, but where it's the right
> tool it's invaluable (top-down parsers, some graph algorithms...).
> We teach it primarily because by the time a student has a good
> handle on how to write a recursive function they understand
> functions in general really well.

Yep, there are definitly cases where it's pretty much the only right
answer. If you try to avoid it, you end up writing what turns into a
simulation of recursion -- and doing that correctly isn't easy.

--
Grant




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


Re: Lambda in parameters

2020-12-17 Thread Cameron Simpson
On 17Dec2020 23:52, Abdur-Rahmaan Janhangeer  wrote:
>Here is a famous question's solution

These look like implementations of Lisp operators, which I've never 
found easy to remember. So I'll do this from first principles, but 
looking at the (uncommented) code.

This is some gratuitiously tricky code. Maybe that's needed for these 
operators. But there's a lot here, so let's unpick it:

>def cons(a, b):
>def pair(f):
>return f(a, b)
>return pair

Cons returns "pair", a function which itself accepts a function "f", 
calls it with 2 values "a, b" and returns the result. For ultra 
trickiness, those 2 values "a, b" are the ones you passed to the initial 
call to cons().

This last bit is a closure: when you define a function, any nonlocal 
variables (those you use but never assign to) have the defining scope 
available for finding them. So the "pair" function gets "a" and "b" from 
those you passed to "cons".

Anyway, cons() returns a "pair" function hooked to the "a" and "b" you 
called it with.

>def car(c):
>return c(lambda a, b: a)

The function accepts a function, and calls that function with "lambda a, 
b: a", which is itself a function which returns its first argument. You 
could write car like this:

def car(c):
def first(a, b):
return a
return c(first)

The lambda is just a way to write a simple single expression function.

>print(cons(1, 2)(lambda a, b: a))

What is "cons(1,2)". That returns a "pair" function hooked up to the a=1 
and b=2 values you supplied. And the pair function accepts a function of 
2 variables.

What does this do?

cons(1, 2)(lambda a, b: a)

This takes the function returns by cons(1,2) and _calls_ that with a 
simple function which accepts 2 values and returns the first of them.

So:

cons(1,2) => "pair function hooked to a=1 and b=2"

Then call:

pair(lambda a, b: a)

which sets "f" to the lambda function, can calls that with (a,b). So it 
calls the lambda function with (1,2). Which returns 1.

>print(car(cons(1, 2)))

The "car" function pretty much just embodies the call-with-the-lambda.

>but i don't understand how lambda achieves this

If you rewite the lambda like this:

def a_from_ab(a,b):
return a

and then rewrite the first call to cons() like this:

cons(1,2)(a_from_ab)

does it make any more sense?

Frankly, I think this is a terrible way to solve this problem, whatever 
the problem was supposed to be - that is not clear.

On the other hand, I presume it does implement the Lisp cons and car 
functions. I truly have no idea, I just remember these names from my 
brief brush with Lisp in the past.

Cheers,
Cameron Simpson 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function returns old value

2020-12-17 Thread Cameron Simpson
On 17Dec2020 14:22, Michael F. Stemper  wrote:
>On 17/12/2020 03.57, Peter J. Holzer wrote:
>>On 2020-12-17 03:06:32 -, Bischoop wrote:
>>>pasting from my IDE to vim/slrn was messing syntax,
>>
>>You can
>>
>>:set paste
>>
>>in vim to prevent it from messing with pasted content (don't forget to
>>set nopaste afterwards).
>
>What's the difference between that and
>:set ai
>and
>:set noai

Well, based on my experience (since the above is what I always do) that 
leave my automatic line folding and related "line wrapping" stuff still 
in play. Which I routinely have to repair if the pasted code is at all 
wide.

[ Experiments with ":set paste". ]

Yeah, the paste mode turns all that wrapping stuff off, and ":set 
nopaste" restores it intact. Ok, I guess I'm going to have to retrain my 
fingers now.

>>With newer vims that's rarely necessary though since they can 
>>distinguish
>>between input that was pasted and input that was typed.

Mine doesn't seem to (vim inside a MacOS iTerm).

>I thought that I was going nuts when I encountered that. Any idea how to
>defeat such a so-called 'feature"?

You mean having vim figure that out? I dunno. I came here from vi and 
haven't fully embraced al the stuff vim has.

I _did_ discover recently that somehow iTerm and/or vim knows about my 
vim split buffers and doesn't cross the entirely in-vim-curses window 
boundary, very very handy. I guess iTerm may know about terminal 
scrolling regions, if that's how vim implements the windowing stuff.

Cheers,
Cameron Simpson 
-- 
https://mail.python.org/mailman/listinfo/python-list