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


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

Prob. Code Downloaded for Programming the Semantic Web (python code)

Started byBruce Whealton <futurewavewebdevelopment@gmail.com>
First post2014-07-25 17:06 -0700
Last post2014-07-26 03:05 -0400
Articles 11 — 8 participants

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


Contents

  Prob. Code Downloaded for Programming the Semantic Web (python code) Bruce Whealton <futurewavewebdevelopment@gmail.com> - 2014-07-25 17:06 -0700
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Skip Montanaro <skip@pobox.com> - 2014-07-25 19:21 -0500
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Dan Stromberg <drsalists@gmail.com> - 2014-07-25 17:52 -0700
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Ian Kelly <ian.g.kelly@gmail.com> - 2014-07-25 19:39 -0600
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Steven D'Aprano <steve+gmane@pearwood.info> - 2014-07-26 11:28 +1000
      Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Bruce Whealton <futurewavewebdevelopment@gmail.com> - 2014-07-28 03:39 -0700
        Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-07-28 15:28 +0000
          Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Bruce Whealton <futurewavewebdevelopment@gmail.com> - 2014-07-28 17:57 -0700
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Chris Angelico <rosuav@gmail.com> - 2014-07-26 13:25 +1000
      Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Bruce Whealton <futurewavewebdevelopment@gmail.com> - 2014-07-28 04:07 -0700
    Re: Prob. Code Downloaded for Programming the Semantic Web (python code) Terry Reedy <tjreedy@udel.edu> - 2014-07-26 03:05 -0400

#75216 — Prob. Code Downloaded for Programming the Semantic Web (python code)

FromBruce Whealton <futurewavewebdevelopment@gmail.com>
Date2014-07-25 17:06 -0700
SubjectProb. Code Downloaded for Programming the Semantic Web (python code)
Message-ID<8e593a0d-cf61-4b1a-8273-8309496e3696@googlegroups.com>
Hello all,
       I downloaded some code accompanying the book "Programming the Semantic Web."  This question is not Semantic Web related and I doubt that one needs to know anything about the Semantic Web to help  me with this.  It's the first code sample in the book, I'm embarrassed to say.  I have the code shared here (just one file, not the majority of the book or anything): http://pastebin.com/e870vjYK

OK, Eclipse with PyDev doesn't like this first line, with the function:
def add(self, (sub, pred, obj)):

It complains about the parentheses just before sub.  Simply removing them just moves me down to another error.  I did try using python 3.x (3.4 to be specific), which meant changing print statements to function calls.  Of course, that didn't fix the errors I was mentioning.  The text uses python 2.7.x.  

There are other places where I thought that there were too many parentheses and I tried removing one set of them.  For example this snippet here:

    def remove(self, (sub, pred, obj)):
        """
        Remove a triple pattern from the graph.
        """
        triples = list(self.triples((sub, pred, obj)))

Are the two sets parentheses needed after self.triples?  That syntax is confusing to me.  It seems that it should be
triples = list(self.triples(sub, pred, obj))

The full listing is here: http://pastebin.com/e870vjYK

I agree with the authors that python is a fun and easy language to use, thus it is strange that I am getting stuck here.

Thanks,
Bruce    

[toc] | [next] | [standalone]


#75217

FromSkip Montanaro <skip@pobox.com>
Date2014-07-25 19:21 -0500
Message-ID<mailman.12322.1406334113.18130.python-list@python.org>
In reply to#75216

[Multipart message — attachments visible in raw view] — view raw

> OK, Eclipse with PyDev doesn't like this first line, with the function:
> def add(self, (sub, pred, obj)):
>
> It complains about the parentheses just before sub.

Seems like this code is Python 2.x.

Skip

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


#75219

FromDan Stromberg <drsalists@gmail.com>
Date2014-07-25 17:52 -0700
Message-ID<mailman.12324.1406335962.18130.python-list@python.org>
In reply to#75216
On Fri, Jul 25, 2014 at 5:21 PM, Skip Montanaro <skip@pobox.com> wrote:
>> OK, Eclipse with PyDev doesn't like this first line, with the function:
>> def add(self, (sub, pred, obj)):
>>
>> It complains about the parentheses just before sub.
>
> Seems like this code is Python 2.x.

For me, this code ran on all of 2.4, 2.5, 2.6 and 2.7, but not on any
of 3.0, 3.1, 3.2, 3.3 or 3.4.

HTH

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


#75220

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-07-25 19:39 -0600
Message-ID<mailman.12325.1406338773.18130.python-list@python.org>
In reply to#75216

[Multipart message — attachments visible in raw view] — view raw

On Jul 25, 2014 6:54 PM, "Dan Stromberg" <drsalists@gmail.com> wrote:
>
> On Fri, Jul 25, 2014 at 5:21 PM, Skip Montanaro <skip@pobox.com> wrote:
> >> OK, Eclipse with PyDev doesn't like this first line, with the function:
> >> def add(self, (sub, pred, obj)):
> >>
> >> It complains about the parentheses just before sub.
> >
> > Seems like this code is Python 2.x.
>
> For me, this code ran on all of 2.4, 2.5, 2.6 and 2.7, but not on any
> of 3.0, 3.1, 3.2, 3.3 or 3.4.

Python 3.x no longer allows tuple parameter unpacking in function
signatures. See PEP 3113.

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


#75225

FromSteven D'Aprano <steve+gmane@pearwood.info>
Date2014-07-26 11:28 +1000
Message-ID<mailman.12329.1406344508.18130.python-list@python.org>
In reply to#75216
On Fri, 25 Jul 2014 17:06:17 -0700, Bruce Whealton wrote:

> OK, Eclipse with PyDev doesn't like this first line, with the function:
> def add(self, (sub, pred, obj)):

In Python 2, you could include parenthesised parameters inside function
declarations as above. That is effectively a short cut for this version,
where you collect a single argument and then expand it into three
variables:

    def add(self, sub_pred_obj):
        sub, pred, obj = sub_pred_obj


In Python 3, that functionality was dropped and is no longer allowed. Now
you have to use the longer form.

[...]
> There are other places where I thought that there were too many
> parentheses and I tried removing one set of them.  For example this
> snippet here:
> 
>     def remove(self, (sub, pred, obj)):
>         """
>         Remove a triple pattern from the graph. """
>         triples = list(self.triples((sub, pred, obj)))

Firstly, the remove method expects to take a *single* argument (remember
that self is automatically provided by Python) which is then automatically
expanded into three variables sub, pred, obj. So you have to call it with a
list or tuple of three items (or even a string of length exactly 3).

Then, having split this list or tuple into three items, it then joins them
back again into a tuple:

    (sub, pred, obj)

passes that tuple to the triples method:

    self.triples((sub, pred, obj))

(not shown, but presumably it uses the same parenthesised parameter trick),
and then converts whatever triples returns into a list:

    list(self.triples((sub, pred, obj)))

that list then being bound to the name "triples".


> Are the two sets parentheses needed after self.triples?  That syntax is
> confusing to me.  It seems that it should be triples =
> list(self.triples(sub, pred, obj))

It's needed because the triples method is written 

    def triples(self, (sub, pred, obj)):

instead of the more obvious:

    def triples(self, sub, pred, obj):



-- 
Steven

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


#75310

FromBruce Whealton <futurewavewebdevelopment@gmail.com>
Date2014-07-28 03:39 -0700
Message-ID<52662cf8-67bd-4005-adb3-05179b30cf11@googlegroups.com>
In reply to#75225
On Friday, July 25, 2014 9:28:32 PM UTC-4, Steven D'Aprano wrote:
> On Fri, 25 Jul 2014 17:06:17 -0700, Bruce Whealton wrote:
Steven,
See below please.  The explanation did help.   
> 
> > OK, Eclipse with PyDev doesn't like this first line, with the function:
> 
> > def add(self, (sub, pred, obj)):
> 
> 
> 
> In Python 2, you could include parenthesised parameters inside function
> declarations as above. That is effectively a short cut for this version,
> where you collect a single argument and then expand it into three
> variables:
> 
> 
> 
>     def add(self, sub_pred_obj):
> 
>         sub, pred, obj = sub_pred_obj
> 
I setup Eclipse to use python 2.7.x and tried to run this and it just gave an error on line 9 where the def add function is declared.  It just says invalid syntax and points at the parentheses that are in the function definition
def add(self, (subj, pred, obj)):
So, from what you said, and others, it seems like this should have worked but eclipse would not run it.  I could try to load it into IDLE.
> 
> 
> 
> In Python 3, that functionality was dropped and is no longer allowed. Now
> you have to use the longer form.
>
I'm not sure I follow what the longer method is.  Can you explain that more, please. 
> 
> 
> [...]
> 
> > There are other places where I thought that there were too many
> 
> > parentheses and I tried removing one set of them.  For example this
> 
> > snippet here:
> 
> > 
> 
> >     def remove(self, (sub, pred, obj)):
> 
> >         """
> 
> >         Remove a triple pattern from the graph. """
> 
> >         triples = list(self.triples((sub, pred, obj)))
> 
> 
> 
> Firstly, the remove method expects to take a *single* argument (remember
> 
> that self is automatically provided by Python) which is then automatically
> 
> expanded into three variables sub, pred, obj. So you have to call it with a
> 
> list or tuple of three items (or even a string of length exactly 3).
> 

> Then, having split this list or tuple into three items, it then joins them
> 
> back again into a tuple:
> 
> 
> 
>     (sub, pred, obj)
 
> passes that tuple to the triples method:
 
>     self.triples((sub, pred, obj))
> 
> 
> 
> (not shown, but presumably it uses the same parenthesised parameter trick),
> 
> and then converts whatever triples returns into a list:
> 
The full code listing should be available in the code paste link that I included.
> 
> 
>     list(self.triples((sub, pred, obj)))
> 
> 
> 
> that list then being bound to the name "triples".
> 
> 
Thanks, the explanation helped,
Bruce

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


#75316

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-07-28 15:28 +0000
Message-ID<53d66c28$0$29966$c3e8da3$5496439d@news.astraweb.com>
In reply to#75310
On Mon, 28 Jul 2014 03:39:48 -0700, Bruce Whealton wrote:

> I setup Eclipse to use python 2.7.x and tried to run this and it just
> gave an error on line 9 where the def add function is declared.

First step is to confirm that Eclipse actually is using Python 2.7. Can 
you get it to run this code instead? Put this in a module, and then run 
it:

import sys
print(sys.version)


Once you have confirmed that Eclipse really is running 2.7, next is to 
confirm what the syntax error actually is. Carefully check the source 
code that there are no missing close-parentheses just before the "def 
add" method. (Sometimes, a missing parenthesis won't show up as a Syntax 
Error until *after* the actual error.)

It may be helpful to see the exact syntax error. If possible, cut and 
paste (don't retype!) the full error message. It should look something 
like this:

py> def add(a, (b, c)):
  File "<stdin>", line 1
    def add(a, (b, c)):
               ^
SyntaxError: invalid syntax

Notice that the caret ^ points to where Python discovers the error.

If you confirm that Eclipse is using Python 2.7, but it still complains 
about the parenthesis, my guess -- and it's only a guess -- is that 
somehow you have an invisible or non-printing character inserted into the 
file at that position, and that's causing the Python parser to choke. I 
can demonstrate a working example indirectly, with the exec function:

py> exec("def x(a,(b,c)): pass")  # Works fine.
py> x
<function x at 0xb7e71a74>

Now here it is again, but with an invisible control character inserted:

py> exec("def x(a,\a(b,c)): pass")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    def x(a,(b,c)): pass
            ^
SyntaxError: invalid syntax


Notice that when Python prints the error, the \a control character 
doesn't show up. It's there, but you can't see it.


> It just
> says invalid syntax and points at the parentheses that are in the
> function definition def add(self, (subj, pred, obj)):
> So, from what you said, and others, it seems like this should have
> worked but eclipse would not run it.  I could try to load it into IDLE.

Whenever you have trouble with one IDE, it's good to get a second opinion 
in another IDE. They might both be buggy, but they're unlikely to both 
have the same bug.

Also, try to run the file directly from the shell, without an IDE. from 
the system shell (cmd.exe if using Windows, bash or equivalent for 
Linux), run:

python27 /path/to/yourfile.py

You'll obviously need to adjust the pathname, possibly even give the full 
path to the Python executable.


[...]
>> In Python 3, that functionality was dropped and is no longer allowed.
>> Now you have to use the longer form.
>>
> I'm not sure I follow what the longer method is.  Can you explain that
> more, please.

I referred to the parenthesised parameter version as a short cut for a 
method that takes a single argument, then manually expands that argument 
into three items. Let me show them together to make it more obvious:

# Unparenthesised version, with manual step.
def add(self, sub_pred_obj):
    sub, pred, obj = sub_pred_obj
    do_stuff_with(sub or pred or obj)

# Parenthesised shortcut.
def add(self, (sub, pred, obj)):
    do_stuff_with(sub or pred or obj)

Both methods take a single argument, which must be a sequence of exactly 
three values. The second version saves a single line, hence the first 
version is longer :-)


-- 
Steven

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


#75333

FromBruce Whealton <futurewavewebdevelopment@gmail.com>
Date2014-07-28 17:57 -0700
Message-ID<2b384969-f9ed-4cfd-801c-1ddbab678d19@googlegroups.com>
In reply to#75316
On Monday, July 28, 2014 11:28:40 AM UTC-4, Steven D'Aprano wrote:
> On Mon, 28 Jul 2014 03:39:48 -0700, Bruce Whealton wrote:
Stephen,
    I went to my Ubuntu box inside vmware and added a #!/usr/bin/env python2.7 to the top.  Then I made the file executable and it ran the code perfectly. 

> 
> First step is to confirm that Eclipse actually is using Python 2.7. Can 
> 
> you get it to run this code instead? Put this in a module, and then run 
> 
> it:
> 
> 
> 
> import sys
> 
> print(sys.version)
> 
> 
I had both python2.7 and python3.4.  I could be less specific with my shebang line but what the heck.  
> 
> 
> 
I then installed pydev into my eclipse environment within the Ubuntu virtual machine and it ran the program just fine.  So, I suspect the extra character was 
only an issue on Windows.  I thought I had it setup to show even hidden characters.  
Anyway, thanks so much for all the help...everyone.  It might be interesting for me to convert this to a module that runs with python 3.
Bruce 
> 
> 
> > It just
> 
> > says invalid syntax and points at the parentheses that are in the
> 
> > function definition def add(self, (subj, pred, obj)):
> 
> > So, from what you said, and others, it seems like this should have
> 
> > worked but eclipse would not run it.  I could try to load it into IDLE.
> 
> 
> 
> Whenever you have trouble with one IDE, it's good to get a second opinion 
> 
> in another IDE. They might both be buggy, but they're unlikely to both 
> 
> have the same bug.
> 
> 
> 
> Also, try to run the file directly from the shell, without an IDE. from 
> 
> the system shell (cmd.exe if using Windows, bash or equivalent for 
> 
> Linux), run:
> 
> 
> 
> python27 /path/to/yourfile.py
> 
> 
> 
> You'll obviously need to adjust the pathname, possibly even give the full 
> 
> path to the Python executable.
> 
> 
> 
> 
> 
> [...]
> 
> >> In Python 3, that functionality was dropped and is no longer allowed.
> 
> >> Now you have to use the longer form.
> 
> >>
> 
> > I'm not sure I follow what the longer method is.  Can you explain that
> 
> > more, please.
> 
> 
> 
> I referred to the parenthesised parameter version as a short cut for a 
> 
> method that takes a single argument, then manually expands that argument 
> 
> into three items. Let me show them together to make it more obvious:
> 
> 
> 
> # Unparenthesised version, with manual step.
> 
> def add(self, sub_pred_obj):
> 
>     sub, pred, obj = sub_pred_obj
> 
>     do_stuff_with(sub or pred or obj)
> 
> 
> 
> # Parenthesised shortcut.
> 
> def add(self, (sub, pred, obj)):
> 
>     do_stuff_with(sub or pred or obj)
> 
> 
> 
> Both methods take a single argument, which must be a sequence of exactly 
> 
> three values. The second version saves a single line, hence the first 
> 
> version is longer :-)
> 
> 
> 
> 
> 
> -- 
> 
> Steven

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


#75226

FromChris Angelico <rosuav@gmail.com>
Date2014-07-26 13:25 +1000
Message-ID<mailman.12330.1406345118.18130.python-list@python.org>
In reply to#75216
On Sat, Jul 26, 2014 at 10:06 AM, Bruce Whealton
<futurewavewebdevelopment@gmail.com> wrote:
> OK, Eclipse with PyDev doesn't like this first line, with the function:
> def add(self, (sub, pred, obj)):

As others have said, this is something that changed in Python 3. So
you have two parts to the problem: firstly, your code is bound to
Python 2 by a triviality, and secondly, Eclipse is complaining about
it.

One solution would be to teach Eclipse that this is legal, or for you
to just ignore its complaints. If your code works in Python 2.7, then
there's no big problem. You could try telling Eclipse that you're
using Python 2 (maybe by putting a shebang at the top of your script),
but that may not work; in any case, that's just an issue with the
editor.

But a better solution, IMO, would be to avoid that implicit tuple
unpacking. It's not a particularly clear feature, and I'm not sorry
it's gone from Py3. The simplest way to change it is to just move it
into the body:

def add(self, args):
    sub, pred, obj = args
    # rest of code as before

Preferably with a better name than 'args'. Alternatively, change the
places that call add() and have them provide four separate arguments,
in which case the signature would simply be:

def add(self, sub, pred, obj):

like you'd expect.

>         triples = list(self.triples((sub, pred, obj)))
>
> Are the two sets parentheses needed after self.triples?  That syntax is
> confusing to me.  It seems that it should be
> triples = list(self.triples(sub, pred, obj))

No, that's correct. The extra parens force that triple to be a single
tuple of three items, rather than three separate arguments. Here's a
simpler example:

>>> lst = []
>>> lst.append(1,2,3)
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    lst.append(1,2,3)
TypeError: append() takes exactly one argument (3 given)
>>> lst.append((1,2,3))
>>> addme = 4,5,6
>>> lst.append(addme)
>>> lst
[(1, 2, 3), (4, 5, 6)]

The list append method wants one argument, and appends that argument
to the list. Syntactically, the comma has multiple meanings; when I
assign 4,5,6 to a single name, it makes a tuple, but in a function
call, it separates args in the list. I don't see why the triples()
function should be given a single argument, though; all it does is
immediately unpack it. It'd be better to just remove the parens and
have separate args:

        triples = list(self.triples(sub, pred, obj))

   def triples(self, sub, pred, obj):

While I'm looking at the code, a few other comments. I don't know how
much of this is your code and how much came straight from the book,
but either way, don't take this as criticism, but just as suggestions
for ways to get more out of Python.

Inside remove(), you call a generator (triples() uses yield to return
multiple values), then construct a list, and then iterate exactly once
over that list. Much more efficient and clean to iterate directly over
what triples() returns, as in save(); that's what generators are good
for.

In triples(), the code is deeply nested and repetitive. I don't know
if there's a way to truly solve that, but I would be inclined to
flatten it out a bit; maybe check for just one presence, to pick your
index, and then merge some of the code that iterates over an index.
Not sure though.

(Also: It's conventional to use "is not None" rather than "!= None" to
test for singletons. It's possible for something to be equal to None
without actually being None.)

I would recommend moving to Python 3, if you can. Among other
benefits, the Py3 csv module allows you to open a text file rather
than opening a binary file and manually encoding/decoding all the
parts separately. Alternatively, if you don't need this to be saving
and loading another program's files, you could simply use a different
file format, which would remove the restrictions (and messes) of the
CSV structure.

Instead of explicitly putting "f.close()" at the end of your load and
save methods, check out the 'with' statement. It'll guarantee that the
file's closed even if you leave early, get an exception, or anything
like that. Also, I'd tend to use the .decode() and .encode() methods,
rather than the constructors. So here's how I'd write a Py2 load:

    def load(self, filename):
        with open(filename, "rb") as f:
            for sub, pred, obj in csv.reader(f):
                self.add((sub.decode("UTF-8"), pred.decode("UTF-8"),
obj.decode("UTF-8")))

(You might want to break that back out into three more lines, but this
parallels save(). If you break this one, you probably want to break
save() too.)

Hope that helps!

ChrisA

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


#75311

FromBruce Whealton <futurewavewebdevelopment@gmail.com>
Date2014-07-28 04:07 -0700
Message-ID<29f62bf3-1ded-4074-8809-ba2a5f5d0a44@googlegroups.com>
In reply to#75226
On Friday, July 25, 2014 11:25:15 PM UTC-4, Chris Angelico wrote:
> On Sat, Jul 26, 2014 at 10:06 AM, Bruce Whealton
> 
Chris,
    In response to your comments below, I'm comfortable changing this to use python 3.
> As others have said, this is something that changed in Python 3. So
> you have two parts to the problem: firstly, your code is bound to
> Python 2 by a triviality, and secondly, Eclipse is complaining about
> it.
> 
 
> 
> But a better solution, IMO, would be to avoid that implicit tuple
> unpacking. It's not a particularly clear feature, and I'm not sorry
> it's gone from Py3. The simplest way to change it is to just move it
> into the body:
> 

OK, that makes sense. So, I cut out the "Alternatively... " suggestion you made.
> 
> 
> def add(self, args):
> 
>     sub, pred, obj = args
> 
>     # rest of code as before
> 
> 
> 
> Preferably with a better name than 'args'.

Yes, I could call it triples. 
> 
> >         triples = list(self.triples((sub, pred, obj)))
> 
> >
> 
> > Are the two sets parentheses needed after self.triples?  That syntax is
> 
> > confusing to me.  It seems that it should be
> 
> > triples = list(self.triples(sub, pred, obj))
> 
> 
> 
> No, that's correct. The extra parens force that triple to be a single
> 
> tuple of three items, rather than three separate arguments. Here's a
> 
> simpler example:
> 
> >>> lst = []
> 
> >>> lst.append(1,2,3)
> 
> Traceback (most recent call last):
> 
>   File "<pyshell#25>", line 1, in <module>
> 
>     lst.append(1,2,3)
> 
> TypeError: append() takes exactly one argument (3 given)
> 
> >>> lst.append((1,2,3))
> 
> >>> addme = 4,5,6
> 
> >>> lst.append(addme)
> 
> >>> lst
> 
> [(1, 2, 3), (4, 5, 6)]
> 
> 
This is helpful and makes sense... clarifies it for me.
> 
> The list append method wants one argument, and appends that argument 
> to the list. Syntactically, the comma has multiple meanings; when I
> assign 4,5,6 to a single name, it makes a tuple, but in a function
> call, it separates args in the list. I don't see why the triples()
> function should be given a single argument, though; all it does is
> immediately unpack it. It'd be better to just remove the parens and 
> have separate args:
> 
 
>         triples = list(self.triples(sub, pred, obj))
>
I didn't see the above in the code... Is this something I would need to add and if so, where? 
> 
> 
>    def triples(self, sub, pred, obj):
> 
> 
> 
> While I'm looking at the code, a few other comments. I don't know how
> much of this is your code and how much came straight from the book,
> but either way, don't take this as criticism, but just as suggestions 
> for ways to get more out of Python.
> 
So far it is just from the book, and just serves as an example...  It is also a few years old, having been published in 2009.
> 
> 
> Inside remove(), you call a generator (triples() uses yield to return
> multiple values), then construct a list, and then iterate exactly once
> over that list. Much more efficient and clean to iterate directly over
> what triples() returns, as in save(); that's what generators are good
> for.
> 
> 
> 
> In triples(), the code is deeply nested and repetitive. I don't know
> if there's a way to truly solve that, but I would be inclined to 
> flatten it out a bit; maybe check for just one presence, to pick your
> index, and then merge some of the code that iterates over an index.
> Not sure though.
> 
I would have to get a better understanding of this.  
> 
> 
> (Also: It's conventional to use "is not None" rather than "!= None" to
> 
> test for singletons. It's possible for something to be equal to None
> 
> without actually being None.)
> 
> 
> 
> I would recommend moving to Python 3, if you can. Among other
> benefits, the Py3 csv module allows you to open a text file rather
> than opening a binary file and manually encoding/decoding all the
> parts separately. Alternatively, if you don't need this to be saving
> and loading another program's files, you could simply use a different
> file format, which would remove the restrictions (and messes) of the 
> CSV structure.

I was curious about why the binary flag was being used.  It just made no sense to me.
> 
> 
> 
> Instead of explicitly putting "f.close()" at the end of your load and
> save methods, check out the 'with' statement. It'll guarantee that the
> file's closed even if you leave early, get an exception, or anything
> 
> like that. Also, I'd tend to use the .decode() and .encode() methods,
> rather than the constructors. So here's how I'd write a Py2 load:

I would like to see this in python 3 format.
> 
>     def load(self, filename):
> 
>         with open(filename, "rb") as f:
> 
>             for sub, pred, obj in csv.reader(f):
> 
>                 self.add((sub.decode("UTF-8"), pred.decode("UTF-8"),
> 
> obj.decode("UTF-8")))
> 
> 
> 
> (You might want to break that back out into three more lines, but this
> 
> parallels save(). If you break this one, you probably want to break
> 
> save() too.)
> 
> 
> 
> Hope that helps!
> 
> 
> 
> ChrisA

Thanks,
Bruce

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


#75236

FromTerry Reedy <tjreedy@udel.edu>
Date2014-07-26 03:05 -0400
Message-ID<mailman.12340.1406358361.18130.python-list@python.org>
In reply to#75216
On 7/25/2014 8:06 PM, Bruce Whealton wrote:

The book has python 2.x code. If the modules in the book use the Natural 
Language Toolkit (nltk), then I believe you are currently stuck with 
using 2.7.

If it does not, and you want to run with 3.3 or 3.4, then use 2to3 to do 
most to all of the conversion for you.

C:\Programs\Python34>python Tools/scripts/2to3.py -h
Usage: 2to3 [options] file|dir ...

Options:
   -h, --help            show this help message and exit
   -d, --doctests_only   Fix up doctests only
   -f FIX, --fix=FIX     Each FIX specifies a transformation; default: all
   -j PROCESSES, --processes=PROCESSES
                         Run 2to3 concurrently
   -x NOFIX, --nofix=NOFIX
                         Prevent a transformation from being run
   -l, --list-fixes      List available transformations
   -p, --print-function  Modify the grammar so that print() is a function
   -v, --verbose         More verbose logging
   --no-diffs            Don't show diffs of the refactoring
   -w, --write           Write back modified files
   -n, --nobackups       Don't write backups for modified files
   -o OUTPUT_DIR, --output-dir=OUTPUT_DIR
                         Put output files in this directory instead of
                         overwriting the input files.  Requires -n.
   -W, --write-unchanged-files
                         Also write files even if no changes were required
                         (useful with --output-dir); implies -w.
   --add-suffix=ADD_SUFFIX
                         Append this string to all output filenames. 
Requires
                         -n if non-empty.  ex: --add-suffix='3' will 
generate
                         .py3 files.

This is the user interface for lib2to3.

-- 
Terry Jan Reedy

[toc] | [prev] | [standalone]


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


csiph-web