python list substring - python

I am trying to read the variables from newreg.py (e.g. state, district, dcode, etc, a long list which in turn picking up data from a web form) into insertNew.py.
I have currently read the whole file into a list named 'lines'. Now, how do I filter each variable (like- state, district, etc. approx 50-55 variables. This 'list' also has html code as I have read the whole web page into it) from list 'lines'?
Is there a better and efficient way to do it ?
Once I am able to read each variable, I need to concatenate these value ( convert into string) and insert into MongoDB.
Lastly when the data has been inserted into DB, 'home.py' page opens.
I am giving details so that a complete picture is available for some solution which can be given. I hope it I have been able to keep it simple as well as complete.
I want to loop over the list (sample below) and filter out the variables (before '=' sign values). The following is in 'newreg.py' :
state = form.getvalue('state','ERROR')
district = form.getvalue('district','ERROR')
dcode = form.getvalue('Dcode','ERROR')
I read a file / page into a list
fp = open('/home/dev/wsgi-scripts/newreg.py','r')
lines = fp.readlines()
so that I can create dictionary to insert into MongoDB.eg.
info = {'state' : state , 'district' : district, . . . . }
{key : value } [value means --- which is the variable from the above list]
Thanks
but i am getting the following errors when i do
print getattr(newreg, 'state')
the error is
>>> print getattr(newreg, 'state')
Traceback (most recent call last):
File "<stdin>", line 1, in module
AttributeError: 'module' object has no attribute 'state'
I also tried
>>> print newreg.state
Traceback (most recent call last):
File "<stdin>", line 1, in module
AttributeError: 'module' object has no attribute 'state'
This is how I added the module
>>> import os,sys
>>> sys.path.append('/home/dev/wsgi-scripts/')
>>> import newreg
>>> newreg_vars = dir(newreg)
>>> print newreg_vars
['Connection', 'Handler', '__builtins__', '__doc__', '__file__', '__name__',
'__package__', 'application', 'cgi', 'datetime', 'os', 'sys', 'time']
Handler in the above list is a class in the following
#!/usr/bin/env python
import os, sys
import cgi
from pymongo import Connection
import datetime
import time
class Handler:
def do(self, environ, start_response):
form = cgi.FieldStorage(fp=environ['wsgi.input'],
environ=environ)
state = form.getvalue('state','<font color="#FF0000">ERROR</font>')
district = form.getvalue('district','<font color="#FF0000">ERROR</font>')
dcode = form.getvalue('Dcode','<font color="#FF0000">ERROR</font>')

I am assuming you want to copy the variables from one Python module to another at runtime.
import newreg
newreg_vars = dir(newreg)
print newreg_vars
will print all of the attributes of the module "newreg".
To read the variables from the module:
print getattr(newreg, 'state')
print getattr(newreg, 'district')
print getattr(newreg, 'dcode')
or if you know the names of the attributes:
print newreg.state
print newreg.district
print newreg.dcode
To change the attributes into strings, use a list comprehension (or a generator):
newreg_strings = [str(item) for item in newreg_vars]
This will save you lots of effort, as you will not have to parse "newreg" as a text file with re.
As a side note: Type conversion is not concatenation (although concatenation may involve type conversion in some other programming languages).

Related

Getting the last created item selection

I run a command in which it creates a new camera, however at the end of the said function, there is no selection nor does the function selects the object after it has run its course.
So are there any commands in which I could possible query for the last created item?
I tried using `cmds.listHistory' but that will only shows you results if there is already a selection..
Any ways in which I can get around with it?
Additionally, say I am using the following command using the
cameraShape...
aaa = "cameraShape1"
mel.eval('<Some mel-based command> cameraShape.transformX cameraShape.transformY cameraShape.transformZ;')
but when I tried writing that command in another way such as :
mel.eval('<Some mel-based command> %s.transformX %s.transformY %s.transformZ;' %aaa)
I got an error saying
# Error: not enough arguments for format string
# Traceback (most recent call last):
# File "<maya console>", line 1, in <module>
# TypeError: not enough arguments for format string #
Where am I writing it wrong exactly? I tried writing like %aaa, aaa, aaa still the same error occurs
Why can't you just stuff the new camera into a variable instead of relying on selection?
new_camera, new_camera_shape = cmds.camera()
You're not using the right syntax when formatting with %:
"My name is %s" % "Jon Snow" # Works for single
"My name is %s and I was born in %s" % ("Jon Snow", "Winterfell") # Multiple
Personally I prefer format() as it's suppose to be more forward compatible for Python 3:
"My name is {0} and I was born in {1}".format("Jon Snow", "Winterfell")
Detect new objects:
scene_before = cmds.ls(l=True, transforms=True)
# Run command to import object here
scene_after = cmds.ls(l=True, transforms=True)
new_objs = list( set(scene_after).difference(scene_before) )
If you want to keep the last created object. You can create a class that contain a variable history where your append in your other script the last object created.
class History:
idCounter = []
def __init__(self, name):
History.idCounter.append(name)
print(History.idCounter)
for name in ['nana', 'tata', 'zaza']:
objectCreated = History(name)

PYTHON : There is a function similar to ast.literal_eval ()?

I've got a problem with the utilisation of ast.literal_eval(). In the example below, I only want to convert the string (myText) to dictionnary. But ast.literal_eval() try to evaluate <__main__.myClass instance at 0x0000000052D64D88> and give me an error. I completely anderstand this error but I would like to know if there is a way to avoid it (with an other function or with an other way to use the function ast.literal_eval)
import ast
myText = "{<__main__.myClass instance at 0x0000000052D64D88>: value}"
ast.literal_eval(myText)
# Error: invalid syntax
# Traceback (most recent call last):
# File "<maya console>", line 4, in <module>
# File "C:\Program Files\Autodesk\Maya2016\bin\python27.zip\ast.py", line 49, in literal_eval
# node_or_string = parse(node_or_string, mode='eval')
# File "C:\Program Files\Autodesk\Maya2016\bin\python27.zip\ast.py", line 37, in parse
# return compile(source, filename, mode, PyCF_ONLY_AST)
# File "<unknown>", line 1
# {<__main__.myClass instance at 0x0000000052D64D88>: value}
# ^
# SyntaxError: invalid syntax #
Thank you in advance for your help !
What you really want to do is dump your data using pickle.dump and load it using pickle.load (or equivalent, such as json, etc.). Using repr(data) to dump the data will cause problems like this.
If you just need to salvage the data you have already generated, you might get away with something like the following:
def my_literal_eval(s):
s = re.sub(r"<__main__.myClass instance at 0x([^>]+)>", r'"<\1>"', s)
dct = ast.literal_eval(s)
return {myClass(): v for v in dct.itervalues()}
Example of usage:
>>> import ast, re
>>> class myClass(object): pass
...
>>> myText = "{<__main__.myClass instance at 0x0000000052D64D88>: {'name': 'theName'}, <__main__.myClass instance at 0x0000000052D73F48>: {'name': 'theName'}}"
>>> my_literal_eval(myText)
{<__main__.myClass object at 0x7fbdc00a4b90>: {'name': 'theName'}, <__main__.myClass object at 0x7fbdc0035550>: {'name': 'theName'}}
This will work only if the myClass instances don't have any useful information, but are only needed for identity. The idea is to first fix up the string by replacing the <__main__.myClass instance ...> strings with something that can be parsed by ast.literal_eval, and then replace those with actual myClass instances - provided these can be constructed without arguments, which hinges on the above assumption.
If this initial assumption doesn't hold, then your data is, as Ignacio put it, irreversibly damaged, and no amount of clever parsing will retrieve the lost bits.

Generating instances of class in loop gives TypeError: 'list' object is not callable

I've looked through a lot of replies regarding this error, however none was helpfull for my special case and since I'm new to Python, I have difficulties applying the hints to my problem.
I have a class in a file Aheat.py that reads
class Aheat():
name = ""
time = 0
place = 0
def __init__(self,name,time,place):
self.name = name
self.time = time
self.place = place
And a file main.py where I want to read a html file, extract information, and create a list of objects of my class to work with them later on.
The (hopefully) essential part of my main.py reads
import urllib2
import re
from Aheat import Aheat
s = read something from url
ssplit = re.split('<p', s) # now every entry of ssplit contains an event
# and description and all the runners
HeatList = []
for part in ssplit:
newHeat = Aheat("foo",1,1) # of course this is just an example
HeatList.append(newHeat)
But this gives me the following error:
Traceback (most recent call last):
File "/home/username/Workspace/ECLIPSE/running/main.py", line 22, in <module>
newHeat = Aheat("foo",1,1)
TypeError: 'list' object is not callable
which is thrown when performing the second iteration.
If I take out the generation of the object of the loop, i.e.
newHeat = Aheat("foo",1,1)
for part in ssplit:
HeatList.append(newHeat)
My code executes without a problem, but this is not what I want. I'm also not sure, if I can initialize a specific number of instances a priori, since the number of objects is estimated in the loop.
I'm using Eclipse and Python 2.7.
regex is going to bite you.
<p == <pre> || <progress> || <param> || <p> || (any user created directives on a page.)
follow the links in your comments to read up on why we shouldn't parse html with regex.
Thanks, #MarkR ( btw, I was only supplementing your comment and I was agreeing with you )
Why not put the list in your class or better yet extend list functionality with your class.
class AHeat(list):
def append(self,name,time,place):
return super(AHeat,self).append([name,time,place])
# main
heatList= AHeat()
heatList.append("foo",1,2)
heatList.append("bar",3,4)
print(heatList[0])
print(heatList[1])
> ['foo', 1, 2]
> ['bar', 3, 4]
Also

objectify and etree elements

The module I've been writing works finestkind with the test data file, but totally moofs on the live data from flickrapi.
After days of frustration (see, I DO have a lot of nothing to do!) I think I found the problem, but I don't know the fix for it.
Internal test data returns a type() of: <type 'str'>
External test data returns a type() of: <type 'str'> ## opening &
reading external XML
Live data returns a type() of: <class
'xml.etree.ElementTree.Element'>
Beyond this point in the module, I use objectify. Objectify parses <type 'str'> just fine, but it will not read the etree elements. I think I need to convert the class 'xml.etree.ElementTree.Element' to str(), but haven't sussed that out yet.
The error I get from objectify.fromstring() is:
Traceback (most recent call last):
File "C:\Mirc\Python\Temp Files\test_lxml_2.py", line 101, in <module>
Grp = objectify.fromstring(flickr.groups_getInfo(group_id=gid))
File "lxml.objectify.pyx", line 1791, in lxml.objectify.fromstring (src\lxml\lxml.objectify.c:20904)
File "lxml.etree.pyx", line 2994, in lxml.etree.fromstring (src\lxml\lxml.etree.c:63296)
File "parser.pxi", line 1614, in lxml.etree._parseMemoryDocument (src\lxml\lxml.etree.c:93607)
ValueError: can only parse strings
Please help before the boss turns loose those damn flying monkeys again!!!
import fileinput
from lxml import html, etree, objectify
import re
import time
import flickrapi
if '#N' in gid:
try:
if tst:
Grp = objectify.fromstring(test_data)
else:
Grp = objectify.fromstring(flickr.groups_getInfo(group_id=gid))
fErr = ''
mn = Grp.xpath(u'//group')[0].attrib
res = Grp.xpath(u'//restrictions')[0].attrib
root = Grp.group
gNSID = gid
gAlias = ""
err_tst = getattr(root, "not-there", "Error OK")
gName = getattr(root, "name", "")
Images = getattr(root, 'pool_count', (-1))
Mbr = getattr(root, "members", (-1))
The solution is to stop converting your live data to xml.etree.ElementTree.Element objects before invoking the objectify api.
If that's impossible (which I doubt), you can render the xml back to a text representation with lxml.etree.tostring, then pass that to etree.objectify.fromstring.
I think the "test_data" that you pass to objectify.fromstring is instansce of String IO , so you must read it first then objectify:
objectify.fromstring(test_data.read())

Python sys.argv TypeErrors with printing function results?

I have been trying to learn how to use sys.argv properly, while calling an executable file from the command line.
I wanted to have the functions results print to the command line when passing the filename and argument on the command line but, I get a TypeError.
So far I have:
#! /usr/bin/env python
import mechanize
from BeautifulSoup import BeautifulSoup
import sys
def dictionary(word):
br = mechanize.Browser()
response = br.open('http://www.dictionary.reference.com')
br.select_form(nr=0)
br.form['q'] = sys.argv
br.submit()
definition = BeautifulSoup(br.response().read())
trans = definition.findAll('td',{'class':'td3n2'})
fin = [i.text for i in trans]
query = {}
for i in fin:
query[fin.index(i)] = i
return query
print dictionary(sys.argv)
When I call this:
./this_file.py 'pass'
I am left with this error message:
Traceback (most recent call last):
File "./hot.py", line 20, in <module>
print dictionary(sys.argv)
File "./hot.py", line 10, in dictionary
br.form['q'] = sys.argv
File "/usr/local/lib/python2.7/dist-packages/mechanize/_form.py", line 2782, in __setitem__
control.value = value
File "/usr/local/lib/python2.7/dist-packages/mechanize/_form.py", line 1217, in __setattr__
raise TypeError("must assign a string")
TypeError: must assign a string
With
br.form['q'] = sys.argv
you are assigning a list of strings here instead of a string.
>>> type(sys.argv)
<type 'list'>
>>> type(sys.argv[0])
<type 'str'>
>>>
You want to identify a specific string to assign via an index.
Most likely it will be be index 1 given what you have in your post (and since index 0 is the name of the script). So perhaps
br.form['q'] = sys.argv[1]
will do for you. Of course it could be another index too, depending on your particular application/needs.
Note as #Dougal observes in a helpful comment below, the function parameter word in the function is not being used. You are calling your dictionary function sending it sys.argv and then ought to refer to word inside the function. The type doesn't change only the name that you refer to the command line args inside your function. The idea of word is good as it avoids the use of global variables. If you refer to use globals (not really encouraged) then removing word is recommended as it will be confusing to have it there).
So your statement should really read
br.form['q'] = word[1]

Categories