C structure to Python class or dict? - python

I heard and read that, defining large number of information is easy using class structure, which is defined in C language (see C Code below).
I want to defined similar way using Python. I need little favor on code, and I am in new learner group of Python.
Any suggestion about which way make it easy to define? Going dict is fine, but class is best.
Example in C code below (and I have additional similar structures and information):
typedef struct
{
U16 ID;
S8 Name[32];
S8 Description[96];
S8 Units[16];
enum eType Type;
F32 Scaling;
F32 Offset;
BOOL Writeable;
} sDataInfo;
/* ID, Name, Description, Unit, Type, Scaling, Offset, Writable */
sDataInfo data_items[] =
{
0x0202, "dtc_num_of_faults_", "Number of DTCs", "", u8, 1, 0, FALSE,
0x2007, "FlBodyVertLocSel_A_Meas_", "FL Vertical Acceleration", "m/s^2", s16, 0.05, 0, FALSE,
0x2008, "FrBodyVertLocSel_A_Meas_", "FR Vertical Acceleration", "m/s^2", s16, 0.05, 0, FALSE,
0x2022, "RlBodyVertLocSel_A_Meas_", "RL Vertical Acceleration", "m/s^2", s16, 0.05, 0, FALSE
}
It is important to know every one the above code can be changed in Python. None of question answered for above in any online chain.
And expecting some examples as well.

As I said in a comment, I'm not sure exactly what you want...but here's one guess:
from pprint import pprint
import sys
def sprintf(format, *args):
return format % args
def _attributes_from_dict(d):
self = d.pop('self')
for n, v in d.items():
setattr(self, n, v)
class DataInfo(object):
fieldnames = 'id, name, description, units, type, scaling, offset, writeable'.split(', ')
def __init__(self, id, name, description, units, type, scaling, offset, writeable):
_attributes_from_dict(locals())
def __repr__(self): # optional
values = tuple(getattr(self, fieldname) for fieldname in self.fieldnames)
id = values[0]
remainder = ', '.join(map(repr, values[1:]))
return sprintf('%s(0x%04x, %s)', self.__class__.__name__, id, remainder)
u8, s16 = 0, 1 # enum eType names and values
data_items = [
DataInfo(*args) for args in [
(0x0202, "dtc_num_of_faults_", "Number of DTCs", "", u8, 1, 0, False),
(0x2007, "FlBodyVertLocSel_A_Meas_", "FL Vertical Acceleration", "m/s^2", s16, 0.05, 0, False),
(0x2008, "FrBodyVertLocSel_A_Meas_", "FR Vertical Acceleration", "m/s^2", s16, 0.05, 0, False),
(0x2022, "RlBodyVertLocSel_A_Meas_", "RL Vertical Acceleration", "m/s^2", s16, 0.05, 0, False),
]
]
pprint(data_items)
Output:
[DataInfo(0x0202, 'dtc_num_of_faults_', 'Number of DTCs', '', 0, 1, 0, False),
DataInfo(0x2007, 'FlBodyVertLocSel_A_Meas_', 'FL Vertical Acceleration', 'm/s^2', 1, 0.05, 0, False),
DataInfo(0x2008, 'FrBodyVertLocSel_A_Meas_', 'FR Vertical Acceleration', 'm/s^2', 1, 0.05, 0, False),
DataInfo(0x2022, 'RlBodyVertLocSel_A_Meas_', 'RL Vertical Acceleration', 'm/s^2', 1, 0.05, 0, False)]

Related

blender 2.92 python overriding

I have seen quite a few questions regarding this issue, and I have not been able to wrap my head around it.
So here is a concrete example.
I create a cube and in edit mode I add loopcuts. No sweat!
I copy the code from the info window and I try it out in a script and I get the ominous RuntimeError: Operator bpy.ops.mesh.loopcut_slide.poll() expected a view3d region & editmesh error message.
I understand now that it is about first giving python the right context by overriding. And alas, I do not know how to do it!
Here is the code:
import bpy
import os
os.system("cls")
# remove the default cube...
objs = bpy.data.objects
for obj in objs:
if obj.name.find("Cube") == 0:
bpy.data.objects.remove(obj, do_unlink=True)
# add a cube!
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=True, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
# do something to it to be sure that we have it...
bpy.data.objects['Cube'].scale[0] = 10
# THE CODE BELOW GIVES THE RuntimeError: Operator bpy.ops.mesh.loopcut_slide.poll() expected a view3d region & editmesh error message.
# What is the override code I have to use to fix it????????
bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"number_cuts":16, "smoothness":0, "falloff":'INVERSE_SQUARE', "object_index":0, "edge_index":4, "mesh_select_mode_init":(True, False, False)}, TRANSFORM_OT_edge_slide={"value":0, "single_side":False, "use_even":False, "flipped":False, "use_clamp":True, "mirror":True, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "correct_uv":True, "release_confirm":False, "use_accurate":False})
import bpy
import os
os.system("cls")
objs = bpy.data.objects
for obj in objs:
if obj.name.find("Cube") == 0:
bpy.data.objects.remove(obj, do_unlink=True)
# add a cube!
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=True, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
# do something to it to be sure that we have it...
bpy.data.objects['Cube'].scale[0] = 10
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
for region in area.regions:
if region.type == 'WINDOW':
override = {'area': area, 'region': region, 'edit_object':bpy.context.edit_object}
bpy.ops.mesh.loopcut_slide(override,MESH_OT_loopcut={"number_cuts":16, "smoothness":0, "falloff":'INVERSE_SQUARE', "object_index":0, "edge_index":4, "mesh_select_mode_init":(True, False, False)}, TRANSFORM_OT_edge_slide={"value":0, "single_side":False, "use_even":False, "flipped":False, "use_clamp":True, "mirror":True, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "correct_uv":True, "release_confirm":False, "use_accurate":False})

Using Python Scripting to set animation timecode zero in motionbuilder

Everyone.
I have some animation file that the start time is not zero. I am trying to create a script that will set the animation timecode to zero. For example, the picture shows the timecode is not from zero. Thank you very much for your help。
enter image description here
I'm a bit late but this is probably still interesting to share!
You can set your current take's timespan easily using an FBTimeSpan() instance like this, by specifying a start and end frame as FBTime() objects:
lStartFrame = 0
lEndFrame = 100
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
But I guess that what you are looking for is a way to offset your animation and make it start at 0, isn't it?
Here are two functions from my own library, using the Story mode to offset your current animation at a given frame. The first one works on the current or all characters of your scene (character animation track). The second one on selected conponents (generic animation track). For each one you can pass as argument the frame it should start from and if you want to frame the new timespan at the end (replace your old first/last frames with the new ones).
from pyfbsdk import *
def offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True):
''' Offset current/all(default) characters animation to a given frame, 0 by default '''
# get list of current/all characters
if all_chars:
char_list = FBSystem().Scene.Characters
else:
char_list = [FBApplication().CurrentCharacter]
# get initial timespan
lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()
# turn on Story mode
FBStory().Mute = False
# process character list
for char in char_list:
# set timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# set current character
FBApplication().CurrentCharacter = char
# insert character animation track
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, FBStory().RootFolder)
track.Name = '{}_charAnimTrack'.format(FBApplication().CurrentCharacter.Name)
track.Details.append(FBApplication().CurrentCharacter)
# insert take in story mode
take = FBSystem().CurrentTake
inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
# move inserted clip to given frame
inserted_clip.Start = FBTime(0,0,0,frame)
# frame new timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
# defining plot options and plot to current take
PlotOptions = FBPlotOptions()
PlotOptions.ConstantKeyReducerKeepOneKey = True
PlotOptions.PlotAllTakes = False
PlotOptions.PlotOnFrame = True
PlotOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
PlotOptions.PlotTranslationOnRootOnly = True
PlotOptions.PreciseTimeDiscontinuities = True
PlotOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
PlotOptions.UseConstantKeyReducer = True
char.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, PlotOptions)
# empty Story mode
for track in FBStory().RootFolder.Tracks:
for clip in track.Clips:
clip.FBDelete()
track.FBDelete()
# set back original timespan if specified
if not frame_anim:
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# turn off Story mode
FBStory().Mute = True
def offset_generic_animation_at_frame(frame = 0, frame_anim = True):
''' Offset selected components animation to a given frame, 0 by default '''
# get selected components
lModelList = FBModelList()
FBGetSelectedModels(lModelList)
if not lModelList:
raise ValueError("Select at least one component")
# get initial timespan
lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()
# turn on Story mode
FBStory().Mute = False
# set timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# insert generic animation track and add selected components to it
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackAnimation, FBStory().RootFolder)
track.Name = 'genericAnimTrack'
for comp in lModelList:
track.Details.append(comp)
# insert take in story mode
take = FBSystem().CurrentTake
inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
# move inserted clip to given frame
inserted_clip.Start = FBTime(0,0,0,frame)
# frame new timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
# plot selected take
lOptions = FBPlotOptions()
lOptions.ConstantKeyReducerKeepOneKey = False
lOptions.PlotAllTakes = False
lOptions.PlotOnFrame = True
lOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
lOptions.PlotTranslationOnRootOnly = False
lOptions.PreciseTimeDiscontinuities = True
lOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
lOptions.UseConstantKeyReducer = False
FBSystem().CurrentTake.PlotTakeOnSelected(lOptions)
# empty Story mode
for track in FBStory().RootFolder.Tracks:
for clip in track.Clips:
clip.FBDelete()
track.FBDelete()
# set back original timespan if specified
if not frame_anim:
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# turn off Story mode
FBStory().Mute = True
# MAIN
offset_generic_animation_at_frame(frame = 0, frame_anim = False)
offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True)

Python Key Error filtering MySQL

So I have a little program which makes a DB call and then converts it into a PDF.
I have most of them working but this last one is returning a Key Error on me and I cannot figure out why.
Here is an example of the data being returned by the DB:
((None, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 26, 0, 26), (1, 1, 0, 0, 0, 17, 0, 18), (2, 0, 0, 0, 0, 15, 0, 16))
The Traceback:
Traceback (most recent call last):
File "C:\Users\Ace\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:/Users/Ace/Desktop/IPNV/KP_App/FML/firstapp.py", line 232, in hrday_in
hourday_filter(noodle, dest, drange)
File "C:\Users\Ace\Desktop\IPNV\KP_App\FML\dataIN.py", line 187, in hourday_filter
doc.export(pths, drange)
File "C:\Users\Ace\Desktop\IPNV\KP_App\FML\calazan.py", line 58, in export
reverse=reverse_order)
KeyError: 'h'
Im not even sure where the 'h' comes from.
Here is the function that I run the data through to prepare for the pdf generation:
def hourday_filter(tuna, pth, drange):
data = []
for hr, number, local, chicken, alligator, ace, lola, chunk in tuna:
data.append({'hour': hr,
'number': number,
'local': local,
'long': chicken,
'inter': alligator,
'income': ace,
'tandem': lola,
'total': chunk})
fields = (
('hour', 'Hour of Day'),
('number', 'Internal Calls '),
('local', 'Local Calls'),
('long', 'Long Distance Calls'),
('inter', 'International Calls '),
('income', 'Incoming Calls'),
('tandem', 'Tandem Calls'),
('total', 'Total Calls'),
)
pths = pth + '/HourofDay.pdf'
doc = DataToPdf(fields, data, sort_by='hr',
title='Hour of Day Report')
doc.export(pths, drange)
And From there the data is passed to this function to actually convert it too pdf.
class DataToPdf:
"""
Export a list of dictionaries to a table in a PDF file.
"""
def __init__(self, fields, data, sort_by=None, title=None):
"""
Arguments:
fields - A tuple of tuples ((fieldname/key, display_name))
specifying the fieldname/key and corresponding display
name for the table header.
data - The data to insert to the table formatted as a list of
dictionaries.
sort_by - A tuple (sort_key, sort_order) specifying which field
to sort by and the sort order ('ASC', 'DESC').
title - The title to display at the beginning of the document.
"""
self.fields = fields
self.data = data
self.title = title
self.sort_by = sort_by
def export(self, filename, drange, data_align='LEFT', table_halign='LEFT'):
doc = SimpleDocTemplate(filename, pagesize=letter)
styles = getSampleStyleSheet()
styleH = styles['Heading1']
styleD = styles['Heading4']
date = time.strftime("%m/%d/%Y")
date2 = 'Ran on: ' + date
date3 = ' For the period ' + str(drange[0]) + ' to ' + str(drange[1]) # Edit here to display report date range
story = []
if self.title:
story.append(Paragraph(self.title, styleH))
story.append(Spacer(1, 0.25 * inch))
story.append(Paragraph(date2, styleD))
story.append(Spacer(1, 0.015 * inch))
story.append(Paragraph(date3, styleD))
if self.sort_by:
reverse_order = False
if str(self.sort_by[1]).upper() == 'DESC':
reverse_order = False
self.data = sorted(self.data,
key=itemgetter(self.sort_by[0]),
reverse=reverse_order)
converted_data = self.__convert_data()
table = Table(converted_data, hAlign=table_halign)
table.setStyle(TableStyle([
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 0), (0, -1), data_align),
('INNERGRID', (0, 0), (-1, -1), 0.50, colors.black),
('BOX', (0, 0), (-1, -1), 0.25, colors.black),
]))
data_len = len(converted_data)
for each in range(data_len):
if each % 2 == 0:
bg_color = colors.whitesmoke
else:
bg_color = colors.lightgrey
table.setStyle(TableStyle([('BACKGROUND', (0, each), (-1, each), bg_color)]))
story.append(table)
doc.build(story)
def __convert_data(self):
"""
Convert the list of dictionaries to a list of list to create
the PDF table.
"""
# Create 2 separate lists in the same order: one for the
# list of keys and the other for the names to display in the
# table header.
keys, names = zip(*[[k, n] for k, n in self.fields])
new_data = [names]
for d in self.data:
new_data.append([d[k] for k in keys])
return new_data
Is it possible that first result of the db (the null one) is causing this? I've made about a dozen of these reports now with no problems, not sure where I am messing up here.
So thanks to FamousJameous I realized that it was indeed the first field killing my filter. The sort_by call did not know how to deal with the NULL value. I managed to fix it by removing that first field from the tuple.
The database returned the results into the variable result
From there:
new_result = result[1:]
This line removed the NULL line and stopped the error

"Blinking" animation in Python with libavg

I'm working on a project using libavg and a series of RectNodes. What I'm trying to do is play an animation that makes each node light up white for 2,5 seconds, and then fades back. Every time you click one of the nodes, the same animation should happen for that specific node.
I'm using the AVGApp class, and a list with RectNode id and how many times they are supposed to light up, like (id1, 2)
def playAnim(self, animarr):
for i in range(0, len(animarr)):
i, count = animarr[i]
sid = "r" + str(i)
node = g_player.getElementByID(sid)
while count > 0:
self.blink(node)
count -= 1
return
and my code for blink:
def blink(self, node):
pos = node.pos
size = node.size
covernode = avg.RectNode(pos=pos, size=size, fillopacity=0,
parent = self._parentNode, fillcolor="ffffff",
color="000000", strokewidth=2)
self.animObj = LinearAnim(covernode, 'fillopacity', 1000, 0, 1)
self.animObj.start()
self.animObj = LinearAnim(covernode, 'fillopacity', 1000, 1, 0)
self.animObj.start()
covernode.unlink(True)
return
I'm calling it with:
def _enter(self):
(some other stuff here)
print "Let's get started!"
self.playAnim(self.animArr)
print "Your turn!"
Any help is greatly appreciated, the libavg Reference isn't helping me much.
The problem is that anim.start() is non-blocking.
Instead of only returning after the animation is finished, it will return immediately and the animation will be executed concurrently. This means at the same time your function starts two animations and unlinks the node that should be animated.
So instead you should use the end callbacks that can be given to the animations to trigger one step after another. The the blink function could then look like this:
def blink(self, node):
pos = node.pos
size = node.size
covernode = avg.RectNode(pos=pos, size=size, fillopacity=0,
parent = self._parentNode, fillcolor="ffffff",
color="000000", strokewidth=2)
fadeOutAnim = LinearAnim(covernode, 'fillopacity', 1000, 1, 0, False,
None, covernode.unlink)
fadInAnim= LinearAnim(covernode, 'fillopacity', 1000, 0, 1, False,
None, fadeOutAnim.start)
fadInAnim.start()
If you want the node to stay white for a certain amount of time you have to insert another step using either a WaitAnim or player.setTimeout().
(https://www.libavg.de/reference/current/player.html#libavg.avg.Player)
def blink(self, node):
pos = node.pos
size = node.size
covernode = avg.RectNode(pos=pos, size=size, fillopacity=0,
parent = self._parentNode, fillcolor="ffffff",
color="000000", strokewidth=2)
fadeOutAnim = LinearAnim(covernode, 'fillopacity', 1000, 1, 0, False,
None, covernode.unlink
)
fadInAnimObj = LinearAnim(covernode, 'fillopacity', 1000, 0, 1, False,
None, lambda:self.wait(500, fadeOutAnim.start)
)
fadInAnimObj.start()
def wait(self, time, end_cb):
avg.Player.get().setTimeout(time, end_cb)

pyOpenGL VBOs with index

I want to draw a Rectangle in pyOpenGL using VBOs with indices. I am using the glDrawRangeElements() function for that but I always get the same mistake in the line glDrawRangeElements:
WindowsError: exception: access violation reading 0x00000000
I tried a lot of things and was looking on the internet for the solution and was studying code examples all day so now I really do not know how to go on. It would be nice if someone here could help me.
This is should be the part of the code in which the error is created:
vertexPositions = [[-0.75, -0.75, 0.0],
[0.75, -0.75, 0.0],
[0.75, 0.75, 0.0],
[-0.75, 0.75, 0.0] ]
vertexIndices = [0, 1, 2,
1, 2, 3]
vertexComponents = 3
positionBufferObject = None
indexBufferObject = None
x = 0
def glGenVertexArray():
vao_id = GL.GLuint(0)
vertex_array_object.glGenVertexArrays(1, vao_id)
return vao_id.value
def initialize_vertex_buffer():
global positionBufferObject, indexBufferObject
indexBufferObject = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject)
array_type = (GL.GLushort * len(vertexIndices))
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, len(vertexIndices) * 2,
array_type(*vertexIndices), GL.GL_STATIC_DRAW)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0)
positionBufferObject = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, positionBufferObject)
array_type = (GL.GLfloat * len(vertexPositions))
GL.glBufferData(GL.GL_ARRAY_BUFFER,
len(vertexPositions[0])*len(vertexPositions)*sizeOfFloat,
array_type(*vertexPositions), GL.GL_STATIC_DRAW
)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
glBindVertexArray( glGenVertexArray() )
def init():
initialize_vertex_buffer()
def display():
global x
GL.glClearColor(0.0, 0.0, 0.0, 0.0)
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
GL.glEnableClientState(GL.GL_INDEX_ARRAY)
GL.glLoadIdentity()
GL.glTranslate(0, 0, -5)
GL.glRotate(x, 0, 1, 0)
GL.glBindVertexArray(glGenVertexArray())
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, positionBufferObject)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject)
GL.glEnableVertexAttribArray(0)
GL.glDrawRangeElements(GL.GL_TRIANGLES,0, 4, 6, GL.GL_UNSIGNED_SHORT, c_void_p(0))
#GL.glVertexAttribPointer(0, vertexComponents, GL.GL_FLOAT, False, 0, null)
#GL.glDrawArrays(GL.GL_QUADS, 0, len(vertexPositions) / vertexComponents)
GL.glDisableVertexAttribArray(0)
GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
GL.glDisableClientState(GL.GL_INDEX_ARRAY)
pygame.display.flip()
I have to admit that do not really have a clue of all these things yet, just trying to understand it because I need it for a project, so if there are any additional mistakes I have overlooked so far please tell my ;)
Thanks in advance
Shouldn't your call:
GL.glBindVertexArray (glGenVertexArray())
be
GL.glBindVertexArray (GL.glGenVertexArray())
Also, you probably want to keep track of that vertex array so you can delete it later and free up the resources it uses.

Categories