I'm trying to learn SPARQL and I'm using python's rdflib to train.
I've done a few tries, but any ASK query always seems to give me back a True result.
For instance, i tried the following:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import rdflib
mygraph=rdflib.Graph();
mygraph.parse('try.ttl',format='n3');
results=mygraph.query("""
ASK {?p1 a <http://false.com>}
""")
print bool(results)
The result is true, even if there is no subject of type false.com in 'try.ttl'.
Can anyone explain me why?
Thank you in advance for your help!
UPDATE: Reading the rdflib manual, I found out that results is of type list and (in my case) should contain a single boolean with the return value from the ask query.
I tried the following:
for x in results:
print x
And I got "None".
I'm guessing I don't use the query method in the right way.
The documentation doesn't actually says that it's of type list, but that you can iterate over it, or you can convert it to a boolean:
If the type is "ASK", iterating will yield a single bool (or
bool(result) will return the same bool)
This means that print bool(results), as you've done, should work. In fact, your code does work for me:
$ touch try.ttl
$ cat try.ttl # it's empty
$ cat test.py # same code
#!/usr/bin/python
# -*- coding: utf-8 -*-
import rdflib
mygraph=rdflib.Graph();
mygraph.parse('try.ttl',format='n3');
results=mygraph.query("""
ASK {?p1 a <http://false.com>}
""")
print bool(results)
$ ./test.py # the data is empty, so there's no match
False
If we add some data to the file that would make the query return true, we get true:
$ cat > try.ttl
<http://example.org> a <http://false.com> .
$ cat try.ttl
<http://example.org> a <http://false.com> .
$ ./test.py
True
Maybe you're using an older version of the library? Or a newer version and a bug was introduced? I'm using 4.0.1:
$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg_resources
>>> pkg_resources.get_distribution("rdflib").version
'4.0.1'
Related
I've just started using python and I'm creating a simple program that will ask whoever the user is a question and then from the text file I will extract a specific line and print that line and along with the line - at the end I will add their answer. here's the code.
question = input("do you want to print the line")
if "yes" in question:
print(open("tp.txt").readlines()[:10][-1],end=question)
The issue is that ,end=question) puts the users answer on a new line. I know that end= is the same as \n. So I'm just wondering is there a way or an alternative to stop 'end=' from automatically creating a new line?
print(open("tp.txt").readlines()[:10][-1],
is the way I open and read a specific line from the file
since its a 'nice' shortcut to do than rather dowith open (filename.txt,'r') as f:
The problem is that the lines returned by readlines() contain the ending newline:
$ echo 'a
> b
> c
> ' > test_file.txt
$ python3
Python 3.5.2 (default, Jul 5 2016, 12:43:10)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> with open('test_file.txt') as f:
... print(f.readlines())
...
['a\n', 'b\n', 'c\n', '\n']
See the \n? Note the difference bewteen:
>>> print('a\n')
a
>>>
And:
>>> print('a')
a
>>>
So you want to remove that:
>>> with open('test_file.txt') as f:
... for line in f:
... print(line.rstrip('\n'), end='<something>')
...
a<something>b<something>c<something><something>>>>
I have this python code in my script.
dataBase = str(request.forms.get('db'))
data = "/usr/local/Calpont/mysql/bin/mysql --defaults-file=/usr/local/Calpont/mysql/my.cnf -u root %s -e \"show tables like \'f_\%s\'\"" %(dataBase)
But its giving me the following error when I run it:-
TypeError: not enough arguments for format string
Any help?
You have two %s markers in your format string:
... -u root %s -e \"show tables like \'f_\%s\' ...
^^ ^^
but only one argument, database.
You need to have enough arguments for the number of markers. Most likely, this is a simple matter of one of the following.
If you are trying to use another parameter, you need to provide it, such as with ... % (dataBase, tableName).
If you are trying to use the literal % mark, you need to escape it as %%, not \% as you may be thinking.
Given the fact you're using like, I consider the second the most likely possibility, as % is the wildcard for that operator.
The following transcripts may make the problem clearer:
pax> python
Python 2.7.3 (default, Mar 14 2014, 11:57:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "... -u root %s -e \"show tables like \'f_\%s\' ..." %("A")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> print "... -u root %s -e \"show tables like \'f_\%s\' ..." %("A","B")
... -u root A -e "show tables like 'f_\B' ...
>>> print "... -u root %s -e \"show tables like \'f_%%\' ..." %("A")
... -u root A -e "show tables like 'f_%' ...
>>> _
The first and second commands shows that using two %s markers requires two arguments.
The third command shows how to properly escape % in the string.
I have an application that requires saving a list as it grows. This is a step towards doing AI learning stuff. Anyway here is my code:
vocab = ["cheese", "spam", "eggs"]
word = raw_input()
vocab.append(word)
However when the code is run the finished vocab will return to just being cheese, spam and eggs. How can I make whatever I append to the list stay there permenantly even when windows CMD is closed and I return to the code editing stage. Is this clear enough??
Thanks
You're looking into the more general problem of object persistence. There are bazillions of ways to do this. If you're just starting out, the easiest way to save/restore data structures in Python is using the pickle module. As you get more advanced, there are different methods and they all have their trade-offs...which you'll learn when you need to.
You could use json and files, something like this:
import json
#write the data to a file
outfile = open("dumpFile", 'w')
json.dump(vocab, outfile)
#read the data back in
with open("dumpFile") as infile:
newVocab = json.load(infile)
This has the advantage of being a plain text file, so you can view the data stored in it easily.
Look into pickle
With it, you can serialize a Python data structure and then reload it like so:
>>> import pickle
>>> vocab =["cheese", "spam", "eggs"]
>>> outf=open('vocab.pkl','wb')
>>> pickle.dump(vocab,outf)
>>> outf.close()
>>> quit()
Python interpreter is now exited, restart Python and reload the data structure:
abd-pb:~ andrew$ python
Python 2.7.1 (r271:86882M, Nov 30 2010, 10:35:34)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pklf=open('vocab.pkl','rb')
>>> l=pickle.load(pklf)
>>> l
['cheese', 'spam', 'eggs']
You could use pickle, but as a technique it's limited to python programs. The normal way to deal with persistent data is to write it to a file. Just read your word list from a regular text file (one word per line), and write out an updated word list later. Later you can learn how to keep this kind of information in a database (more powerful but less flexible than a file).
You can happily program for years without actually needing pickle, but you can't do without file i/o and databases.
PS. Keep it simple: You don't need to mess with json, pickle or any other structured format unless and until you NEED structure.
I'm trying to solve exercise 15's extra credit questions of Zed Shaw's Learn Python the Hard Way but I've ran into a problem. The code is as follows:
from sys import argv
script, filename = argv
txt = open(filename)
print "Here's your file %r:" % filename
print txt.read()
print "I'll also ask you to type it again:"
file_again = raw_input("> ")
txt_again = open(file_again)
print txt_again.read()
print txt_again.read()
I understand all the code that has been used, but extra credit question 7 asks:
Startup python again and use open from the prompt. Notice how you can open files and run read on them right there?
I've tried inputting everything I could think of in terminal (on a mac) after first starting up python with the 'python' command, but I can't get the code to run. What should I be doing to get this piece of code to run from the prompt?
Zed doesn't say to run this particular piece of code from within Python. Obviously, that code is getting the filename value from the parameters you used to invoke the script, and if you're just starting up the Python shell, you haven't used any parameters.
If you did:
filename = 'myfilename.txt'
txt = open(filename)
then it would work.
I just started with open(xyz.txt)
Well, yes, of course that isn't going to work, because you don't have a variable xyz, and even if you did, it wouldn't have an attribute txt. Since it's a file name, you want a string "xyz.txt", which you create by putting it in quotes: 'xyz.txt'. Notice that Python treats single and double quotes more or less the same; unlike in languages like C++ and Java, there is not a separate data type for individual characters - they're just length-1 strings.
Basically, just like in this transcript (I've added blank lines to aid readability):
pax:~$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> xyz = open ("minimal_main.c")
>>> print xyz.read()
int main (void) {
return 0;
}
>>> xyz.close()
>>> <CTRL-D>
pax:~$ _
All it's showing you is that you don't need a script in order to run Python commands, the command line interface can be used in much the same way.
print open('ex15_sample.txt').read()
After running python in terminal, we'll use open('filename.txt') to open the file and using the dot operator we can apply the read() function directly on it.
After running Python in terminal,
abc = open ("ex15_sample.txt")
print abc.read()
That should do.
I'm trying to implement a simple method to read new lines from a log file each time the method is called.
I've looked at the various suggestions both on stackoverflow (e.g. here) and elsewhere for simulating "tail" functionality; most involve using readline() to read in new lines as they're appended to the file. It should be simple enough, but can't get it to work properly on OS X 10.6.4 with the included Python 2.6.1.
To get to the heart of the problem, I tried the following:
Open two terminal windows.
In one, create a text file "test.log" with three lines:
one
two
three
In the other, start python and execute the following code:
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.stat('test.log')
posix.stat_result(st_mode=33188, st_ino=23465217, st_dev=234881025L, st_nlink=1, st_uid=666, st_gid=20, st_size=14, st_atime=1281782739, st_mtime=1281782738, st_ctime=1281782738)
>>> log = open('test.log')
>>> log.tell()
0
>>> log.seek(0,2)
>>> log.tell()
14
>>>
So we see with the tell() that seek(0,2) brought us to the end of the file as reported by os.stat(), byte 14.
In the first shell, add another two lines to "test.log" so that it looks like this:
one
two
three
four
five
Go back to the second shell, and execute the following code:
>>> os.stat('test.log')
posix.stat_result(st_mode=33188, st_ino=23465260, st_dev=234881025L, st_nlink=1, st_uid=666, st_gid=20, st_size=24, st_atime=1281783089, st_mtime=1281783088, st_ctime=1281783088)
>>> log.seek(0,2)
>>> log.tell()
14
>>>
Here we see from os.stat() that the file's size is now 24 bytes, but seeking to the end of the file somehow still points to byte 14?? I've tried the same on Ubuntu with Python 2.5 and it works as I expect. I tried with 2.5 on my Mac, but got the same results as with 2.6.
I must be missing something fundamental here. Any ideas?
How are you adding two more lines to the file?
Most text editors will go through operations a lot like this:
fd = open(filename, read)
file_data = read(fd)
close(fd)
/* you edit your file, and save it */
unlink(filename)
fd = open(filename, write, create)
write(fd, file_data)
The file is different. (Check it with ls -li; the inode number will change for almost every text editor.)
If you append to the log file using your shell's >> redirection, it'll work exactly as it should:
$ echo one >> test.log
$ echo two >> test.log
$ echo three >> test.log
$ ls -li test.log
671147 -rw-r--r-- 1 sarnold sarnold 14 2010-08-14 04:15 test.log
$ echo four >> test.log
$ ls -li test.log
671147 -rw-r--r-- 1 sarnold sarnold 19 2010-08-14 04:15 test.log
>>> log=open('test.log')
>>> log.tell()
0
>>> log.seek(0,2)
>>> log.tell()
19
$ echo five >> test.log
$ echo six >> test.log
>>> log.seek(0,2)
>>> log.tell()
28
Note that the tail(1) command has an -F command line option to handle the case where the file is changed, but a file by the same name exists. (Great for watching log files that might be periodically rotated.)
Short answer: no, your assumptions are.
Your text editor is creating a new file with the same name, not modifying the old file in place. You can see in your stat result that the st_ino is different. If you were to do os.fstat(log.fileno()), you'd get the old size and old st_ino.
If you want to check for this in your implementation of tail, periodically compare the st_ino of the stat and fstat results. If they differ, there's a new file with the same name.