Re: Why do these statements evaluate the way they do?

2016-05-07 Thread Kev Dwyer
Anthony Papillion wrote:

> I'm trying to figure out why the following statements evaluate the way
> they do and I'm not grasping it for some reason. I'm hoping someone can
> help me.
> 
> 40+2 is 42 #evaluates to True
> But
> 2**32 is 2**32 #evaluates to False
> 
> This is an example taken from a Microsoft blog on the topic. They say the
> reason is because the return is based on identity and not value but, to
> me, these statements are fairly equal.
> 
> Can someone clue me in?
> 
> Anthony

The *is* operator tests for identity, that is whether the objects on either 
side of the operator are the same object.

CPython caches ints in the range -5 to 256 as an optimisation, so ints in 
this range are always the same object, and so the is operator returns True.

Outside this range, a new int is created as required, and comparisons using 
is return False.

This can be seen by looking at the id of the ints:

Python 3.5.1 (default, Dec 29 2015, 10:53:52)   

[GCC 4.8.3 20140627 [gcc-4_8-branch revision 212064]] on linux  

Type "help", "copyright", "credits" or "license" for more information. 
>>> a = 42
>>> b = 42
>>> a is b
True
>>> id(a)
9186720
>>> id(b)
9186720
>>> c = 2 ** 32
>>> d = 2 ** 32
>>> c is d
False
>>> id(c)
140483107705136
>>> id(d)
140483107705168

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Rustom Mody
On Saturday, May 7, 2016 at 12:13:59 PM UTC+5:30, Gregory Ewing wrote:
> Steven D'Aprano wrote:
> > Who is setting and enforcing this quota, and given that only about 1 in 20
> > Python programmers is a woman, do you think men are seriously missing out
> > on any opportunities?
> 
> Suppose there are 100 people wanting to ask questions, and
> there is only time to answer 10 questions. If the 1 in 20
> ratio holds, then 5 of those people are women and the other
> 95 are men.
> 
> Alternating between men and women means that all of the
> women get their questions answered, and only 5/95 of the
> men. So in this example, if you're a woman you have a 100%
> chance of getting answered, and if you're a man you only
> have a 5.26% chance.
> 
> Whether you think this is a good strategy or not,
> beliavsky is right that it's not "equal".

Usually I steer away from these (type of) discussions.
However... Trump  seems to be winning
And with that there are these kind of discussions...
Here's a short snippet of an exchange I had with an ex-student of mine:
-
Student: This may be a pretty controversial statement. But if I'd have voting
rights in this country I'd have voted for Trump.

You are at-least getting what you are seeing. Everyone else is trying to be
politically correct where as this guy doesn't give rat's a** about it.

My response: Political correctness is incorrect doesn't mean
Political incorrectness is correct  :-)
---

On the question of quotas:
Any corrective system that seeks to redress an inquity must BY-DESIGN
asymptotically self-destruct.
Else we have a problem being 'cured' with a remedy-worse-than-the-evil.
IOW: A world of A-oppresses-B is not improved by one of B-oppresses-A.

As examples of asymptotic self-destruction:
1. Say there is a quota for education for some kind of minority.
Should it be the same from kindergarten to MDs in neuro-surgery?
If yes would you go to such a quota-MD when the need arises?

2. Likewise say a quota of say X% seats reserved is put in place.
Should this X remain untouched for 5? 10? 20? 50? 100? years

As for Guido's Q/A practices: I find it good that he does as he does...
As long as it does not become a habit!!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why do these statements evaluate the way they do?

2016-05-07 Thread Stephen Hansen
On Fri, May 6, 2016, at 11:36 PM, Anthony Papillion wrote:
> I'm trying to figure out why the following statements evaluate the way
> they do and I'm not grasping it for some reason. I'm hoping someone can
> help me.
> 
> 40+2 is 42 #evaluates to True
> But
> 2**32 is 2**32 #evaluates to False
> 
> This is an example taken from a Microsoft blog on the topic. They say the
> reason is because the return is based on identity and not value but, to
> me, these statements are fairly equal.

Yes, those statements are fairly *equal*. But you are not testing
*equality*. The "is" operator is testing *object identity*.

>>> a = 123456
>>> b = 123456
>>> a is b
False
>>> a == b
True

Equality means, "do these objects equal the same", identity means, "are
these specific objects the exact same objects".

In the above, a and b are different objects. There's two objects that
contain a value of 12345. They are equal (see the == test), but they are
different objects. 

If you write on a piece of paper "12345", and I write on a piece of
paper "12345", are those two pieces of paper identical? Of course not.
Your paper is in your hand, mine is in mine. These are different pieces
of paper. Just look at them: they're clearly not the same thing. That
said, if you look at the number they contain, they're the same value.

Our two pieces of paper are equivalent, but they're different objects.

This might get confusing for you because:

>>> a = 123
>>> b = 123
>>> a is b
True
>>> a == b 
True

This happens because Python caches small integers, so everytime you
write '123', it re-uses that same '123' object everyone else is using.
It shares those objects as an optimization.

The long and short of it is: you should almost never use 'is' for
comparing integers (or strings). It doesn't mean what you think it does
and isn't useful to you. Compare equality.

In general, the only things you should use 'is' for is when comparing to
singletons like None, True or False (And consider strongly not comparing
against False/True with is, but instead just 'if thing' and if its True,
it passes).

Otherwise, 'is' should only be used when you're comparing *object
identity*. You don't need to do that usually. Only do it when it matters
to you that an object with value A might be equal to an object of value
B, but you care that they're really different objects.


-- 
Stephen Hansen
  m e @ i x o k a i  . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Stephen Hansen
On Fri, May 6, 2016, at 11:43 PM, Gregory Ewing wrote:
> Steven D'Aprano wrote:
> > Who is setting and enforcing this quota, and given that only about 1 in 20
> > Python programmers is a woman, do you think men are seriously missing out
> > on any opportunities?
> 
> Suppose there are 100 people wanting to ask questions, and
> there is only time to answer 10 questions. If the 1 in 20
> ratio holds, then 5 of those people are women and the other
> 95 are men.
> 
> Alternating between men and women means that all of the
> women get their questions answered, and only 5/95 of the
> men. So in this example, if you're a woman you have a 100%
> chance of getting answered, and if you're a man you only
> have a 5.26% chance.
> 
> Whether you think this is a good strategy or not,
> beliavsky is right that it's not "equal".

This is a pedantically and nonsensical definition of "equal", that
ignores the many, many reasons why there are 1 in 20 women in that
conference. Its looking at the end effect and ignoring everything that
leads up to it, and deciding its instead special rights -- this is the
great argument against minorities getting a voice, that their requests
for equal *opportunity* are instead *special rights* that diminish the
established majority's entrenched power. 

Those women are dealing with suppression, discrimination and dismissal
on multiple levels that leave them in a disenfranchised position. 

Recognizing those faults and taking corrective action is fundamentally
an act in the name of equality. 

Correcting for inequalities can not, itself, be a purely "equal" task
done in pure blindness of the contextual reality of what is going on in
the world. 

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why do these statements evaluate the way they do?

2016-05-07 Thread Chris Angelico
On Sat, May 7, 2016 at 5:49 PM, Stephen Hansen  wrote:
> The long and short of it is: you should almost never use 'is' for
> comparing integers (or strings). It doesn't mean what you think it does
> and isn't useful to you. Compare equality.
>
> In general, the only things you should use 'is' for is when comparing to
> singletons like None, True or False (And consider strongly not comparing
> against False/True with is, but instead just 'if thing' and if its True,
> it passes).
>
> Otherwise, 'is' should only be used when you're comparing *object
> identity*. You don't need to do that usually. Only do it when it matters
> to you that an object with value A might be equal to an object of value
> B, but you care that they're really different objects.

Equality sometimes is immaterial; there are times when you want to
know whether this object you got back is the same one that was sent
in, and equality's out of the question. (It's funny how there's this
parallel thread about "equal opportunity", in which gender equality is
the focus. In this thread, equality really CAN be irrelevant.) For
example, to adequately distinguish between "argument omitted" and
"some argument was provided", this idiom is commonly used:

_SENTINEL = object()
def next(iterator, default=_SENTINEL):
try:
return iterator.__next__()
except StopIteration:
if default is _SENTINEL: raise
return default

It makes no difference whatsoever whether the default might compare
equal to something; all that matters is: "Is this the sentinel?". And
this check is faster and safer than equality, anyway.

But with integers and strings, always do equality checks. (Interned
strings can safely be identity-checked, which would be faster in the
case where they're unequal, but that's a micro-optimization that's
safe ONLY if both strings have definitely been interned, so it's
better not to bother.)

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


Re: Slight problems with python in Windows

2016-05-07 Thread Peter Toye
Thanks Zachary.

I should have put a newbie warning as I've never used or installed Python 
before, so some of what you've written goes over my head! 


Friday, May 6, 2016, 5:17:23 PM, you wrote:

> Hi Peter,

> On Fri, May 6, 2016 at 6:22 AM, Peter Toye  wrote:
>> I'm trying to install Python under Windows 7 so that I can use git-review 
>> and have found a few niggling issues.
>>
>> 1) Apparently (according to the git-review pages) pip has a problem with 
>> directories with spaces in their names. Python's default installation 
>> directory is under Program Files. I agree that this is a pip issue rather 
>> than a Python one, but maybe a warning message would help?

> I don't believe this is true anymore, I've successfully used pip with
> 3.5 installed in Program Files, and also just now in a test venv named
> "test venv".  Do note that with installation in Program Files, you get
> the benefits of the install directory being writable only to
> administrators, but also the drawbacks: only administrators can use
> pip to install to the global site-packages.  You can use either 'pip
> --user', or create a venv in a directory writable to you and use it.
> Also note that you can't use "pip.exe" to upgrade pip itself since it
> can't overwrite "pip.exe" while it's in use; use 'python -m pip'
> instead.

My information is obviously out of date - I'll try to get it changed in the 
git-review wiki.


>> 2) According to the Programs and Files section of the Windows Control Panel, 
>> installing Python also installs something called the Python Launcher. When I 
>> try to remove this (so I can reinstall Python in a better directory) is 
>> comes up with an error message:

> The Python Launcher is a very handy tool called 'py.exe' which makes
> it much easier to use more than one version of Python on a Windows
> machine.  In an all users install, py.exe is installed to C:\Windows
> and is thus always available on PATH, so you can invoke Python 3.5 by
> calling 'py -3.5' without having to adjust your PATH.  The error
> message is odd, though, would you mind trying to reproduce it and
> opening a bug at bugs.python.org?

When I have time.This has already taken longer than it should...

>> Error opening installation log file.  Verify that the specified log file 
>> location exists and is writable.
>>
>> After reinstalling I now have 2 copies of the launcher I hope it doesn't 
>> give me any problems.

> It shouldn't.  The launcher only installs 2 files, py.exe and pyw.exe
> (counterpart to pythonw.exe), both in C:\Windows.

>> 3) After uninstalling Python the installation directory is still there with 
>> a few files in it (possibly connected with the previous issue). Can I just 
>> delete it?

> Yes, that should be fine.  I would guess it's still there due to pip
> artifacts in Lib\ and Scripts\.

> Hope this helps,

It does - thanks.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Marko Rauhamaa
Gregory Ewing :

> Suppose there are 100 people wanting to ask questions, and there is
> only time to answer 10 questions. If the 1 in 20 ratio holds, then 5
> of those people are women and the other 95 are men.
>
> Alternating between men and women means that all of the women get
> their questions answered, and only 5/95 of the men. So in this
> example, if you're a woman you have a 100% chance of getting answered,
> and if you're a man you only have a 5.26% chance.

The United States has an "egalitarian" quota system that seeks to
promote diversity. By law, at most 7% of green cards can be awarded to
citizens of any individual country. So, by this fair principle, in any
given year, at most 7% of the green cards can go to citizens of Finland
(pop. 5 million) and at most 7% of the green cards can go to citizens of
India (pop. 1 billion).

   https://www.uscis.gov/tools/glossary/country-limit>

Indian and Chinese H1B holders are getting screwed, which is of course
the whole objective of the country limits.

The US used to have more explicitly worded immigration laws:

   https://en.wikipedia.org/wiki/Chinese_Exclusion_Act>
   https://en.wikipedia.org/wiki/Asian_Exclusion_Act>


How this relates to Python? Well, I bet thousands of Asian Python coders
in the United States are under the threat of deportation because of
country limits.

See also:

   http://www.petition2congress.com/14376/eliminate-per-country-limi
   t-in-employment-based-green-card>


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


Re: A fun python CLI program for all to enjoy!

2016-05-07 Thread alister
On Sat, 07 May 2016 18:24:45 +1200, Gregory Ewing wrote:

> DFS wrote:
>> Maybe it worked because the last time the file was written to was in a
>> for loop, so I got lucky and the files weren't truncated?  Don't know.
> 
> It "works" because CPython disposes of objects as soon as they are not
> referenced anywhere. Other implementations of Python (e.g. Jython, PyPy)
> might not do that.

to provide an example try the following code in the interactive 
interpreter

>>>f=open('somefile','w')
>>print f.write('line 1')
None
>>>print f.close
built-in method close of file object at 0x7fb4c9580660>
>>>print f.write('line 2')
None
>>>print f.close()
None
>>>print f.write('line 3')
ValueError: I/O operation on closed file

somefile will contain

line 1
line 2





-- 
manager in the cable duct
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Slight problems with python in Windows

2016-05-07 Thread Peter Toye
Zachary,

An update - see below.

Best regards,

Peter
mailto:[email protected]
www.ptoye.com


>> 2) According to the Programs and Files section of the Windows Control Panel, 
>> installing Python also installs something called the Python Launcher. When I 
>> try to remove this (so I can reinstall Python in a better directory) is 
>> comes up with an error message:

> The Python Launcher is a very handy tool called 'py.exe' which makes
> it much easier to use more than one version of Python on a Windows
> machine.  In an all users install, py.exe is installed to C:\Windows
> and is thus always available on PATH, so you can invoke Python 3.5 by
> calling 'py -3.5' without having to adjust your PATH.  The error
> message is odd, though, would you mind trying to reproduce it and
> opening a bug at bugs.python.org?

>> Error opening installation log file.  Verify that the specified log file 
>> location exists and is writable.
>>

I tried uninstalling the launcher before uninstalling Python and it worked OK. 
Obviously there's a dependency here. Or the Python uninstaller should also 
uninstall the launcher first.

But one other oddity. For reasons I don't quite follow, the page 
https://www.python.org/downloads/  downloads the 32-bit version of Python, 
which is what I first installed without knowing any better. Then I noticed that 
the installation had (32-bit) in it, poked around a bit and found the 64-bit 
version. When I installed that the launcher still said (32-bit). Possible bug 
here, and certainly a very misleading web page?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why do these statements evaluate the way they do?

2016-05-07 Thread Steven D'Aprano
On Sat, 7 May 2016 04:36 pm, Anthony Papillion wrote:

> I'm trying to figure out why the following statements evaluate the way
> they do and I'm not grasping it for some reason. I'm hoping someone can
> help me.
> 
> 40+2 is 42 #evaluates to True
> But
> 2**32 is 2**32 #evaluates to False

That is not a guarantee of the language, it is an implementation detail.

The only language guarantee is that:

40 + 2 == 42

which MUST be true. But the Python interpreter has a choice here:

- it can create *two* distinct int objects with value 42;

- or it can cache the int object and re-use it.

In the first case, `40 + 2 is 42` will return False. In the second case, it
will return True.

Remember that `is` does not test for equality, it checks for object
identity, namely, "are the two objects one and the same object?"

The standard Python interpreter caches "small integers". The definition
of "small" depends on the version, but 42 is included, and 2**32 is not. So
you may find that

40 + 2 is 42

re-uses the same cached object and returns True, but

2**32 is 2**32

creates a new int object each time and returns False.


The lesson here is:

(1) ** NEVER ** use `is` to test for equality. The `is` operator is not a
funny well of spelling == it is a completely different operator that tests
for object identity.

(2) You cannot rely on Python object caches, as that is implementation and
version dependent. It is an optimization, to speed up some arithmetic at
the expense of using a little more memory.

(3) Almost the only acceptable use for `is` is to test for the singleton
object None. (There are other uses, but they are unusual and testing for
None is common. Always write:

if obj is None: ...

rather than:

if obj == None: ...


But for (nearly) everything else, always use == equality.




-- 
Steven

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Gregory Ewing

Stephen Hansen wrote:

On Fri, May 6, 2016, at 11:43 PM, Gregory Ewing wrote:


Whether you think this is a good strategy or not,
beliavsky is right that it's not "equal".


This is a pedantically and nonsensical definition of "equal", that
ignores the many, many reasons why there are 1 in 20 women in that
conference.


You seem to be saying that if we did take all that into
account, and did the arithmetic accordingly, we would
conclude that Guido was, after all, treating the men and
the women equally.

But that doesn't follow. If it's really the case that for
every woman at the conference there were another 19 that
wanted to go but were prevented simply because they are
women, then treating the women who did happen to make it
to the conference preferentially does nothing to help the
ones who didn't.

I suppose on purely arithmetic grounds you could say that
out of the total population of potential attendees, men
and women ended up with an equal chance of getting a
question answered at the conference. But that assumes the
goal of getting a question answered is the only one that
matters. Missing out on the conference altogether is
surely a much bigger injustice!

So Guido's affirmative action can at best redress only
a small part of the balance. But depending on the
circumstances, it could actually make it *worse*.

Suppose for some bizarre reason the women who made it
to the conference did so because they had red hair. (Maybe
the guy taking the conference bookings had a thing for
redheads, I don't know.) Now we have the situation where
every red-haired female python enthusiast is guaranteed
to get their question answered, simply because of the
colour of their hair. All the non-red-haired female
python enthusiasts might not be very happy about that.

Now admittedly that's a pretty far-fetched scenario, but
without knowing all the reasons for those 19 out of 20
women being barred from the conference, we can't *know*
that there isn't something equally spurious happening.


Correcting for inequalities can not, itself, be a purely "equal" task
done in pure blindness of the contextual reality of what is going on in
the world.


I don't think I disagree with that.

I tend toward the view that it's not possible to fix
those kinds of inequalities by concatenating them with
further inequalities. They can only truly be addressed
by removing whatever barriers are responsible in the
first place.

Don't get me wrong, I'm not saying Guido shouldn't have
done what he did. But I don't think it makes sense to talk
about it in terms of equality, except in a very narrow
mathematical way, and then only by making some very
handwavey assumptions about the numbers involved.

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


Re: A fun python CLI program for all to enjoy!

2016-05-07 Thread Peter Otten
DFS wrote:

> getAddresses.py
> 
> Scrapes addresses from www.usdirectory.com and stores them in a SQLite
> database, or writes them to text files for mailing labels, etc
> 
> Now, just by typing 'fast food Taco Bell  10 db all' you can find
> out how many Taco Bells are within 10 miles of you, and store all the
> addresses in your own address database.
> 
> No more convoluted Googling, or hitting the 'Next Page' button, or
> fumbling with the Yellow Pages...
> 
> Note: the db structure is flat on purpose, and the .csv files aren't
> quote delimited.
> 
> Put the program in its own directory.  It creates the SQLite database
> there, and writes files there, too.
> 
> Reviews of code, bug reports, criticisms, suggestions for improvement,
> etc are all welcome.

- Avoid module-level code and global variables
- Use functions that do one thing and operate on explicitly passed arguments
- You have 

if store == ...:
   ...

sprinkled across your module. You will have to change your code in many 
places if you want to add another output format. With a linear structure 
like

STORE_FUNCS = {
"db": store_in_db,
"txt": store_as_text,
"csv": store_as_csv,
}

def main():
args = read_arguments()
records = read_records(args)
records = unique(records)
if args.limit:
records = itertools.islice(records, args.limit)
STORE_FUNCS[args.storage_format](args, records)

if __name__ == "__main__":
main()

further enhancements will be a lot easier to implement.

The main() function avoids accidental uncontrolled globals. If you want one 
you have to declare it:

def main():
global verbose
args = read_arguments()
verbose = args.verbose
...


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


How to see html code under the particular web page element?

2016-05-07 Thread zljubisic
Hi,

on page:
https://hrti.hrt.hr/#/video/show/2203605/trebizat-prica-o-jednoj-vodi-i-jednom-narodu-dokumentarni-film

there is a picture and in the middle of the picture there is a text "Prijavite 
se za gledanje!"

If I open the page in firefox and then use menu Tools > Web developer > Page 
source, there is no such text, but if i right click on the "Prijavite se za 
gledanje!" and than choose "Inspect element" I get the following html code:

Prijavite se za 
gledanje!

What is the difference between firfox Page source and inspect element?
How go get html with "Prijavite se za gledanje!" element by using python 3?

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Steven D'Aprano
On Sat, 7 May 2016 06:50 pm, Marko Rauhamaa wrote:

> The United States has an "egalitarian" quota system that seeks to
> promote diversity. By law, at most 7% of green cards can be awarded to
> citizens of any individual country. So, by this fair principle, in any
> given year, at most 7% of the green cards can go to citizens of Finland
> (pop. 5 million) and at most 7% of the green cards can go to citizens of
> India (pop. 1 billion).
> 
>https://www.uscis.gov/tools/glossary/country-limit>

Obviously this system is a conspiracy to benefit citizens of Andorra
(population 85 thousand), Marshall Islands (pop. 70 thousand),
Liechtenstein (pop. 37 thousand), Nauru (pop. 9 thousand) and the Vatican
City (pop. 842).


> Indian and Chinese H1B holders are getting screwed, which is of course
> the whole objective of the country limits.

The *whole* objective? You don't think that *part* of the objective may be
to ensure that citizens of countries other than India and China can get
green cards too? Given that there are only a limited number of green cards
available overall, without per country limits it is conceivable that they
would all go to people from one or two countries.

Perhaps the country limits are also in place, at least in part, to manage
the rate at which new immigrants arrive in the country?

It's not that country limits act as a permanent barrier to getting a green
card. It's a per year limit, and there is a first-come, first-served queue
system in place. If an applicant is otherwise eligible for a green card,
the country limit will only delay, not prevent, them from getting a green
card.

E.g. if there are (let's say) a maximum of 1000 green cards available for
people from Nauru, and the entire population applies in 2016. Let's assume
that they are all eligible under one clause or another (e.g. family ties,
employment, refugee status, national interest, etc.). Then the first 1000
applicants will be granted a green card in the first year, followed by the
next 1000 the following year, and so on. New applicants go to the back of
the queue.

Meanwhile, this unexpected flood of immigrants from Nauru have no effect on
the chances of Pope Francis being granted a green card, what with the
Vatican having its own country limit of 1000 as well.


> The US used to have more explicitly worded immigration laws:
> 
>https://en.wikipedia.org/wiki/Chinese_Exclusion_Act>
>https://en.wikipedia.org/wiki/Asian_Exclusion_Act>

Yes, many countries had, and still have, overtly racist immigration laws.
You should try immigrating into Japan, or Saudi Arabia, and getting
citizenship.


> How this relates to Python? Well, I bet thousands of Asian Python coders
> in the United States are under the threat of deportation because of
> country limits.

I'm not sure why you think that "H1B holders" are at threat of deportation.
So long as they meet the conditions of the work visa, they are entirely
entitled to stay and work in the country.

There are good arguments for removing the H1B programme. It's used to flood
the market with relatively cheap labour made up of people who are less
likely to unionise and more likely to put up with bad treatment, and drive
wages down for others in the same field. But the inequities of the H1B
programme are not caused by the existence of country limits.




-- 
Steven

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 1:16 AM, Steven D'Aprano  wrote:
>
> Obviously this system is a conspiracy to benefit citizens of Andorra
> (population 85 thousand), Marshall Islands (pop. 70 thousand),
> Liechtenstein (pop. 37 thousand), Nauru (pop. 9 thousand) and the Vatican
> City (pop. 842).

The Vatican City is always standing by to mess with your statistics.
Never mind about its pop. density - it has the highest pope density in
the world, peaking at roughly 2 per square kilometer.

The way I'd read the 7% maximum is a requirement on immigration to
accept people from a variety of origin countries - at least fifteen
unique countries per year, assuming the maximum number of green cards
is issued. But immigration laws are a pretty terrible mess the world
over, from what I've seen, and I wish countries could drop the whole
"but we have to protect ourselves from foreigners" thing. At some
point, those "foreigners" become "citizens", and just as worthy of
your protection as those who were born here - why fight them off for a
while before you welcome them?

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Marko Rauhamaa
Steven D'Aprano :

> On Sat, 7 May 2016 06:50 pm, Marko Rauhamaa wrote:
>> Indian and Chinese H1B holders are getting screwed, which is of course
>> the whole objective of the country limits.
>
> The *whole* objective? You don't think that *part* of the objective
> may be to ensure that citizens of countries other than India and China
> can get green cards too? Given that there are only a limited number of
> green cards available overall, without per country limits it is
> conceivable that they would all go to people from one or two
> countries.

And? If 40% of the humanity happens to live in China and India, they
should have a 40% chance at getting in if you were targeting some kind
of ethnic fairness.

However, the whole ethnic consideration is silly at best, cruel at
worst. You should only look at human beings as individuals.

> Perhaps the country limits are also in place, at least in part, to
> manage the rate at which new immigrants arrive in the country?

No, there's a separate annual total maximum.

> It's not that country limits act as a permanent barrier to getting a green
> card. It's a per year limit, and there is a first-come, first-served queue
> system in place. If an applicant is otherwise eligible for a green card,
> the country limit will only delay, not prevent, them from getting a green
> card.

If you do the math, the wait times grow without bounds. In the end, they
may grow longer than your lifetime.

>> How this relates to Python? Well, I bet thousands of Asian Python coders
>> in the United States are under the threat of deportation because of
>> country limits.
>
> I'm not sure why you think that "H1B holders" are at threat of
> deportation. So long as they meet the conditions of the work visa,
> they are entirely entitled to stay and work in the country.

An H1B is only good for 6 years max. From then on, you'll be out of
status. You might still get some kind of provision to stay while you
wait for your paperwork to be processed, but as far as I know, you are
not allowed to exit the United States while you wait.

I was an H1B holder. Because of an amusing bureaucratic adventure (the
INS lost my paperwork and would only lift a finger after a court found
the United States in contempt), I ran out of status and was subject to
deportation for a couple of years. Luckily, I was part of a special
legal provision that allowed you to get a green card as long as you had
started the process before a particular date. One of the final steps in
the process was to file the actual green card application. One of the
questions on the application form was: "Are you in the country legally?"
I answered, "No," and the form instructed me to add $1,000 to the
application fee.

My process took five years.

> There are good arguments for removing the H1B programme. It's used to
> flood the market with relatively cheap labour made up of people who
> are less likely to unionise and more likely to put up with bad
> treatment, and drive wages down for others in the same field. But the
> inequities of the H1B programme are not caused by the existence of
> country limits.

I don't think I ever ran into that phenomenon. It's of course difficult
to measure based on individual experiences alone.

What I can tell from the current labor market in Finland is that it is
very difficult to find any*body*, let alone any native, who'd *apply*
for decent, run-of-the-mill software development jobs. And Finland is in
a slump, with constant news of IT layoffs, especially considering the
ongoing Nokia/Microsoft implosion. It's really weird.

I have never run into a situation where the employer has decided to hire
a software developer based on a salary bidding competition. What
companies are doing is they are outsourcing whole projects or products
to, say, Latvian or Russian companies, but that has little to do with
guest worker policies.


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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Marko Rauhamaa
Chris Angelico :

> But immigration laws are a pretty terrible mess the world over, from
> what I've seen, and I wish countries could drop the whole "but we have
> to protect ourselves from foreigners" thing. At some point, those
> "foreigners" become "citizens", and just as worthy of your protection
> as those who were born here - why fight them off for a while before
> you welcome them?

There's a strong racist undercurrent there for sure, but it's not the
whole story. You need to put some impedance to uncontrolled immigration.

A functional, enlightened, prosperous democracy is a very recent
historical anomaly. You don't want to jeopardize it naïvely.


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


Re: How to see html code under the particular web page element?

2016-05-07 Thread Larry Martell
On Sat, May 7, 2016 at 10:27 AM,   wrote:
> Hi,
>
> on page:
> https://hrti.hrt.hr/#/video/show/2203605/trebizat-prica-o-jednoj-vodi-i-jednom-narodu-dokumentarni-film
>
> there is a picture and in the middle of the picture there is a text 
> "Prijavite se za gledanje!"
>
> If I open the page in firefox and then use menu Tools > Web developer > Page 
> source, there is no such text, but if i right click on the "Prijavite se za 
> gledanje!" and than choose "Inspect element" I get the following html code:
>
>  class="btn btn-green buy-options sign-in-vod ng-binding">Prijavite se za 
> gledanje!
>
> What is the difference between firfox Page source and inspect element?
> How go get html with "Prijavite se za gledanje!" element by using python 3?

There's probably some Angular JS code involved with this. Look at the
source (not the page source, the source code in the developer's
tools).
-- 
https://mail.python.org/mailman/listinfo/python-list


pylint woes

2016-05-07 Thread DFS
This more-anal-than-me program generated almost 2 warnings for every 
line of code in my program.  w t hey?



  DFS comments
+-++ ---
|message id   |occurrences |
+=++
|mixed-indentation|186 | I always use tab
+-++
|invalid-name |82  | every single variable name?!
+-++
|bad-whitespace   |65  | mostly because I line up =
 signs:
 var1  = value
 var10 = value

+-++
|trailing-whitespace  |59  | heh!
+-++
|multiple-statements  |23  | do this to save lines.
 Will continue doing it.
+-++
|no-member|5   |

"Module 'pyodbc' has no 'connect' member"   Yes it does.
"Module 'pyodbc' has no 'Error' member" Yes it does.

Issue with pylint, or pyodbc?

+-++
|line-too-long|5   | meh
+-++
|wrong-import-order   |4   | does it matter?
+-++
|missing-docstring|4   | what's the difference between
 a docstring and a # comment?
+-++
|superfluous-parens   |3   | I like to surround 'or'
 statments with parens
+-++
|redefined-outer-name |3   | fixed. changed local var names.
+-++
|redefined-builtin|2   | fixed. Was using 'zip' and 'id'
+-++
|multiple-imports |2   | doesn't everyone?
+-++
|consider-using-enumerate |2   | see below [1]
+-++
|bad-builtin  |2   | warning because I used filter?
+-++
|unused-import|1   | fixed
+-++
|unnecessary-pass |1   | fixed. left over from
 Try..Except
+-++
|missing-final-newline|1   | I'm using Notepad++, with
 EOL Conversion set to
 'Windows Format'.  How
 or should I fix this?
+-++
|fixme|1   | a TODO statement
+-++

Global evaluation
-
Your code has been rated at -7.64/10



I assume -7.64 is really bad?

Has anyone ever in history gotten 10/10 from pylint for a non-trivial 
program?





After fixes and disabling various warnings:
"Your code has been rated at 8.37/10"


That's about as good as it's gonna get!



[1]
pylint says "Consider using enumerate instead of iterating with range 
and len"


the offending code is:
for j in range(len(list1)):
  do something with list1[j], list2[j], list3[j], etc.

enumeration would be:
for j,item in enumerate(list1):
  do something with list1[j], list2[j], list3[j], etc.

Is there an advantage to using enumerate() here?






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


Re: After a year using Node.js, the prodigal son returns

2016-05-07 Thread Laurent Pointal
Chris Angelico wrote:

> On Fri, May 6, 2016 at 11:45 PM, Grant Edwards
>  wrote:
>>> JavaScript is terrible. Really, really bad. And because of that, it
>>> has the potential to sweep the world.
>>
>> If your reasoning is correct, it'll never be able to overtake PHP.
>>
>> I've never written anything over a hundred or two lines in JavaScript,
>> but for small stuff it seems OK -- though as others have noted there
>> are some oddly missing batteries that result in use of a lot of small
>> external libraries for things that any C, PHP, or Python user would
>> have expected to be in the standard library.
> 
> Except that it's pretty easy to switch out PHP for Python, or anything
> else. JavaScript is what it is because it's hard to just use a
> different language.

Maybe Pyhton, using Brython (http://www.brython.info/)

(ok, its translated into JavaScript for execution in the web browser… maybe 
somedays it will be asmsjs)

A+
Laurent.

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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 2:51 AM, DFS  wrote:
> [1]
> pylint says "Consider using enumerate instead of iterating with range and
> len"
>
> the offending code is:
> for j in range(len(list1)):
>   do something with list1[j], list2[j], list3[j], etc.
>
> enumeration would be:
> for j,item in enumerate(list1):
>   do something with list1[j], list2[j], list3[j], etc.
>
> Is there an advantage to using enumerate() here?

The suggestion from a human would be to use zip(), or possibly to
change your data structures.

for item1, item2, item3 in zip(list1, list2, list3):
do something with the items

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Random832
On Sat, May 7, 2016, at 11:16, Steven D'Aprano wrote:
> > Indian and Chinese H1B holders are getting screwed, which is of course
> > the whole objective of the country limits.
> 
> The *whole* objective? You don't think that *part* of the objective may
> be
> to ensure that citizens of countries other than India and China can get
> green cards too?

If not for the quotas, a citizen of some other country would have an
equal chance to get a green card as a citizen of India or China. This is
a much simpler question than Python convention attendees, since there
are *in fact* more Indian or Chinese people in actual existence than
citizens of any given other country, which can't be blamed on any form
of discrimination.

> Perhaps the country limits are also in place, at least in part, to manage
> the rate at which new immigrants arrive in the country?

That's immaterial, we're not talking about a limit on the total number
of visas.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Michael Selik
On Sat, May 7, 2016 at 12:56 PM DFS  wrote:

> |mixed-indentation|186 | I always use tab
>

Don't mix tabs and spaces. I suggest selecting all lines and using your
editor to convert spaces to tabs. Usually there's a feature to "tabify".


> +-++
> |invalid-name |82  | every single variable name?!
>

Class names should be CamelCase
Everything else should be lowercase_with_underscores


> +-++
> |bad-whitespace   |65  | mostly because I line up =
>   signs:
>   var1  = value
>   var10 = value
>

Sure, that's your style. But pylint likes a different style. It's good to
use a standard. If it's just you, I suggest conforming to pylint. If you're
already on a team, use your team's standard.

+-++
> |trailing-whitespace  |59  | heh!
>

Get rid of it. Save some bytes.


> +-++
> |multiple-statements  |23  | do this to save lines.
>   Will continue doing it.
>

If you want to share your code with others, you should conform to community
standards to make things easier for others to read. Further, if you think
the core contributors are expert programmers, you should probably take
their advice: "sparse is better than dense". Do your future-self a favor
and write one statement per line. Today you find it easy to read. Six
months from now you won't.


> +-++
> |no-member|5   |
>
> "Module 'pyodbc' has no 'connect' member"   Yes it does.
> "Module 'pyodbc' has no 'Error' member" Yes it does.
>
> Issue with pylint, or pyodbc?
>

Not sure. Maybe pyodbc is written in a way that pylint can't see it's
connect or Error method/attribute.


> +-++
> |line-too-long|5   | meh
>

Yeah, I think 80 characters can be somewhat tight. Still, 5 long lines in
200ish lines of code? Sounds like you might be doing too much in those
lines or have too many levels of indentation.
"Sparse is better than dense"
"Flat is better than nested"


> +-++
> |wrong-import-order   |4   | does it matter?
>

No. I think pylint likes to alphabetize. With only 4 imports, it doesn't
matter. Still, why not alphabetize?


> +-++
> |missing-docstring|4   | what's the difference between
>   a docstring and a # comment?
>

Docstrings are tools for introspection. Many things in Python access the
__doc__ attribute to help you. Comments are never seen by module users.


> +-++
> |superfluous-parens   |3   | I like to surround 'or'
>   statments with parens
>

Ok. But over time you'll get used to not needing them. Edward Tufte says
you should have a high "information-to-ink" ratio.


> +-++
> |redefined-outer-name |3   | fixed. changed local var names.
> +-++
> |redefined-builtin|2   | fixed. Was using 'zip' and 'id'
> +-++
> |multiple-imports |2   | doesn't everyone?
>

Yeah, I do that as well.


> +-++
> |consider-using-enumerate |2   | see below [1]
>

As Chris explained.


> +-++
> |bad-builtin  |2   | warning because I used filter?
>

I think pylint likes comprehensions better. IMHO filter is OK. If you're
using a lambda, change to a comprehension.


> +-++
> |unused-import|1   | fixed
> +-++
> |unnecessary-pass |1   | fixed. left over from
>   Try..Except
> +-++
> |missing-final-newline|1   | I'm using Notepad++, with
>   EOL Conversion set to
>   'Windows Format'.  How
>   or should I fix this?
>

Add a few blank lines to the end of your file.


> +-++
> |fixme|1   | a TODO statement
> +-++
>
> Global evaluation
> -
> Your code has been rated at -7.64/10
>
>
>
> I assume -7.64 is really bad?
>
> Has anyone ever in history gotten 10/10 from pylint for a non-trivial
> program?
>

I'm certain of it.
-- 
https://mail.python.org/mailman/listinfo/python-list


redirecting stdout and stderr to /dev/null

2016-05-07 Thread Jim Dodgen
I'm new to python but well versed on other languages such as C and Perl

I'm have problems redirecting stdout and stderr to /dev/null in a
program that does a fork and exec. T found this method googling around and
it is
quite elegant compared to to the Perl version.

So to isolate things I made a much shorter test program and it still is not
redirecting. What am I doing wrong?

test program test.py
- cut here ---
import sys
import os

f = open(os.devnull, 'w')
sys.stdout = f
sys.stderr = f
os.execl("/bin/ping", "",  "-w", "20",  "192.168.1.1");
-- cut here ---


results when  run

root@dev:/home/jim# python test.py
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.36 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.00 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=1.01 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=1.16 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=1.02 ms
^C
--- 192.168.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 1.002/1.114/1.361/0.136 ms
root@dev:/home/jim#

*Jim Dodgen*
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Peter Pearson
On Sat, 7 May 2016 12:51:00 -0400, DFS  wrote:
> This more-anal-than-me program generated almost 2 warnings for every 
> line of code in my program.  w t hey?

Thank you for putting a sample of pylint output in front of my eyes;
you inspired me to install pylint and try it out.  If it teaches me even
half as much as it's teaching you, I'll consider it a great blessing.

-- 
To email me, substitute nowhere->runbox, invalid->com.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Christopher Reimer

On 5/7/2016 9:51 AM, DFS wrote:
Has anyone ever in history gotten 10/10 from pylint for a non-trivial 
program?


I routinely get 10/10 for my code. While pylint isn't perfect and 
idiosyncratic at times, it's a useful tool to help break bad programming 
habits. Since I came from a Java background, I had to unlearn everything 
from Java before I could write Pythonic code. It might help to use an 
IDE that offers PEP8-compliant code suggestions (I use PyCharm IDE).



That's about as good as it's gonna get!


You can do better.  You should strive for 10/10 whenever possible, 
figure out why you fall short and ask for help on the parts that don't 
make sense.


pylint says "Consider using enumerate instead of iterating with range 
and len"


the offending code is:
for j in range(len(list1)):
  do something with list1[j], list2[j], list3[j], etc.


This code is reeking with bad habits to be broken. Assigning a throwaway 
variable to walk the index is unnecessary when Python can do it for you 
behind the scenes. As Chris A. pointed out in his post, you should use 
zip() to walk through the values of each list at the same time.


Thank you,

Chris R.

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


Re: python - handling HTTP requests asynchronously

2016-05-07 Thread Michael Selik
On Fri, May 6, 2016 at 3:01 AM  wrote:

> The PDF is generated through an external API. Since currently is generated
> on demand, this is handled synchronously via an HTTP request/response.


Are you sending the request or are you receiving the request?
If you are sending, you can just use threads as you are only doing IO.
If you are receiving the requests and generating PDFs, you may want to use
subprocesses if the PDF-generation is compute-intensive.


> 3) multiprocessing module, with e.g. 10 as workers limit.
>

multiprocessing.Pool is an easy way to use subprocesses
multiprocessing.pool.ThreadPool is an easy way to use threads. It's not
well documented, but has the exact same interface as Pool.

the goal is to use the API concurrently (e.g. send 10 or 100 http requests
> simultaneously, depending on how many concurrent requests the API can
> handle).
>

Sounds like you want to use threads. How does the API let you know you're
hitting it too frequently? Perhaps you want to code an exponential backoff
and retry wrapper for your API requests.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Stephen Hansen
Pylint is very opinionated. Feel free to adjust its configuration to
suit your opinions of style.

In particular, several of these might be related to PEP8 style issues.

On Sat, May 7, 2016, at 09:51 AM, DFS wrote:
>DFS comments
> +-++ ---
> |message id   |occurrences |
> +=++
> |mixed-indentation|186 | I always use tab

And yet, it appears there's some space indentation in there. In
Notepad++ enable View->Show Symbol->Show White Space and Tab and Show
Indent Guide.

> +-++
> |invalid-name |82  | every single variable name?!

It probably defaults to PEP8 names, which are variables_like_this, not
variablesLikeThis.

> +-++
> |bad-whitespace   |65  | mostly because I line up =
>   signs:
>   var1  = value
>   var10 = value

Yeah and PEP8 says don't do that. Adjust the configuration of pylint if
you want.

> +-++
> |multiple-statements  |23  | do this to save lines.
>   Will continue doing it.

This you really shouldn't do, imho. Saving lines is not a virtue,
readability is -- dense code is by definition less readable.

> +-++
> |no-member|5   |
> 
> "Module 'pyodbc' has no 'connect' member"   Yes it does.
> "Module 'pyodbc' has no 'Error' member" Yes it does.
> 
> Issue with pylint, or pyodbc?

Pylint. 

> +-++
> |line-too-long|5   | meh

I'm largely meh on this too. But again its a PEP8 thing.

> +-++
> |wrong-import-order   |4   | does it matter?

Its useful to have a standard so you can glance and tell what's what and
from where, but what that standard is, is debatable.

> +-++
> |missing-docstring|4   | what's the difference between
>   a docstring and a # comment?

A docstring is a docstring, a comment is a comment. Google python
docstrings :) Python prefers files to have a docstring on top, and
functions beneath their definition. Comments should be used as little as
possible, as they must be maintained: an incorrect comment is worse then
no comment.

Go for clear code that doesn't *need* commenting.

> +-++
> |superfluous-parens   |3   | I like to surround 'or'
>   statments with parens

Why?

> +-++
> |multiple-imports |2   | doesn't everyone?

I don't actually know what its complaining at.

> +-++
> |bad-builtin  |2   | warning because I used filter?

Don't know what its complaining at about here either.

> +-++
> |missing-final-newline|1   | I'm using Notepad++, with
>   EOL Conversion set to
>   'Windows Format'.  How
>   or should I fix this?

Doesn't have anything to do with it. Just scroll to the bottom and press
enter. It wants to end on a newline, not code.

> Global evaluation
> -
> Your code has been rated at -7.64/10
> 
> I assume -7.64 is really bad?
> 
> Has anyone ever in history gotten 10/10 from pylint for a non-trivial 
> program?

No clue, I don't use pylint at all.

> [1]
> pylint says "Consider using enumerate instead of iterating with range 
> and len"
> 
> the offending code is:
> for j in range(len(list1)):
>do something with list1[j], list2[j], list3[j], etc.
> 
> enumeration would be:
> for j,item in enumerate(list1):
>do something with list1[j], list2[j], list3[j], etc.
> 
> Is there an advantage to using enumerate() here?

Its cleaner, easier to read. In Python 2 where range() returns a list,
its faster. (In python2, xrange returns a lazy evaluating range)

Use the tools Python gives you. Why reinvent enumerate when its built
in?

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Martin A. Brown

Hello there,

>I'm new to python but well versed on other languages such as C and 
>Perl
>
>I'm have problems redirecting stdout and stderr to /dev/null in a 
>program that does a fork and exec. T found this method googling 
>around and it is quite elegant compared to to the Perl version.
>
>So to isolate things I made a much shorter test program and it 
>still is not redirecting. What am I doing wrong?
>
>test program test.py
>- cut here ---
>import sys
>import os
>
>f = open(os.devnull, 'w')
>sys.stdout = f
>sys.stderr = f
>os.execl("/bin/ping", "",  "-w", "20",  "192.168.1.1");
>-- cut here ---

Think about the file descriptors.

Unix doesn't care what the name is, rather that the process inherits 
the FDs from the parent.  So, your solution might need to be a bit 
more complicated to achieve what you desire.  Run the following to 
see what I mean.

  realstdout = sys.stdout
  realstderr = sys.stderr
  f = open(os.devnull, 'w')
  sys.stdout = f
  sys.stderr = f
  
  print("realstdout FD: %d" % (realstdout.fileno(),), file=realstdout)
  print("realstderr FD: %d" % (realstderr.fileno(),), file=realstdout)
  print("sys.stdout FD: %d" % (sys.stdout.fileno(),), file=realstdout)
  print("sys.stderr FD: %d" % (sys.stderr.fileno(),), file=realstdout)

That should produce output that looks like this:

  realstdout FD: 1
  realstderr FD: 2
  sys.stdout FD: 3
  sys.stderr FD: 3

I hope that's a good hint...

I like the idea of simply calling the next program using one of the 
exec() variants, but you'll have to adjust the file descriptors, 
rather than just the names used by Python.

If you don't need to exec(), but just run a child, then here's the 
next hint (this is for Python 3.5):

  import subprocess
  cmd = ["ping", "-w", "20",  "192.168.1.1"]
  devnull = subprocess.DEVNULL
  proc = subprocess.run(cmd, stdout=devnull, stderr=devnull)
  proc.check_returncode()

(By the way, your "ping" command looked like it had an empty token 
in the second arg position.  Looked weird to me, so I removed it 
in my examples.)

For subprocess.run, see:

  https://docs.python.org/3/library/subprocess.html#subprocess.run

For earlier Python versions without run(), you can use Popen():

  import subprocess
  cmd = ["/bin/ping", "-w", "20",  "192.168.1.1"]
  devnull = subprocess.DEVNULL
  proc = subprocess.Popen(cmd, stdout=devnull, stderr=devnull)
  retcode = proc.wait()
  if retcode != 0:
  raise FlamingHorribleDeath

You will have to define FlamingHorribleDeath or figure out what you 
want to do in the event of the various different types of 
failureif you don't then, you'll just see this:

  NameError: name 'FlamingHorribleDeath' is not defined

Good luck,

-Martin

-- 
Martin A. Brown
http://linux-ip.net/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Stephen Hansen
On Sat, May 7, 2016, at 11:52 AM, Christopher Reimer wrote:
> You can do better.  You should strive for 10/10 whenever possible, 
> figure out why you fall short and ask for help on the parts that don't 
> make sense.

I think this is giving far too much weight to pylint's opinion on what
is "good" or "bad" programming habits.

-- 
Stephen Hansen
  m e @ i x o k a i  . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to see html code under the particular web page element?

2016-05-07 Thread zljubisic

> There's probably some Angular JS code involved with this. Look at the
> source (not the page source, the source code in the developer's
> tools).

Is it possible to get that code using python?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Christopher Reimer

On 5/5/2016 7:57 PM, Stephen Hansen wrote:

On Thu, May 5, 2016, at 07:46 PM, Dan Sommers wrote:

On Thu, 05 May 2016 18:37:11 -0700, Stephen Hansen wrote:


 ''.join(x for x in string if x.isupper())
The difference is, both filter and your list comprehension *build a
list* which is not needed, and wasteful. The above skips building a
list, instead returning a generator ...

filter used to build a list, but now it doesn't (where "used to" means
Python 2.7 and "now" means Python 3.5; I'm too lazy to track down the
exact point(s) at which it changed):

Oh, didn't know that. Then again the OP was converting the output of
filter *into* a list, which wasted a list either way.


My line of code was something I copied off the Internet and modified it 
until it did I exactly what I wanted it to do. That means that the many 
Python 2 code examples available on the Internet are using a redundant 
list operation with Python 3. Isn't that a "smell" that pylint should 
pick up on?


Thank you,

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


Re: pylint woes

2016-05-07 Thread Terry Reedy

On 5/7/2016 12:51 PM, DFS wrote:

This more-anal-than-me program generated almost 2 warnings for every
line of code in my program.  w t hey?


If you don't like it, why do you use it?

I suppose the answer is that it did find a few things to check.  You 
might be happier with pychecker, which is much less aggressive.  I 
believe will find the things you did fix.




  DFS comments
+-++ ---
|message id   |occurrences |
+=++
|mixed-indentation|186 | I always use tab
+-++
|invalid-name |82  | every single variable name?!


I would need examples to comment.


+-++
|trailing-whitespace  |59  | heh!


Any code editor should have a command to fix this.
IDLE: Format => strip trailing whitespace
Notepad++: Macro => trim trailing and save, Alt-Shift-S
others ...


+-++
|no-member|5   |

"Module 'pyodbc' has no 'connect' member"   Yes it does.
"Module 'pyodbc' has no 'Error' member" Yes it does.

Issue with pylint, or pyodbc?


Worth looking into.  Could be a bug somewhere. But I don't have pyodbc 
installed.



+-++
|line-too-long|5   | meh


For following the PEP guideline when patching CPython, this is helpful.


+-++
|wrong-import-order   |4   | does it matter?


Consistency in imports ultimately makes easier reading.
Many idlelib files use this order: stdlib modules other than tkinter and 
idlelib (alphabetically); tkinter (tkinter first, then submodules); 
idlelib (alphabetically).  When I edit files, I sometimes reorder 
imports to conform.



+-++
|missing-docstring|4   | what's the difference between
 a docstring and a # comment?


# Comments only appear in the source
'''Docstrings are copied to the compiled code object, are interactively 
accessible, and are used for help(ojb) output.'''




+-++
|superfluous-parens   |3   | I like to surround 'or'
 statments with parens


I would need examples to comment



+-++
|bad-builtin  |2   | warning because I used filter?


If they are still doing this in the latest release, it is an arrogance 
and inconsistency bug on their part.  Disable this check.



+-++
|missing-final-newline|1   | I'm using Notepad++, with
 EOL Conversion set to
 'Windows Format'.


That says to replace final '\n' with '\r\n'.  It does not affect a 
missing final newline ;-)


   How or should I fix this?

Fix by hitting 'Enter' at the end of the last line.
Should you?  I think it a good habit.


After fixes and disabling various warnings:
"Your code has been rated at 8.37/10"


Being able to customize pylint by turning off warnings is its saving 
feature.


--
Terry Jan Reedy


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


Re: pylint woes

2016-05-07 Thread Christopher Reimer

On 5/7/2016 12:23 PM, Stephen Hansen wrote:

On Sat, May 7, 2016, at 11:52 AM, Christopher Reimer wrote:

You can do better.  You should strive for 10/10 whenever possible,
figure out why you fall short and ask for help on the parts that don't
make sense.

I think this is giving far too much weight to pylint's opinion on what
is "good" or "bad" programming habits.


I forgot to add the warning, "Use pylint with a dash of salt on a lemon 
slice and a shot of tequila." :)


Thank you,

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


Re: pylint woes

2016-05-07 Thread Ray Cote
On Sat, May 7, 2016 at 2:52 PM, Christopher Reimer <
[email protected]> wrote:

> On 5/7/2016 9:51 AM, DFS wrote:
>
>> Has anyone ever in history gotten 10/10 from pylint for a non-trivial
>> program?
>>
>
> I routinely get 10/10 for my code. While pylint isn't perfect and
> idiosyncratic at times, it's a useful tool to help break bad programming
> habits.
>

I’m impressed with 10/10.
My approach is to ensure flake8 (a combination of pyflakes and pep8
checking) does not report any warnings and then run pyLint as a final
check.
Code usually ends up in the 9.0 to 9.5 range, sometimes a bit higher.
Also find it useful to add some additional short names we use to the
 allowed names list.

Biggest issue I have with pyLint is that it complains when function
parameters are indented twice vs. once. pyFlakes likes the twice.
Example:
def function_name(
parm_1,
long_parm_name,
….
end_of_long_list_of params)
parm_1 = long_parm_name

—Ray




-- 
Raymond Cote, President
voice: +1.603.924.6079 email: [email protected] skype:
ray.cote
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Christopher Reimer

On 5/5/2016 6:37 PM, Stephen Hansen wrote:

On Thu, May 5, 2016, at 06:26 PM, Christopher Reimer wrote:

Which is one is correct (Pythonic)? Or does it matter?

First, pylint is somewhat opinionated, and its default options shouldn't
be taken as gospel. There's no correct: filter is fine.


Since the code I'm working on is resume fodder (i.e., "Yes, I code in 
Python! Check out my chess engine code on GitHub!"), I want it to be as 
Pythonic and PEP8-compliant as possible. That includes scoring 10/10 
with pylint. Never know when an asshat hiring manager would reject my 
resume out of hand because my code fell short with pylint.


For my purposes, I'm using the list comprehension over filter to keep 
pylint happy.


Thank you,

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


Re: pylint woes

2016-05-07 Thread Christopher Reimer

On 5/7/2016 12:52 PM, Ray Cote wrote:


I’m impressed with 10/10.
My approach is to ensure flake8 (a combination of pyflakes and pep8
checking) does not report any warnings and then run pyLint as a final
check.


I just installed pyflakes and ran it against my 10/10 files. It's not 
complaining about anything. So I ran it against my unit tests that I'm 
still writing, haven't cleaned up and checked against pylint. I got 
dinged for using a star import on a file with a common variables, which 
was an easy fix.


Thank you,

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Marko Rauhamaa
Christopher Reimer :
> Never know when an asshat hiring manager would reject my resume out of
> hand because my code fell short with pylint.

Remember that it's not only the company checking you out but also you
checking the company out.

Would you want to work for an asshat hiring manager?

Of course, you might not have the luxury of being picky.


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


Re: python chess engines

2016-05-07 Thread Christopher Reimer

On 5/3/2016 10:13 PM, DFS wrote:

Wanted to start a new thread, rather than use the 'motivated' thread.

Can you play your game at the console?


Nope. Only displays the board on the console. An early version had the 
forward movement for pawns implemented.


The way I think about a chess engine is it doesn't even display a 
board.  It accepts a move as input, records the move, analyzes the 
positions after the move, and returns the next move.


My code has display and engine as separate classes with a main loop 
coordinating things between the two. The main loop requests the board 
state (dict) from the engine class and passes that to show board on the 
display class.



Here's the UCI protocol.
http://download.shredderchess.com/div/uci.zip


Very interesting. Something to add to my research notes. I'll muddle 
through with my code and let it grow organically for now.  If I decide 
to write a chess engine that implements the UCI protocol, I'll start 
over with a clean slate.


Thank you,

Chris R.

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 5:17 AM, Christopher Reimer
 wrote:
> On 5/5/2016 6:37 PM, Stephen Hansen wrote:
>>
>> On Thu, May 5, 2016, at 06:26 PM, Christopher Reimer wrote:
>>>
>>> Which is one is correct (Pythonic)? Or does it matter?
>>
>> First, pylint is somewhat opinionated, and its default options shouldn't
>> be taken as gospel. There's no correct: filter is fine.
>
>
> Since the code I'm working on is resume fodder (i.e., "Yes, I code in
> Python! Check out my chess engine code on GitHub!"), I want it to be as
> Pythonic and PEP8-compliant as possible. That includes scoring 10/10 with
> pylint. Never know when an asshat hiring manager would reject my resume out
> of hand because my code fell short with pylint.
>
> For my purposes, I'm using the list comprehension over filter to keep pylint
> happy.

Wrong thinking. Make it Pythonic - but don't concern yourself with
pylint's final score. Read pylint's output and learn from it, but
don't treat a 10/10 score as the ultimate in ratings, because it just
isn't.

Also, be sure you read this part of PEP 8:

https://www.python.org/dev/peps/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Nathan Hilterbrand



On 05/07/2016 05:22 PM, Chris Angelico wrote:

On Sun, May 8, 2016 at 5:17 AM, Christopher Reimer
 wrote:


pylint. Never know when an asshat hiring manager would reject my resume out
of hand because my code fell short with pylint.



I see that as a good motivation to make sure your code was good, clean, 
and definitely did fall a bit short with pylint.


I have worked for asshat managers before.  It is something to be avoided.

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Stephen Hansen
On Sat, May 7, 2016, at 12:17 PM, Christopher Reimer wrote:
> On 5/5/2016 6:37 PM, Stephen Hansen wrote:
> > On Thu, May 5, 2016, at 06:26 PM, Christopher Reimer wrote:
> >> Which is one is correct (Pythonic)? Or does it matter?
> > First, pylint is somewhat opinionated, and its default options shouldn't
> > be taken as gospel. There's no correct: filter is fine.
> 
> Since the code I'm working on is resume fodder (i.e., "Yes, I code in 
> Python! Check out my chess engine code on GitHub!"), I want it to be as 
> Pythonic and PEP8-compliant as possible. That includes scoring 10/10 
> with pylint. Never know when an asshat hiring manager would reject my 
> resume out of hand because my code fell short with pylint.
> 
> For my purposes, I'm using the list comprehension over filter to keep 
> pylint happy.

Bear in mind, when I say, "Pylint is opinionated", I mean the tool --
especially in its default configuration -- has its own opinion of what
is good style, and *I think its wrong on a number of points*. 

Its fine to use, but I'd read over PEP8 (the document, not the tool) and
apply style guide recommendations thoughtfully, not mechanically. 

-- 
Stephen Hansen
  m e @ i x o k a i  . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python - handling HTTP requests asynchronously

2016-05-07 Thread lordluke80
Il giorno sabato 7 maggio 2016 21:04:47 UTC+2, Michael Selik ha scritto:
> On Fri, May 6, 2016 at 3:01 AM  wrote:
> 
> > The PDF is generated through an external API. Since currently is generated
> > on demand, this is handled synchronously via an HTTP request/response.
> 
> 
> Are you sending the request or are you receiving the request?
> If you are sending, you can just use threads as you are only doing IO.
> If you are receiving the requests and generating PDFs, you may want to use
> subprocesses if the PDF-generation is compute-intensive.
> 
> 
> > 3) multiprocessing module, with e.g. 10 as workers limit.
> >
> 
> multiprocessing.Pool is an easy way to use subprocesses
> multiprocessing.pool.ThreadPool is an easy way to use threads. It's not
> well documented, but has the exact same interface as Pool.
> 
> the goal is to use the API concurrently (e.g. send 10 or 100 http requests
> > simultaneously, depending on how many concurrent requests the API can
> > handle).
> >
> 
> Sounds like you want to use threads. How does the API let you know you're
> hitting it too frequently? Perhaps you want to code an exponential backoff
> and retry wrapper for your API requests.

Thanks for the reply.
Currently the django view that does the job does three http request:
- the first does a POST and send the payload used during the PDF rendering, the 
response contains a url to check the pdf generation progress;
- the second loop over that url, checking the progress of pdf generation. Once 
the response contains the keyword 'status': 'complete', then it give also a url 
for the file retrieval;
- the third one is a GET to retrieve the file, the reponse contains the binary 
content of the file, then this content is read and wrapped as attachment of a 
django http response, and then returned to the user.

the goal is to reuse the existing code as much as possible, possibly doing 
concurrently, and saving the file instead on a folder.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 7:35 AM, Stephen Hansen  wrote:
> On Sat, May 7, 2016, at 12:17 PM, Christopher Reimer wrote:
>> On 5/5/2016 6:37 PM, Stephen Hansen wrote:
>> > On Thu, May 5, 2016, at 06:26 PM, Christopher Reimer wrote:
>> >> Which is one is correct (Pythonic)? Or does it matter?
>> > First, pylint is somewhat opinionated, and its default options shouldn't
>> > be taken as gospel. There's no correct: filter is fine.
>>
>> Since the code I'm working on is resume fodder (i.e., "Yes, I code in
>> Python! Check out my chess engine code on GitHub!"), I want it to be as
>> Pythonic and PEP8-compliant as possible. That includes scoring 10/10
>> with pylint. Never know when an asshat hiring manager would reject my
>> resume out of hand because my code fell short with pylint.
>>
>> For my purposes, I'm using the list comprehension over filter to keep
>> pylint happy.
>
> Bear in mind, when I say, "Pylint is opinionated", I mean the tool --
> especially in its default configuration -- has its own opinion of what
> is good style, and *I think its wrong on a number of points*.

Agreed. The OP has already run into this, and disabled some checks;
the logical next step is to stop treating a 10/10 score as mandatory.

> Its fine to use, but I'd read over PEP8 (the document, not the tool) and
> apply style guide recommendations thoughtfully, not mechanically.

Definitely. It's times like this that I'm really annoyed by the abuse
of the name "pep8" to mean the tool, especially since it's not
perfectly matched to the document (notably, it can't encode the
flexibilities, so it comes out as rigid).

Tools like this can be incredibly useful. But they are TOOLS, and the
code belongs to you. They are not your masters.

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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 4:42 AM, Michael Selik  wrote:
>
>> +-++
>> |line-too-long|5   | meh
>>
>
> Yeah, I think 80 characters can be somewhat tight. Still, 5 long lines in
> 200ish lines of code? Sounds like you might be doing too much in those
> lines or have too many levels of indentation.
> "Sparse is better than dense"
> "Flat is better than nested"

Others have commented on this, but I'll weigh in with one point that
hasn't been mentioned yet. A lot of tools will complain when you
exceed 80 (or 79) characters per line; but it depends somewhat on *how
far* you exceeded it. Some people opt instead for a 100-character
limit, or even 120, but most programmers agree that a 200-character
line (or more!) is too long.

So if this is complaining about five lines out of your entire program
that just snuck over the 80-character limit (eg 86 characters long),
it's not a concern, and my recommendation would be to relax the
restriction. And if those few lines are ginormous hunks of data
(static list initialization, or something), you might consider dumping
them out to external files rather than wrapping them into big code
blocks. But if they're truly long lines of code, wrap or split them.

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


Re: python, ctypes and GetIconInfo issue

2016-05-07 Thread mymyxin
Hello eryk sun,

thank you very much for your help and detailed answers.
With the provided links and useful information I should be
able to get a better understanding how ctypes works internally.

Thank you
Hubert

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Christopher Reimer

On 5/7/2016 2:22 PM, Chris Angelico wrote:

On Sun, May 8, 2016 at 5:17 AM, Christopher Reimer
 wrote:
Since the code I'm working on is resume fodder (i.e., "Yes, I code in 
Python! Check out my chess engine code on GitHub!"), I want it to be 
as Pythonic and PEP8-compliant as possible. That includes scoring 
10/10 with pylint. Never know when an asshat hiring manager would 
reject my resume out of hand because my code fell short with pylint. 
For my purposes, I'm using the list comprehension over filter to keep 
pylint happy. 

Wrong thinking. Make it Pythonic - but don't concern yourself with
pylint's final score. Read pylint's output and learn from it, but
don't treat a 10/10 score as the ultimate in ratings, because it just
isn't.

I agree with that in principle. But...

Also, be sure you read this part of PEP 8:

https://www.python.org/dev/peps/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds
Recruiters and hiring managers *are* hobgoblins with with little minds. 
And definitely not PEP8-complaint. :)


When I was out of work for two years (2009-10), underemployed for six 
months (working 20 hours per month), and filed for Chapter Seven 
bankruptcy in 2011, I  only had 20 job interviews during that time. That 
was a learning experience. I did everything possible to present myself 
and my resume as perfectly as possible. When I had another bout of 
unemployment that lasted eight months (2013-14), I had 60 job interviews 
and three job offers to pick from at the end. Of course, that was for IT 
support contracts. Maybe programming jobs will have fewer hobgoblins.


Thank you,

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Radek Holý
2016-05-07 21:17 GMT+02:00 Christopher Reimer :

> On 5/5/2016 6:37 PM, Stephen Hansen wrote:
>
>> On Thu, May 5, 2016, at 06:26 PM, Christopher Reimer wrote:
>>
>>> Which is one is correct (Pythonic)? Or does it matter?
>>>
>> First, pylint is somewhat opinionated, and its default options shouldn't
>> be taken as gospel. There's no correct: filter is fine.
>>
>
> Since the code I'm working on is resume fodder (i.e., "Yes, I code in
> Python! Check out my chess engine code on GitHub!"), I want it to be as
> Pythonic and PEP8-compliant as possible. That includes scoring 10/10 with
> pylint. Never know when an asshat hiring manager would reject my resume out
> of hand because my code fell short with pylint.
>
> For my purposes, I'm using the list comprehension over filter to keep
> pylint happy.
>
>
> Thank you,
>
> Chris R.
> --
> https://mail.python.org/mailman/listinfo/python-list
>


Don't forget that you can also place a pylintrc file (with some reasonable
comments) into the repository or use the other means to disable selected
rules
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Christopher Reimer

On 5/7/2016 1:31 PM, Marko Rauhamaa wrote:

Christopher Reimer :

Never know when an asshat hiring manager would reject my resume out of
hand because my code fell short with pylint.

Remember that it's not only the company checking you out but also you
checking the company out.

Would you want to work for an asshat hiring manager?

Of course, you might not have the luxury of being picky.


Most asshat managers I've dealt with often say to me, "Here's a mole 
hole, go fix it." I look at the mole hole (little problem), look at the 
mountain (big problem) in the distant, and jump over the mole hole to 
start climbing the mountain. After I reduce the mountain to a mole hole, 
the asshat manager gets promoted and I'm looking for a job again.


Thank you,

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


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Jim Dodgen
*Thanks for the help*



On Sat, May 7, 2016 at 12:16 PM, Martin A. Brown 
wrote:

>
> Hello there,
>
> >I'm new to python but well versed on other languages such as C and
> >Perl
> >
> >I'm have problems redirecting stdout and stderr to /dev/null in a
> >program that does a fork and exec. T found this method googling
> >around and it is quite elegant compared to to the Perl version.
> >
> >So to isolate things I made a much shorter test program and it
> >still is not redirecting. What am I doing wrong?
> >
> >test program test.py
> >- cut here ---
> >import sys
> >import os
> >
> >f = open(os.devnull, 'w')
> >sys.stdout = f
> >sys.stderr = f
> >os.execl("/bin/ping", "",  "-w", "20",  "192.168.1.1");
> >-- cut here ---
>
> Think about the file descriptors.
>
> Unix doesn't care what the name is, rather that the process inherits
> the FDs from the parent.  So, your solution might need to be a bit
> more complicated to achieve what you desire.  Run the following to
> see what I mean.
>
>   realstdout = sys.stdout
>   realstderr = sys.stderr
>   f = open(os.devnull, 'w')
>   sys.stdout = f
>   sys.stderr = f
>
>   print("realstdout FD: %d" % (realstdout.fileno(),), file=realstdout)
>   print("realstderr FD: %d" % (realstderr.fileno(),), file=realstdout)
>   print("sys.stdout FD: %d" % (sys.stdout.fileno(),), file=realstdout)
>   print("sys.stderr FD: %d" % (sys.stderr.fileno(),), file=realstdout)
>
> That should produce output that looks like this:
>
>   realstdout FD: 1
>   realstderr FD: 2
>   sys.stdout FD: 3
>   sys.stderr FD: 3
>
> I hope that's a good hint...
>
> I like the idea of simply calling the next program using one of the
> exec() variants, but you'll have to adjust the file descriptors,
> rather than just the names used by Python.
>
> If you don't need to exec(), but just run a child, then here's the
> next hint (this is for Python 3.5):
>
>   import subprocess
>   cmd = ["ping", "-w", "20",  "192.168.1.1"]
>   devnull = subprocess.DEVNULL
>   proc = subprocess.run(cmd, stdout=devnull, stderr=devnull)
>   proc.check_returncode()
>
> (By the way, your "ping" command looked like it had an empty token
> in the second arg position.  Looked weird to me, so I removed it
> in my examples.)
>

The empty token is needed but useless, it is arg[0] most people just repeat
the program name


>
> For subprocess.run, see:
>
>   https://docs.python.org/3/library/subprocess.html#subprocess.run
>
> For earlier Python versions without run(), you can use Popen():
>
>   import subprocess
>   cmd = ["/bin/ping", "-w", "20",  "192.168.1.1"]
>   devnull = subprocess.DEVNULL
>   proc = subprocess.Popen(cmd, stdout=devnull, stderr=devnull)
>   retcode = proc.wait()
>   if retcode != 0:
>   raise FlamingHorribleDeath
>
> You will have to define FlamingHorribleDeath or figure out what you
> want to do in the event of the various different types of
> failureif you don't then, you'll just see this:
>
>   NameError: name 'FlamingHorribleDeath' is not defined
>
> Good luck,
>
> -Martin
>
> --
> Martin A. Brown
> http://linux-ip.net/


seems not to find subprocess.DEVNULL

I'm on 2.7.6  Ubuntu, and 2.7.9 on Raspbian  I expect I need 3.5

here are some Tracebacks I get, the second one is when I tried os.devnull
in place of subprocess.DEVNULL


Traceback (most recent call last):
  File "test.py", line 5, in 
devnull = subprocess.DEVNULL
AttributeError: 'module' object has no attribute 'DEVNULL'


Traceback (most recent call last):
  File "test.py", line 6, in 
proc = subprocess.Popen(cmd, stdout=os.devnull, stderr=os.devnull)
  File "/usr/lib/python2.7/subprocess.py", line 702, in __init__
errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.7/subprocess.py", line 1128, in _get_handles
c2pwrite = stdout.fileno()
AttributeError: 'str' object has no attribute 'fileno'


One other observation it looks as Popen behaves the same way as my fork
exec would
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 9:54 AM, Jim Dodgen  wrote:
> The empty token is needed but useless, it is arg[0] most people just repeat
> the program name

Far from useless. It's how a process learns its own name, and yes,
repeating the image name is the most common way to provide that.

> One other observation it looks as Popen behaves the same way as my fork
> exec would

Indeed. In fact, I would strongly recommend never using an explicit
fork/exec from Python - always use subprocess or equivalent. On
non-Unix platforms, fork/exec may not be available, but subprocess can
use other methods of invoking programs.

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


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Jim Dodgen
Thanks Chris

I now have things working using a version 3.4.3 it finds subprocess.DEVNULL
just fine

*Jim Dodgen*







On Sat, May 7, 2016 at 5:10 PM, Chris Angelico  wrote:

> On Sun, May 8, 2016 at 9:54 AM, Jim Dodgen  wrote:
> > The empty token is needed but useless, it is arg[0] most people just
> repeat
> > the program name
>
> Far from useless. It's how a process learns its own name, and yes,
> repeating the image name is the most common way to provide that.
>
> > One other observation it looks as Popen behaves the same way as my fork
> > exec would
>
> Indeed. In fact, I would strongly recommend never using an explicit
> fork/exec from Python - always use subprocess or equivalent. On
> non-Unix platforms, fork/exec may not be available, but subprocess can
> use other methods of invoking programs.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 1:01 PM, Chris Angelico wrote:

On Sun, May 8, 2016 at 2:51 AM, DFS  wrote:

[1]
pylint says "Consider using enumerate instead of iterating with range and
len"

the offending code is:
for j in range(len(list1)):
  do something with list1[j], list2[j], list3[j], etc.

enumeration would be:
for j,item in enumerate(list1):
  do something with list1[j], list2[j], list3[j], etc.

Is there an advantage to using enumerate() here?


The suggestion from a human would be to use zip(), or possibly to
change your data structures.


Happens like this:

address data is scraped from a website:

names = tree.xpath()
addr  = tree.xpath()

I want to store the data atomically, so I parse street, city, state, and 
zip into their own lists.


"1250 Peachtree Rd, Atlanta, GA 30303

street = [s.split(',')[0] for s in addr]
city   = [c.split(',')[1].strip() for c in addr]
state  = [s[-8:][:2] for s in addr]
zipcd  = [z[-5:] for z in addr]

names  = ["Taco Bell", "Wendy's"]
addr   = ['928 Buford Dr, Tucker, GA 30043', '4880 Ptree Pkwy, Atlanta, 
GA 30303']

street = ['928 Buford Dr', '4880 Sugarloaf Pkwy']
city   = ['Tucker','Atlanta']
state  = ['GA','GA']
zipcd  = ['30043','30303']


When you say 'possibly change data structures'... to what?




for item1, item2, item3 in zip(list1, list2, list3):
do something with the items


ziplists = zip(names,street,city,state,zipcd)
print ziplists

[('Taco Bell', '928 Buford Dr', 'Tucker', 'GA', '30043'),
 ("Wendy's", '4880 Sugarloaf Pkwy', 'Atlanta', 'GA', '30303')]



Why is it better to zip() them up and use:

for item1, item2, item3 in zip(list1, list2, list3):
 do something with the items

than

for j in range(len(list1)):
   do something with list1[j], list2[j], list3[j], etc.

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


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Ben Finney
Jim Dodgen  writes:

> I'm have problems redirecting stdout and stderr to /dev/null in a
> program that does a fork and exec.

You may be interested in the ‘python-daemon’ library
https://pypi.python.org/pypi/python-daemon/>. It takes care of all
the fiddly bits to turn your program into a well-behaved Unix daemon.

-- 
 \ “I wish there was a knob on the TV to turn up the intelligence. |
  `\  There's a knob called ‘brightness’ but it doesn't work.” |
_o__) —Eugene P. Gallagher |
Ben Finney

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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 11:16 AM, DFS  wrote:
> On 5/7/2016 1:01 PM, Chris Angelico wrote:
>> The suggestion from a human would be to use zip(), or possibly to
>> change your data structures.
>
>
> Happens like this:
>
> address data is scraped from a website:
>
> names = tree.xpath()
> addr  = tree.xpath()
>
> I want to store the data atomically, so I parse street, city, state, and zip
> into their own lists.
>
> "1250 Peachtree Rd, Atlanta, GA 30303
>
> street = [s.split(',')[0] for s in addr]
> city   = [c.split(',')[1].strip() for c in addr]
> state  = [s[-8:][:2] for s in addr]
> zipcd  = [z[-5:] for z in addr]

So you're iterating over addr lots of times, and building separate
lists. As an alternative, you could iterate over it *once*, and have a
single object representing an address.

> Why is it better to zip() them up and use:
>
> for item1, item2, item3 in zip(list1, list2, list3):
>  do something with the items
>
> than
>
>
> for j in range(len(list1)):
>do something with list1[j], list2[j], list3[j], etc.

Because 'j' is insignificant here, as is the length of the list. What
you're doing is iterating over three parallel lists - not counting
numbers. Imagine that, instead of lists, you just have *sequences* -
ordered collections of things. You can follow a recipe without knowing
the numbers of the individual lines; you just need to know the
sequence. Here, iterate over this collection:

* Collect ingredients.
* Cream the butter and the sugar.
* Sift the salt into the flour.
* Fold the mixture into an origami crane.

These instructions work whether they're numbered or not.

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


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Ben Finney
Chris Angelico  writes:

> On Sun, May 8, 2016 at 9:54 AM, Jim Dodgen  wrote:
> > The empty token is needed but useless, it is arg[0] most people just
> > repeat the program name
>
> Far from useless. It's how a process learns its own name, and yes,
> repeating the image name is the most common way to provide that.

In particular, a program's name may not be its file name; it can be
called by one of several different names dependeing on how it is
installed on the system.

Certainly the programmer writing the code cannot hard-code what the
command name will be that invokes the program. Only ‘sys.argv[0]’, read
at run time, can tell.

> Indeed. In fact, I would strongly recommend never using an explicit
> fork/exec from Python - always use subprocess or equivalent. On
> non-Unix platforms, fork/exec may not be available, but subprocess can
> use other methods of invoking programs.

I've already mentioned earlier, but to be sure: the ‘python-daemon’
library https://pypi.python.org/pypi/python-daemon/> takes care of
the details of becoming a Unix daemon process.

-- 
 \  “… a Microsoft Certified System Engineer is to information |
  `\ technology as a McDonalds Certified Food Specialist is to the |
_o__)   culinary arts.” —Michael Bacarella |
Ben Finney

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Terry Reedy

On 5/7/2016 3:17 PM, Christopher Reimer wrote:


For my purposes, I'm using the list comprehension over filter to keep
pylint happy.


How sad.  The pylint developers arrogantly take it on themselves to 
revise Python, against the wishes of Guido and the other core 
developers, and you and feel obligated to follow them.


They should at least add a disclaimer "Using the default options, pylint 
checks that your code complies with the pylint-approved subset of Python."


--
Terry Jan Reedy

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


Re: pylint woes

2016-05-07 Thread Terry Reedy

On 5/7/2016 3:52 PM, Ray Cote wrote:


Biggest issue I have with pyLint is that it complains when function
parameters are indented twice vs. once. pyFlakes likes the twice.
Example:
def function_name(
parm_1,
long_parm_name,
….
end_of_long_list_of params)
parm_1 = long_parm_name


This is the recommendation in PEP 8.  I would otherwise insert a blank 
line before the body.


tjr



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


Re: pylint woes

2016-05-07 Thread Stephen Hansen
On Sat, May 7, 2016, at 06:16 PM, DFS wrote:

> Why is it better to zip() them up and use:
> 
> for item1, item2, item3 in zip(list1, list2, list3):
>   do something with the items
> 
> than
> 
> for j in range(len(list1)):
> do something with list1[j], list2[j], list3[j], etc.

Although Chris has a perfectly good and valid answer why conceptually
the zip is better, let me put forth: the zip is simply clearer, more
readable and more maintainable.

This is a question of style and to a certain degree aesthetics, so is
somewhat subjective, but range(len(list1)) and list1[j] are all
indirection, when item1 is clearly (if given a better name then 'item1')
something distinct you're working on.

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 9:36 PM, Chris Angelico wrote:

On Sun, May 8, 2016 at 11:16 AM, DFS  wrote:

On 5/7/2016 1:01 PM, Chris Angelico wrote:

The suggestion from a human would be to use zip(), or possibly to
change your data structures.



Happens like this:

address data is scraped from a website:

names = tree.xpath()
addr  = tree.xpath()

I want to store the data atomically, so I parse street, city, state, and zip
into their own lists.

"1250 Peachtree Rd, Atlanta, GA 30303

street = [s.split(',')[0] for s in addr]
city   = [c.split(',')[1].strip() for c in addr]
state  = [s[-8:][:2] for s in addr]
zipcd  = [z[-5:] for z in addr]


So you're iterating over addr lots of times, and building separate
lists. As an alternative, you could iterate over it *once*, and have a
single object representing an address.



I like the idea of one iteration, but how?   (I'll be trying myself 
before I check back in)


Remember, it's required to split the data up, to give flexibility in 
sorting, searching, output, etc.


I saw a cool example where someone built a list and used it to do a bulk 
INSERT.  That probably won't work well here, because one of the options 
I give the user is # of addresses to store.  So I do invididual INSERTs 
using the 'for j in range()' method, which makes it easier to track how 
many addresses have been stored.




Why is it better to zip() them up and use:

for item1, item2, item3 in zip(list1, list2, list3):
 do something with the items

than


for j in range(len(list1)):
   do something with list1[j], list2[j], list3[j], etc.


Because 'j' is insignificant here, as is the length of the list.


Sorry, but I don't understand what you mean by insignificant.  j keeps 
track of the position in the list - regardless of the length of the list.




What
you're doing is iterating over three parallel lists - not counting
numbers. Imagine that, instead of lists, you just have *sequences* -
ordered collections of things. You can follow a recipe without knowing
the numbers of the individual lines; you just need to know the
sequence. Here, iterate over this collection:

* Collect ingredients.
* Cream the butter and the sugar.
* Sift the salt into the flour.
* Fold the mixture into an origami crane.

These instructions work whether they're numbered or not.


Again, not following you.


The only reason

for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.

or

for item1, item2, item3 in zip(list1, list2, list3):
do something with the items

works is because each list has the same number of items.


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


Re: pylint woes

2016-05-07 Thread MRAB

On 2016-05-08 03:14, Stephen Hansen wrote:

On Sat, May 7, 2016, at 06:16 PM, DFS wrote:


Why is it better to zip() them up and use:

for item1, item2, item3 in zip(list1, list2, list3):
  do something with the items

than

for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.


Although Chris has a perfectly good and valid answer why conceptually
the zip is better, let me put forth: the zip is simply clearer, more
readable and more maintainable.

This is a question of style and to a certain degree aesthetics, so is
somewhat subjective, but range(len(list1)) and list1[j] are all
indirection, when item1 is clearly (if given a better name then 'item1')
something distinct you're working on.


+1

If you're iterating through multiple sequences in parallel, zip is the 
way to go.


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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Steven D'Aprano
On Sun, 8 May 2016 04:40 am, Random832 wrote:

> On Sat, May 7, 2016, at 11:16, Steven D'Aprano wrote:
>> > Indian and Chinese H1B holders are getting screwed, which is of course
>> > the whole objective of the country limits.
>> 
>> The *whole* objective? You don't think that *part* of the objective may
>> be
>> to ensure that citizens of countries other than India and China can get
>> green cards too?
> 
> If not for the quotas, a citizen of some other country would have an
> equal chance to get a green card as a citizen of India or China. 

If you have a big hat with 5,000,000 tickets marked "Indian", and 500
tickets marked "Finish", and you stick your hand in the hat and rummage
around and pick a random ticket, do you really think that you have an equal
chance of selecting an Indian ticket and a Finish ticket?


> This is 
> a much simpler question than Python convention attendees, since there
> are *in fact* more Indian or Chinese people in actual existence than
> citizens of any given other country, which can't be blamed on any form
> of discrimination.
> 
>> Perhaps the country limits are also in place, at least in part, to manage
>> the rate at which new immigrants arrive in the country?
> 
> That's immaterial, we're not talking about a limit on the total number
> of visas.

How is it immaterial? Regardless of the limit on the total number of visas,
per country limits put an upper limit how quickly new immigrants from any
one specific country can arrive.



-- 
Steven

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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 12:15 PM, DFS  wrote:
> On 5/7/2016 9:36 PM, Chris Angelico wrote:
>>
>> On Sun, May 8, 2016 at 11:16 AM, DFS  wrote:
>>>
>>> street = [s.split(',')[0] for s in addr]
>>> city   = [c.split(',')[1].strip() for c in addr]
>>> state  = [s[-8:][:2] for s in addr]
>>> zipcd  = [z[-5:] for z in addr]
>>
>>
>> So you're iterating over addr lots of times, and building separate
>> lists. As an alternative, you could iterate over it *once*, and have a
>> single object representing an address.
>
> I like the idea of one iteration, but how?   (I'll be trying myself before I
> check back in)
>
> Remember, it's required to split the data up, to give flexibility in
> sorting, searching, output, etc.

Start by unpacking the comprehensions into statement form.

street = []
for s in addr:
street.append(s.split(',')[0])
city = []
for c in addr:
city.append(c.split(',')[1].strip())
state = []
for s in addr:
state.append(s[-8:][:2])
zipcd = []
for z in addr:
zipcd.append(z[-5:])

Now see how you're doing the same thing four times? Let's start by
keeping it the way it is, but combine the loops.

street, city, state, zipcd = [], [], [], []
for a in addr:
street.append(a.split(',')[0])
city.append(a.split(',')[1].strip())
state.append(a[-8:][:2])
zipcd.append(a[-5:])

Side point: I prefer collections to be named in the plural, so these
would be "streets", and "addrs". This lets you follow a very simple
rule of iteration: "for item in collection" or "for singular in
plural". In this case, "for address in addresses" is classic
iteration.

So, now that you have a single loop picking up the different pieces,
it's easy to build up a simple object that represents an address.

# Either this
from collections import namedtuple
Address = namedtuple("Address", ["street", "city", "state", "zipcd"])
# or this
from types import SimpleNamespace
class Address(SimpleNamespace): pass

addresses = []
for a in addr:
addresses.append(Address(
street=a.split(',')[0],
city=a.split(',')[1].strip(),
state=a[-8:][:2],
zipcd=a[-5:],
)

Voila! One iteration, and a single object representing an address.

> I saw a cool example where someone built a list and used it to do a bulk
> INSERT.  That probably won't work well here, because one of the options I
> give the user is # of addresses to store.  So I do invididual INSERTs using
> the 'for j in range()' method, which makes it easier to track how many
> addresses have been stored.

You could slice it if you actually want that.

>>> Why is it better to zip() them up and use:
>>>
>>> for item1, item2, item3 in zip(list1, list2, list3):
>>>  do something with the items
>>>
>>> than
>>>
>>>
>>> for j in range(len(list1)):
>>>do something with list1[j], list2[j], list3[j], etc.
>>
>>
>> Because 'j' is insignificant here, as is the length of the list.
>
> Sorry, but I don't understand what you mean by insignificant.  j keeps track
> of the position in the list - regardless of the length of the list.

Right, but *who cares* what the position is? All you want to do is the
"do something" bit. Don't think in terms of concrete and discrete
operations in a computer; think in the abstract (what are you trying
to accomplish?), and then represent that in code.

>> What
>> you're doing is iterating over three parallel lists - not counting
>> numbers. Imagine that, instead of lists, you just have *sequences* -
>> ordered collections of things. You can follow a recipe without knowing
>> the numbers of the individual lines; you just need to know the
>> sequence. Here, iterate over this collection:
>>
>> * Collect ingredients.
>> * Cream the butter and the sugar.
>> * Sift the salt into the flour.
>> * Fold the mixture into an origami crane.
>>
>> These instructions work whether they're numbered or not.
>
> Again, not following you.
>
>
> The only reason
>
> for j in range(len(list1)):
> do something with list1[j], list2[j], list3[j], etc.
>
> or
>
> for item1, item2, item3 in zip(list1, list2, list3):
> do something with the items
>
> works is because each list has the same number of items.

Sure, but who cares what each item's position is? All that matters is
that they have corresponding positions, which is what zip() does.

Imagine you don't even have the whole lists yet. Imagine someone's
still writing stuff to them as you work. Maybe they're infinite in
length. You can't iterate up to the length of list1, because it
doesn't HAVE a length. But you can still zip it up with other parallel
collections, and iterate over them all.

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Steven D'Aprano
On Sun, 8 May 2016 07:35 am, Stephen Hansen wrote:

> I'd read over PEP8 (the document, not the tool) and
> apply style guide recommendations thoughtfully, not mechanically.


Guido is not a fan of automated PEP8 checkers. He agrees entirely with your
comment: apply style guides thoughtfully, not mechanically.

(Cannot be repeated often enough.)


-- 
Steven

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


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 10:14 PM, Stephen Hansen wrote:

On Sat, May 7, 2016, at 06:16 PM, DFS wrote:


Why is it better to zip() them up and use:

for item1, item2, item3 in zip(list1, list2, list3):
  do something with the items

than

for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.


Although Chris has a perfectly good and valid answer why conceptually
the zip is better, let me put forth: the zip is simply clearer, more
readable and more maintainable.

>

This is a question of style and to a certain degree aesthetics, so is
somewhat subjective, but range(len(list1)) and list1[j] are all
indirection, when item1 is clearly (if given a better name then 'item1')
something distinct you're working on.



The lists I actually use are:

for j in range(len(nms)):
 cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
 vals = nms[j],street[j],city[j],state[j],zipcd[j]


The enumerated version would be:

ziplists = zip(nms,street,city,state,zipcd)
for nm,street,city,state,zipcd in ziplists:
 cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
 vals = nm,street,city,state,zipcd


I guess the enumeration() is a little nicer to look at.  Why do you 
think it's more maintainable?



Aside: I haven't tried, but is 'names' a bad idea or illegal for the 
name of a python list or variable?



Thanks

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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 12:43 PM, Steven D'Aprano  wrote:
> On Sun, 8 May 2016 04:40 am, Random832 wrote:
>
>> On Sat, May 7, 2016, at 11:16, Steven D'Aprano wrote:
>>> > Indian and Chinese H1B holders are getting screwed, which is of course
>>> > the whole objective of the country limits.
>>>
>>> The *whole* objective? You don't think that *part* of the objective may
>>> be
>>> to ensure that citizens of countries other than India and China can get
>>> green cards too?
>>
>> If not for the quotas, a citizen of some other country would have an
>> equal chance to get a green card as a citizen of India or China.
>
> If you have a big hat with 5,000,000 tickets marked "Indian", and 500
> tickets marked "Finish", and you stick your hand in the hat and rummage
> around and pick a random ticket, do you really think that you have an equal
> chance of selecting an Indian ticket and a Finish ticket?

So the question is: Do we care about country equality or individual
equality? You can't have both. As soon as you divide a population up
into unequal parts, you have to figure out what you actually mean by
"equality". For instance, should the states in a country have equal
representation in federal government, or should their sway be affected
by the number of people in each state? In a Wikipedia article, how
much space should be given to a narrowly-held view compared to a
widely-held one? In a summary of a thousand people's comments, how
many favorable ones and how many unfavorable ones should be quoted? In
an extreme case of the latter, suppose you have room to post ten
comments, and of the thousand, only four were against. Do you post all
four, and restrict the other side to four to be "fair", or do you post
one of them against nine "yea" comments, or do you pick randomly from
the entire pool of questions (which would give you a 4% chance of
drawing even a single negative comment)? Which is "fairest"?

If two people both want to enter the country, it's *obviously* right
that they should have equal chance as individuals. And it's equally
obvious that it's not fair to let one highly populous country push out
every other country. Somewhere in there you need math and decisions.

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


Re: Pylint prefers list comprehension over filter...

2016-05-07 Thread Christopher Reimer

On 5/7/2016 6:40 PM, Terry Reedy wrote:

On 5/7/2016 3:17 PM, Christopher Reimer wrote:


For my purposes, I'm using the list comprehension over filter to keep
pylint happy.


How sad.  The pylint developers arrogantly take it on themselves to
revise Python, against the wishes of Guido and the other core
developers, and you and feel obligated to follow them.

They should at least add a disclaimer "Using the default options, pylint
checks that your code complies with the pylint-approved subset of Python."


I wasn't aware that I was picking sides in a religious war by altering 
one line of code. O_o


Thank you,

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


Re: pylint woes

2016-05-07 Thread Steven D'Aprano
On Sun, 8 May 2016 02:51 am, DFS wrote:

> This more-anal-than-me program generated almost 2 warnings for every
> line of code in my program.  w t hey?
> 
> 
>DFS comments
> +-++ ---
> |message id   |occurrences |
> +=++
> |mixed-indentation|186 | I always use tab

Obviously not. There are 186 occurrences where you use mixed tabs and
spaces.

Try running Tabnanny on you file:

python -m tabnanny 


> +-++
> |invalid-name |82  | every single variable name?!

Maybe. What are they called?


> +-++
> |bad-whitespace   |65  | mostly because I line up =
>   signs:
>   var1  = value
>   var10 = value

Yuck. How much time do you waste aligning assignments whenever you add or
delete or edit a variable?


> +-++
> |trailing-whitespace  |59  | heh!
> +-++
> |multiple-statements  |23  | do this to save lines.
>   Will continue doing it.

Why? Do you think that there's a world shortage of newline characters? Is
the Enter key on your keyboard broken?


> +-++
> |no-member|5   |
> 
> "Module 'pyodbc' has no 'connect' member"   Yes it does.
> "Module 'pyodbc' has no 'Error' member" Yes it does.
> 
> Issue with pylint, or pyodbc?

*shrug* More likely with Pylint.


> +-++
> |line-too-long|5   | meh
> +-++
> |wrong-import-order   |4   | does it matter?

Probably not. I'm curious what it thinks is the right import order.



> +-++
> |missing-docstring|4   | what's the difference between
>   a docstring and a # comment?

Comments exist only in the source code.

Docstrings are available for interactive use with help(), for runtime
introspection, and for doctests.

https://docs.python.org/2/library/doctest.html


> +-++
> |multiple-imports |2   | doesn't everyone?

You mean something like this?

import spam, ham, eggs, cheese

*shrug* It's a style thing.


> +-++
> |consider-using-enumerate |2   | see below [1]

Absolutely use enumerate.


> +-++
> |bad-builtin  |2   | warning because I used filter?

Well that's just stupid. Bad PyLint. This should absolutely not be turned on
by default.


-- 
Steven

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


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 3:40 PM, Terry Reedy wrote:

On 5/7/2016 12:51 PM, DFS wrote:

This more-anal-than-me program generated almost 2 warnings for every
line of code in my program.  w t hey?


If you don't like it, why do you use it?



I've never used it before last night.  I was shocked at what it spewed 
back at me.





I suppose the answer is that it did find a few things to check.  You
might be happier with pychecker, which is much less aggressive.


I'll give it a shot.




I believe will find the things you did fix.


I'm not parsing this statement.  You mean pychecker will find the same 
things pylint found, and that I fixed?


If it finds them after I fixed them... it's a magical program :)



DFS comments

+-++ ---
|message id   |occurrences |
+=++
|mixed-indentation|186 | I always use tab
+-++
|invalid-name |82  | every single variable name?!


I would need examples to comment.



Invalid constant name "cityzip" (invalid-name)
Invalid constant name "state" (invalid-name)
Invalid constant name "miles" (invalid-name)
Invalid constant name "store" (invalid-name)
Invalid variable name "rs" (invalid-name)




+-++
|trailing-whitespace  |59  | heh!


Any code editor should have a command to fix this.
IDLE: Format => strip trailing whitespace
Notepad++: Macro => trim trailing and save, Alt-Shift-S
others ...


That did it.



+-++
|no-member|5   |

"Module 'pyodbc' has no 'connect' member"   Yes it does.
"Module 'pyodbc' has no 'Error' member" Yes it does.

Issue with pylint, or pyodbc?


Worth looking into.  Could be a bug somewhere. But I don't have pyodbc
installed.


+-++
|line-too-long|5   | meh


For following the PEP guideline when patching CPython, this is helpful.


+-++
|wrong-import-order   |4   | does it matter?


Consistency in imports ultimately makes easier reading.
Many idlelib files use this order: stdlib modules other than tkinter and
idlelib (alphabetically); tkinter (tkinter first, then submodules);
idlelib (alphabetically).  When I edit files, I sometimes reorder
imports to conform.



It complains 2x about this:

import os, sys, time, datetime
import pyodbc, sqlite3
import re, requests
from lxml import html


But I think there are some pylint bugs here:
-

standard import "import pyodbc, sqlite3" comes before "import pyodbc, 
sqlite3" (wrong-import-order)


  * complains that the line comes before itself?

-

standard import "import re, requests" comes before "import pyodbc, 
sqlite3" (wrong-import-order)


  * So I switched them, and then it complained about that:

standard import "import pyodbc, sqlite3" comes before "import re, 
requests" (wrong-import-order)


-

You can't win with pylint...

And, the author probably isn't a native English-speaker, since when he 
says 'comes before' I think he means 'should come before'.







+-++
|missing-docstring|4   | what's the difference between
 a docstring and a # comment?


# Comments only appear in the source
'''Docstrings are copied to the compiled code object, are interactively
accessible, and are used for help(ojb) output.'''



+-++
|superfluous-parens   |3   | I like to surround 'or'
 statments with parens


I would need examples to comment



if ("Please choose a state" in str(matches)):
if (var == "val" or var2 == "val2"):



+-++
|bad-builtin  |2   | warning because I used filter?


If they are still doing this in the latest release, it is an arrogance
and inconsistency bug on their part.  Disable this check.


$ pylint --version
No config file found, using default configuration
pylint 1.5.5,
astroid 1.4.5
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:32:19) [MSC v.1500 
32 bit (Intel)]



It says "Used builtin function 'filter'. Using a list comprehension can 
be clearer. (bad-builtin)"





+-++
|missing-final-newline|1   | I'm using Notepad++, with
 EOL Conversion set to
 'Windows Format'.


That says to replace final '\n' with '\r\n'.  It does not affect a
missing final newline ;-)

 

Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 2:52 PM, Christopher Reimer wrote:

On 5/7/2016 9:51 AM, DFS wrote:

Has anyone ever in history gotten 10/10 from pylint for a non-trivial
program?


I routinely get 10/10 for my code. While pylint isn't perfect and
idiosyncratic at times, it's a useful tool to help break bad programming
habits. Since I came from a Java background, I had to unlearn everything
from Java before I could write Pythonic code. It might help to use an
IDE that offers PEP8-compliant code suggestions (I use PyCharm IDE).


That's about as good as it's gonna get!


You can do better.


10/10 on pylint isn't better.  It's being robotic and conforming to the 
opinions of the author of that app.


In fact, I think:

import os, sys, time, socket

is much more readable than, and preferable to,

import os
import sys
import time
import socket

but pylint complains about the former.





You should strive for 10/10 whenever possible,


nah



figure out why you fall short and ask for help on the parts that don't
make sense.


I actually agree with ~3/4 of the suggestions it makes.  My code ran 
fine before pylint tore it a new one, and it doesn't appear to run any 
better after making various fixes.


But between you clp guys and pylint, the code is definitely improving.




pylint says "Consider using enumerate instead of iterating with range
and len"

the offending code is:
for j in range(len(list1)):
  do something with list1[j], list2[j], list3[j], etc.


This code is reeking with bad habits to be broken. Assigning a throwaway
variable to walk the index is unnecessary when Python can do it for you
behind the scenes.


Don't you think python also allocates a throwaway variable for use with 
zip and enumerate()?





As Chris A. pointed out in his post, you should use
zip() to walk through the values of each list at the same time.


Yeah, zip looks interesting.  I just started using python a month ago, 
and didn't know about zip until pylint pointed it out (it said I 
redefined a builtin by using 'zip' as a list name).


Edit: I already put zip() it in place.  Only improvement I think is it 
looks cleaner - got rid of a bunch of [j]s.







Thank you,

Chris R.



No, thank /you/,

DFS




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


Re: Python is an Equal Opportunity Programming Language

2016-05-07 Thread Random832
On Sat, May 7, 2016, at 22:43, Steven D'Aprano wrote:
> > If not for the quotas, a citizen of some other country would have an
> > equal chance to get a green card as a citizen of India or China. 
> 
> If you have a big hat with 5,000,000 tickets marked "Indian", and 500
> tickets marked "Finish", and you stick your hand in the hat and rummage
> around and pick a random ticket, do you really think that you have an
> equal
> chance of selecting an Indian ticket and a Finish ticket?

But that's not what it is. You would have, say, 1,000 tickets labeled
"green card" and 100,000 tickets labeled "no green card", and  (say)
12,000 Indian people and 50 Finnish people each get their turn drawing
from that same bucket. In your version, the Finnish people draw from a
bucket with 500 green card tickets and no "no green card" cards, and the
Indian people draw from a bucket with 500 green card tickets and 11,500
"no green card" tickets.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Stephen Hansen
On Sat, May 7, 2016, at 08:04 PM, DFS wrote:
> The lists I actually use are:
> 
> for j in range(len(nms)):
>   cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>   vals = nms[j],street[j],city[j],state[j],zipcd[j]
> 
> 
> The enumerated version would be:
> 
> ziplists = zip(nms,street,city,state,zipcd)
> for nm,street,city,state,zipcd in ziplists:
>   cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>   vals = nm,street,city,state,zipcd
> 
> 
> I guess the enumeration() is a little nicer to look at.  Why do you 
> think it's more maintainable?

Code is read more then its written.

That which is nicer to look at, therefore, is easier to read.

That which is easier to read is easier to maintain.

Beyond that, its simpler, and more clearly articulates in the local
space what's going on. 

> Aside: I haven't tried, but is 'names' a bad idea or illegal for the 
> name of a python list or variable?

Nothing wrong with names. Or 'name', for that matter. Try to avoid
abbreviations.

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: redirecting stdout and stderr to /dev/null

2016-05-07 Thread Jim Dodgen
Great help.  My Python program is a rewrite of a Perl program I wrote. An
interesting exercise.
The reason being it is targeted for a Raspberry Pi  and for the Pi Python
has the most support.



*Jim Dodgen*







On Sat, May 7, 2016 at 6:38 PM, Ben Finney 
wrote:

> Chris Angelico  writes:
>
> > On Sun, May 8, 2016 at 9:54 AM, Jim Dodgen  wrote:
> > > The empty token is needed but useless, it is arg[0] most people just
> > > repeat the program name
> >
> > Far from useless. It's how a process learns its own name, and yes,
> > repeating the image name is the most common way to provide that.
>
> In particular, a program's name may not be its file name; it can be
> called by one of several different names dependeing on how it is
> installed on the system.
>
> Certainly the programmer writing the code cannot hard-code what the
> command name will be that invokes the program. Only ‘sys.argv[0]’, read
> at run time, can tell.
>
> > Indeed. In fact, I would strongly recommend never using an explicit
> > fork/exec from Python - always use subprocess or equivalent. On
> > non-Unix platforms, fork/exec may not be available, but subprocess can
> > use other methods of invoking programs.
>
> I've already mentioned earlier, but to be sure: the ‘python-daemon’
> library https://pypi.python.org/pypi/python-daemon/> takes care of
> the details of becoming a Unix daemon process.
>
> --
>  \  “… a Microsoft Certified System Engineer is to information |
>   `\ technology as a McDonalds Certified Food Specialist is to the |
> _o__)   culinary arts.” —Michael Bacarella |
> Ben Finney
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 1:28 PM, DFS  wrote:
> Invalid constant name "cityzip" (invalid-name)
> Invalid constant name "state" (invalid-name)
> Invalid constant name "miles" (invalid-name)
> Invalid constant name "store" (invalid-name)
> Invalid variable name "rs" (invalid-name)

... huh?? The first four seem to have been incorrectly detected as
constants. How are they used?

The last one is probably "too short". Or something.

> standard import "import re, requests" comes before "import pyodbc, sqlite3"
> (wrong-import-order)
>
>   * So I switched them, and then it complained about that:
>
> standard import "import pyodbc, sqlite3" comes before "import re, requests"
> (wrong-import-order)
>
> -
>
> You can't win with pylint...

Probably that means it got confused by the alphabetization - "pyodbc"
should come before "re" and "requests", but "sqlite3" should come
after. Either fix the first problem by splitting them onto separate
lines, or ignore this as a cascaded error.

My general principle is that things on one line should *belong* on one
line. So having "import re, requests" makes no sense, but I might have
something like "import os, sys" when the two modules are both used in
one single line of code and never again. Otherwise, splitting them out
is the easiest.


>>> +-++
>>> |superfluous-parens   |3   | I like to surround 'or'
>>>  statments with parens
>>
>>
>> I would need examples to comment
>
>
>
> if ("Please choose a state" in str(matches)):
> if (var == "val" or var2 == "val2"):

Cut the parens. Easy!

> It says "Used builtin function 'filter'. Using a list comprehension can be
> clearer. (bad-builtin)"

Kill that message and keep using filter.

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


Re: pylint woes

2016-05-07 Thread Stephen Hansen
On Sat, May 7, 2016, at 08:28 PM, DFS wrote:
> >> +-++
> >> |superfluous-parens   |3   | I like to surround 'or'
> >>  statments with parens
> >
> > I would need examples to comment
> 
> 
> if ("Please choose a state" in str(matches)):
> if (var == "val" or var2 == "val2"):

Gah, don't do that. You're adding meaningless noise. 

Especially in the first case.

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 1:38 PM, DFS  wrote:
>> This code is reeking with bad habits to be broken. Assigning a throwaway
>> variable to walk the index is unnecessary when Python can do it for you
>> behind the scenes.
>
>
> Don't you think python also allocates a throwaway variable for use with zip
> and enumerate()?

Nope. But even if it did, it wouldn't matter. Concern yourself with
your code, and let the implementation take care of itself.

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


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 11:25 PM, Steven D'Aprano wrote:

On Sun, 8 May 2016 02:51 am, DFS wrote:


This more-anal-than-me program generated almost 2 warnings for every
line of code in my program.  w t hey?


   DFS comments
+-++ ---
|message id   |occurrences |
+=++
|mixed-indentation|186 | I always use tab


Obviously not. There are 186 occurrences where you use mixed tabs and
spaces.



I mean I always use tab after :

The program won't run otherwise.  If I use spaces, 100% of the time it 
throws:


IndentationError: unindent does not match any outer indentation level





Try running Tabnanny on you file:

python -m tabnanny 



Didn't seem to do anything.




+-++
|invalid-name |82  | every single variable name?!


Maybe. What are they called?



+-++
|bad-whitespace   |65  | mostly because I line up =
  signs:
  var1  = value
  var10 = value


Yuck. How much time do you waste aligning assignments whenever you add or
delete or edit a variable?


Lots.  It takes hours to add or delete 3 whitespaces.




+-++
|trailing-whitespace  |59  | heh!
+-++
|multiple-statements  |23  | do this to save lines.
  Will continue doing it.


Why? Do you think that there's a world shortage of newline characters? Is
the Enter key on your keyboard broken?


I do it because I like it.

if verbose: print var

python doesn't complain.






+-++
|no-member|5   |

"Module 'pyodbc' has no 'connect' member"   Yes it does.
"Module 'pyodbc' has no 'Error' member" Yes it does.

Issue with pylint, or pyodbc?


*shrug* More likely with Pylint.





+-++
|line-too-long|5   | meh
+-++
|wrong-import-order   |4   | does it matter?


Probably not. I'm curious what it thinks is the right import order.



"wrong-import-order (C0411):
 %s comes before %s Used when PEP8 import order is not respected 
(standard imports first, then third-party libraries, then local imports)"


https://docs.pylint.org/features.html



I think there are some pylint bugs here:
-

standard import "import pyodbc, sqlite3" comes before "import pyodbc, 
sqlite3" (wrong-import-order)


  * complains that the line comes before itself?

-

standard import "import re, requests" comes before "import pyodbc, 
sqlite3" (wrong-import-order)


  * So I switched them, and then it complained about that:

standard import "import pyodbc, sqlite3" comes before "import re, 
requests" (wrong-import-order)


-






+-++
|missing-docstring|4   | what's the difference between
  a docstring and a # comment?


Comments exist only in the source code.

Docstrings are available for interactive use with help(), for runtime
introspection, and for doctests.

https://docs.python.org/2/library/doctest.html


Thanks



+-++
|multiple-imports |2   | doesn't everyone?


You mean something like this?

import spam, ham, eggs, cheese

*shrug* It's a style thing.


pylint gives you demerits for that.




+-++
|consider-using-enumerate |2   | see below [1]


Absolutely use enumerate.



Everyone else says so, too.  But other than cleaner-looking code, I'm 
not understanding how it's a real advantage over:


for j in range(len(list)):





+-++
|bad-builtin  |2   | warning because I used filter?


Well that's just stupid. Bad PyLint. This should absolutely not be turned on
by default.



It says "Used builtin function 'filter'. Using a list comprehension can 
be clearer. (bad-builtin)"



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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 2:10 PM, DFS  wrote:
>>> +-++
>>> |trailing-whitespace  |59  | heh!
>>> +-++
>>> |multiple-statements  |23  | do this to save lines.
>>>   Will continue doing it.
>>
>>
>> Why? Do you think that there's a world shortage of newline characters? Is
>> the Enter key on your keyboard broken?
>
>
> I do it because I like it.
>
> if verbose: print var
>
> python doesn't complain.

That's a massively-debated point. In that specific example, I'd
support the one-liner; however, I'd also recommend this technique:

# for Python 2, you need to start with this line
from __future__ import print_function

if verbose:
verbiage = print
else:
def verbiage(*args): pass

Then, instead of "if verbose: print(var)", you would use
"verbiage(var)". Of course, you want something better than "verbiage"
as your name; the nature of your verbose output might give a clue as
to what name would work.

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


Re: pylint woes

2016-05-07 Thread DFS

On 5/7/2016 11:51 PM, Chris Angelico wrote:

On Sun, May 8, 2016 at 1:28 PM, DFS  wrote:

Invalid constant name "cityzip" (invalid-name)
Invalid constant name "state" (invalid-name)
Invalid constant name "miles" (invalid-name)
Invalid constant name "store" (invalid-name)
Invalid variable name "rs" (invalid-name)


... huh?? The first four seem to have been incorrectly detected as
constants. How are they used?


The first four are set once and not changed.  Probably that's why it 
calls it a constant.






The last one is probably "too short". Or something.


In this case, rs is a pyodbc row object.

rs = cursor.fetchone()




standard import "import re, requests" comes before "import pyodbc, sqlite3"
(wrong-import-order)

  * So I switched them, and then it complained about that:

standard import "import pyodbc, sqlite3" comes before "import re, requests"
(wrong-import-order)

-

You can't win with pylint...


Probably that means it got confused by the alphabetization - "pyodbc"
should come before "re" and "requests", but "sqlite3" should come
after. Either fix the first problem by splitting them onto separate
lines, or ignore this as a cascaded error.

My general principle is that things on one line should *belong* on one
line. So having "import re, requests" makes no sense, but I might have
something like "import os, sys" when the two modules are both used in
one single line of code and never again. Otherwise, splitting them out
is the easiest.



I like to put them on a related line.  Didn't know where re belonged, 
and I don't like putting them on single line each.





+-++
|superfluous-parens   |3   | I like to surround 'or'
 statments with parens



I would need examples to comment




if ("Please choose a state" in str(matches)):
if (var == "val" or var2 == "val2"):


Cut the parens. Easy!



Maybe.  I actually like my 'or' parens.  Habit maybe, because of this 
situation:


if (var == "val" or var2 == "val2") and (var3 == val3 or var4 == val4):





It says "Used builtin function 'filter'. Using a list comprehension can be
clearer. (bad-builtin)"


Kill that message and keep using filter.



Unfortunately, 'bad-builtin' caught 2 truly bad uses of built-ins (zip() 
and id()), so I'll leave that warning in.



2.7.11 built-ins:

abs()   divmod()input() open()  staticmethod()
all()   enumerate() int()   ord()   str()
any()   eval()  isinstance()pow()   sum()
basestring()execfile()  issubclass()print() super()
bin()   file()  iter()  property()  tuple()
bool()  filter()len()   range() type()
bytearray() float() list()  raw_input() unichr()
callable()  format()locals()reduce()unicode()
chr()   frozenset() long()  reload()vars()
classmethod()   getattr()   map()   repr()  xrange()
cmp()   globals()   max()   reversed()  zip()
compile()   hasattr()   memoryview()round() __import__()
complex()   hash()  min()   set()   
delattr()   help()  next()  setattr()   
dict()  hex()   object()slice() 
dir()   id()oct()   sorted()


I probably would've used dict as an object name at some point, too.


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


Re: pylint woes

2016-05-07 Thread Chris Angelico
On Sun, May 8, 2016 at 2:40 PM, DFS  wrote:
>>> It says "Used builtin function 'filter'. Using a list comprehension can
>>> be
>>> clearer. (bad-builtin)"
>>
>>
>> Kill that message and keep using filter.
>
>
>
> Unfortunately, 'bad-builtin' caught 2 truly bad uses of built-ins (zip() and
> id()), so I'll leave that warning in.
>

Hrm, that would be called "shadowing" built-ins, not bad use of them.
Shadowing isn't usually a problem - unless you actually need id(),
there's nothing wrong with using the name id for a database key. Very
different from this message though.

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


Re: pylint woes

2016-05-07 Thread Ian Kelly
On Sat, May 7, 2016 at 9:28 PM, DFS  wrote:
> But I think there are some pylint bugs here:
> -
>
> standard import "import pyodbc, sqlite3" comes before "import pyodbc,
> sqlite3" (wrong-import-order)
>
>   * complains that the line comes before itself?

I think that it actually wants you to import sqlite3 (a standard
library module) before pyodbc (a third-party module). The message is
confusing because they happen to be on the same line. PEP8 has some
advice on import ordering, which this probably follows.

>
> -
>
> standard import "import re, requests" comes before "import pyodbc, sqlite3"
> (wrong-import-order)
>
>   * So I switched them, and then it complained about that:
>
> standard import "import pyodbc, sqlite3" comes before "import re, requests"
> (wrong-import-order)

Same thing. It wants the re import to come before pyodbc, and it wants
sqlite3 to come before requests.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pylint woes

2016-05-07 Thread Jussi Piitulainen
DFS writes:

> The lists I actually use are:
>
> for j in range(len(nms)):
>  cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>  vals = nms[j],street[j],city[j],state[j],zipcd[j]
>
>
> The enumerated version would be:
>
> ziplists = zip(nms,street,city,state,zipcd)
> for nm,street,city,state,zipcd in ziplists:
>  cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>  vals = nm,street,city,state,zipcd
>
>
> I guess the enumeration() is a little nicer to look at.  Why do you
> think it's more maintainable?

The following variations avoid the naming of the result of zip at all,
and also save a line or two, depending on what you actually do in the
loop, without introducing overly long lines. Judge for yourself.

You don't need to name the individual components, if you only actually
use vals:

for vals in zip(nms,street,city,state,zipcd):
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"


Or you can opt to name the tuple and its components the other way
around:

for vals in zip(nms,street,city,state,zipcd):
nm,street,city,state,zipcd = vals
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
-- 
https://mail.python.org/mailman/listinfo/python-list