Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Modules Of Pythonista Displayed With Help
-
Hi,
I wanted a list of modules importable in Pythonista and display corresponding help() text.
As i found help() spewing out text to console for each module cumbersome, i wrote this snippet.
I am sure there must be better ways to doing this. But I am just learning, and
it works :)
Also I learned a little bit about stdout, pkgutil, StringIO in this process.
More Power To Pythonista!# View help text for all the importable modules # using StringIO # Edited based on suggestions by @shtek & @Phuket2 # Edited to make use of contextlib.redirect_stdout # coding: utf-8 import ui, pkgutil from io import StringIO from contextlib import redirect_stdout w, h = ui.get_screen_size() fontsize = 15 if w > 767: fontsize = 24 if w > 1500: fontsize = 36 modulelist = [] for pkg in pkgutil.iter_modules(): modulelist.append(pkg[1]) def load_action(sender): ttval = (ttableview1.data_source.items[sender.selected_row]) # redirecting output using contextlib.redirect_stdout help_str = StringIO() with redirect_stdout(help_str): help(ttval) helptext = help_str.getvalue() ttextview1.text = helptext ttextview1 = ui.TextView(name='ttextview1', frame=(w * .3, 0, w * .7, h * .9), flex='WH', text='Click Any Module On Left', border_width=1, border_color=0, font=('<system>', fontsize), bg_color = 'lightyellow', text_color = 'red') ttextview1.editable = False ttableview1 = ui.TableView(name='ttableview1', frame=(0, 0, w * .3, h * .9), flex='HR', border_width=1, border_color=0, row_height=h / 20, seperator_color = 'red', alpha = .8) list_source = ui.ListDataSource(sorted(modulelist)) list_source.font = ('Avenir Next Condensed', fontsize) list_source.text_color = 'red' list_source.highlight_color = 'yellow' ttableview1.data_source = ttableview1.delegate = list_source ttableview1.data_source.action = load_action vname = str(len(modulelist)) + ' Modules' view = ui.View(name=vname, bg_color = 'yellow', frame=(0, 0, w, h * .9)) view.add_subview(ttableview1) view.add_subview(ttextview1) view.present(title_bar_color = 'yellow')
-
better add color, search and remove keyboard
-
@ramvee, as I am using an external keyboard, I dont see the keyboard. I also think you need a search or maybe a filter is a better word in this case. I think a simple 'is in' filter would work fine. Another think you could think about if you wanted, is a way to scale your fonts. My list font is way to small because I am on a IPad Pro 12.9.
Was interesting for me to see how you captured the stdout. I had thought about how you would go about it before, but never got around to seeing it done -
@shtek and @Phuket2 ,
Thank you for your suggestions,
i edited the code to suppress the keyboard, added color and tried to use scaleable fonts.
However i need more learning to incorporate search/filter option.ps. @Phuket2 , was shocked to see that your 12.9 iPad Pro has a screen resolution of 2732 X 2048 pixels! Wow! :)
-
@ramvee , yes I really love the iPad Pro. But everyone has there own idea. Below, i did some code to illustrate a filter. Sure you can do it. I tried to keep it straight fwd, i hope i did that. But it really is easy. The hardest part is to get the view to behave itself:). As I mentioned before, for this data I would say a simple filter like below, should be enough. It's very simple, case insensitive and no wild cards etc...
Its not a full implementation of what you need, but its pretty close I think.import ui from random import choice from faker import Faker fake = Faker() # if you want random data each time this is run, comment out the line below. fake.seed(2017) def generate_fake_names(num_names): ''' use faker module to generate a list fake first & last names ''' return ['{} {}'.format(fake.first_name(), fake.last_name()) for _ in range(num_names)] class MyClass(ui.View): def __init__(self, items=None, *args, **kwargs): super().__init__(*args, **kwargs) self.tf = None self.items = items if items else [] self.table = None self.make_view() def make_view(self): _v_gap = 5 # make a textfield tf = ui.TextField(frame=self.bounds.inset(5, 5), flex='w', placeholder='Filter', clear_button_mode='always', autocapitalization=ui.AUTOCAPITALIZE_NONE, spellchecking_type=False ) tf.height = 32 tf.delegate = self self.tf = tf self.add_subview(tf) # make a table tbl = ui.TableView(frame=self.bounds.inset(5, 5), corner_radius=3, flex='wh') tbl.y = tf.frame.max_y + _v_gap tbl.height = self.height - tf.frame.max_y - _v_gap * 2 # -- Add a ui.ListDataSource tbl.data_source = ui.ListDataSource(self.items) self.table = tbl self.add_subview(tbl) def textfield_did_change(self, textfield): self.filter_data(textfield.text) def filter_data(self, filter_text=''): ft = filter_text.lower() if not len(ft): self.table.data_source.items = self.items else: self.table.data_source.items =\ [s for s in self.items if ft in s.lower()] if __name__ == '__main__': style = choice(['sheet', '', 'popover', 'panel', 'sidebar']) # style = 'sheet' f = (0, 0, 300, 400) v = MyClass(frame=f, items=(generate_fake_names(100)), bg_color='teal', name=style) v.present(style=style, animated=False)
-
@Phuket2
Very nice example, my friend thank you!
I will try and learn it!
Grateful 😁