How to center printed text with pyfiglet in Python - python

I would want to print on the center text that has been made with py-figlet (https://github.com/pwaller/pyfiglet).
My code looks like this:
from pyfiglet import Figlet
f = Figlet(font='ascii___')
def DrawText(text):
return f.renderText(text)
print(DrawText('text')) <- Center it
On output I would want to have text printed on center with pyfiglet printing.

You can smartly use .center() with shutil module:
from pyfiglet import Figlet
import shutil
f = Figlet(font='ascii___')
def DrawText(text,center=True):
if center:
print(*[x.center(shutil.get_terminal_size().columns) for x in f.renderText(text).split("\n")],sep="\n")
else:
print(f.renderText(text))
DrawText('text',center=True)

You can use the keyword justify with 'auto', 'left', 'center', or 'right'
I did this:
import pyfiglet
txt = "title"
banner = pyfiglet.figlet_format(txt, font="slant", justify="center")
print(banner)
I couldn't find a decent documentation of the module.
So I had to dig through the code, and found the keywords for the FigletBuilder class constructor. It starts like this:
class FigletBuilder(object):
"""
Represent the internals of the build process
"""
def __init__(self, text, font, direction, width, justify):
self.text = list(map(ord, list(text)))
self.direction = direction
self.width = width
self.font = font
self.justify = justify
the OptionParser in the main() function (currently line 865), also gives an indication on how to use the keywords, just in case you want to learn more about how to use the keyword arguments, but don't want to scroll through about 1000 lines of code ^^

Related

Python tkinter print result can't complete

import filecmp
import os
import tkinter as tk
import tkinter.font as tkFont
from tkinter import *
def gg():
disk = (number_entry.get())
if disk == "2" :
DIRS = [r'C:\Newtest\1', r'C:\Newtest\2', r'C:\Newtest\3',r'C:\Newtest\4',r'C:\Newtest\5',r'C:\Newtest\6',r'C:\Newtest\7',r'C:\Newtest\8',r'C:\Newtest\9',r'C:\Newtest\10']
FILES = [('copy1.txt', 'copy2.txt'), ('fcmp1.txt', 'fcmp2.txt'), ('filecp1.txt', 'filecp2.txt')]
for e, dir in enumerate(DIRS, 1):
cmp = True
for file in FILES:
try:
if not filecmp.cmp(os.path.join(dir, file[0]), os.path.join(dir, file[1])):
cmp = False
break
except Exception as ex:
print(f'Error -> {ex}', file=sys.stderr)
continue
x = (f'E_{e} compare {"pass" if cmp else "fail"}')
print(x)
result_label.configure(text=x,wraplength=300,font=fontExample3)
DIRS = [r'C:\Newtest\1', r'C:\Newtest\2', r'C:\Newtest\3',r'C:\Newtest\4',r'C:\Newtest\5',r'C:\Newtest\6',r'C:\Newtest\7',r'C:\Newtest\8',r'C:\Newtest\9',r'C:\Newtest\10']
FILES = [('copy1.txt', 'copy2.txt'), ('fcmp1.txt', 'fcmp2.txt'), ('filecp1.txt', 'filecp2.txt')]
for e, dir in enumerate(DIRS, 1):
cmp = True
window = tk.Tk()
window.title('XXX')
window.geometry('1200x700')
window.configure(background='Azure')
fontExample = tkFont.Font(family="Segoe UI", size=20)
fontExample2 = tkFont.Font(family="Segoe UI", size=10)
fontExample3 = tkFont.Font(family="Segoe UI", size=15)
header_label = tk.Label(window, text='XXXX',font=fontExample)
header_label.pack()
number_frame = tk.Frame(window)
number_frame.pack(side=tk.TOP)
number_label = tk.Label(number_frame, text='Number of disks',font=fontExample2)
number_label.pack(side=tk.LEFT)
number_entry = tk.Entry(number_frame)
number_entry.pack(side=tk.LEFT)
result_label = tk.Label(window)
result_label.pack()
calculate_btn = tk.Button(window, text='First calculate', command=gg,font=fontExample3)
calculate_btn.pack()
window.mainloop()
Dear All ,
I have the question in the line:
result_label.configure(text=x,wraplength=300,font=fontExample3)
I want the result can print complete like my console.
Consele result is :
E_1 compare pass
E_2 compare fail
E_3 compare pass
E_4 compare pass
E_5 compare pass
E_6 compare pass
E_7 compare pass
E_8 compare pass
E_9 compare pass
E_10 compare fail
But in the tkinter result is -> E_10 compare fail
Please tolerate me as a newbie in tkinter.
Thanks!
If you want to add to the text that is already on the label, you can do this:
result_label.configure(text=result_label['text'] + x + '\n')
result_label['text'] returns the current text of the widget (equivalent to result_label.cget('text'))
You also don't need to configure wraplength and font each time, just do it once when creating the label like this:
result_label = tk.Label(window, wraplenght=300, font=fontExample3)
Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Have two blank lines around function and class declarations.

underline text with odfpy

I'd like to generate an odf file with odfpy, and am stuck on underlining text.
Here is a minimal example inspired from official documentation, where i can't find any information about what attributes can be used and where.
Any suggestion?
from odf.opendocument import OpenDocumentText
from odf.style import Style, TextProperties
from odf.text import H, P, Span
textdoc = OpenDocumentText()
ustyle = Style(name="Underline", family="text")
#uprop = TextProperties(fontweight="bold") #uncommented, this works well
#uprop = TextProperties(attributes={"fontsize":"26pt"}) #this either
uprop = TextProperties(attributes={"underline":"solid"}) # bad guess, wont work !!
ustyle.addElement(uprop)
textdoc.automaticstyles.addElement(ustyle)
p = P(text="Hello world. ")
underlinedpart = Span(stylename=ustyle, text="This part would like to be underlined. ")
p.addElement(underlinedpart)
p.addText("This is after the style test.")
textdoc.text.addElement(p)
textdoc.save("myfirstdocument.odt")
Here is how I finally got it:
I created a sample document with underlining using libreoffice, and unzipped it. Looking in styles.xml part of the extracted files, I got the part that makes underlining in the document:
<style:style style:name="Internet_20_link" style:display-name="Internet link" style:family="text">
<style:text-properties fo:color="#000080" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/>
</style:style>
The interesting style attributes are named: text-underline-style,
text-underline-width and text-underline-color.
To use them in odfpy, '-' characters must be removed, and attributes keys must be used as str (with quotes) like in the following code. A correct style family (text in our case) must be specified in the Style constructor call.
from odf.opendocument import OpenDocumentText
from odf.style import Style, TextProperties
from odf.text import H, P, Span
textdoc = OpenDocumentText()
#underline style
ustyle = Style(name="Underline", family="text") #here style family
uprop = TextProperties(attributes={
"textunderlinestyle":"solid",
"textunderlinewidth":"auto",
"textunderlinecolor":"font-color"
})
ustyle.addElement(uprop)
textdoc.automaticstyles.addElement(ustyle)
p = P(text="Hello world. ")
underlinedpart = Span(stylename=ustyle, text="This part would like to be underlined. ")
p.addElement(underlinedpart)
p.addText("This is after the style test.")
textdoc.text.addElement(p)
textdoc.save("myfirstdocument.odt")

Why does python-docx ignore rlt = true?

I need to write into a docx file from python (which i'm a bit new at) but i have to do it written rtl. After days of googling, the best I could do is this:
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT as WD_STYLE_TYPE
from docx.shared import Pt
from docx.shared import Inches, Pt
# create docx file
document = Document()
# create paragraph
para = document.add_paragraph()
# create run
run = para.add_run("Hello World")
# create style
mystyle = document.styles.add_style("mystyle", 2)
run.style = mystyle
font = run.font
font.rtl = True # SET RIGHT TO LEFT
document.save(r"C:\Users\USER\Desktop\Code\TofesEfes\WordTes.docx")
the problem is that for some reason the code just ignores this line:
font.rtl = True # SET RIGHT TO LEFT
If I try to change it to:
font.bold = True # SET FONT TO BOLD
the font will come out bold.
I also tried changing the text to be in a rtl languge and nothin changed.
Does anyone here have any idea why it's doing this?

Calling function from UI class in maya resulting in nonetype error

I'm building a toolbox UI using python in Maya, and I keep on getting a Nonetype error when I call one of the imported functions. This is the script for the toolbox:
class Toolbox():
import maya.cmds as cmds
def __init__(self):
self.window_name = "mlToolbox"
def create(self):
self.delete()
self.window_name = cmds.window(self.window_name)
self.m_column = cmds.columnLayout(p = self.window_name, adj = True)
cmds.button(p=self.m_column,label = 'MyButton', c=lambda *arg: cmds.polySphere(r = 2))
cmds.button(p=self.m_column, label = 'Make_Control', command = lambda *args: self.ControlBTN())
cmds.button(p=self.m_column, label = 'Find Center of All Selected', command = lambda *args: self.CenterBTN())
cmds.button(p=self.m_column, label = 'Find Center of Each Selected Object', command = lambda *args: self.IndiCenterBTN())
self.colorname = cmds.textField(placeholderText = 'Enter color name...')
cmds.button(p=self.m_column, label = 'ChangeColor', command = lambda *args: self.colorBtn())
self.MinAndMax = cmds.textField()
cmds.button(p=self.m_column, label = 'Random Scatter', command = lambda *args: self.ScatterBTN())
cmds.showWindow(self.window_name)
cmds.button(p=self.m_column, label = 'Select Everything', command = lambda *args: self.selectBTN())
def CenterBTN(self):
import CenterSelected
CenterSelected.Locator()
def ScatterBTN(self):
import Scatter
value = cmds.textField(self.MinAndMax, q=True)
Scatter.RandomScatter(value)
cmds.intField(self.moveMin, self.moveMax, self.rotMin, self.rotMax, self.scaleMin, self.scaleMax, e=True, text='')
def IndiCenterBTN(self):
import ManySelected
ManySelected.LocatorMany()
def colorBtn(self):
import ColorControl
value = cmds.textField(self.colorname, q=True, text = True)
ColorControl.colorControl(value)
cmds.textField(self.colorname, e=True, text='')
def selectBTN(self):
import tools
tools.selectAll()
def delete(self):
if cmds.window(self.window_name, exists=True):
cmds.deleteUI(self.window_name)
def ControlBTN(self):
import CreateControl
CreateControl.createControl()
myTool = Toolbox()
myTool.create()
And this is the function that I'm having trouble with:
def RandomScatter(MinAndMax):
import random
import maya.cmds as cmds
Stuff = cmds.ls(sl=True)
i=0
for i in range(random.randint(1,100)):
Stuff.append(cmds.duplicate(Stuff))
cmds.move( (random.randint(MinAndMax[0], MinAndMax[1])), (random.randint(MinAndMax[0], MinAndMax[1])), (random.randint(MinAndMax[0], MinAndMax[1])), Stuff[i], absolute=True )
cmds.rotate( (random.randint(MinAndMax[2], MinAndMax[3])), (random.randint(MinAndMax[2], MinAndMax[3])), (random.randint(MinAndMax[2], MinAndMax[3])), Stuff[i], absolute=True )
cmds.scale( (random.randint(MinAndMax[4], MinAndMax[5])), (random.randint(MinAndMax[4], MinAndMax[5])), (random.randint(MinAndMax[4], MinAndMax[5])), Stuff[i], absolute=True )
i = i+1
RandomScatter() works fine as long as I call it on it's own using a RandomScatter([a, b, c, d, e, f]) format, but when I try to call it Toolbox(), I get "Scatter.py line 21: 'NoneType' object has no attribute 'getitem'" as an error. It also happens when I try to use the intField() command instead of textField(). The UI window builds just fine; the error only happens after I enter input into the text field and press the button that's supposed to call RandomScatter(). It seems like the input isn't making it to the MinAndMax list, so when it reaches "cmds.move( (random.randint(MinAndMax[0]," it can't find anything to put in the MinAndMax[0] slot, or any of the slots after that, but I can't figure out why. Does anyone have any advice?
I didn't test your code and didn't read it totally, but I can already say that your strange "lambda" usage doesn't make any sens.
lambda *args: self.ControlBTN()
this lambda execute self.ControlBTN during the cmds.button definition and provide to it a function which return None.
that like doing that:
self.ControlBTN()
function = def func(): return None
cmds.button(p=self.m_column, label = 'Make_Control', command=function)
I advise you to reread the documentation about the "python lambda".
replace this by:
cmds.button(p=self.m_column, label = 'Make_Control', command=self.ControlBTN)
...
def ControlBTN(self, *args)
...
That should help
good luck
As written self.MinAndMax is a text field; even if you get the value from it it'll be a string and you won't be able to index into it to get the individual items -- and your indexing will be thrown off if any of the numbers are negative or have decimals. The lazy solution is to use a FloatFieldGrp which lets you have 2-4 numberic inputs. It's a bit annoying to get at all of the values at once (see the way it's done below) but it will avoid many issues with trying to parse the text field.
Also, this line doesn't make sense in context:
cmds.intField(self.moveMin, self.moveMax, self.rotMin, self.rotMax, self.scaleMin, self.scaleMax, e=True, text='')
You're not seeing the error because it's failing in the previous line, but the first argument ought to be the name of an existing intField.
In any case, I'd refactor this a bit to keep the argument parsing out of the scatter function, so you can separate out the working logic from the UI parsing logic. It'll make it much easier to spot where things have gone off the rails:
import random
import maya.cmds as cmds
class TestGUI(object):
def __init__(self):
self.window = cmds.window()
self.layout = cmds.rowLayout(nc=3)
self.min_xyz = cmds.floatFieldGrp( numberOfFields=3, label='min', value1=-10, value2=-10, value3=-10 )
self.max_xyz= cmds.floatFieldGrp( numberOfFields=3, label='min', value1=10, value2=10, value3=10 )
cmds.button(label='scatter', c = self.scatter)
cmds.showWindow(self.window)
def scatter(self, *_):
selected = cmds.ls(sl=True)
if not selected:
cmds.warning("select something")
return
min_xyz = (
cmds.floatFieldGrp(self.min_xyz, q=True, v1=True),
cmds.floatFieldGrp(self.min_xyz, q=True, v2=True),
cmds.floatFieldGrp(self.min_xyz, q=True, v3=True)
)
max_xyz = (
cmds.floatFieldGrp(self.max_xyz, q=True, v1=True),
cmds.floatFieldGrp(self.max_xyz, q=True, v2=True),
cmds.floatFieldGrp(self.max_xyz, q=True, v3=True)
)
print "scatter settings:", min_xyz, max_xyz
rand_scatter(selected, min_xyz, max_xyz)
def rand_scatter(selection, min_xyz, max_xyz):
dupe_count = random.randint(1, 10)
duplicates = [cmds.duplicate(selection) for n in range(dupe_count)]
for dupe in duplicates:
destination = [random.randint(min_xyz[k], max_xyz[k]) for k in range(3)]
cmds.xform(dupe, t=destination, absolute=True)
print (dupe, destination)
t = TestGUI() # shows the window; hit 'scatter' to test
My version changes your logic a bit -- you were duplicating your selection list, which would cause the number of items to grow exponentially (as each duplication would also duplicate the previous dupes). I'm not sure if that's inline with your intention or not.
You can avoid the extra lambdas by including a *_ in the actual button callback; it's a minor maya irritant that buttons always have that useless first argument.
As an aside, I'd try not to do imports inside of function bodies. If the imported module is not available, it's better to know at the time this file is imported rather than only when the user clicks a button -- it's much easier to spot a missing module if you do all your imports in a block at the top.

How to draw lines in IronPython with Winforms?

I've started working with IronPython in #Develop, and i love the integration with IronPython and Windows Forms, it lets you create the GUI like is were Visual Basic or C#
The question i have is simple, how to draw a line into a PictureBox when it's clicked? I've found this code about drawing lines, but i know how to adapt it to a PictureBox.
This is the code i've found:
http://www.zetcode.com/tutorials/ironpythontutorial/painting/
So, what should i put in "def PictureBox1Click(self, sender, e):"?
Any help or guide would be gratly appreciated.
Here is a simple example that draws a line on a picture box when it is clicked.
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class MainForm(Form):
def __init__(self):
self.InitializeComponent()
self.pen = System.Drawing.Pen(System.Drawing.Color.Black);
def InitializeComponent(self):
self._pictureBox1 = System.Windows.Forms.PictureBox()
self._pictureBox1.BeginInit()
self.SuspendLayout()
#
# pictureBox1
#
self._pictureBox1.Location = System.Drawing.Point(13, 13)
self._pictureBox1.Name = "pictureBox1"
self._pictureBox1.Size = System.Drawing.Size(259, 237)
self._pictureBox1.TabIndex = 0
self._pictureBox1.TabStop = False
self._pictureBox1.Click += self.PictureBox1Click
#
# MainForm
#
self.ClientSize = System.Drawing.Size(284, 262)
self.Controls.Add(self._pictureBox1)
self.Name = "MainForm"
self.Text = "PyWinForm"
self._pictureBox1.EndInit()
self.ResumeLayout(False)
def PictureBox1Click(self, sender, e):
g = self._pictureBox1.CreateGraphics()
g.DrawLine(self.pen, 10, 10, 400, 200)

Categories