I am getting AttributeError: 'TBXTools' has no attribute 'cur' - python

I have a file called TBXTools I am trying to run it through another file using
from TBXTools import *
e=TBXTools()
Looks very simple ain't it. But when I run it I get this error:
AttributeError: 'TBXTools' has no attribute 'cur'
Now I have that method, right there on 'TBXTools' file . So what's wrong? Please help
def load_sl_tl_corpus(self,slcorpusfile, tlcorpusfile, encoding="utf-8"):
'''Loads a bilingual corpus in Moses format (that is, in two independent files. It expects one segment per line.'''
self.slcf=codecs.open(slcorpusfile,"r",encoding=encoding)
self.tlcf=codecs.open(tlcorpusfile,"r",encoding=encoding)
self.sl_data=[]
self.tl_data=[]
self.continserts=0
while 1:
self.sl_segment=self.slcf.readline()
if not self.sl_segment:
break
self.tl_segment=self.tlcf.readline()
self.continserts+=1
self.max_id_corpus+=1
self.sl_record=[]
self.tl_record=[]
self.sl_segment=self.sl_segment.rstrip()
self.tl_segment=self.tl_segment.rstrip()
self.sl_record.append(self.max_id_corpus)
self.tl_record.append(self.max_id_corpus)
self.sl_record.append(self.sl_segment)
self.tl_record.append(self.tl_segment)
self.sl_data.append(self.sl_record)
self.tl_data.append(self.tl_record)
if self.continserts==self.maxinserts:
self.cur.executemany("INSERT INTO sl_corpus (id, segment) VALUES (?,?)",self.sl_data)
self.cur.executemany("INSERT INTO tl_corpus (id, segment) VALUES (?,?)",self.tl_data)
self.sl_data=[]
self.tl_data=[]
self.continserts=0
with self.conn:
self.cur.executemany("INSERT INTO sl_corpus (id, segment) VALUES (?,?)",self.sl_data)
self.cur.executemany("INSERT INTO tl_corpus (id, segment) VALUES (?,?)",self.tl_data)
self.conn.commit()
I am calling it like this:
e.load_sl_corpus("Main corpus.txt")
Note: I tried to run it through python -tt but I got the same error
Here are a small sample from my input file:
Clearance returns value as a percent of sales retail amount.
purchase order estimated landed cost each time this item is received at this location, or the primary supplier cost, depending on the merchandising system options.
purchase order estimated landed cost each time this item is received at this location, or the primary supplier cost, depending on the merchandising system options.
Retail value of original planned markdown amounts due to regular sales.
Quantity of unavailable clearance inventory at a location at the beginning of the reporting period, across all inventory status codes.
The percent of demand that flows through to net sales, after accounting for returns and cancellations. Derived as the sum of returns and cancellations divided by demand sales retail value, subtracted from 1 to get the inverse percent value.
#RICP2# - Shrink Non-Clr Cost Amt
Customer Segment Occupation Code
Flexible fact column 31 for text or non-numeric values.
Edit:
I am already create a function to connect my database please have a look below:
def create_project(self,project_name,sl_lang,tl_lang="null",overwrite=False):
'''Opens a project. If the project already exists, it raises an exception. To avoid the exception use overwrite=True. To open existing projects, use the open_project method.'''
if os.path.isfile(project_name) and not overwrite:
raise Exception("This file already exists")
else:
if os.path.isfile(project_name) and overwrite:
os.remove(project_name)
self.sl_lang=sl_lang
self.tl_lang=tl_lang
self.conn=sqlite3.connect(project_name)
self.cur = self.conn.cursor()
self.cur2 = self.conn.cursor()
with self.conn:
self.cur = self.conn.cursor()

You need to initialize the property cur before using it inside constructor.
Please include you __init__() function definition here also.

Related

Querying a varchar entry for a partial string

I am wondering if there is a way to query a table for a partial match to a string.
For instance, I have a table that lists drug treatments, but sometimes there are multiple drugs in
a single treatment. These come into the database as a varchar entry with both drugs separated by a semicolon (this formatting could be changed if it helped).
I know I can query on a full string, i.e.
Pharmacology() & 'treatment = "control"'
But if my entry is 'gabazine;TPMPA', is there a way to query on just 'TPMPA' and find all strings containing 'TPMPA'?
Alternatively, I could make a part table that populates just for cases where there are multiple drugs, which I could then use for querying these cases, but I am not sure how to set up the entries for better querying when the number of drugs is variable (i.e. is there a way to query inside a blob with a python list?)
Here's my table with some entries in case it helps:
my table
and my table definition (part table only there as a dummy):
#schema
class Pharmacology(dj.Computed):
definition = """
# information about pharmacological treatments
-> Presentation
-> PharmInfo
---
treatment :varchar(255) # string of the treatment name from hdf5 file
control_flag :int # 1 if control 0 if in drug
concentration :varchar(255) # drug concentration(s), "0" for controls
multiple_drug_flag :int # 1 if multiple drugs, else 0
"""
class MultipleDrugInfo(dj.Part):
definition = """
-> Pharmacology
---
list_of_drugs :blob # list of drugs in multi-drug cases
You can do that with the LIKE keyword
Pharmacology() & 'treatment LIKE "%TPMPA%"'
The % is wildcard in mysql.

Odd behavior with begins_with and a binary column in DynamoDB

Summary
When querying a binary range key using begins_with, some results are not returned even though they begin with the value being queried. This appears to only happen with certain values, and only in DynamoDB-local - not the AWS hosted version of DynamoDB.
Here is a gist you can run that reproduces the issue: https://gist.github.com/pbaughman/922db7b51f7f82bbd9634949d71f846b
Details
I have a DynamoDB table with the following schema:
user_id - Primary Key - binary - Contains 16 byte UUID
project_id_item_id - Sort Key - binary - 32 bytes - two UUIDs concatinated
While running my unit tests locally using the dynamodb-local docker image I have observed some bizarre behavior
I've inserted 20 items into my table like this:
table.put_item(
Item={
'user_id': user_id.bytes,
'project_id_item_id': project_id.bytes + item_id.bytes
}
)
Each item has the same user_id and the same project_id with a different item_id.
When I attempt to query the same data back out, sometimes (maybe 1 in 5 times that I run the test) I only get some of the items back out:
table.query(
KeyConditionExpression=
Key('user_id').eq(user_id.bytes) &
Key('project_id_item_id').begins_with(project_id.bytes))
)
# Only returns 14 items
If I drop the 2nd condition from the KeyConditionExpression, I get all 20 items.
If I run a scan instead of a query and use the same condition expression, I get all 20 items
table.scan(
FilterExpression=
Key('user_id').eq(user_id.bytes) &
Key('project_id_item_id').begins_with(project_id.bytes))
)
# 20 items are returned
If I print the project_id_item_id of every item in the table, I can see that they all start with the same project_id:
[i['project_id_item_id'].value.hex() for i in table.scan()['Items']]
# Result:
|---------Project Id-----------|
['76761923aeba4edf9fccb9eeb5f80cc40604481b26c84c73b63308dd588a4df1',
'76761923aeba4edf9fccb9eeb5f80cc40ec926452c294c909befa772b86e2175',
'76761923aeba4edf9fccb9eeb5f80cc460ff943b36ec44518175525d6eb30480',
'76761923aeba4edf9fccb9eeb5f80cc464e427afe84d49a5b3f890f9d25ee73b',
'76761923aeba4edf9fccb9eeb5f80cc466f3bfd77b14479a8977d91af1a5fa01',
'76761923aeba4edf9fccb9eeb5f80cc46cd5b7dec9514714918449f8b49cbe4e',
'76761923aeba4edf9fccb9eeb5f80cc47d89f44aae584c1c9da475392cb0a085',
'76761923aeba4edf9fccb9eeb5f80cc495f85af4d1f142608fae72e23f54cbfb',
'76761923aeba4edf9fccb9eeb5f80cc496374432375a498b937dec3177d95c1a',
'76761923aeba4edf9fccb9eeb5f80cc49eba93584f964d13b09fdd7866a5e382',
'76761923aeba4edf9fccb9eeb5f80cc4a6086f1362224115b7376bc5a5ce66b8',
'76761923aeba4edf9fccb9eeb5f80cc4b5c6872aa1a84994b6f694666288b446',
'76761923aeba4edf9fccb9eeb5f80cc4be07cd547d804be4973041cfd1529734',
'76761923aeba4edf9fccb9eeb5f80cc4c48daab011c449f993f061da3746a660',
'76761923aeba4edf9fccb9eeb5f80cc4d09bc44973654f39b95a91eb3e291c68',
'76761923aeba4edf9fccb9eeb5f80cc4d0edda3d8c6643ad8e93afe2f1b518d4',
'76761923aeba4edf9fccb9eeb5f80cc4d8d1f6f4a85e47d78e2d06ec1938ee2a',
'76761923aeba4edf9fccb9eeb5f80cc4dc7323adfa35423fba15f77facb9a41b',
'76761923aeba4edf9fccb9eeb5f80cc4f948fb40873b425aa644f220cdcb5d4b',
'76761923aeba4edf9fccb9eeb5f80cc4fc7f0583f593454d92a8a266a93c6fcd']
As a sanity check, here is the project_id I'm using in my query:
print(project_id)
76761923-aeba-4edf-9fcc-b9eeb5f80cc4 # Matches what's returned by scan above
Finally, the most bizarre part is I can try to match fewer bytes of the project ID and I start to see all 20 items, then zero items, then all 20 items again:
hash_key = Key('hash_key').eq(hash_key)
for n in range(1,17):
short_key = project_id.bytes[:n]
range_key = Key('project_id_item_id').begins_with(short_key)
count = table.query(KeyConditionExpression=hash_key & range_key)['Count']
print("If I only query for 0x{:32} I find {} items".format(short_key.hex(), count))
Gets me:
If I only query for 0x76 I find 20 items
If I only query for 0x7676 I find 20 items
If I only query for 0x767619 I find 20 items
If I only query for 0x76761923 I find 20 items
If I only query for 0x76761923ae I find 20 items
If I only query for 0x76761923aeba I find 20 items
If I only query for 0x76761923aeba4e I find 20 items
If I only query for 0x76761923aeba4edf I find 0 items
If I only query for 0x76761923aeba4edf9f I find 20 items
If I only query for 0x76761923aeba4edf9fcc I find 0 items
If I only query for 0x76761923aeba4edf9fccb9 I find 20 items
If I only query for 0x76761923aeba4edf9fccb9ee I find 0 items
If I only query for 0x76761923aeba4edf9fccb9eeb5 I find 20 items
If I only query for 0x76761923aeba4edf9fccb9eeb5f8 I find 20 items
If I only query for 0x76761923aeba4edf9fccb9eeb5f80c I find 20 items
If I only query for 0x76761923aeba4edf9fccb9eeb5f80cc4 I find 15 items
I am totally dumbfounded by this pattern. If the range key I'm searching for is 8, 10 or 12 bytes long I get no matches. If it's 16 bytes long I get fewer than 20 but more than 0 matches.
Does anybody have any idea what could be going on here? The documentation indicates that the begins_with expression works with Binary data. I'm totally at a loss as to what could be going wrong. I wonder if DynamoDB-local is doing something like converting the binary data to strings internally to do the comparisons and some of these binary patterns don't convert correctly.
It seems like it might be related to the project_id UUID. If I hard-code it to 76761923-aeba-4edf-9fcc-b9eeb5f80cc4 in the test, I can make it miss items every time.
This may be a six year old bug in DynamoDB local I will leave this question open in case someone has more insight, and I will update this answer if I'm able to find out more information from Amazon.
Edit: As of June 23rd, they have managed to reproduce the issue and it is in the queue to be fixed in a future release.
2nd Edit: As of August 4th, they are investigating the issue and a fix will be released shortly

Extracting quantities of elements with IfcOpenShell in python

I am trying to read the deepest level of quantities for objects in an ifc file, using IfcOpenShell in Python. So far I have:
import ifcopenshell
path = r'D:\ifcos_1\slab.ifc'
ifc_file = ifcopenshell.open(path)
geometries = ifc_file.by_type("IfcProduct")
for geometry in geometries:
if geometry.is_a("IfcSlab"):
print geometry
test = geometry.IfcPhysicalQuantity()
print test
I've studied the definitions
No matter which type of function I try to place for the test = geometry.X(), I get an error:
File "C:\Python27\lib\site-packages\ifcopenshell\entity_instance.py", line 48, in __getattr__
"entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name))
AttributeError: entity instance of type 'IfcSlab' has no attribute 'IfcPhysicalQuantity'
Not sure how to solve this and would appreciate help.
EDIT:
Further work which gets the slab and further references:
for geometry in geometries:
if geometry.is_a("IfcSlab"):
print geometry
definedBy = geometry.IsDefinedBy
print definedBy[0]
for each in definedBy:
test = each.is_a()
print test
As of this moment the obstacle is the compatibility with IFC4, which I will try to recompile with instructions from this forum post.
EDIT 2:
Further work using for now the IFC 2x3 standard, with a file that has quantity information (verified via the raw data). The following is the relevant code:
for geometry in geometries:
if geometry.is_a("IfcSlab"):
definedBy = geometry.IsDefinedBy
for line in definedBy:
test = line.is_a()
# print test
if line.is_a() == 'IfcRelDefinesByProperties' or line.is_a() == 'IfcRelDefinesByType':
step1 = line.RelatingPropertyDefinition
step2 = step1.is_a()
print step2
There is an error no matter what I place after step1 = line., none of the following give a result:
line.IfcPropertySet
line.IfcElementQuantity
line.RelatingPropertyDefiniton
The output from this code is nevertheless:
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcElementQuantity
IfcElementQuantity
Which means that I can access IfcElementQuantity but none of the Attributes work. I've looked at schema reference but can't find the correct one.
When implementing this you should take care which version of IFC your import library works on - the version distributed by the IfcOpenShell-Website works with IFC2X3. For IFC4 you will probably need to compile a version yourself. (you can check your IFC version with ifcopenshell.schema_identifier)
I am putting links up to the buildingSMART IFC 4 definition even if I am talking about IFC2X3. Differences to IFC2X3 are marked in red on the buildingSMART web page. And the IFC4 definition is nicer to read (IMO).
Quantities aren't directly attached like an attribute. They are written as property sets and then related to the element or element type. So first you should ensure your IFC file contains quantities - otherwise you will not find any. Usually you start with a specific product - ifc_file.by_type('IfcSlab'). You can reach the property sets via inverse attributes - those are usually set up by the IFC library, they don't appear directly as attribute in the file.
I took you example file and shortened it to about a third (so it's still a valid IFC2X3 file):
ISO-10303-21;
HEADER;FILE_DESCRIPTION(('ViewDefinition [Custom, QuantityTakeOffAddOnView, SpaceBoundary2ndLevelAddOnView]','Option [Drawing Scale: 100.000000]','Option [Global Unique Identifiers (GUID): Keep existing]','Option [Elements to export: Visible elements (on all stories)]','Option [Partial Structure Display: Entire Model]','Option [IFC Domain: All]','Option [Structural Function: All Elements]','Option [Convert Grid elements: On]','Option [Convert IFC Annotations and ARCHICAD 2D elements: Off]','Option [Convert 2D symbols of Doors and Windows: Off]','Option [Explode Composite and Complex Profile elements into parts: On]','Option [Export geometries that Participates in Collision Detection only: Off]','Option [Elements in Solid Element Operations: Extruded/revolved]','Option [Elements with junctions: Extruded/revolved without junctions]','Option [Slabs with slanted edge(s): Extruded]','Option [Use legacy geometric methods as in Coordination View 1.0: Off]','Option [IFC Site Geometry: As boundary representation (BRep)]','Option [IFC Site Location: At Project Origin]','Option [Curtain Wall export mode: Container Element]','Option [Railing export mode: Single Element]','Option [Stair export mode: Container Element]','Option [Properties To Export: All properties]','Option [Space containment: On]','Option [IFC Domain For Space Containment: All]','Option [Bounding Box: Off]','Option [Geometry to type objects: Off]','Option [Element Properties: All]','Option [Property Type Element Parameter: On]','Option [Quantity Type Element Parameter: On]','Option [IFC Base Quantities: On]','Option [Window Door Lining and Panel Parameters: On]','Option [IFC Space boundaries: On]','Option [ARCHICAD Zone Categories as IFC Space classification data: On]','Option [Element Classifications: On]'),'2;1');
FILE_NAME('D:\\Side Projects\\Paragraph3\\The database\\IFC Files\\Local tests\\ifcos_1\\slab.ifc','2018-06-13T18:28:40',('Architect'),('Building Designer Office'),'The EXPRESS Data Manager Version 5.02.0100.09 : 26 Sep 2013','IFC file generated by GRAPHISOFT ARCHICAD-64 21.0.0 INT FULL Windows version (IFC2x3 add-on version: 3005 INT FULL).','The authorising person');
FILE_SCHEMA(('IFC2X3'));
ENDSEC;
DATA;
#1= IFCPERSON($,'Undefined',$,$,$,$,$,$);
#7= IFCPERSONANDORGANIZATION(#1,#10,$);
#10= IFCORGANIZATION('GS','GRAPHISOFT','GRAPHISOFT',$,$);
#11= IFCAPPLICATION(#10,'21.0.0','ARCHICAD-64','IFC2x3 add-on version: 3005 INT FULL');
#12= IFCOWNERHISTORY(#7,#11,$,.ADDED.,$,$,$,1528907320);
#13= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#14= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#16= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17= IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.0174532925199),#16);
#18= IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#19= IFCCONVERSIONBASEDUNIT(#18,.PLANEANGLEUNIT.,'DEGREE',#17);
#29= IFCUNITASSIGNMENT((#13,#14,#19));
#31= IFCDIRECTION((1.,0.,0.));
#35= IFCDIRECTION((0.,0.,1.));
#37= IFCCARTESIANPOINT((0.,0.,0.));
#39= IFCAXIS2PLACEMENT3D(#37,#35,#31);
#40= IFCDIRECTION((0.,1.));
#42= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.00000000000E-5,#39,#40);
#45= IFCPROJECT('344O7vICcwH8qAEnwJDjSU',#12,'Project',$,$,$,$,(#42),#29);
#59= IFCLOCALPLACEMENT($,#39);
#62= IFCSITE('20FpTZCqJy2vhVJYtjuIce',#12,'Site',$,$,#59,$,$,.ELEMENT.,(47,33,34,948800),(19,3,17,204400),0.,$,$);
#68= IFCRELAGGREGATES('0Du7$nzQXCktKlPUTLFSAT',#12,$,$,#45,(#62));
#74= IFCQUANTITYLENGTH('GrossPerimeter',$,$,0.);
#76= IFCQUANTITYAREA('GrossArea',$,$,0.);
#77= IFCELEMENTQUANTITY('2GNZepdf73fvGc$0W6rozj',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#74,#76));
#82= IFCRELDEFINESBYPROPERTIES('2Hm9JvZjohDNSD2kdxZI3b',#12,$,$,(#62),#77);
#93= IFCLOCALPLACEMENT(#59,#39);
#95= IFCBUILDING('00tMo7QcxqWdIGvc4sMN2A',#12,'Building',$,$,#93,$,$,.ELEMENT.,$,$,$);
#97= IFCRELAGGREGATES('2b_h_mYcGArd6glJG2Fmbt',#12,$,$,#62,(#95));
#101= IFCQUANTITYAREA('GrossFloorArea',$,$,0.);
#102= IFCELEMENTQUANTITY('1kQMlmT0rD35a9E43iKTas',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#101));
#104= IFCRELDEFINESBYPROPERTIES('0L87OdSD3DqSTjSRlAciZL',#12,$,$,(#95),#102);
#115= IFCLOCALPLACEMENT(#93,#39);
#117= IFCBUILDINGSTOREY('1oZ0wPs_PE8ANCPg3bIs4j',#12,'Ground Floor',$,$,#115,$,$,.ELEMENT.,0.);
#119= IFCRELAGGREGATES('118jwqMnuwK1xuf97w7fU5',#12,$,$,#95,(#117));
#180= IFCSLAB('3W29Drc$H6CxK3FGIxjJNl',#12,'SLA - 001',$,$,$,$,'E0089375-9BF4-4633-B503-3D04BBB535EF',.FLOOR.);
#195= IFCRELCONTAINEDINSPATIALSTRUCTURE('04ldtj6cp2dME6CiP80Bzh',#12,$,$,(#180),#117);
#326= IFCPROPERTYSINGLEVALUE('Fragility rating',$,IFCLABEL('0'),$);
#327= IFCPROPERTYSINGLEVALUE('Tile dimensions',$,IFCLABEL('Undefined'),$);
#328= IFCPROPERTYSINGLEVALUE('Anti-static Surface',$,IFCBOOLEAN(.F.),$);
#329= IFCPROPERTYSINGLEVALUE('Non-skid Surface',$,IFCBOOLEAN(.F.),$);
#330= IFCPROPERTYSET('0LYX8AqOOS9ft8M4aJYEYa',#12,'FLOORINGS',$,(#326,#327,#328,#329));
#332= IFCRELDEFINESBYPROPERTIES('1G6WWCSQGg0PdTnW7hwMrM',#12,$,$,(#180),#330);
#335= IFCPROPERTYSINGLEVALUE('Renovation Status',$,IFCLABEL('Existing'),$);
#336= IFCPROPERTYSET('0cR6wsk2QWcLKPchA8mF3u',#12,'AC_Pset_RenovationAndPhasing',$,(#335));
#338= IFCRELDEFINESBYPROPERTIES('3nYD8KGPhoBw5okmj1JjsA',#12,$,$,(#180),#336);
#341= IFCQUANTITYLENGTH('Width',$,$,300.);
#342= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#343= IFCQUANTITYAREA('GrossArea',$,$,28.);
#344= IFCQUANTITYAREA('NetArea',$,$,28.);
#345= IFCQUANTITYVOLUME('GrossVolume',$,$,8.4);
#346= IFCQUANTITYVOLUME('NetVolume',$,$,8.4);
#347= IFCELEMENTQUANTITY('1RfXJewSc7OCIaD$L2ZoXT',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#341,#342,#343,#344,#345,#346));
#349= IFCRELDEFINESBYPROPERTIES('085uLttAQRllG3nL_YikZ8',#12,$,$,(#180),#347);
#375= IFCQUANTITYVOLUME('Gross Volume of the Slab',$,$,8.4);
#376= IFCQUANTITYVOLUME('Gross Volume of the Slab with Holes',$,$,8.4);
#377= IFCQUANTITYLENGTH('Holes Perimeter',$,$,0.);
#378= IFCQUANTITYAREA('Holes Surface Area',$,$,0.);
#379= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#381= IFCQUANTITYAREA('Top Surface Area',$,$,28.);
#382= IFCELEMENTQUANTITY('0DuZ12CVtssgcIQPaQ$1sp',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#375,#376,#377,#378,#379,#381));
#384= IFCRELDEFINESBYPROPERTIES('0KgGv0Y8Fc2jg8BCPhxnM5',#12,$,$,(#180),#382);
#393= IFCSLABTYPE('0K1otpnkQcEpOBXPxnZ3dB',#12,'Timber - Floor 300',$,$,(#396),$,'14072DF3-C6E6-A63B-360B-859EF18C39CB',$,.FLOOR.);
#395= IFCRELDEFINESBYTYPE('353egCMRpZtJd$CDCoSsCb',#12,$,$,(#180),#393);
#352= IFCQUANTITYAREA('Area',$,$,28.);
#353= IFCQUANTITYLENGTH('Height',$,$,300.);
#354= IFCQUANTITYVOLUME('Net Volume',$,$,8.4);
#396= IFCELEMENTQUANTITY('1Zyxf4r7NogSp4V7ORMpET',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#352,#353,#354));
ENDSEC;
END-ISO-10303-21;
This is a slab with an area measurement attached. It should have an inverse attribute IsDefinedBy. In IFC2X3 this points to a list of entities IfcRelDefinesByProperties and IfcRelDefinesByType. With IFC4 IfcRelDefinesByType will be put in the inverse attribute IsTypedBy.
Each IfcRelDefinesByProperties point to a property set in their attribute RelatingPropertyDefinition. There are various property set types, you want it to be of type IfcElementQuantity when searching for physical quantities. You will have to check at run time which type you currently hold while iterating the list of property relations.
The quantity set has a list of IfcPhysicalQuantities attached in the attribute Quantities. These can be simple quantities or complex quantities, which are composed of multiple simple quantities. For simple quantities there are specific subtypes for area, count or weight. Again you will have to check at runtime for the concrete type.
The area quantity itself has a name and description to give further context (not ours, but possibly in the real world). The value attribute is named after the quantity type, so IfcQuantityArea has an attribute AreaValue. Also of interest is attribute Unit which is a reference to the unit of the value. If it is not set (as in our example) you will need to look for assigned units at the IfcProject entity.
Unfortunately this might not be all. If the object (here our IfcSlab) has an assigned object type, that type can also have property sets attached (I modified the example file to be this case). Thy type entity does not have an inverse attribute, but a direct one, HasProperties. If it is set, you can discover attached properties through it.
To summarise, you will probably need multiple loops:
For each object, get property sets
For each property set, test if it is quantity set
For each quantity set, go through quantities
And potentially repeat this search if the object has a user defined type.
The following code should do exactly this (written on my machine with python 3.5.4 and ifcopenshell with IFC2X3 schema)):
Get all slabs from the file (there is only one)
Go through all entities in the inverse attribute IsDefinedBy - these can be IfcRelDefinesByProperties or IFcRelDefinesByType.
Get property sets from the entity
Check if the given property set is IfcElementQuantity and proceed to print quantitites if it is.
import ifcopenshell
def print_quantities(property_definition):
if 'IfcElementQuantity' == property_definition.is_a():
for quantity in property_definition.Quantities:
if 'IfcQuantityArea' == quantity.is_a():
print('Area value: ' + str(quantity.AreaValue))
if 'IfcQuantityVolume' == quantity.is_a():
print('Volume value: ' + str(quantity.VolumeValue))
if 'IfcQuantityLength' == quantity.is_a():
print('Length value: ' + str(quantity.LengthValue))
ifc_file = ifcopenshell.open('slab.ifc')
products = ifc_file.by_type('IfcSlab')
for product in products:
if product.IsDefinedBy:
definitions = product.IsDefinedBy
for definition in definitions:
#In IFC2X3 this could be property or type
#in IFC4 type is in inverse attribute IsTypedBy
if 'IfcRelDefinesByProperties' == definition.is_a():
property_definition = definition.RelatingPropertyDefinition
print_quantities(property_definition)
if 'IfcRelDefinesByType' == definition.is_a():
type = definition.RelatingType
if type.HasPropertySets:
for property_definition in type.HasPropertySets:
print_quantities(property_definition)
For the example this results in:
Length value: 300.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Length value: 0.0
Area value: 0.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Length value: 300.0
Volume value: 8.4
Quantities in IFC are stored in quantity sets, which are very similar in structure to property sets. IfcOpenShell offers utility functions to extract this data in a schema-agnostic manner:
for slab in ifc_file.by_type("IfcSlab"):
quantities = ifcopenshell.util.element.get_psets(slab, qtos_only=True)
print(quantities) # A dictionary of qtos and quantities
# For example print(quantities["Qto_SlabBaseQuantities"]["GrossVolume"])
I wrote a few functions once, to extract all properties.
https://github.com/johannesmichael/ifc-python/blob/master/modules/ifc_pset_utils.py
Might not be complete, but can give you an idea.
I extract all to excel for further analyzis.
BaseQuantities:
def get_related_quantities(ifc_instance):
"""
Returns a list of IfcElementQuantity for given IFC ID
argument: ifc_instance
return: list of property sets
"""
quantities_list =[]
for x in ifc_instance.IsDefinedBy:
if x.is_a("IfcRelDefinesByProperties"):
if x.RelatingPropertyDefinition.is_a("IfcElementQuantity"):
quantities_list.append(x.RelatingPropertyDefinition)
return quantities_list
def get_quantity_single_value(x):
"""
Returns a dict of dicts of IfcElementQuantity single values.
Returning a dictionary of dictionaries
is used, because it is easy to transform to pandas.DataFrame
argument: IFC Element as contained in list from get_related_property_sets()
return: dict of property single values like {"IfcName":"xx", "IfcGlobalId": "klkhlkh", ......}
"""
quantities_dicts = {}
for y in x.Quantities:
if y.is_a('IfcQuantityArea'):
quantities_dicts.update({y.Name:y.AreaValue})
if y.is_a('IfcQuantityLength'):
quantities_dicts.update({y.Name:y.LengthValue})
if y.is_a('IfcQuantityVolume'):
quantities_dicts.update({y.Name:y.VolumeValue})
if y.is_a('IfcQuantityCount'):
quantities_dicts.update({y.Name:y.CountValue})
if y.is_a('IfcQuantityWeight'):
quantities_dicts.update({y.Name:y.WeightValue})
return quantities_dicts
This was done for IFC 2x3 TC1
Hope that helps

Python & SQLite3 You did not supply a Value for binding 6

I apologize if this is redundant but I can't seem to find the answer.
I've supplied all the values. Still it gives me error that I did not supply value for binding 6. This is My code
def Update_Employee(id,name,phoneno,address,nic,
joindate,email,picture,role,status,
salary,username,password):
with conn:
c.execute("UPDATE Employee "
"SET emp_Name=:emp_name,"
"emp_PhoneNo=:emp_phoneno,"
"emp_Address=:emp_address,"
"emp_NIC=:emp_nic,"
"emp_JoinDate=:emp_joindate,"
"emp_Email=:emp_email"
"emp_Picture=:emp_picture,"
"emp_role=:emp_role,"
"emp_status=:emp_Status,"
"emp_salary=:emp_Salary,"
"emp_Username=:emp_username,"
"emp_Password=:emp_password "
"WHERE emp_ID=:emp_id",
{'emp_id':id,
'emp_name':name,
'emp_phoneno':phoneno,
'emp_address':address,
'emp_nic':nic,
'emp_joindate':joindate,
'emp_email':email,
'emp_picture':picture,
'emp_role':role,
'emp_Status':status,
'emp_Salary':salary,
'emp_username':username,
'emp_password':password})
I've double checked the attributes in my database. Names\spellings are 100% alright and all the values have been suppplied.

sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 3, and there are 1 supplied

one of my A Level students are trying to get their code to work in Python 3 but it keeps coming up with the error message: "sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 3, and there are 1 supplied". The code is as follows:
import sqlite3
def query(sql,data):
with sqlite3.connect("DogBreeds.db") as db:
cursor = db.cursor()
cursor.execute(sql,data)
db.commit()
def insert_dog_breed_data(records):
sql = "insert into DogBreed(Breed, Description, Previous_Litters) values (?,?,?)"
for record in records:
query(sql,record)
def insert_dog_data(records):
sql = "insert into Dogs (Name, Date of Birth, Gender, DogBreedID) values (?,?,?,?)"
for record in records:
query(sql,record)
if __name__ == "__main__":
dog_breeds = [("Shih Tzu",),("Jack Russell",),("Great Dane",),("Husky"("Cavalier King Charles Spaniel",),("Pug")]
insert_dog_breed_data(dog_breeds)
dogs = [("Steve", "10/08/2006", "Male",1),("John","08/05/2017", "Male",2),("Ellen", "25/12/2013","Female",3),("Betty", "13/01/2000", "Female",4),("Charlie", "30/03/2000", "Female",5),("Fred", "04/05/2000", "Male",5)]
insert_dog_data(dogs)
and the full error message is:
Traceback (most recent call last): File "G:\Dog Breeder Scenario - Python\Insert data 2.py", line 21, in <module>
insert_dog_breed_data(dog_breeds) File "G:\Dog Breeder Scenario - Python\Insert data 2.py", line 12, in insert_dog_breed_data
query(sql,record) File "G:\Dog Breeder Scenario - Python\Insert data 2.py", line 6, in query
cursor.execute(sql,data)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 3, and there are 1 supplied.
As a guide they are following the tutorial from Python School website - Task 4 from https://pythonschool.net/databases/inserting-data/
Any help will be appreciated.
Thanks.
You're passing a list of single-item tuples into insert_dog_breed_data - containing the breed name only - but the SQL query is expecting three items - name, description, previous_litters.
Note, one of the most useful skills a new programmer can learn is how to read error messages. All the information they - and you - needed to solve this themselves was presented in that message.
The problem is (as #DanielRoseman explained) that sqlite expects tuples containing 3 items each (Breed, Description, Previous_Litters) but the ones you are providing only contain one since:
dog_breeds = [("Shih Tzu",),("Jack Russell",),("Great Dane",),("Husky"("Cavalier King Charles Spaniel",),("Pug")])
One solution would be to modify your dog_breeds tuples before passing it on to the insert_dog_breed_data function as follows:
dog_breeds = [(x,) + ('', '') for x in dog_breeds]
Assuming you do not have the info on the Description and Previous_Litters available.
which will create tuples like this one: ("Shih Tzu", '', '')

Categories