Using french characters with pyRevit or RPS - revitpythonshell

I'd like to print dialogs in french using pyRevit scripts. As soon as I include an accent like "ê" in my code, the pyRevit script doesn't even execute.
But if I do for instance print "être" in RevitPythonShell, no problem.
Why? Why the different treatment, and can it be handeled with pyRevit?
Thanks a lot,
Arnaud.

It is all about encoding and decoding. I reccommend you to read this nice article on the subject : http://sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/
You should prefix all your scripts with : # coding: utf8
# coding: utf8
__title__ = "TextEncoding"
print("être")
PyRevit output :

Im not sure about PyRevit, but I can use French characters when making Revit Dialogs in the RevitPythonShell like this:
dialog = TaskDialog("être")
dialog.MainContent = "être"
dialog.Show()
And when using Winforms like this:
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form, Label
form = Form()
form.Width = 300
form.Height = 100
label = Label()
label.Text = 'Here is some French Text: "être"'
label.Width = 280
label.Height = 70
label.Parent = form
form.ShowDialog()
Could you post some code showing in what instance it fails?

Related

Update a field within a NamedTuple (from typing)

I'm looking for a more pythonic way to update a field within a NamedTuple (from typing).
I get field name and value during runtime from a textfile und therefore used exec, but I believe, there must be a better way:
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
from typing import NamedTuple
class Template (NamedTuple):
number : int = 0
name : str = "^NAME^"
oneInstance = Template()
print(oneInstance)
# If I know the variable name during development, I can do this:
oneInstance = oneInstance._replace(number = 77)
# I get this from a file during runtime:
para = {'name' : 'Jones'}
mykey = 'name'
# Therefore, I used exec:
ExpToEval = "oneInstance = oneInstance._replace(" + mykey + " = para[mykey])"
exec(ExpToEval) # How can I do this in a more pythonic (and secure) way?
print(oneInstance)
I guess, from 3.7 on, I could solve this issue with dataclasses, but I need it for 3.6
Using _replace on namedtuples can not be made "pythonic" whatsoever. Namedtuples are meant to be immutable. If you use a namedtuple other developers will expect that you do not intent to alter your data.
A pythonic approach is indeed the dataclass. You can use dataclasses in Python3.6 as well. Just use the dataclasses backport from PyPi.
Then the whole thing gets really readable and you can use getattrand setattr to address properties by name easily:
from dataclasses import dataclass
#dataclass
class Template:
number: int = 0
name: str = "^Name^"
t = Template()
# use setattr and getattr to access a property by a runtime-defined name
setattr(t, "name", "foo")
print(getattr(t, "name"))
This will result in
foo

Revit Python Shell - Change Parameter Group

I'm trying to write a quick script to open a family document, change the parameter group of 2 specified parameters, and then close and save the document. I've done multiple tests and I am able to change the parameter groups of the specified parameters, but the changes of the groups don't save back to the family file. When I open the newly saved family, the parameter groups revert back to their original group.
This is with Revit 2017.2.
The same script, when run in RPS in Revit 2018 will do as desired.
import clr
import os
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import UIApplication
from System.IO import Directory, SearchOption
searchstring = "*.rfa"
dir = r"C:\Users\dboghean\Desktop\vanity\2017"
docs = []
if Directory.Exists(dir):
files = Directory.GetFiles(dir, searchstring, SearchOption.AllDirectories)
for f in files:
name, extension = os.path.splitext(f)
name2, extension2 = os.path.splitext(name)
if extension2:
os.remove(f)
else:
docs.append(f)
else:
print("Directory does not exist")
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
uiapp = UIApplication(app)
currentPath = doc.PathName
pgGroup = BuiltInParameterGroup.PG_GRAPHICS
for i in docs:
doc = app.OpenDocumentFile(i)
paramList = [i for i in doc.FamilyManager.Parameters]
t = Transaction(doc, "test")
t.Start()
for i in paramList:
if i.Definition.Name in ["Right Sidesplash Edge line", "Left Sidesplash Edge line"]:
i.Definition.ParameterGroup = pgGroup
t.Commit()
doc.Close(True)
Any ideas?
Thanks!
I can confirm that this happens in Revit 2017. Strange!
A simple way around it is to arbitrarily rename the parameter using doc.FamilyManager.RenameParameter, then rename it back to the original name.
So in your case this would be three additional lines of code after changing the Parameter group:
originalName = i.Definition.Name
doc.FamilyManager.RenameParameter(i, "temp")
doc.FamilyManager.RenameParameter(i, originalName)
Doesnt get to the root problem, but works around it

Django Haystack with elasticsearch returning empty queryset while data exists

I am doing a project in Python, django rest framework. I am using haystack SearchQuerySet. My code is here.
from haystack import indexes
from Medications.models import Salt
class Salt_Index(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
name = indexes.CharField(model_attr='name',null=True)
slug = indexes.CharField(model_attr='slug',null=True)
if_i_forget = indexes.CharField(model_attr='if_i_forget',null=True)
other_information = indexes.CharField(model_attr='other_information',null=True)
precautions = indexes.CharField(model_attr='precautions',null=True)
special_dietary = indexes.CharField(model_attr='special_dietary',null=True)
brand = indexes.CharField(model_attr='brand',null=True)
why = indexes.CharField(model_attr='why',null=True)
storage_conditions = indexes.CharField(model_attr='storage_conditions',null=True)
side_effects = indexes.CharField(model_attr='side_effects',null=True)
def get_model(self):
return Salt
def index_queryset(self, using=None):
return self.get_model().objects.all()
and my views.py file is -
from django.views.generic import View
from haystack.query import SearchQuerySet
from django.core import serializers
class Medication_Search_View(View):
def get(self,request,format=None):
try:
get_data = SearchQuerySet().all()
print get_data
serialized = ss.serialize("json", [data.object for data in get_data])
return HttpResponse(serialized)
except Exception,e:
print e
my python manage.py rebuild_index is working fine (showing 'Indexing 2959 salts') but in my 'views.py' file , SearchQuerySet() is returning an empty query set...
I am very much worried for this. Please help me friends if you know the reason behind getting empty query set while I have data in my Salt model.
you should check app name it is case sensitive.try to write app name in small letters
My problem is solved now. The problem was that i had wriiten apps name with capital letters and the database tables were made in small letters(myapp_Student). so it was creating problem on database lookup.

Python/Tkinter How to update information in grid

I'm running Python 3.2.2 and writing some code to test sockets. For the ease of testing, I'm using Tkinter to add a GUI interface. What I have yet to figure out is how to update the information in the grid I'm using. I want to update "host2" and "port2" in the functions "change1" and "change3" in the following code:
import socket
from tkinter import *
import tkinter.simpledialog
root = Tk()
root.title("Server")
root.iconbitmap("etc.ico")
root.geometry("350x100+200+200")
frame = Frame(root)
host1 = Label(frame,text="Host: ").grid(row=0,column=0)
port1 = Label(frame,text="Port: ").grid(row=1,column=0)
HOST = 'localhost'
PORT = 11111
STATUS = 'EMPTY'
host2 = Label(frame,text=HOST,width=10).grid(row=0,column=1)
port2 = Label(frame,text=PORT,width=10).grid(row=1,column=1)
status1 = Label(root,text=STATUS)
status1.pack(side=RIGHT,padx=2,pady=2)
def change1():
global HOST
HOST= tkinter.simpledialog.askstring(title="Host",prompt="Enter the IP of the Host.")
host2.grid_forget()
def change3():
global PORT
PORT= tkinter.simpledialog.askinteger(title="Port",prompt="Enter the Port of the IP.")
port2.grid_forget()
def go1():
global HOST
global PORT
home = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
home.bind((HOST, PORT))
home.listen(1)
conn, addr = home.accept()
print (addr)
while 1:
data = conn.recv(1024)
if not data: break
global STATUS
STATUS = data.decode('UTF-8')
conn.send(bytes('Received "Hello World"','UTF-8'))
conn.close()
global status1
status1.pack_forget()
status1.pack(side=RIGHT,padx=2,pady=2)
change = Button(frame, text="Change Host", width=10,command=change1).grid(row=0,column=2)
change2 = Button(frame, text="Change Port", width=10,command=change3).grid(row=1,column=2)
go = Button(frame, text="GO!",command=go1,width =10).grid(row=2,column=2)
frame.pack(side=LEFT)
mainloop()
Any help on the matter would be much appreciated! Thanks!
Your problems begin with this line:
host1 = Label(frame,text="Host: ").grid(row=0,column=0)
What you are doing is creating a label, using grid to place the label on the screen, then assigning host1 the result of the grid() command, which is the empty string. This makes it impossible to later refer to host1 to get a reference to the label.
Instead, you need to save a reference to the label. With that reference you can later change anything you want about the label:
host1 = Label(frame, text="Host: ")
host1.grid(row=0, column=0)
...
if (something_has_changed):
host1.configure(text="Hello, world!")
Take it from someone with over a decade of experience with tk, it's better to separate your widget creation and layout. Your layout will almost certainly change over the course of development and it's much easier to do that when all your layout code is in one place. My layouts may change a lot but my working set of widgets rarely does, so I end up only having to change one block of code rather than dozens of individual lines interleaved with other code.
For example, my code generally looks roughly like this:
labell = tk.Label(...)
label2 = tk.Label(...)
entry1 = tk.Entry(...)
label1.grid(...)
label2.grid(...)
entry1.grid(...)
Of course, I use much better variable names.
First, before going in depth with this problem. I want to highlight out a few things. In this line.
host2 = Label(frame,text=HOST,width=10).grid(row=0,column=1)
I want you to separate the gridding part from the declaration of the variable. Because it will create a No Type object that you cant work with. It will create many problems in the future that may take a lot of your time. If you have any variables structured like this that are not just going to be served as lines of text. Change the structure of that of that variable to the structure that I described above. Anyways, going back to what you where saying but in more depth is that to change the text of the Labels. What I would do if its going to be changed by function is in that function that you are wanting to change the text of the Label. Put in lines like this.
host2['text'] = 'Your New Text'
port2['text'] = 'Your New Text'
# or
host2.configure(text = 'Your New Text')
port2.configure(text = 'Your New Text')
This will change the text of your labels to the newly changed text or In other words replaces the text with the new text.

How to export an R citation output into endnote?

How can I easily import citations from R into endnote obtained by for instance
citation("ggplot2")
Is there a good workflow for this or do I manually have to do it?
How automated this can be will depend on what Endnote can import. It seems BibTeX import is not currently possible out of the box, and requires some extra software. See for example: http://www.lib.uts.edu.au/content/faq/how-can-i-import-bibliography-endnote-bibtex-latex-what-about-converting-other-way-endno
Read ?bibentry and in particular the argument style and the Details section. See if Endnote can import data in any of those formats? I doubt it, but I have never used Endnote.
If not, we can go the BibTeX route if you install something that allows you to import BibTeX into Endnote.
> utils:::print.bibentry(citation("ggplot2"), style = "Bibtex")
#Book{,
author = {Hadley Wickham},
title = {ggplot2: elegant graphics for data analysis},
publisher = {Springer New York},
year = {2009},
isbn = {978-0-387-98140-6},
url = {http://had.co.nz/ggplot2/book},
}
To get this out into a file for passing to an import utility, you can use capture.output()
capture.output(utils:::print.bibentry(citation("ggplot2"), style = "Bibtex"),
file = "endnote_import.bib")
Which gives a file with the following content:
$ cat endnote_import.bib
#Book{,
author = {Hadley Wickham},
title = {ggplot2: elegant graphics for data analysis},
publisher = {Springer New York},
year = {2009},
isbn = {978-0-387-98140-6},
url = {http://had.co.nz/ggplot2/book},
}
which you should be able to import with third party tools.

Resources