Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #34347 > unrolled thread

Re: Confused compare function :)

Started byBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
First post2012-12-06 01:19 +0100
Last post2012-12-06 19:25 +0000
Articles 20 on this page of 41 — 15 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Confused compare function :) Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-06 01:19 +0100
    Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-06 00:42 +0000
      Re: Confused compare function :) Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-12-06 13:41 -0500
      Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 19:55 +0100
    Re: Confused compare function :) Rotwang <sg552@hotmail.co.uk> - 2012-12-06 03:22 +0000
      Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-06 04:32 +0000
        Re: Confused compare function :) Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-06 09:49 +0100
          Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-06 11:47 +0000
            Re: Confused compare function :) peter <pjmakey2@gmail.com> - 2012-12-06 08:55 -0300
              Re: Confused compare function :) Hans Mulder <hansmu@xs4all.nl> - 2012-12-06 14:32 +0100
                Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-07 00:47 +1100
            Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-06 23:14 +1100
              Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-07 22:16 +0000
                Re: Confused compare function :) Terry Reedy <tjreedy@udel.edu> - 2012-12-08 02:01 -0500
                Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-08 18:17 +1100
                Re: Confused compare function :) MRAB <python@mrabarnett.plus.com> - 2012-12-08 17:50 +0000
              Re: Confused compare function :) Ramchandra Apte <maniandram01@gmail.com> - 2012-12-08 19:07 -0800
                Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-09 14:22 +1100
                  Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-09 07:39 +0000
              Re: Confused compare function :) Ramchandra Apte <maniandram01@gmail.com> - 2012-12-08 19:07 -0800
            Re: Confused compare function :) Neil Cerutti <neilc@norwich.edu> - 2012-12-06 13:51 +0000
              Re: Confused compare function :) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-07 02:55 +0000
                Re: Confused compare function :) Neil Cerutti <neilc@norwich.edu> - 2012-12-07 16:40 +0000
          Re: Confused compare function :) Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-12-06 14:33 +0100
            Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-07 00:58 +1100
              Re: Confused compare function :) Hans Mulder <hansmu@xs4all.nl> - 2012-12-06 15:21 +0100
                Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-07 01:28 +1100
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 15:22 +0100
            Re: Confused compare function :) Dave Angel <d@davea.name> - 2012-12-06 09:40 -0500
            Re: Confused compare function :) peter <pjmakey2@gmail.com> - 2012-12-06 11:46 -0300
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 17:16 +0100
            Re: Confused compare function :) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-12-06 16:52 +0000
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 18:08 +0100
            Re: Confused compare function :) MRAB <python@mrabarnett.plus.com> - 2012-12-06 17:10 +0000
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 18:31 +0100
            Re: Confused compare function :) MRAB <python@mrabarnett.plus.com> - 2012-12-06 17:52 +0000
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-06 19:25 +0100
            Re: Confused compare function :) Anatoli Hristov <tolidtm@gmail.com> - 2012-12-07 14:36 +0100
          Re: Confused compare function :) Rotwang <sg552@hotmail.co.uk> - 2012-12-06 19:24 +0000
        Re: Confused compare function :) Chris Angelico <rosuav@gmail.com> - 2012-12-06 20:34 +1100
        Re: Confused compare function :) Rotwang <sg552@hotmail.co.uk> - 2012-12-06 19:25 +0000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#34386

FromNeil Cerutti <neilc@norwich.edu>
Date2012-12-06 13:51 +0000
Message-ID<aibm71Fqt9uU3@mid.individual.net>
In reply to#34377
On 2012-12-06, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> total = 0
> for s in list_of_strings:
>     try:
>         total += int(s)
>     except ValueError:
>         pass  # Not a number, ignore it.

If it's internal data, perhaps. Of course, that would mean I had
the option of *not* creating that stupid list_of_strings.

-- 
Neil Cerutti

[toc] | [prev] | [next] | [standalone]


#34443

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-12-07 02:55 +0000
Message-ID<50c15a9a$0$21853$c3e8da3$76491128@news.astraweb.com>
In reply to#34386
On Thu, 06 Dec 2012 13:51:29 +0000, Neil Cerutti wrote:

> On 2012-12-06, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> total = 0
>> for s in list_of_strings:
>>     try:
>>         total += int(s)
>>     except ValueError:
>>         pass  # Not a number, ignore it.
> 
> If it's internal data, perhaps. Of course, that would mean I had the
> option of *not* creating that stupid list_of_strings.


Not necessarily, it depends on the application.

If you have a spreadsheet, and create a formula =SUM(A1:A50) the expected 
behaviour is to just skip anything that is not a valid number, not raise 
an error. Sometimes correct application-level behaviour is to just ignore 
input that it doesn't care about.

One of the things that I used to despise with a passion about MYOB is 
that if you clicked on the window outside of a button or field, it would 
scream at you "ERROR ERROR ERROR - that was not a button or field!!!!" 
That is to say, it would beep. I mean, *who fscking cares* that the user 
clicks in the window background? It's a harmless tick, like tapping your 
desk, just ignore it.

As a general rule, library functions should be strict about reporting 
errors, while applications may be more forgiving about errors that they 
don't care about. The "don't care about" part is important though -- your 
word processor shouldn't care about low level networking errors, but it 
should care if it can't save a file to a network drive. 


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#34477

FromNeil Cerutti <neilc@norwich.edu>
Date2012-12-07 16:40 +0000
Message-ID<aiekf2FhjftU2@mid.individual.net>
In reply to#34443
On 2012-12-07, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
> On Thu, 06 Dec 2012 13:51:29 +0000, Neil Cerutti wrote:
>
>> On 2012-12-06, Steven D'Aprano
>> <steve+comp.lang.python@pearwood.info> wrote:
>>> total = 0
>>> for s in list_of_strings:
>>>     try:
>>>         total += int(s)
>>>     except ValueError:
>>>         pass  # Not a number, ignore it.
>> 
>> If it's internal data, perhaps. Of course, that would mean I
>> had the option of *not* creating that stupid list_of_strings.
>
> Not necessarily, it depends on the application.

I agree. I personally wouldn't want, e.g., 12.0 to get silently
skipped so I've never done this. I've never done anything like
that, but I can imagine it.

> If you have a spreadsheet, and create a formula =SUM(A1:A50)
> the expected behaviour is to just skip anything that is not a
> valid number, not raise an error. Sometimes correct
> application-level behaviour is to just ignore input that it
> doesn't care about.
>
> One of the things that I used to despise with a passion about
> MYOB is that if you clicked on the window outside of a button
> or field, it would scream at you "ERROR ERROR ERROR - that was
> not a button or field!!!!" That is to say, it would beep. I
> mean, *who fscking cares* that the user clicks in the window
> background? It's a harmless tick, like tapping your desk, just
> ignore it.

What happens in Word during a Mail Merge if an invalid field is
in the data file, one you don't even care about: You get to click
on a modular dialog box for every record you're merging with to
say IGNORE. And you can't quit.

> As a general rule, library functions should be strict about
> reporting errors, while applications may be more forgiving
> about errors that they don't care about. The "don't care about"
> part is important though -- your word processor shouldn't care
> about low level networking errors, but it should care if it
> can't save a file to a network drive. 

You have to draw the line somewhere in any case, and drawing it
all the way over to IGNORE is bound right some of the time. It
would be, I guess, Cargo Cult programming to never ignore errors.

-- 
Neil Cerutti

[toc] | [prev] | [next] | [standalone]


#34382

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2012-12-06 14:33 +0100
Message-ID<k9q6s4$os9$1@r03.glglgl.gl>
In reply to#34369
Am 06.12.2012 09:49 schrieb Bruno Dupuis:

> The point is Exceptions are made for error handling, not for normal
> workflow. I hate when i read that for example:
>
>      try:
>          do_stuff(mydict[k])
>      except KeyError:
>          pass

I as well, but for other reasons (see below). But basically this is EAFP.


> (loads of them in many libraries and frameworks)
> instead of:
>
>      if k in mydict:
>          do_stuff(mydict[k])

This is LBYL, C-style, not Pythonic.

I would do

     try:
         value = mydict[k]
     except KeyError:
         pass
     else:
         do_stuff(k)

Why? Because do_stuff() might raise a KeyError, which should not go 
undetected.


Thomas

[toc] | [prev] | [next] | [standalone]


#34387

FromChris Angelico <rosuav@gmail.com>
Date2012-12-07 00:58 +1100
Message-ID<mailman.557.1354802285.29569.python-list@python.org>
In reply to#34382
On Fri, Dec 7, 2012 at 12:33 AM, Thomas Rachel
<nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
wrote:
> Am 06.12.2012 09:49 schrieb Bruno Dupuis:
>
>> The point is Exceptions are made for error handling, not for normal
>> workflow. I hate when i read that for example:
>>
>>      try:
>>          do_stuff(mydict[k])
>>      except KeyError:
>>          pass
>
> I would do
>
>     try:
>         value = mydict[k]
>     except KeyError:
>         pass
>     else:
>         do_stuff(k)
>
> Why? Because do_stuff() might raise a KeyError, which should not go
> undetected.

(Assuming first off that you meant "do_stuff(value)", not
"do_stuff(k)", in that last line)

That has quite different functionality, though. The original wouldn't
have called do_stuff at all if k is not in dict, behaviour which is
matched by both his EAFP and his LBLY. But your version, in the event
of a KeyError, will call do_stuff with the previous value of value, or
raise NameError if there is no such previous value. I don't think
that's intentional.

The only way around it that I can see is an extra condition or jump -
something like:

def call_if_present(mydict,k,do_stuff):
    """Equivalent to
    do_stuff(mydict[k])
    if the key is present; otherwise, does not call do_stuff, and
returns None."""
    try:
        value = mydict[k]
    except KeyError:
        return
    return do_stuff(value)

It'll propagate any other exceptions from the subscripting (eg
TypeError if you give it a list instead of a dict), and any exceptions
from do_stuff itself. But it's getting a bit unwieldy.

ChrisA

[toc] | [prev] | [next] | [standalone]


#34390

FromHans Mulder <hansmu@xs4all.nl>
Date2012-12-06 15:21 +0100
Message-ID<50c0a9e2$0$6963$e4fe514c@news2.news.xs4all.nl>
In reply to#34387
On 6/12/12 14:58:01, Chris Angelico wrote:
> On Fri, Dec 7, 2012 at 12:33 AM, Thomas Rachel
> <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
> wrote:
>> > Am 06.12.2012 09:49 schrieb Bruno Dupuis:
>> >
>>> >> The point is Exceptions are made for error handling, not for normal
>>> >> workflow. I hate when i read that for example:
>>> >>
>>> >>      try:
>>> >>          do_stuff(mydict[k])
>>> >>      except KeyError:
>>> >>          pass
>> >
>> > I would do
>> >
>> >     try:
>> >         value = mydict[k]
>> >     except KeyError:
>> >         pass
>> >     else:
>> >         do_stuff(k)
>> >
>> > Why? Because do_stuff() might raise a KeyError, which should not go
>> > undetected.

> (Assuming first off that you meant "do_stuff(value)", not
> "do_stuff(k)", in that last line)

> That has quite different functionality, though. The original wouldn't
> have called do_stuff at all if k is not in dict, behaviour which is
> matched by both his EAFP and his LBLY. But your version, in the event
> of a KeyError, will call do_stuff with the previous value of value, or
> raise NameError if there is no such previous value. I don't think
> that's intentional.

Errhm, no.  Look again.  The do_stuff(value) call is in the "else:"
clause, so it will only be done of there was no Exception of any
kind, and in that case the assignment to value must have succeeded.

-- HansM

[toc] | [prev] | [next] | [standalone]


#34393

FromChris Angelico <rosuav@gmail.com>
Date2012-12-07 01:28 +1100
Message-ID<mailman.562.1354804118.29569.python-list@python.org>
In reply to#34390
On Fri, Dec 7, 2012 at 1:21 AM, Hans Mulder <hansmu@xs4all.nl> wrote:
> Errhm, no.  Look again.  The do_stuff(value) call is in the "else:"
> clause, so it will only be done of there was no Exception of any
> kind, and in that case the assignment to value must have succeeded.

DOH! My bad. Sorry! I somehow didn't see your else, *and* didn't think
of that clause when doing up my "fixed" version. Yep, else is
precisely what this calls for, and (assuming the change I mentioned)
your code does indeed match the original.

ChrisA

[toc] | [prev] | [next] | [standalone]


#34391

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-06 15:22 +0100
Message-ID<mailman.559.1354803788.29569.python-list@python.org>
In reply to#34382
Guys I'm still confusing my script is working better, but not enough.
I did a logfile to see which products are not found anymore in the CSV
and I found some that are present but python says they are not ??

Here is the product in the CSV:
MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;

Here is what python reports:
e2208hds-b2, 721 not found
e2273hds-b1, 722 not found
e2274hds-b2, 723 not found
e2407hds-b1, 724 not found

And here is my final code: ( I hope it look better now :) )

def Change_price(): # Changes the price in the DB if the price in the
CSV is changed
    TotalUpdated = 0 # Counter for total updated
    TotalSKUFound = 0 # Total SKU from the DB coresponds to the one in the CSV
    TotalSKUinDB = 0 # Total SKU in the DB
    for row in PRODUCTSDB:
        TotalSKUinDB +=1
        db_sku = row["sku"].lower()
        db_price = float(row["price"])
        found = False
        try:
            for x in pricelist:
                try:
                    csv_price = x[6]
                    csv_price = csv_price.replace(",",".")
                    csv_price = float(csv_price)
                    csv_new_price = csv_price*1.10
                    csv_sku = x[4].lower()
                    csv_stock = int(x[7]) # I used this as normally I
used  stock in the condition
                    match = re.search(db_sku, csv_sku)
                    if len(db_sku) != 0 and match:
                        TotalSKUFound +=1
                        if csv_new_price < db_price and csv_stock > 0:
                            print db_sku, csv_price, db_price, csv_new_price
                            Update_SQL(csv_new_price, db_sku)
                            TotalUpdated += 1
                            found = True

                except IndexError: # I have a lot of index error in
the CSV (empty fields) and the loop gives "index error" I  don't care
about them
                    pass
                except ValueError:
                    pass
                except TypeError:
                    pass
        except IndexError:
            pass
        if not found: WriteLog(db_sku, db_sku,)
    TotalNotFound = TotalSKUinDB - TotalSKUFound
    print "Total SKU in the DB %s" % TotalSKUinDB
    print "Total SKU coresponds to the DB and CSV %s" % TotalSKUFound
    print "Total updated: %s" % TotalUpdated
    print"Total not found with in the distributor: %s" % TotalNotFound

[toc] | [prev] | [next] | [standalone]


#34394

FromDave Angel <d@davea.name>
Date2012-12-06 09:40 -0500
Message-ID<mailman.563.1354804876.29569.python-list@python.org>
In reply to#34382
On 12/06/2012 08:58 AM, Chris Angelico wrote:
> On Fri, Dec 7, 2012 at 12:33 AM, Thomas Rachel
> <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
> wrote:
>> Am 06.12.2012 09:49 schrieb Bruno Dupuis:
>>
>>> The point is Exceptions are made for error handling, not for normal
>>> workflow. I hate when i read that for example:
>>>
>>>      try:
>>>          do_stuff(mydict[k])
>>>      except KeyError:
>>>          pass
>> I would do
>>
>>     try:
>>         value = mydict[k]
>>     except KeyError:
>>         pass
>>     else:
>>         do_stuff(k)
>>
>> Why? Because do_stuff() might raise a KeyError, which should not go
>> undetected.
> (Assuming first off that you meant "do_stuff(value)", not
> "do_stuff(k)", in that last line)
>
> That has quite different functionality, though. The original wouldn't
> have called do_stuff at all if k is not in dict, behaviour which is
> matched by both his EAFP and his LBLY. But your version, in the event
> of a KeyError, will call do_stuff with the previous value of value, or
> raise NameError if there is no such previous value.

Nope.  The else clause will only execute if no exception occurs in the
value= line.

>  I don't think
> that's intentional.
>
> The only way around it that I can see is an extra condition or jump -
> something like:
>
> def call_if_present(mydict,k,do_stuff):
>     """Equivalent to
>     do_stuff(mydict[k])
>     if the key is present; otherwise, does not call do_stuff, and
> returns None."""
>     try:
>         value = mydict[k]
>     except KeyError:
>         return
>     return do_stuff(value)
>
> It'll propagate any other exceptions from the subscripting (eg
> TypeError if you give it a list instead of a dict), and any exceptions
> from do_stuff itself. But it's getting a bit unwieldy.
>
> ChrisA


-- 

DaveA

[toc] | [prev] | [next] | [standalone]


#34396

Frompeter <pjmakey2@gmail.com>
Date2012-12-06 11:46 -0300
Message-ID<mailman.565.1354805649.29569.python-list@python.org>
In reply to#34382
On 12/06/2012 10:58 AM, Chris Angelico wrote:
> On Fri, Dec 7, 2012 at 12:33 AM, Thomas Rachel
> <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
> wrote:
>> Am 06.12.2012 09:49 schrieb Bruno Dupuis:
>>
>>> The point is Exceptions are made for error handling, not for normal
>>> workflow. I hate when i read that for example:
>>>
>>>       try:
>>>           do_stuff(mydict[k])
>>>       except KeyError:
>>>           pass
>> I would do
>>
>>      try:
>>          value = mydict[k]
>>      except KeyError:
>>          pass
>>      else:
>>          do_stuff(k)
>>
>> Why? Because do_stuff() might raise a KeyError, which should not go
>> undetected.
> (Assuming first off that you meant "do_stuff(value)", not
> "do_stuff(k)", in that last line)
>
> That has quite different functionality, though. The original wouldn't
> have called do_stuff at all if k is not in dict, behaviour which is
> matched by both his EAFP and his LBLY. But your version, in the event
> of a KeyError, will call do_stuff with the previous value of value, or
> raise NameError if there is no such previous value. I don't think
> that's intentional.
>
> The only way around it that I can see is an extra condition or jump -
> something like:
>
> def call_if_present(mydict,k,do_stuff):
>      """Equivalent to
>      do_stuff(mydict[k])
>      if the key is present; otherwise, does not call do_stuff, and
> returns None."""
>      try:
>          value = mydict[k]
>      except KeyError:
>          return
>      return do_stuff(value)
>
> It'll propagate any other exceptions from the subscripting (eg
> TypeError if you give it a list instead of a dict), and any exceptions
> from do_stuff itself. But it's getting a bit unwieldy.
>
> ChrisA
Ok, is seems like my example code, don't like :). Is ok, it was a poor 
example.
This a more complex example that create a python daemons process.
In these case you see the help of try catch. To watch an Operating 
system problem (80% of the cases), when the fork is created. Or  you can 
initialize a logging (in the catch statement)
and watch the log file with tail -f.


import sys, os
def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
     # Perform first fork.
     try:
         pid = os.fork( )
         if pid > 0:
             sys.exit(0) # Exit first parent.
     except OSError, e:
         sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, 
e.strerror))
         sys.exit(1)
# Decouple from parent environment.
     os.chdir("/")
     os.umask(0)
     os.setsid( )
# Perform second fork.
     try:
         pid = os.fork( )
         if pid > 0:
             sys.exit(0) # Exit second parent.
     except OSError, e:
         sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, 
e.strerror))
         sys.exit(1)
# The process is now daemonized, redirect standard file descriptors.
     for f in sys.stdout, sys.stderr: f.flush( )
     si = file(stdin, 'r')
     so = file(stdout, 'a+')
     se = file(stderr, 'a+', 0)
     os.dup2(si.fileno( ), sys.stdin.fileno( ))
     os.dup2(so.fileno( ), sys.stdout.fileno( ))
     os.dup2(se.fileno( ), sys.stderr.fileno( ))

Or imagine that you are manage master-slave's connections (for examples 
to an ldap databse - or a monitor system tools), you can use try catch.
If all the server's are down, maybe you want to be inform about it, you 
can put a function to send a email to your account

In simple works try: catch is 'GOOD'.

ipserver = {"192.168.1.13": ["monitoreo", 22],
             "192.168.1.18": ["usuarios-dns", 22, 53, 139, 389, 445, 
631, 3306, 4900, 8765],
             "192.168.1.72": ["sistemas-ldap", 22, 80, 139, 389, 445, 
631, 3306, 4900, 8765],
             "192.168.1.74": ["terminales", 22,139, 445, 389, 4900],
             "192.168.1.80": ["backup", 22, 139, 445],
             "192.168.1.1": ["router", 21, 22, 25, 80, 110, 143, 465, 3128],
             "192.168.1.90": ["router", 5900]
             }

def portstatus(self, **kwargs):
         ports = kwargs.get("ports")
         server = kwargs.get("server")
         if len(ports) > 0:
             logging.info("chequeando puertos %s" % server)
             for a in ports:
                 try:
                     sock = socket()
                     sock.connect((server,a))
                     sock.close
                 except:
                     logging.info("informando errores en puerto %s" % a)
                     today = str(datetime.today())
                     subprocess.Popen("for a in $(seq 1 15); do beep; 
done", shell=True)
                     self.sendreport(ip=server, server=server, 
cuerpo="El puerto  %s esta caido en %s - %s" % (a, server, today), 
asunto="El puerto  %s esta caido en %s - %s" % (a, server, today))
         else:
             logging.info("no hay puertos que chequear")






[toc] | [prev] | [next] | [standalone]


#34401

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-06 17:16 +0100
Message-ID<mailman.569.1354810592.29569.python-list@python.org>
In reply to#34382
On Thu, Dec 6, 2012 at 3:22 PM, Anatoli Hristov <tolidtm@gmail.com> wrote:
> Guys I'm still confusing my script is working better, but not enough.
> I did a logfile to see which products are not found anymore in the CSV
> and I found some that are present but python says they are not ??
>
> Here is the product in the CSV:
> MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
> 1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;
>
> Here is what python reports:
> e2208hds-b2, 721 not found
> e2273hds-b1, 722 not found
> e2274hds-b2, 723 not found
> e2407hds-b1, 724 not found
>
> And here is my final code: ( I hope it look better now :) )
>
> def Change_price(): # Changes the price in the DB if the price in the
> CSV is changed
>     TotalUpdated = 0 # Counter for total updated
>     TotalSKUFound = 0 # Total SKU from the DB coresponds to the one in the CSV
>     TotalSKUinDB = 0 # Total SKU in the DB
>     for row in PRODUCTSDB:
>         TotalSKUinDB +=1
>         db_sku = row["sku"].lower()
>         db_price = float(row["price"])
>         found = False
>         try:
>             for x in pricelist:
>                 try:
>                     csv_price = x[6]
>                     csv_price = csv_price.replace(",",".")
>                     csv_price = float(csv_price)
>                     csv_new_price = csv_price*1.10
>                     csv_sku = x[4].lower()
>                     csv_stock = int(x[7]) # I used this as normally I
> used  stock in the condition
>                     match = re.search(db_sku, csv_sku)
>                     if len(db_sku) != 0 and match:
>                         TotalSKUFound +=1
>                         if csv_new_price < db_price and csv_stock > 0:
>                             print db_sku, csv_price, db_price, csv_new_price
>                             Update_SQL(csv_new_price, db_sku)
>                             TotalUpdated += 1
>                             found = True
>
>                 except IndexError: # I have a lot of index error in
> the CSV (empty fields) and the loop gives "index error" I  don't care
> about them
>                     pass
>                 except ValueError:
>                     pass
>                 except TypeError:
>                     pass
>         except IndexError:
>             pass
>         if not found: WriteLog(db_sku, db_sku,)
>     TotalNotFound = TotalSKUinDB - TotalSKUFound
>     print "Total SKU in the DB %s" % TotalSKUinDB
>     print "Total SKU coresponds to the DB and CSV %s" % TotalSKUFound
>     print "Total updated: %s" % TotalUpdated
>     print"Total not found with in the distributor: %s" % TotalNotFound

No one have an idea ?

Thanks

[toc] | [prev] | [next] | [standalone]


#34404

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2012-12-06 16:52 +0000
Message-ID<mailman.570.1354812701.29569.python-list@python.org>
In reply to#34382
On 06/12/2012 16:16, Anatoli Hristov wrote:

>
> No one have an idea ?
>
> Thanks
>

Basically because your code is crap.  Others have already suggested 
refactoring your code to make it easier to follow.  Try (diabolical pun 
very deliberate) following that advice.  Failing that find out how much 
it'll cost to fix and get your cheque book out, perhaps that'll focus 
your mind.  I'll not apologise for being blunt as your follow up is less 
than two hours after your previous post.

-- 
Cheers.

Mark Lawrence.

[toc] | [prev] | [next] | [standalone]


#34406

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-06 18:08 +0100
Message-ID<mailman.572.1354813687.29569.python-list@python.org>
In reply to#34382
>> No one have an idea ?
>>
>> Thanks
>>
>
> Basically because your code is crap.  Others have already suggested
> refactoring your code to make it easier to follow.

Thank you Mark for your notes. I changed the name of the variables as
was suggested before.
I know my code should be crappy, but at least I try as I'm a beginner
in a programming at all - this is a good exercise for me.

>Try (diabolical pun very
> deliberate) following that advice.  Failing that find out how much it'll
> cost to fix and get your cheque book out, perhaps that'll focus your mind.
> I'll not apologise for being blunt as your follow up is less than two hours
> after your previous post.

It seems the arrogance is in your blood :p Nice shot


Anatoli

[toc] | [prev] | [next] | [standalone]


#34407

FromMRAB <python@mrabarnett.plus.com>
Date2012-12-06 17:10 +0000
Message-ID<mailman.573.1354813801.29569.python-list@python.org>
In reply to#34382
On 2012-12-06 14:22, Anatoli Hristov wrote:
> Guys I'm still confusing my script is working better, but not enough.
> I did a logfile to see which products are not found anymore in the CSV
> and I found some that are present but python says they are not ??
>
> Here is the product in the CSV:
> MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
> 1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;
>
> Here is what python reports:
> e2208hds-b2, 721 not found
> e2273hds-b1, 722 not found
> e2274hds-b2, 723 not found
> e2407hds-b1, 724 not found
>
> And here is my final code: ( I hope it look better now :) )
>
> def Change_price(): # Changes the price in the DB if the price in the CSV is changed
>      TotalUpdated = 0 # Counter for total updated
>      TotalSKUFound = 0 # Total SKU from the DB coresponds to the one in the CSV
>      TotalSKUinDB = 0 # Total SKU in the DB
>      for row in PRODUCTSDB:
>          TotalSKUinDB +=1
>          db_sku = row["sku"].lower()
>          db_price = float(row["price"])
>          found = False
>          try:
>              for x in pricelist:
>                  try:
>                      csv_price = x[6]
>                      csv_price = csv_price.replace(",",".")
>                      csv_price = float(csv_price)
>                      csv_new_price = csv_price*1.10
>                      csv_sku = x[4].lower()
>                      csv_stock = int(x[7]) # I used this as normally I used  stock in the condition
 >                      match = re.search(db_sku, csv_sku)

This line is equivalent to:

     match = db_sku in csv_sku

This means that it's looking for db_sku anywhere in csv_sku. For
example, all of these are true: "72" in "720"; "20" in "720"; "720" in
"720"; etc.

>                      if len(db_sku) != 0 and match:
>                          TotalSKUFound +=1

TotalSKUFound is incremented if it finds a match.

Can "db_sku in csv_sku" be true multiple times for a given value of
db_sku? (See above.) Is it possible that TotalSKUFound is incremented
multiple times for some values of csv_sku?

>                          if csv_new_price < db_price and csv_stock > 0:
>                              print db_sku, csv_price, db_price, csv_new_price
>                              Update_SQL(csv_new_price, db_sku)
>                              TotalUpdated += 1
>                              found = True

It sets found to True if it updated.
>
>                  except IndexError: # I have a lot of index error in the CSV (empty fields) and the loop gives "index error" I  don't care about them
>                      pass
>                  except ValueError:
>                      pass
>                  except TypeError:
>                      pass

Even after finding a match (and possibly updating), it continues
iterating though pricelist.

>          except IndexError:

There's no need to catch IndexError here because the only places it
could be raised are also within the inner try..except.

>              pass
>          if not found: WriteLog(db_sku, db_sku,)

Calling it 'found' is misleading, because it's True only if it updated.
If it found a match but didn't update, 'found' will still be False.

>      TotalNotFound = TotalSKUinDB - TotalSKUFound
>      print "Total SKU in the DB %s" % TotalSKUinDB
>      print "Total SKU coresponds to the DB and CSV %s" % TotalSKUFound
>      print "Total updated: %s" % TotalUpdated
>      print"Total not found with in the distributor: %s" % TotalNotFound
>
Using a loop within a loop like this could be the cause of your
problem. It's certainly not the most efficient way of doing it.

[toc] | [prev] | [next] | [standalone]


#34410

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-06 18:31 +0100
Message-ID<mailman.575.1354815089.29569.python-list@python.org>
In reply to#34382
>> Here is the product in the CSV:
>> MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
>> 1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;

This one is still not found and it is in the CSV file - I just don't
get it why !

>>                      if len(db_sku) != 0 and match:
>>                          TotalSKUFound +=1
> TotalSKUFound is incremented if it finds a match.
>
> Can "db_sku in csv_sku" be true multiple times for a given value of
> db_sku? (See above.) Is it possible that TotalSKUFound is incremented
> multiple times for some values of csv_sku?

Most of the SKU's are not doubled in the CSV, but what I will do is to
create new function to compare each SKU so after it founds the SKU in
the file it will return right away to the DB loop.

>>                          if csv_new_price < db_price and csv_stock > 0:
>>                              print db_sku, csv_price, db_price,
>> csv_new_price
>>                              Update_SQL(csv_new_price, db_sku)
>>                              TotalUpdated += 1
>>                              found = True

> It sets found to True if it updated.
>>                  except IndexError: # I have a lot of index error in the
>> CSV (empty fields) and the loop gives "index error" I  don't care about them
>>                      pass
>>                  except ValueError:
>>                      pass
>>                  except TypeError:
>>                      pass
>
>
> Even after finding a match (and possibly updating), it continues
> iterating though pricelist.

Yes it will change after I create the new func.as I assume.

>>          except IndexError:
>
>
         if not found: WriteLog(db_sku, db_sku,)
>
>
> Calling it 'found' is misleading, because it's True only if it updated.
> If it found a match but didn't update, 'found' will still be False.
> Using a loop within a loop like this could be the cause of your
> problem. It's certainly not the most efficient way of doing it.

I will keep you posted THANK YOU

[toc] | [prev] | [next] | [standalone]


#34411

FromMRAB <python@mrabarnett.plus.com>
Date2012-12-06 17:52 +0000
Message-ID<mailman.576.1354816365.29569.python-list@python.org>
In reply to#34382
On 2012-12-06 17:31, Anatoli Hristov wrote:
>>> Here is the product in the CSV:
>>> MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
>>> 1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;
>
> This one is still not found and it is in the CSV file - I just don't
> get it why !
>
[snip]
It's not saying that it's not found, it's saying that it wasn't updated 
because:

     csv_new_price < db_price and csv_stock > 0

was False. Is the new price higher or the same?

[toc] | [prev] | [next] | [standalone]


#34413

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-06 19:25 +0100
Message-ID<mailman.577.1354818332.29569.python-list@python.org>
In reply to#34382
>>>>
>>>> Here is the product in the CSV:
>>>> MONIIE2407HDS-B1;MON;II;E2407HDS-B1;E2407HDS-B1;IIYAMA LCD 24" Wide
>>>> 1920x1080TN Speakers 2ms Black DVI HDMI;133;20;RECTD0.41;0,41;;;;;;;;;
> [snip]
> It's not saying that it's not found, it's saying that it wasn't updated
> because:

You are right, the price at the distributor is higher than the one I
have :) I will update the price what ever the price is I will not
compare it anymore.

Thanks

[toc] | [prev] | [next] | [standalone]


#34458

FromAnatoli Hristov <tolidtm@gmail.com>
Date2012-12-07 14:36 +0100
Message-ID<mailman.606.1354887386.29569.python-list@python.org>
In reply to#34382
>> Calling it 'found' is misleading, because it's True only if it updated.
>> If it found a match but didn't update, 'found' will still be False.
>> Using a loop within a loop like this could be the cause of your
>> problem. It's certainly not the most efficient way of doing it.
>
> I will keep you posted THANK YOU

And here is my final code -- I hope you will like it a little more :)


def Change_price(): # Changes the price in the DB if the price in the
CSV is changed
    TotalUpdated = 0 # Counter for total updated
    TotalSKUNotFound = 0 # Total SKU from the DB coresponds to the one
in the CSV
    TotalSKUinDB = 0

    found = None
    for row in PRODUCTSDB:
        TotalSKUinDB +=1
        db_sku = row["sku"].lower()
        db_price = float(row["price"])
        if CompareWithCSV(db_sku, db_price) == True:
            TotalUpdated +=1
        else:
            TotalSKUNotFound +=1
            Update_SQL_stock(db_sku)
            WriteLog(db_sku, row["product_id"])

    print "Total updated: %s" % TotalUpdated
    print"Total not found with in the distributor: %s" % TotalSKUNotFound
    print "Total products in the DB %s" % TotalSKUinDB

def CompareWithCSV(db_sku, db_price):
    try:
        for x in pricelist:
            try:
                csv_price = x[6]
                csv_price = csv_price.replace(",",".")
                csv_price = float(csv_price)
                csv_new_price = csv_price*1.10
                csv_sku = x[4].lower()
                csv_stock = int(x[7]) # I used this as normally I used
 stock in the condition
                if len(db_sku) != 0 and db_sku == csv_sku and csv_stock > 0:
                    print db_sku, csv_price, db_price, csv_new_price
                    Update_SQL(csv_new_price, db_sku)
                    return True
            except (IndexError, ValueError, TypeError, db_sku): # I
have a lot of index error in the CSV (empty fields) and the loop gives
"index error" I  don't care about them
                WriteErrorLog("Error with CSV file loop: ", db_sku)
    except IndexError:
        WriteErrorLog("Error with CSV file loop: ", db_sku)
    return False

[toc] | [prev] | [next] | [standalone]


#34421

FromRotwang <sg552@hotmail.co.uk>
Date2012-12-06 19:24 +0000
Message-ID<k9qrd2$2a2$1@dont-email.me>
In reply to#34369
On 06/12/2012 08:49, Bruno Dupuis wrote:
> On Thu, Dec 06, 2012 at 04:32:34AM +0000, Steven D'Aprano wrote:
>> On Thu, 06 Dec 2012 03:22:53 +0000, Rotwang wrote:
>>
>>> On 06/12/2012 00:19, Bruno Dupuis wrote:
>>>> [...]
>>>>
>>>> Another advice: never ever
>>>>
>>>> except XXXError:
>>>>       pass
>>>>
>>>> at least log, or count, or warn, or anything, but don't pass.
>>>
>>> Really? I've used that kind of thing several times in my code. For
>>> example, there's a point where I have a list of strings and I want to
>>> create a list of those ints that are represented in string form in my
>>> list, so I do this:
>>>
>>> listofints = []
>>> for k in listofstrings:
>>> 	try:
>>> 		listofints.append(int(k))
>>> 	except ValueError:
>>> 		pass
>>>
>>> Another example: I have a dialog box with an entry field where the user
>>> can specify a colour by entering a string, and a preview box showing the
>>> colour. I want the preview to automatically update when the user has
>>> finished entering a valid colour string, so whenever the entry field is
>>> modified I call this:
>>>
>>> def preview(*args):
>>> 	try:
>>> 		previewbox.config(bg = str(entryfield.get()))
>>> 	except tk.TclError:
>>> 		pass
>>>
>>> Is there a problem with either of the above? If so, what should I do
>>> instead?
>>
>> They're fine.
>>
>> Never, ever say that people should never, ever do something.
>>
>>
>> *cough*
>>
>
> Well, dependening on the context (who provides listofstrings?) I would
> log or count errors on the first one... or not.

The actual reason for the first example is that I have a text widget 
with a bunch of tags (which are identified by strings), and I want to 
add a new tag whose name doesn't coincide with any of the existing tag 
names. I achieve this by setting my listofstrings equal to the list of 
existing tag names, and setting the new tag name as

str(max(listofints) + 1) if listofints else '0'

I realise that there are a bunch of other ways I could have done this. 
But I haven't a clue how I could rewrite the second example without 
using a try statement (other than by writing a function that would 
recognise when a string defines a valid Tkinter colour, including the 
long and possibly version-dependent list of colours with Zoolanderesque 
names like 'LightSteelBlue3').


> On the second one, I would split the expression, because (not sure of
> that point, i didn't import tk for years) previewbox.config and
> entryfield.get may raise a tk.TclError for different reasons.
>
> The point is Exceptions are made for error handling, not for normal
> workflow.

Although I'm something of a noob, I'm pretty sure the Python community 
at large would disagree with this, as evidenced by the fact that 'EAFP' 
is an entry in the official Python glossary:

EAFP
     Easier to ask for forgiveness than permission. This common Python
     coding style assumes the existence of valid keys or attributes and
     catches exceptions if the assumption proves false. This clean and
     fast style is characterized by the presence of many try and except
     statements. The technique contrasts with the LBYL style common to
     many other languages such as C.

(from http://docs.python.org/2/glossary.html)

-- 
I have made a thing that superficially resembles music:

http://soundcloud.com/eroneity/we-berated-our-own-crapiness

[toc] | [prev] | [next] | [standalone]


#34370

FromChris Angelico <rosuav@gmail.com>
Date2012-12-06 20:34 +1100
Message-ID<mailman.550.1354786472.29569.python-list@python.org>
In reply to#34358
On Thu, Dec 6, 2012 at 7:49 PM, Bruno Dupuis
<python.ml.bruno.dupuis@lisael.org> wrote:
>
> The point is Exceptions are made for error handling, not for normal
> workflow. I hate when i read that for example:
>
>     try:
>         do_stuff(mydict[k])
>     except KeyError:
>         pass
>
> (loads of them in many libraries and frameworks)
> instead of:
>
>     if k in mydict:
>         do_stuff(mydict[k])
>
> Note that the performances are better with the latter.
>

This is the age-old question of EAFP vs LBYL.

The check-first "Look Before You Leap" option has a small chance of
race condition. If something changes between the 'if' and the usage,
maybe from another thread or maybe a signal handler or perhaps some
object's __del__ method gets called or who knows what, you'll have a
problem.

Python's usual philosophy is that it's Easier to Ask Forgiveness than
Permission. Just do it, and jump out if you can't. This technique
plays *very* nicely with generic handlers. For instance, at work I
wrote an HTTP daemon that's supposed to receive XML-encoded POST data
with a particular structure. The handler function (called once for
every HTTP request) looks something like this, in Pythonesque
pseudocode:

def handler(req):
  try:
    msg = parse_xml(req.body) # returns a dict of dicts/lists/strings
    stuff = msg["soapenv:Envelope"]["soapenv:Body"]["GetItemTransactionsResponse"]
    sig = stuff["Item"]["ApplicationData"]
    if sig.does.not.match(): return "Bad request"
    sscanf(sig,"FOO %d %d %d",account,table,row)
    accountdata[account][table][row] = 1
    return "Done and successful."
  except:
    log_error_to_stderr()
    return "Done."

I don't particularly care _what_ the error is. Most of the time, I
won't even bother to look at the log file (it's run via an Upstart
job, and stderr is redirected to a file), but if I'm having problems,
I can go check. Generally, exceptions thrown by that code are the
result of malformed info packets; since it's basic HTTP, it's easy for
anyone to send a request in, and I don't care to see those errors
logged. In fact, the logging to stderr can even get commented out in
production, and used only when there's actually a problem being
diagnosed.

To try to handle all possible errors in that code by LBLY, I would
need to pepper the code with conditions and an appropriate 'return'
statement (and, though the pseudo-code has the function returning a
string, the actual code involves an explicit "send this response"
call). Plus, I'd need to predict every possible failure. With EAFP,
all I need is one simple "catch" handler for the whole block of code,
and I can easily eyeball just a few function exit points to see that
an appropriate HTTP response will always be sent.

Each has its place.

ChrisA

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.python


csiph-web