Pretty polynomials with wx.lib.fancytext

TrustyTony 1 Tallied Votes 720 Views Share

Here some experiments to pretty print polynomials with help of vegaseat's tip of wx.lib.fancytext.

Gribouillis commented: nice math example +4
import itertools
import random
import wx
import wx.lib.fancytext as fancytext
 
class FancyText(wx.Panel):
    """display fancytext on a panel"""
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
     
    def OnPaint(self, evt):
        """generate the fancytext on a paint dc canvas"""
        dc = wx.PaintDC(self)
        fancytext.RenderToDC(xml_str, dc, 0, 20)

def standardize(mypoly):
    """ Drop trailing 0, [] if only those """
    return next((mypoly[:ind+1] for ind, item in reversed(list(enumerate(mypoly))) if item), [])

def add_poly(first,second):
    """Adds 2 _polynomials first and second
    ([2,3],[4,5] => [6,8])"""
    return standardize([sum(pair) for pair in itertools.izip_longest(first, second, fillvalue=0)])

def mul_poly(first, second):
    """Multiply polynomial first with polynomial second """
    return (add_poly( mul_poly(first[1:],
                           [0]+ second[:]),
                    [ first[0] * x for x in second ])
            if standardize(first) and standardize(second)
            else [])

def poly_part_string(power, factor):
    if factor < 0:
        return '-'+poly_part_string(power, -factor)
    if not factor:
        return ''
    if power==1:
        return '%sx' % factor if factor != 1 else 'x'
    elif power==0:
        return str(factor)
    else:
        return (('x**%s' % power) if factor == 1 else ('%sx**%s' % (factor, power)))

def poly_part_xml_string(power, factor):
    if factor < 0:
        return '-'+poly_part_xml_string(power, -factor)
    if not factor:
        return ''
    if power==1:
        return '%sx' % factor if factor != 1 else 'x'
    elif power==0:
        return str(factor)
    else:
        return (('x<sup>%s</sup>' % power) if factor == 1 else ('%sx<sup>%s</sup>' % (factor, power)))

def polynomial_to_xml_string(poly1):
    """ produce readable polynom by adding '+' in front of positive polynomials and leaving out 0 * parts """
    return ''.join('+'+part if not(part.startswith('-')) else part
                for part in (poly_part_xml_string(p,c)
                                 for p,c in reversed(list(enumerate(poly1)))
                                 )
                    if part).lstrip(' +') # take out possible first plus or space

def polynomial_to_string(poly1):
    """ produce readable polynom by adding '+' in front of positive polynomials and leaving out 0 * parts """
    return ''.join('+'+part if not(part.startswith('-')) else part
                    for part in (poly_part_string(p,c)
                                 for p,c in reversed(list(enumerate(poly1)))
                                 )
                    if part).lstrip(' +') # take out possible first plus or space

def random_polynomial(count, const=20):
    """ produce max count random pollynomials with integer constants [-const,const] inclusive range """
    return [random.randint(-const,const) for _ in xrange(random.randint(1, count))]

app = wx.App(0)
frame = wx.Frame(None, wx.ID_ANY, title='wxPython fancy text',
pos=(100, 50), size=(1000, 250))

poly1, poly2 = random_polynomial(4), random_polynomial(10)
xml_str = """
<font family="swiss" color="blue" size="20">
   %s
* %s
_______________________________________________________
  %s
</font>
""" % (polynomial_to_xml_string(poly1), polynomial_to_xml_string(poly2), polynomial_to_xml_string(mul_poly(poly1, poly2)))

FancyText(frame)
frame.Show(True)
app.MainLoop()
Gribouillis 1,391 Programming Explorer Team Colleague

You can easily modify the code above so that the polynomials get changed on mouse click:

import itertools
import random
import wx
import wx.lib.fancytext as fancytext
 
class FancyText(wx.Panel):
    """display fancytext on a panel"""
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_UP, self.OnClick)
        self.xml_str = xml_str()
     
    def OnPaint(self, evt):
        """generate the fancytext on a paint dc canvas"""
        dc = wx.PaintDC(self)
        b = wx.Brush(colour=self.GetBackgroundColour())
        dc.SetBrush(b)
        sz = self.GetSize()
        dc.DrawRectangle(0,0,sz.width,sz.height)
        fancytext.RenderToDC(self.xml_str, dc, 0, 20)

    def OnClick(self, evt):
        self.xml_str = xml_str()
        self.OnPaint(evt)

def standardize(mypoly):
    """ Drop trailing 0, [] if only those """
    return next((mypoly[:ind+1] for ind, item in reversed(list(enumerate(mypoly))) if item), [])

def add_poly(first,second):
    """Adds 2 _polynomials first and second
    ([2,3],[4,5] => [6,8])"""
    return standardize([sum(pair) for pair in itertools.izip_longest(first, second, fillvalue=0)])

def mul_poly(first, second):
    """Multiply polynomial first with polynomial second """
    return (add_poly( mul_poly(first[1:],
                           [0]+ second[:]),
                    [ first[0] * x for x in second ])
            if standardize(first) and standardize(second)
            else [])

def poly_part_string(power, factor):
    if factor < 0:
        return '-'+poly_part_string(power, -factor)
    if not factor:
        return ''
    if power==1:
        return '%sx' % factor if factor != 1 else 'x'
    elif power==0:
        return str(factor)
    else:
        return (('x**%s' % power) if factor == 1 else ('%sx**%s' % (factor, power)))

def poly_part_xml_string(power, factor):
    if factor < 0:
        return '-'+poly_part_xml_string(power, -factor)
    if not factor:
        return ''
    if power==1:
        return '%sx' % factor if factor != 1 else 'x'
    elif power==0:
        return str(factor)
    else:
        return (('x<sup>%s</sup>' % power) if factor == 1 else ('%sx<sup>%s</sup>' % (factor, power)))

def polynomial_to_xml_string(poly1):
    """ produce readable polynom by adding '+' in front of positive polynomials and leaving out 0 * parts """
    return ''.join('+'+part if not(part.startswith('-')) else part
                for part in (poly_part_xml_string(p,c)
                                 for p,c in reversed(list(enumerate(poly1)))
                                 )
                    if part).lstrip(' +') # take out possible first plus or space

def polynomial_to_string(poly1):
    """ produce readable polynom by adding '+' in front of positive polynomials and leaving out 0 * parts """
    return ''.join('+'+part if not(part.startswith('-')) else part
                    for part in (poly_part_string(p,c)
                                 for p,c in reversed(list(enumerate(poly1)))
                                 )
                    if part).lstrip(' +') # take out possible first plus or space

def random_polynomial(count, const=20):
    """ produce max count random pollynomials with integer constants [-const,const] inclusive range """
    return [random.randint(-const,const) for _ in xrange(random.randint(1, count))]

app = wx.App(0)
frame = wx.Frame(None, wx.ID_ANY, title='wxPython fancy text',
pos=(100, 50), size=(1000, 250))

def xml_str():
    poly1, poly2 = random_polynomial(4), random_polynomial(10)
    xml_str = """
<font family="swiss" color="blue" size="20">
   %s
* %s
_______________________________________________________
  %s
</font>
""" % (polynomial_to_xml_string(poly1), polynomial_to_xml_string(poly2), polynomial_to_xml_string(mul_poly(poly1, poly2)))
    return xml_str

FancyText(frame)
frame.Show(True)
app.MainLoop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.