Call overloaded methods from Ironpython - overloading

I would like to call the Curve.Trim(CurveEnd, Double) method from the RhinoCommon API via IronPython. How can I make sure I don't get the overload for Curve.Trim(Double, Double)?
crv.Trim(geo.CurveEnd.End, 8.8)
#raised: Message: expected float, got CurveEnd
Note: If you want to try it yourself you will need to install a trial version of Rhino. It includes a Python editor.
Edit / Addition: the .Overloads property as mentioned by Jeff does not work here either. A snippet for testing:
import rhinoscriptsyntax as rs
import Rhino.Geometry as geo
import System
# first draw a curve longer than 8.8 units
crvO = rs.GetObject() # to pick that curve on the 3d GUI screen
crv = rs.coercecurve(crvO) # to get Rhino.Geometry.Curve
# these both don't work:
crv.Trim(geo.CurveEnd.End, 8.8)
#Message: expected float, got CurveEnd
crv.Trim.Overloads[geo.CurveEnd, System.Double](geo.CurveEnd.End, 8.8)
#Message: Trim() takes at least 2147483647 arguments (2 given)
rhinscriptsyntax is a library based on Rhino namespace from RhinoCommon

Use the .Overloads property to access a method's overloads:
csv.Trim.Overloads[CurveEnd, float](geo.CurveEnd.End, 8.8)
The docs.

I'm late to the party. But this code works (out the override).
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import System
crv_id = rs.GetObject()
crv = rs.coercecurve(crv_id)
trimmed = crv.Trim(Rhino.Geometry.CurveEnd.End, 4)
sc.doc.Objects.Replace(crv_id, trimmed)
sc.doc.Views.Redraw()

Related

Cannot iterate over AbstractOrderedScalarSet before it has been constructed (initialized)

I have just started with pyomo and Python, and trying to create a simple model but have a problem with adding a constraint.
I followed the following example from GitHub
https://github.com/brentertainer/pyomo-tutorials/blob/master/introduction/02-lp-pyomo.ipynb
import pandas as pd
import pyomo.environ as pe
import pyomo.opt as po
#DATA
T=3;
CH=2;
time = ['t{0}'.format(t+1) for t in range(T)]
CHP=['CHP{0}'.format(s+1) for s in range(CH)]
#Technical characteristic
heat_maxprod = {'CHP1': 250,'CHP2': 250} #Only for CHPS
#MODEL
seq=pe.ConcreteModel
### SETS
seq.CHP = pe.Set(initialize = CHP)
seq.T = pe.Set(initialize = time)
### PARAMETERS
seq.heat_maxprod = pe.Param(seq.CHP, initialize = heat_maxprod) #Max heat production
### VARIABLES
seq.q_DA=pe.Var(seq.CHP, seq.T, domain=pe.Reals)
### CONSTRAINTS
##Maximum and Minimum Heat Production
seq.Heat_DA1 = pe.ConstraintList()
for t in seq.T:
for s in seq.CHP:
seq.Heat_DA1.add( 0 <= seq.q_DA[s,t])
seq.Heat_DA2 = pe.ConstraintList()
for t in seq.T:
for s in seq.CHP:
seq.Heat_DA2.add( seq.q_DA[s,t] <= seq.heat_maxprod[s])
### OBJECTIVE
seq.obj=Objective(expr=sum( seq.C_fuel[s]*(seq.rho_heat[s]*seq.q_DA[s,t]) for t in seq.T for s in seq.CHP))
When I run the program I am getting the following error:
RuntimeError: Cannot iterate over AbstractOrderedScalarSet 'AbstractOrderedScalarSet' before it has been constructed (initialized): 'iter' is an attribute on an Abstract component and cannot be accessed until the component has been fully constructed (converted to a Concrete component) using AbstractModel.create_instance() or AbstractOrderedScalarSet.construct().
Can someone, please, help with an issue? Thanks!
P.S. I know that the resulting answer for the problem is zero, I just want to make it work in terms of correct syntaxis.
In this line of code:
seq=pe.ConcreteModel
You are missing parenthesis. So, I think you are just creating an alias for the function instead of calling it.
Try:
seq=pe.ConcreteModel()

Error: undeclared field: 'captures' for type nre.RegexMatch

I'm trying to match a given string with nre:
from nre import findIter, re
const sourceString = """
39
00:04:01,116 --> 00:04:01,783
Attrape.
"""
let srtRex = re"\d+\R\d+:\d+:\d+,\d+ --> \d+:\d+:\d+,\d+\R(\w+)"
for m in findIter(sourceString, srtRex, 0):
echo(m.captures[0])
This doesn't compile though, it fails with Error: undeclared field: 'captures' for type nre.RegexMatch [declared in /usr/local/Cellar/nim/1.2.6/nim/lib/impure/nre.nim(149, 3)].
This is weird, because if I do echo(m), I get the raw strings, so the match itself worked fine. It's only this field I can't access. And that is weird, because in this issue the (working) example code is pretty much the same.
Importing whole modules is idiomatic in Nim, and leads to ambiguities rarely, thanks to a strong type system. see https://narimiran.github.io/2019/07/01/nim-import.html for a great rundown on why Nim doesn't share Python's import issues.
However, here's how to do what you want to do, even if it's not idiomatic Nim:
You're using more than just re and findIter, you also use the proc captures, and the [] proc, so your import line needs to be:
from nre import findIter, re, captures, `[]`
or, for complete namespace separation, but quite ugly, you can:
from nre import nil
let srtRex = nre.re"\d+\R\d+:\d+:\d+,\d+ --> \d+:\d+:\d+,\d+\R(\w+)"
for m in nre.findIter(sourceString, srtRex, 0):
echo(nre.`[]`(nre.captures(m),0))
It seems to be the imports. It works with import nre instead of from nre import findIter, re. But why? I want to keep my namespace clean!

Text Encoding Between Python File, Maya Script Editor, and Maya UI (Python 2.7, Maya 2015, Windows 7)

I've got a python file that I'm loading as a script into the maya script editor. The python file is currently encoded as UTF-8.
I have the need to use the ↑ and ↓ characters (or any other arrow substitutes within Unicode, such as ➘ or ➚, I just want to convey up and down). I'm using the characters as the label of a button. Here's the script:
import Maya.cmds as cmds
def initInterface():
cmds.window("mywin")
cmds.rowColumnLayout("my_rcl", nc=1)
cmds.button(label=u'\↑')
cmds.button(label=u'\↓')
cmds.showWindow("mywin")
initInterface()
The script is saved as myPythonScript.py and is then loaded into the Maya script editor using the load script button.
On execution, I get a UI window and buttons as expected, but the labels for the buttons are now "?" (question marks). I can't seem to get Maya to display the arrows.
To solve this, I've tried a couple of in-code things. Here are a few of my attempts:
# Attempt 1
upArrow = u'\↑'
upArrowEncoded = upArrow.encode("utf-8")
cmds.button(label=upArrowEncoded)
# Result: "?"
# Attempt 2
upArrow = u'\U+2B06'
cmds.button(label=upArrow)
# Result: "?B06"
# Attempt 3
upArrow = u'\U+2B06'
upArrowEncoded = upArrow.encode("utf-8")
cmds.button(label=upArrowEncoded)
# Result: "?"
To be honest (and is likely to be apparent from my code snippets) I've never experimented with text encoding and know next to nothing about it. I'm not sure if I need to change the encoding of my .py file, or encode the string with UTF-16 or something. This is way outside of my area of expertise and I'm having a hard time finding resources to help me understand text and string encoding.
I did check out this:
Unicode Within Maya
And this:
Convert a Unicode String to a String in Python Containing Extra Symbols
But I wasn't able to understand a lot of what I read, and I'm not sure if they relate to this issue or not.
I'm the type of person who doesn't enjoy using code I don't understand (how do people even document that?), so I'm here to ask for links to learning resources and for general advice on the subject, moreso than for a code snippet that does what I want. If it turns out this is not possible, I can use image buttons instead. But they are less efficient and time consuming to produce for each special character I may use.
Thank you for reading through this, and thank you in advance to anyone who can point me in the right direction here. Cheers!
As far as I can tell, the native MayaUi uses/has access to the Code Page 1252 Windows Latin 1 (ANSI) character set (at least on Windows...) as mentioned here, and after some noodling these *all appear to work as advertised.
I'd be curious to see an answer that explained how to change that and access what OP is looking for, but as an alternative to anyone that really truly wants more special characters, may I suggest learning PySide / Qt for building your UI.
Caveats
A lot more boilerplate and setup when it comes to making 'something simple'
Several mayaControls do not have direct Qt implementations (gradientControlNoAttr being a recent discovery, and case in point)
Example is written under the assumption that user has installed and uses Qt.py
Lets dive right in:
import maya.cmds as cmds
import maya.OpenMayaUI as omui
from Qt import QtCore, QtGui
from Qt.QtWidgets import *
from shiboken import wrapInstance
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(long(main_window_ptr), QWidget)
class TestUi(QDialog):
def __init__(self, parent=maya_main_window()):
super(TestUi, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
def create(self):
self.setWindowTitle("TestUi : Unicode")
self.setWindowFlags(QtCore.Qt.Tool)
self.create_controls()
self.create_layout()
self.create_connections()
def create_controls(self):
"""
Create the widgets for the dialog.
"""
# using "Python source code" unicode values
# ie: https://www.fileformat.info/info/unicode/char/2191/index.htm
self.up_button = QPushButton(u'\u2191')
self.down_button = QPushButton(u'\u2193')
self.left_button = QPushButton(u'\u2190')
self.right_button = QPushButton(u'\u2192')
def create_layout(self):
"""
Create the layouts & add widgets
"""
main_layout = QVBoxLayout()
main_layout.setContentsMargins(6, 6, 6, 6)
main_layout.addWidget(self.up_button)
main_layout.addWidget(self.down_button)
main_layout.addWidget(self.left_button)
main_layout.addWidget(self.right_button)
main_layout.addStretch()
self.setLayout(main_layout)
def create_connections(self):
"""
Create the signal/slot connections
"""
self.up_button.clicked.connect(self.on_button_pressed)
self.down_button.clicked.connect(self.on_button_pressed)
self.left_button.clicked.connect(self.on_button_pressed)
self.right_button.clicked.connect(self.on_button_pressed)
def on_button_pressed(self):
print "Button Pressed"
def LaunchUI():
if __name__ == "__main__":
# Development workaround for PySide winEvent error (Maya 2014)
# Make sure the UI is deleted before recreating
try:
test_ui.deleteLater()
test_ui.close()
except:
pass
# Create minimal UI object
test_ui = TestUi()
# Delete the UI if errors occur to avoid causing winEvent
# and event errors (in Maya 2014)
try:
test_ui.create()
test_ui.show()
except:
test_ui.deleteLater()
traceback.print_exc()
LaunchUI()
There's an awful lot to unpack there for not a terribly huge payoff, but the relevant piece of information is living under "create_controls".

Reportlab pdfgen support for bold truetype fonts

I have been using reportlab pdfgen to create dynamic pdf documents for printing. It has been working very well for a number of years.
We are having a fund raising event coming up, and wish to generate pdf receipts with the 'theme' font we are using (specifically talldeco.ttf).
I have set the font no problem using the following:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
ttfFile = "/usr/share/fonts/truetype/ttf-tall-deco/TALLDECO.TTF"
pdfmetrics.registerFont(TTFont("TallDeco", ttfFile))
p.setFont("TallDeco", 18) # Was Times-Bold...
Now comes the issue: some of the text needs to be bold and italics, and the talldeco just comes with 1 file (unlike some of the other fonts). I can bold and italicize text in this font in openoffice.
Per the reportlab users guide (http://www.reportlab.com/software/opensource/rl-toolkit/guide/) page 53, it should be possible and they show some code and the results, but our software is using drawString calls instead of paragraphs. A test app based on the sample noted above:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFontFamily
ttfFile = "/usr/share/fonts/truetype/ttf-tall-deco/TALLDECO.TTF"
pdfmetrics.registerFont(TTFont("TallDeco", ttfFile))
registerFontFamily('TallDeco',normal='TallDeco',bold='TallDeco-Bold',italic='TallDeco-Italic',boldItalic='TallDeco-BoldItalic')
p.setFont("TallDeco-Bold", 18) # Was Times-Bold...
Just gives a Key Error on 'TallDeco-Bold'.
Any suggestions?
TTFont has a subfontIndex parameter.
The following works for me (using reportlab 3.0 on OS X):
menlo_path = "/System/Library/Fonts/Menlo.ttc"
pdfmetrics.registerFont(ttfonts.TTFont("Menlo", menlo_path,
subfontIndex=0))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-Bold", menlo_path,
subfontIndex=1))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-Italic", menlo_path,
subfontIndex=2))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-BoldItalic", menlo_path,
subfontIndex=3))
pdfmetrics.registerFontFamily("Menlo", normal="Menlo", bold="Menlo-Bold",
italic="Menlo-Italic",
boldItalic="Menlo-boldItalic")
The bold, italic and boldItalic fonts need to be defined.
pdfmetrics.registerFont(TTFont("TallDeco-Bold", ttfFile))
pdfmetrics.registerFont(TTFont("TallDeco-Italic", ttfFile))
pdfmetrics.registerFont(TTFont("TallDeco-BoldItalic", ttfFile))
But because they all point to the same ttfFile the output will all look like the default TallDeco i.e. no bold or italic

django import a view function

I have a django application xxx which does a number of things.
I also have a sepaerate application yyy. Which wants to call one of the functions of xxx.
Is there a way for me to import the functions?
For example, in yyy can i say
from toplevel.xxx import doit
Or what is the best approach, I dont want to duplicate code.
Of course, you can fo it.
With a proper import and parameter, you can do it.
#app: app1
#someview.py
def a_view(request, someparam):
#some code here
#app: app2
#otherview.py
from app1.someview import a_view
def another_view(request):
param = 1
a_view(request, param)
As for an example
UPDATE: Wish to mention that, your function a_view() do not have to get a parameter at all. So you can call functions with no paramaters. I just wish to mention that, if your function have paramaters, you have to pass them as if you do within an application.