best tool for rendering short items of text in wxPython and Kivi - kivy

I have a multi-platform app running on desktop (wxPython) and mobile (kivy). In it I want to render small areas of variable text in a window in the app. The text will depend on the state of the app. I am happy to use rtf, html or reStructuredText. I need to use the same source for the text on each platform.
A typical example of a text snippet would be:
Heading
=======
1. With 24 widgets pull a **long** one;
2. with fewer, push a **wide** one.
Which would render as:
Heading
With 24 widgets pull a long one;
with fewer, push a wide one.
My question is: which format should I use?
My preference would be reStructuredText. There appears to be a kivy widget to support this but nothing in wxPython

One solution is to use the docutils package.
This will take reStructuredText and output it as html. I can then use the wxPython wx.html control to display the output.
import wx
import wx.html as wxhtml
from docutils.core import publish_string
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = MainPanel(self)
sizer = wx.BoxSizer()
sizer.Add(self.panel)
self.SetSizerAndFit(sizer)
self.Show()
input_string = ("Heading\n"
"=======\n"
"\n"
"1. With 24 widgets pull a **long** one;\n"
"2. with fewer, push a **wide** one.\n")
self.display_rst(input_string)
def display_rst(self, rst):
html = publish_string(rst, writer_name='html')
self.panel.html.SetPage(html)
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
display_style = wx.VSCROLL|wx.HSCROLL|wx.TE_READONLY|wx.BORDER_SIMPLE
self.html = wxhtml.HtmlWindow(self, -1, size=(300, 200),
style=display_style)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.html)
self.SetSizer(sizer)
if __name__ == "__main__":
SCREEN_APP = wx.App()
MAIN_FRAME = MainFrame(None, title="Display HTML")
SCREEN_APP.MainLoop()

Related

kivy touch events bubbling and overriding on_ methods

The pictures example in /share/kivy-examples/demo/pictures places Image widget in Scatter. I'd like to extend the example and replace Image with <ImageButton#ButtonBehavior+Image>. However, the touch events are not implemented correctly. The ImageButtons are press-able but the drag functionality from the original example is lost.
At first I simply changed Image to <ImageButton#ButtonBehavior+Image> in the pictures.kv file. I see in the documentation that I may need to (re)implement on-press or on_touch_down. To that end, I've added these methods in the Picture class:
class Picture(Scatter):
source = StringProperty(None)
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print('picture touch down')
else:
print('no collide in picture')
super(Picture, self).on_touch_down(touch)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
print('touch move')
super(Picture, self).on_touch_move(touch)
I see the print statements in the terminal. But the ImageButtons are still consuming the on_press, and I know this from a print statement in that event handler. I tried to re-implement on_press and just not do anything with pass, and then I had an idea of calling self.parent.on_touch_down, but I don't have a touch object to pass into it.
One idea would be to
class ImageButton(ButtonBehavior, Image):
'''
def on_press(self):
print("button pressed")
print()
return super(ImageButton, self).on_press()
'''
def on_press(self):
pass
So, say I want the ImageButton to only register a double-clicks, and otherwise, for the widgets to behave just like in the example. How would I achieve that? Somewhat related
While there may be a way of distinguishing between a quick touch_down followed immediately by a touch_up, it is easier to show the desired functionality by letting an ImageButton press be activated with a double_tap:
class ImageButton(ButtonBehavior, Image):
def __init__(self, **kwargs):
super(ImageButton, self).__init__(**kwargs)
def on_touch_down(self, touch):
if self.collide_point(*touch.pos) and touch.is_double_tap:
self.on_press(touch)
return True
return False
def on_press(self,touch):
#whatever else you want to happen
return True

Monitor Changing file in python

How to create a program that monitors a file (for example, text, and when you wrote something new to this file, the program should output that something was added to the file, and when, on the contrary, part of the text was deleted from it, it should write that something was deleted
And it should print to the console exactly which words were deleted or added?
Explanation
I use watchdog to follow the file.
On instantiation of the handler, I read the file's size.
When the file is modified, watchdog calls the on_modified function.
When this method is called, I compare the file's current size to its previous size to determine if the change was additive or subtractive.
You have a few other options when it comes to tracking the file. For example, you could also compare:
the number of lines
the number of words
the number of characters
the exact contents of the file
import os
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class EventHandler(FileSystemEventHandler):
def __init__(self, file_path_to_watch):
self.file_path_to_watch = file_path_to_watch
self._file_size = self._read_file_size()
def _read_file_size(self):
return os.path.getsize(self.file_path_to_watch)
def _print_change(self, new_file_size):
if new_file_size > self._file_size:
print('File modified with additions')
elif new_file_size < self._file_size:
print('File modified with deletions')
def on_modified(self, event):
if event.src_path != self.file_path_to_watch:
return
new_file_size = self._read_file_size()
self._print_change(new_file_size)
self._file_size = new_file_size
if __name__ == "__main__":
file_to_watch = '/path/to/watch.txt'
event_handler = EventHandler(file_to_watch)
observer = Observer()
observer.schedule(event_handler, path=file_to_watch, recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

Saving SEC 10-K annual report text to files (trouble with decoding)

I am trying to bulk-download the text visible to the "end-user" from 10-K SEC Edgar reports (don't care about tables) and save it in a text file. I have found the code below on Youtube, however I am facing 2 challenges:
I am not sure if I am capturing all text, and when I print the URL from below, I receive very weird output (special characters e.g., at the very end of the print-out)
I can't seem to save the text in txt files, not sure if this is due to encoding (I am entirely new to programming).
import re
import requests
import unicodedata
from bs4 import BeautifulSoup
def restore_windows_1252_characters(restore_string):
def to_windows_1252(match):
try:
return bytes([ord(match.group(0))]).decode('windows-1252')
except UnicodeDecodeError:
# No character at the corresponding code point: remove it.
return ''
return re.sub(r'[\u0080-\u0099]', to_windows_1252, restore_string)
# define the url to specific html_text file
new_html_text = r"https://www.sec.gov/Archives/edgar/data/796343/0000796343-14-000004.txt"
# grab the response
response = requests.get(new_html_text)
page_soup = BeautifulSoup(response.content,'html5lib')
page_text = page_soup.html.body.get_text(' ',strip = True)
# normalize the text, remove characters. Additionally, restore missing window characters.
page_text_norm = restore_windows_1252_characters(unicodedata.normalize('NFKD', page_text))
# print: this works however gives me weird special characters in the print (e.g., at the very end)
print(page_text_norm)
# save to file: this only gives me an empty text file
with open('testfile.txt','w') as file:
file.write(page_text_norm)
Try this. If you take the data you expect as an example, it will be easier for people to understand your needs.
from simplified_scrapy import SimplifiedDoc,req,utils
url = 'https://www.sec.gov/Archives/edgar/data/796343/0000796343-14-000004.txt'
html = req.get(url)
doc = SimplifiedDoc(html)
# text = doc.body.text
text = doc.body.unescape() # Converting HTML entities
utils.saveFile("testfile.txt",text)

How to render Manim animations faster?

I found out that this animation takes a lot of time to render when there are more than 20 lines of text. Is there anything I can do to speed it up?
import itertools as it
class FormulaExample(Scene):
def setup(self):
self.text_example = Text("How are we doing?\nPlease help us\nimprove Stack Overflow.\nThanks!", font="Roboto", stroke_width=0)
class FadeInFromDirections(LaggedStart):
CONFIG = {
"directions":[DL,DOWN,DR,RIGHT,UR,UP,UL,LEFT],
"magnitude":1,
"lag_ratio":.05
}
def __init__(self, text , **kwargs):
digest_config(self, kwargs)
self.reverse_directions=it.cycle(list(reversed(self.directions)))
super().__init__(
*[FadeInFromPoint(obj,point=obj.get_center()+d*self.magnitude)
for obj,d in zip(text,self.reverse_directions)],
**kwargs
)
class FadeInFromDirectionsExample(FormulaExample):
def construct(self):
self.play(
FadeInFromDirections(self.text_example),
run_time=3
)
self.wait()
when compiling, you can use low quality mode, this will speed up compilation significantly, (which is good enough for previewing)

Use Kivy app while excel file is being built

So I am trying to create a Kivy app that allows a user to control and monitor various hardware components. Part of the code builds and continuously updates an Excel worksheet that imports temperature readings from the hardware's comm port, along with a time-stamp. I have been able to implement all of this so far, but I am unable to interact with the Kivy app while the Excel worksheet is being built/updated (i.e. while my hardware test is underway), and leaves me unable to use the app's features while the test is running (Such as the 'Pause' or 'Abort' buttons) until the worksheet is no longer being altered. So my question is: Is it possible to export to an Excel file while being able to simultaneously use the Kivy app? And if so, how?
This is part of my code that sets up the Excel worksheet. Thank you in advance!
from kivy.app import App
from openpyxl import Workbook, load_workbook
import time
class HomeScreen(Screen):
def build(self):
return HomeScreen()
def RunExcelFile(self):
wb = Workbook()
ws = wb.active
a = 0
i = 2
while (a < 5):
ws.cell('A1').value = 'Time'
ws.cell('B1').value = 'Batch 1'
ws.cell('C1').value = 'Batch 2'
column = 'A'
row = i
time_cell = column + str(row)
t = time.localtime()
ws.cell(time_cell).value = time.asctime(t)
a = (a + 1)
i = (i + 1)
time.sleep(1)
wb.save("scatter.xlsx")
If you are doing some background job without touching widgets or properties, you can use threading module without problems. Otherwise, you would need to use #mainthread decorator or Clock.
import time
import threading
class HomeScreen(Screen):
def run_excel_file(self):
def job():
for i in xrange(5):
print i
time.sleep(1)
print 'job done'
threading.Thread(target=job).start()

Resources