calling a function from another file - python

I'm writing a code on python where I must import a function from other file. I write import filename and filename.functionname and while I'm writing the first letter of the function name a window pops up on PyCharm showing me the full name of the function, so I guess Python knows that the file has the function I need. When I try it on console it works. But when I run the same thing on my code it gives an error: 'module' object has no attribute 'get_ecc'. what could be the problem? The only import part is the last function, make_qr_code.
""" Create QR error correction codes from binary data, according to the
standards laid out at http://www.swetake.com/qr/qr1_en.html. Assumes the
following when making the codes:
- alphanumeric text
- level Q error-checking
Size is determined by version, where Version 1 is 21x21, and each version up
to 40 is 4 more on each dimension than the previous version.
"""
import qrcode
class Polynomial(object):
""" Generator polynomials for error correction.
"""
# The following tables are constants, associated with the *class* itself
# instead of with any particular object-- so they are shared across all
# objects from this class.
# We break style guides slightly (no space following ':') to make the
# tables easier to read by organizing the items in lines of 8.
def get_ecc(binary_string, version, ec_mode):
""" Create the error-correction code for the binary string provided, for
the QR version specified (in the range 1-9). Assumes that the length of
binary_string is a multiple of 8, and that the ec_mode is one of 'L', 'M',
'Q' or 'H'.
"""
# Create the generator polynomial.
generator_coeffs = get_coefficients(SIZE_TABLE[version, ec_mode][1])
generator_exps = range(len(generator_coeffs) - 1, -1, -1)
generator_poly = Polynomial(generator_coeffs, generator_exps)
# Create the message polynomial.
message_coeffs = []
while binary_string:
message_coeffs.append(qrcode.convert_to_decimal(binary_string[:8]))
binary_string = binary_string[8:]
message_max = len(message_coeffs) - 1 + len(generator_coeffs) - 1
message_exps = range(message_max, message_max - len(message_coeffs), -1)
message_poly = Polynomial(message_coeffs, message_exps)
# Keep dividing the message polynomial as much as possible, leaving the
# remainder in the resulting polynomial.
while message_poly.exps[-1] > 0:
message_poly.divide_by(generator_poly)
# Turn the error-correcting code back into binary.
ecc_string = ""
for item in message_poly.coeffs:
ecc_string += qrcode.convert_to_binary(item, 8)
return ecc_string

Related

Ren'py / Python - insert dynamic variable in class with a while loop - without overwriting with append

I'm currently trying to get into Python and Ren'Py a bit. Since I like to design a lot dynamically
and don't want to use copy&paste so often, I'm trying to create a page that will have ImageButtons with the corresponding number I specify.
In the example below I use "4" - but this can be higher.
I have built a class for this purpose:
Example:
init python:
class PictureSettings(object):
def __init__ (self, ImgIdle, ImgHover, LabelCall):
self.ImgIdle = ImgIdle
self.ImgHover = ImgHover
self.LabelCall = LabelCall
return
For the Idle/Hover and for the Jump.
If I insert in the code now in an object each entry "manually" with append I get all 4 pictures as desired indicated.
Example: (Works - but is not dynamic)
python:
var_pictures = []
var_pictures.append(PictureSettings("img_picture_1_idle", "img_picture_1_hover", "picture_1"))
var_pictures.append(PictureSettings("img_picture_2_idle", "img_picture_2_hover", "picture_2"))
var_pictures.append(PictureSettings("img_picture_3_idle", "img_picture_3_hover", "picture_3"))
var_pictures.append(PictureSettings("img_picture_4_idle", "img_picture_4_hover", "picture_4"))
I would like it to be like this:
Example (Here I get only ""img_picture_4_idle", "img_picture_4_hover", "picture_4""):
$ countlimit = 4
$ count = 1
python:
while count < countlimit:
var_pictures = []
var_pictures.append(PictureSettings(
ImgIdle = "img_picture_[count]_idle",
ImgHover = "img_picture_[count]_hover",
LabelCall = "picture_[count]"))
count += 1
Have already tried various things, unfortunately without success.
For example: with Add - instead of append (because this overwrites the result and leaves only the last entry
I get the following error:
var_pictures.add(PictureSettings( AttributeError: 'RevertableList' object has no attribute 'add')
Maybe someone can help me with the solution so I can keep my code dynamic without copying something X times.
Thanks for your help
You are creating your list inside your loop, so it is recreated every time.
At the end, you only get the last created list.
var_pictures = []
while count < countlimit:
var_pictures.append(PictureSettings(
ImgIdle = "img_picture_[count]_idle",
ImgHover = "img_picture_[count]_hover",
LabelCall = "picture_[count]"))
count += 1
On another subject, if you want to do this in a more pythonic way:
pictures = [] # no need for var_, we know its a variable
for i in range(1, 5):
pictures.append(PictureSettings(
# in python, we prefere snake_case attributes
img_idle=f'img_picture_{i}_idle',
img_hover=f'img_picture_{i}_hover',
...
))
# or even shorter with list comprehension
pictures = [
PictureSettings(
img_idle=f'img_picture_{i}_idle',
)
for i in range(1, 5)
]
By the way, no need to return in your class constructor

Why are wrong bits extracted in python?

I need several k bits at position p extracted in order to convert to decimal value. I use a standard function but still when I test it for a 6/7/8 byte long binary code it is not correct. When I have a 1 byte code it is little-endian but once I use a 8 byte code it is shifted. For one signal (of a 7byte code) it was shifted +7bits but another signal (another ID, 8byte code) was shifted by -21bits. I cannot explain this to myself so I thought of playing around and manually add or subtract bits in order to use the correct bits for calculation. Do you have any idea why this is happening?
Example 8bytes:
extract_k_bits('100001111000000001110111011001000111011111111000001110100111101',16,0)
Output: 001110100111101 instead of 1000011110000000
extract_k_bits('100001111000000001110111011001000111011111111000001110100111101',16,24)
Output: 0110010001110111 instead of 1011001000111011
This is the code I am working with:
import openpyxl
from openpyxl import Workbook
theFile = openpyxl.load_workbook('Adapted_T013.xlsx')
allSheetNames = theFile.sheetnames
print("All sheet names {} " .format(theFile.sheetnames))
sheet = theFile.active
def extract_k_bits(inputBIN,k,p):
end = len(inputBIN) - p
start = end - k + 1
kBitSub = inputBIN[start : end+1]
print(kBitSub)
Dec_Values=int(kBitSub,2)
Here's a working solution:
def extract_k_bits(inputBIN,k):
# Since you always extract 16 bits
# just use the point where you want to extract from
kBitSub = inputBIN[k : k+16]
print(kBitSub)
extract_k_bits('100001111000000001110111011001000111011111111000001110100111101',0)
extract_k_bits('100001111000000001110111011001000111011111111000001110100111101',23)
Output

Retrieve output parameters from an AutoCAD API method in python

I'm trying to retrieve 2 output Arrays from an XRecord in AutoCAD 2016 using python 2.7, with comtypes imported, the first array is an array of integers (DXF Group Codes) and the second array is an array of variants (the values of XRecord).
The opposite way of what this question seeks to
The method of interest is GetXRecordData, which (according to AutoCAD's documentation) if successful returns None, and only accepts 2 output arguments.
when I try to retrieve it with code like
DxfGrCd = []
vals = []
an_XRecord.GetXRecordData(DxfGrCd, vals)
and see the values of DxfGrCd and vals I found no change happened to them, both of them still equal to [], the same is also with
DxfGrCd = {}
vals = {}
anXRecord.GetXRecordData(DxfGrCd, vals)
also no change is applied on them, both of them still equal to {}, even though dictionaries and lists are mutable.
Is there any way to deal with that kind of methods in python?
Well, I haven't figured out any way to do so from python, however, since the data stored in XRecords are just numbers and strings (in my application), stored in the XRecord as variants, I've used MS Excel as a middle man to pass me data.
Note: All numbers I've got were retrieved but as floats.
And all strings were retrieved but their type is unicode. (you can convert them to string easily with the built-in function str())
Here's how I've done that.
First: Creation of The Facilitator Workbook (Our Middle Man)
1-Normally as a regular windows user, open Excel, then open Visual Basic Editor, one way to do that is to go to Developer tab and click on Visual Basic Editor.
2-From the Editor, insert a module (one way is from the menu bar: insert>Module), then left-double click on its default name and type "mod_facilitate", then hit Enter.
3-Left-double click on its icon at the project viewer.
4- A window will appear, copy the following code to it.
Sub getxrecord()
'get running AutoCAD object
Dim mycad As AcadApplication, mydoc As AcadDocument, filepath As String
Set mycad = GetObject(, "AutoCAD.Application.20")
'get the selected drawing, provided from python code
With Sheet1
filepath = .Range(.Cells(1, 1), .Cells(1, 1)).Value
End With
Dim iCount As Integer, i As Integer, j As Integer, CompName As String
iCount = mycad.Documents.Count
For i = 0 To iCount - 1
CompName = mycad.Documents.Item(i).FullName
If CompName Like filepath Then
j = i
Exit For
End If
Next i
Set mydoc = mycad.Documents.Item(j)
Dim name2 As String
'get the object from its provided handle
With Sheet1
handler = .Range(.Cells(2, 1), .Cells(2, 1)).Value
End With
Dim myXRecord As AcadXRecord
Set myXRecord = mydoc.HandleToObject(handler)
Dim DxfGrcd As Variant, Val As Variant
DxfGrcd = Array()
Val = Array()
myXRecord.GetXRecordData DxfGrcd, Val
Dim UB As Integer
UB = UBound(DxfGrcd)
For i = 0 To UB
With Sheet1
.Range(.Cells((i + 1), 2), .Cells((i + 1), 2)).Value = DxfGrcd(i)
.Range(.Cells((i + 1), 3), .Cells((i + 1), 3)).Value = Val(i)
End With
Next i
End Sub
5- From Tools>References Select these reference names, leaving the others at their previous states
AcSmComponents20 1.0 Type Library
AutoCAD 2016 Type Library
CAO 1.0 Type Library
Then click on OK, then hit Ctrl+s to save.
6- Save the file and name it "facilitator", save it within the same directory of your python file. Save it of type Excel Macro-Enabled Workbook (has the extension .xlsm)
7- At your python file, define the function to retrieve XRecord's data as following, I'll tell what are its arguments for:
def XRecord_return(namefile,handle,size):
xl.Range["A1"].Value[xlRangeValueDefault] = namefile
xl.Range["A2"].Value[xlRangeValueDefault] = handle
xl.Application.Run("facilitator.xlsm!mod_facilitate.getxrecord")
dxfgrcd = []
vals = []
for i in range(0,size):
CellB = 'B' + str(i+1)
CellC = 'C' + str(i+1)
dxfgrcd.append(xl.Range[CellB].Value[xlRangeValueDefault])
vals.append(xl.Range[CellC].Value[xlRangeValueDefault])
return dxfgrcd,vals
Second: What to Insure
Note: All the following steps must be written before the definition of XRecord_return
1- AutoCAD must be instantiated from python using a line like autocad = CreateObject("AutoCAD.Application.20",dynamic=True) or autocad = comtypes.client.CreateObject("AutoCAD.Application.20",dynamic=True) depending on the scope of importing and importing form [ import comtypes.client or from comtypes.client import CreateObject ], here, importing scope is the python file's module scope.
2-instantiate Excel using xl = CreateObject("Excel.Application") and open the facilitator file with
xlpath = os.getcwd()
xlpath += '\\facilitator.xlsm'
xl = CreateObject("Excel.Application")
from comtypes.gen.Excel import xlRangeValueDefault
xlwb = xl.Workbooks.Open(Filename=xlpath,ReadOnly=0)
3- You have to know how many elements are stored in the XRecord (excluding the number of associated DXF group codes), this number of elements is what you'll supply to XRecord_return as its size argument.
e.g. An XRecord that stores 3.0 "abc" 5 and have correspondent DXF group codes 1 2 3 is of size 3, not 6.
Third: Supplying Data to The Facilitator Workbook
We need only its first worksheet, you must provide the following data:-
1- The drawing's full path/directory to cell "A1".
To get the drawing's full path if you have its Document object you can get it from the property FullName. This value is what you'll supply to XRecord_return as its namefile argument.
To assign, for instance: xl.Range["A1"].Values[xlRangeValueDefault] = filepath
2-The XRecord's handle value to cell "A2", you can get it from the property Handle of the XRecord. This value is what you'll supply to XRecord_return as its 'handle' argument.
To assign, for instance: xl.Range["A1"].Values[xlRangeValueDefault] = handlevalue
3- After that, wherever you need to get the XRecords data, call the XRecord_return function, like
DxfGrCd,vals = XRecord_return(filepath,handlevalue,size_of_XRecord)
The outputs are lists that contain the correspondent data.
Last, But not Least
When you finish using Excel for retrieving data from as many XRecords as you need, close the facilitator workbook using xlwb.Close(SaveChanges=0)

From Python Code to a Working Executable File (Downsizing Grid Files Program)

I posted a question earlier about a syntax error here Invalid Syntax error in Python Code I copied from the Internet. Fortunately, my problem was fixed really fast thanks to you. However now that there is no syntax error I found myself helpless as I don't know what to do now with this code. As I've said I've done some basic Python Training 3 years ago but the human brain seems to forget things so fast.
So in a few words, I need to reduce the grid resolution of some files to half and I've been searching for a way to do it for weeks. Luckily I found some python code that seems to do exactly what I am looking for. The code is this :
#!/bin/env python
# -----------------------------------------------------------------------------
# Reduce grid data to a smaller size by averaging over cells of specified
# size and write the output as a netcdf file. xyz_origin and xyz_step
# attributes are adjusted.
#
# Syntax: downsize.py <x-cell-size> <y-cell-size> <z-cell-size>
# <in-file> <netcdf-out-file>
#
import sys
import Numeric
from VolumeData import Grid_Data, Grid_Component
# -----------------------------------------------------------------------------
#
def downsize(mode, cell_size, inpath, outpath):
from VolumeData import fileformats
try:
grid_data = fileformats.open_file(inpath)
except fileformats.Uknown_File_Type as e:
sys.stderr.write(str(e))
sys.exit(1)
reduced = Reduced_Grid(grid_data, mode, cell_size)
from VolumeData.netcdf.netcdf_grid import write_grid_as_netcdf
write_grid_as_netcdf(reduced, outpath)
# -----------------------------------------------------------------------------
# Average over cells to produce reduced size grid object.
#
# If the grid data sizes are not multiples of the cell size then the
# final data values along the dimension are not included in the reduced
# data (ie ragged blocks are not averaged).
#
class Reduced_Grid(Grid_Data):
def __init__(self, grid_data, mode, cell_size):
size = map(lambda s, cs: s / cs, grid_data.size, cell_size)
xyz_origin = grid_data.xyz_origin
xyz_step = map(lambda step, cs: step*cs, grid_data.xyz_step, cell_size)
component_name = grid_data.component_name
components = []
for component in grid_data.components:
components.append(Reduced_Component(component, mode, cell_size))
Grid_Data.__init__(self, '', '', size, xyz_origin, xyz_step,
component_name, components)
# -----------------------------------------------------------------------------
# Average over cells to produce reduced size grid object.
#
class Reduced_Component(Grid_Component):
def __init__(self, component, mode, cell_size):
self.component = component
self.mode = mode
self.cell_size = cell_size
Grid_Component.__init__(self, component.name, component.rgba)
# ---------------------------------------------------------------------------
#
def submatrix(self, ijk_origin, ijk_size):
ijk_full_origin = map(lambda i, cs: i * cs, ijk_origin, self.cell_size)
ijk_full_size = map(lambda s, cs: s*cs, ijk_size, self.cell_size)
values = self.component.submatrix(ijk_full_origin, ijk_full_size)
if mode == 'ave':
m = average_down(values, self.cell_size)
I have this saved as a .py file and when I double click it, the command prompt appears for a milisecond and then disappears. I managed to take a screenshot of that command prompt which it says "Unable to create process using 'bin/env python "C:\Users...........py".
What I want to do is to be able to do this downsizing using the Syntax that the code tells me to use :
# Syntax: downsize.py <x-cell-size> <y-cell-size> <z-cell-size>
# <in-file> <netcdf-out-file>
Can you help me ?
Don't run the file by double-clicking it. Run the file by opening a new shell, and typing in the path to the .py file (or just cd to the parent directory) followed by the arguments you want to pass. For example:
python downsize.py 1 2 3 foo bar

Python: How to return an instance of an object along with attributes assigned with setattr

I am still very new to python, but I need to interface with some software that is written as a bunch of python modules (.py files in case I incorrectly identified them as "modules.") This program has some very useful and complicated functions that I really cannot feasibly hack (if nothing else, because every time I update the software, I will have to re-hack everything.)
I have a python script that looks like this:
from software import thingfromsoftware
def mything(x,y,someboolean=True,etc)
var=thingfromsoftware(x,y)
#....code....
setattr(var, 'dimensions', somearraything)
return(var)
Then, if I try:
result=mything(4,5)
then result correctly contains the values of all the attributes first assigned to it via thingfromsoftware but result.dimensions has not been assigned (has no attribute "dimensions")
The goal is to store the dimensions of every result computed and configured by myfunctionthing in some semi-coherent manner.
Real code (upon request)
from ase.structure import nanotube
from ase import Atoms, view, io
from numpy import *
from Avogadro import Molecule, MoleculeFile
import cPickle as pickle
import os
def make_nanotube(n,m,length=1,TYPE='free'):
#This will set up leads so transport occures along the z axis and leads are aligned along the y axis (so they may be separated along the x axis.)
os.chdir("/tmp")
print 'Making ('+str(n)+','+str(m)+') nanotube with '+str(length)+" unit cell as "+str(TYPE)
tube = nanotube(n, m, length=length, bond=1.420, symbol='C')
center=tube.get_center_of_mass()
name='tube:('+str(n)+', '+str(m)+'):unit cells:'+str(length)+':'+str(TYPE)+'.xyz'
io.write(str(name), tube)
print 'Computing bonds'
mol = MoleculeFile.readMolecule(str(name))
RELOAD=0
for atom in mol.atoms[:]:
if len(atom.bonds)<2 and atom.pos[-1]<center[-1]:
print 'Relocating atom '+str(atom.index)+' from '+str(atom.pos[-1])+' to '+str(tube.get_cell()[-1, -1] + atom.pos[-1])
tube.positions[atom.index, -1] += tube.get_cell()[-1, -1]
RELOAD=1
print 'Orienting tube'
tip_atom=tube.get_positions()[:, -1].argmax() #the tip on the right (farther) end
tip=tube.get_positions()[tip_atom]
tube.rotate(append(tip[:-1], 0), append(center[0], zeros(2)), center=center) #rotate so that the tip is slanted toward x-axis (center[0],0,0)
tube.center()
setattr(tube, 'dimensions', [tube.get_cell()[0, 0]/2,tube.get_cell()[-1,-1]])
cell=tube.get_cell()
if TYPE!='bare':
if RELOAD==1:
print 'Recomputing bonds'
io.write(str(name), tube)
mol = MoleculeFile.readMolecule(str(name))
print 'Adding hydrogens'
mol.addHydrogens()
if TYPE=='left lead':
print 'Removing hydrogens from the right side'
for atom in mol.atoms[:]:
if atom.pos[2]<center[2]:
mol.removeHydrogens(atom)
elif TYPE=='right lead':
print 'Removing hydrogens from the left side'
for atom in mol.atoms[:]:
if atom.pos[2]>center[2]:
mol.removeHydrogens(atom)
MoleculeFile.writeMolecule(mol,str(name))
tube=io.read(str(name))
else:
tube.set_cell(cell)
return(tube)
You're doing
tube=io.read(str(name))
if
TYPE!='bare'
So in that case you wouldn't get the dimensions. Could this be why you're having the problem?
Also, have you tried just doing
tube.dimensions = [tube.get_cell()[0, 0] / 2, tube.get_cell()[-1,-1]]
instead of setattr? It's only needed when the name of the attribute to change is stored in a variable name.

Categories