NameError while handling command line arguments - python

I was trying out a few python test scripts with sqlite3.
Here is the script that I wrote
#!/usr/bin/env python
from sqlite3 import dbapi2 as sqlite
from sys import argv,exit
db_name = "filenames.db"
def define_db():
try:
conn = sqlite.connect(db_name)
except IOError as e:
print "problem while creating/connecting the db:",e.args[0]
exit(1)
return conn
def write_db(conn,cursor,fni):
conn.execute("CREATE TABLE IF NOT EXISTS file (filenames TEXT UNIQUE)")
query = "INSERT OR REPLACE INTO file VALUES($filenames)"
cursor.execute(query,[fni])
cursor.close()
conn.commit()
conn.close()
print fni,"should now be in the db"
exit(0)
if __name__ == "__main__":
if len(argv) == 2:
etag = argv[1]
else:
print "no argument given - stopping now"
exit(1)
conn = define_db()
cursor = conn.cursor()
write_db(conn,cursor,fni)
I keep getting this error and was not able to solve it.
Traceback (most recent call last):
File "blah.py", line 37, in <module>
write_db(conn,cursor,fni)
NameError: name 'fni' is not defined
Any idea what the problem is.
At this moment I use python 2.7.3

The last line of your script refers to a name fni that is not defined.

You have not defined the variable "fni", but you are using it.

Static analysis tools like pyflakes or pylint can be useful to catch silly errors like this
If you wrote the bulk of the code in a function (so it doesn't assume blub is a global variable, which don't make pyflakes/pylint complain):
def main():
if len(argv) == 2:
blub = argv[1]
else:
print "no argument given - stopping now"
exit(1)
conn = define_db()
cursor = conn.cursor()
write_db(conn,cursor,fni)
if __name__ == "__main__":
main()
...then you would get a pair of errors, which points out exactly what the error is (you stored the argument in blub, but tried to access it with fni):
$ pip install pyflakes
$ pyflakes example.py
example.py:30: local variable 'blub' is assigned to but never used
example.py:37: undefined name 'fni'

Related

System registry for python

I got this code from Stack overflow but when I try to execute the command I get an error. The code and the error is given below. I would be grateful if someone could help:
import sys
from _winreg import *
# tweak as necessary
version = sys.version[:3]
installpath = sys.prefix
regpath = "SOFTWARE\\Python\\Pythoncore\\%s\\" % (version)
installkey = "InstallPath"
pythonkey = "PythonPath"
pythonpath = "%s;%s\\Lib\\;%s\\DLLs\\" % (
installpath, installpath, installpath
)
def RegisterPy():
try:
reg = OpenKey(HKEY_CURRENT_USER, regpath)
except EnvironmentError as e:
try:
reg = CreateKey(HKEY_CURRENT_USER, regpath)
SetValue(reg, installkey, REG_SZ, installpath)
SetValue(reg, pythonkey, REG_SZ, pythonpath)
CloseKey(reg)
except:
print ("*** Unable to register!")
return
print ("--- Python", version, "is now registered!")
return
if (QueryValue(reg, installkey) == installpath and
QueryValue(reg, pythonkey) == pythonpath):
CloseKey(reg)
print ("=== Python", version, "is already registered!")
return
CloseKey(reg)
print ("*** Unable to register!")
print ("*** You probably have another Python installation!")
if __name__ == "__main__":
RegisterPy()
I get the following error:
from __winreg import *
Traceback (most recent call last):
File "<ipython-input-35-f6f8c1a0ffdd>", line 1, in <module>
from __winreg import *
ModuleNotFoundError: No module named '__winreg'
As the Python 2 documentation for _winreg states,
The _winreg module has been renamed to winreg in Python 3. The 2to3 tool will automatically adapt imports when converting your sources to Python 3.
Check your version of Python. If it is Python 3, as it seems, rename the module references to winreg (without the underscore). Look at the Python 3 documentation.

ValueError: script argument must be unicode. - Python3.5, SQLite3

I'm writing following python script:
import sqlite3
import sys
if len(sys.argv) < 2:
print("Error: You must supply at least SQL script.")
print("Usage: %s table.db ./sql-dump.sql" % (sys.argv[0]))
sys.exit(1)
script_path = sys.argv[1]
if len(sys.argv) == 3:
db = sys.argv[2]
else:
db = ":memory:"
try:
con = sqlite3.connect(db)
with con:
cur = con.cursor()
with open(script_path,'rb') as f:
cur.executescript(f.read())
except sqlite3.Error as err:
print("Error occured: %s" % err)
I saved this program as sqlite_import.py.
I have a database file named test.db and a SQL file world.sql.
Now I tried to run program as:
sqlite_import.py test.db world.sql
But it shows me error like following:
Traceback (most recent call last):
File "C:\Users\Jarvis\OneDrive\Documents\Python\Python Data Visualization Cookbook, 2E\2 Knowing Your Data\sqlite_import.py", line 21, in <module>
cur.executescript(f.read())
ValueError: script argument must be unicode.
Help me to fix this.
You opened the script file as binary:
with open(script_path,'rb') as f:
This produces a b'...' bytes value, not a Unicode str object. Remove the b, and perhaps add an encoding argument to specific what codec to use to decode the data with.

How to call an existing LibreOffice python macro from a python script

Currently I call an existing existing LibreOffice macro with this:
def OnLOtimestamp(self):
try:
pid= Popen(['lowriter '"'"'vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user'"'"],shell=True).pid
except OSError, e:
self.notify_show("Timestamp Error",str(e))
self.ma2.SetLabel("Macro timestamp")
self.database['Time_stamp'] = self.database['Time_stamp'] + 1
The key bit being the Popen call, where the macro name is fs2TimeStamp.py and the function is fs2_TimeStamp but this feels like a cop out and I would rather perform a direct call via Uno.
My research suggests that I may well need to use MasterScriptProvider, XscriptProvider and XscriptInvocation but trying to decipher the Uno API is like swimming through treacle.
Has anybody got a code sample of calling an existing macro in Libreoffice, using Uno?
Edit:
So far the answer appears to be No!
This is the current state of play.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
# a python script to run a libreoffice python macro externally
#
import uno
from com.sun.star.connection import NoConnectException
from com.sun.star.uno import RuntimeException
from com.sun.star.uno import Exception
from com.sun.star.lang import IllegalArgumentException
def test2(*args):
localContext = uno.getComponentContext()
localsmgr = localContext.ServiceManager
resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
try:
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
except NoConnectException as e:
print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")")
return
except IllegalArgumentException as e:
print ("Invalid argument given - ( "+ e.Message+ ")")
return
except RuntimeException as e:
print ("An unknown error occurred: " + e.Message)
return
servmgr = ctx.ServiceManager
desktop = servmgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
model = desktop.getCurrentComponent()
# scriptP = model.getScriptProvider()
# print("scriptP", scriptP)
scriptx = model.getScriptProvider().getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user')
print("scriptx", scriptx)
try:
scriptx.invoke("",0,0)
except IllegalArgumentException as e:
print ("The command given is invalid ( "+ e.Message+ ")")
return
except RuntimeException as e:
print("An unknown error occurred: " + e.Message)
return
except Exception as e:
print ("Script error ( "+ e.Message+ ")")
print(e)
return
except:
print("Error")
return(None)
test2()
This code works happily when invoked as a macro within Libreoffice and scriptx prints out as:
scriptx <pythonscript.PythonScript object at 0x7fa2879c42e8>
however when run from the command line the script does nothing and scriptx prints out as:
scriptx pyuno object (com.sun.star.script.provider.XScript)0x1e749d8{, supportedInterfaces={com.sun.star.lang.XTypeProvider,com.sun.star.script.provider.XScript}}
So either getScriptProvider or getScript are not being provided with something that they require. I am currently at a loss as to what is missing and yet, I feel in my bones that I'm close to a solution.
Can anyone see where I have made a mistake?
Finally, I have a working solution. Ding! Dong!
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
# a python script to run a libreoffice python macro externally
#
import uno
from com.sun.star.connection import NoConnectException
from com.sun.star.uno import RuntimeException
from com.sun.star.uno import Exception
from com.sun.star.lang import IllegalArgumentException
def test2(*args):
localContext = uno.getComponentContext()
localsmgr = localContext.ServiceManager
resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
try:
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
except NoConnectException as e:
print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")")
return
msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")
sp = msp.createScriptProvider("")
scriptx = sp.getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user')
try:
scriptx.invoke((), (), ())
except IllegalArgumentException as e:
print ("The command given is invalid ( "+ e.Message+ ")")
return
except RuntimeException as e:
print("An unknown error occurred: " + e.Message)
return
except Exception as e:
print ("Script error ( "+ e.Message+ ")")
return(None)
test2()
Note: For clarity the existing python script is called fs2TimeStamp.py, it contains 1 (one) function defined as def fs2_TimeStamp(*args):
See the line:
scriptx = sp.getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user')
and it is stored in $HOME/.config/libreoffice/4/user/Scripts/python
For this solution to work, libreoffice must be running in listening mode, so start libreoffice with a command like:
soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore
OR
nohup soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore &
Alternatively you could use the more direct method (for writer in this example):
lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp"
OR
nohup lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp" &
Also note that you must run the script with python3
This is a simpler and more generic version of the first answer, which was very much slanted to my specific problem, which called a macro, which then talked to another program via TCP before inserting text sent via the TCP connection.
This version will run standalone and should be instantly replicable.
As before you must start LibreOffice writer in listening mode (see previous answer for options):
lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp"
This is the external python routine, which must be run with python3:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
# a python script to run a libreoffice python macro externally
# NOTE: for this to run start libreoffice in the following manner
# soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore
# OR
# nohup soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore &
#
import uno
from com.sun.star.connection import NoConnectException
from com.sun.star.uno import RuntimeException
from com.sun.star.uno import Exception
from com.sun.star.lang import IllegalArgumentException
def uno_directmacro(*args):
localContext = uno.getComponentContext()
localsmgr = localContext.ServiceManager
resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
try:
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
except NoConnectException as e:
print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")")
return
msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")
sp = msp.createScriptProvider("")
scriptx = sp.getScript('vnd.sun.star.script:directmacro.py$directmacro?language=Python&location=user')
try:
scriptx.invoke((), (), ())
except IllegalArgumentException as e:
print ("The command given is invalid ( "+ e.Message+ ")")
return
except RuntimeException as e:
print("An unknown error occurred: " + e.Message)
return
except Exception as e:
print ("Script error ( "+ e.Message+ ")")
print(e)
return
return(None)
uno_directmacro()
This is the LibreOffice python macro directmacro.py which should be located in:
$HOME/.config/libreoffice/4/user/Scripts/python
(assuming use of LibreOffice version 4 here)
The directmacro.py macro:
#!/usr/bin/python
class FontSlant():
from com.sun.star.awt.FontSlant import (NONE, ITALIC,)
def directmacro(*args):
#get the doc from the scripting context which is made available to all scripts
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()
text = model.Text
tRange = text.End
cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
doc = XSCRIPTCONTEXT.getDocument()
parentwindow = doc.CurrentController.Frame.ContainerWindow
# your cannot insert simple text and text into a table with the same method
# so we have to know if we are in a table or not.
# oTable and oCurCell will be null if we are not in a table
oTable = cursor.TextTable
oCurCell = cursor.Cell
insert_text = "This is text inserted into a LibreOffice Document\ndirectly from a macro called externally"
Text_Italic = FontSlant.ITALIC
Text_None = FontSlant.NONE
cursor.CharPosture=Text_Italic
if oCurCell == None: # Are we inserting into a table or not?
text.insertString(cursor, insert_text, 0)
else:
cell = oTable.getCellByName(oCurCell.CellName)
cell.insertString(cursor, insert_text, False)
cursor.CharPosture=Text_None
return None

Starting a database connection with sqlanydb inside a fork

Based on an example for forking, I build up this little script:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sqlanydb
import os
def child():
conn = sqlanydb.connect(uid='dba', pwd='sql', eng='somedb_IQ', dbn='somedb')
curs = conn.cursor()
curs.execute("""SELECT * FROM foobaa;""")
os.exit(0)
def parent():
while True:
newpid = os.fork()
if newpid == 0:
child()
else:
pids = (os.getpid(), newpid)
print "parent: %d, child: %d" % pids
if raw_input( ) == 'q': break
parent()
The intention is to do the database action inside a seperate process (big goal later is to run a huge number of queries at the same time).
But when running the script, I'm getting:
parent: 20580, child: 20587
Traceback (most recent call last):
File "connectiontest.py", line 25, in <module>
parent()
File "connectiontest.py", line 19, in parent
child()
File "connectiontest.py", line 8, in child
conn = sqlanydb.connect(uid='dba', pwd='sql', eng='somedb_IQ', dbn='somedb')
File "/usr/local/lib/python2.6/dist-packages/sqlanydb.py", line 461, in connect
return Connection(args, kwargs)
File "/usr/local/lib/python2.6/dist-packages/sqlanydb.py", line 510, in __init__
self.handleerror(*error)
File "/usr/local/lib/python2.6/dist-packages/sqlanydb.py", line 520, in handleerror
eh(self, None, errorclass, errorvalue)
File "/usr/local/lib/python2.6/dist-packages/sqlanydb.py", line 342, in standardErrorHandler
raise errorclass(errorvalue)
sqlanydb.OperationalError: Failed to initialize connection object
What did I might miss?
Since Sybase IQ is based on Sybase ASA, are you sure that you're using the proper keys for the credentials? This (albeit, old) documentation looks like it wants DSN and DSF instead of ENG and DBN.
http://dcx.sybase.com/1101/en/dbprogramming_en11/python-writing-open.html
The issue seems to don't happen by moving import sqlanydb into child()-methode. So it would look something like:
def child():
import sqlanydb
conn = sqlanydb.connect(uid='dba', pwd='sql', dsn='some_db')
curs = conn.cursor()
curs.execute("""SELECT * FROM SA100_1_1;""")
curs.close()
conn.close()
You need to hack the sqlanydb source to print out the actual error being seen. Whatever the problem is is being masked by a generic OperationalError which is not giving enough information to fix the problem. Line 510 is where you need to add a couple prints to figure out what is (not) going on.

Python import error

I am trying to run a python file from the command line with a single parameter in Ubuntu 12.04. The program works if I simply run it from the IDE and pass the parameter in the code. However, if I call 'python readFromSerial1.py 3' in the command prompt, I get:
Traceback (most recent call last):
File "readFromSerial1.py", line 62, in <module>
main()
File "readFromSerial1.py", line 6, in main
readDataFromUSB(time)
File "readFromSerial1.py", line 9, in readDataFromUSB
import usb.core
ImportError: No module named usb.core
I'm a little confused as the module imports correctly if I run from the IDE. I download the pyUSB module and extracted it (its filename is pyusb-1.0.0a3). I then copied this file into
/usr/local/lib/python2.7/site-packages/. Is that the correct procedure? I have a feeling the issue is due to python simply not being able to find the usb module and I need to put it in the correct location. My code is below, and any help would be greatly appreciated:
readFromSerial1.py
import sys
def main():
time = sys.argv[1]
#time = 1
readDataFromUSB(time)
def readDataFromUSB(time):
import usb.core
#find device
dev = usb.core.find(idVendor=0x099e, idProduct=0x0001) #GPS info
#Was the device found?
if dev is None:
raise ValueError('Device not found')
else:
print "Device found!"
#Do this to avoid 'Errno16: Resource is busy'
if dev.is_kernel_driver_active(0):
try:
dev.detach_kernel_driver(0)
except usb.core.USBError as e:
sys.exit("Could not detach kernel driver: %s" % str(e))
#Sets default config
dev.set_configuration()
#Gets default endpoint
endpoint = dev[0][(0,0)][0]
writeObject = open("InputData.txt", "w")
#iterate for time purposes
for i in range(0, (time*6)): #sys.argv is command line variable for time input
data = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, 0, 100000)
sret = ''.join([chr(x) for x in data])
writeObject.write(sret);
print sret
'''
newStr = ''.join(sret[7:14])
compareStr = ",*4F"
if (newStr == compareStr):
print "The GPS is not reading in any values right now. Try going somewhere else with better reception."
else:
print sret[7:14]
'''
writeObject.close()
main()

Categories