• @mikael , thanks for your reply. The more I think about it, when I was a programmer, should never have coded in the workflow like I do here. I always got the data pretty well sorted out very early in the process. Even if I had to use something as crude as a csv file to get started (more often was resource files, c structs or a database or combination of these persistent storage types). Mind you this was not for web deployment, whilst there was a web, without dedicated isdn lines, you had no chance to transmit what we would have called large datasets at the time.
    Of course the data storage building/processing was a totally different process development from your end user application.
    So i think I will try and be more mindful of that in the future. In my little attempts here, i mix all this in together. In hind sight its no wonder I end up chasing my tail so much. In my opinion, I should be basically writing a presentation app that displays and manipulates my data. Not sure how others think about that. But I am going to do it anyway in the hope it will help me focus more.

    Regards to how I used shelve, basically I didn't know what I was doing from a object design perspective. It was just to get something going. I really dont like the whole pickle thing. A few reasons, first I am ignorant about pickling, also version problems with pickling. I also dont like shelve uses 3 files, it drives me crazy. But I used it to get started because everyone could run the code.
    I would have preferred to use TinyDB. But ultimately I would like to have a have a base strorage system that you can subclass. The subclass would inherit the ability to handle a key,value storage. But you could change/extend the underlying storage engine say from shelve to TinyDB with very little work. Hmmmm, well that's what I think I want, at least to start with. For locally run apps, It appears to mean you can do a lot with simple key,value storage systems.
    Also keeps the complexity to data you are likely to be dealing with in a local Pythonista App.

    So i will try a few different things. It's a good learning exercise, even if I do go down the wrong track for a while. I will also try to get my head around your comments about using the dunder methods, setitem & getitem. I used them a long time ago. But got myself in trouble with side effects that can occur if you are not using them properly. Maybe I am a bit better equipped today to use them in a more informed way, maybe not :).

    Again, thanks for your feedback. I really appreciate it. Unfortunately for me to have a in person conversation with a Python programmer, its approx 2 hr travel into Bangkok for meetup's they have there. 2hr's is a very modest estimate, once in Bangkok, then have to get to the venue. Depending on traffic & time you could easily double that. Through the network of Thai's I know, I have come across a few that can program a little in Python, but the language barrier makes it very difficult to have very meaningful conversations. Oh well, thats my life history :). Sorry, just in the mood for typing.

  • @technoway , thanks. I know it has limited value. I use it for part of a basic in file search program I made. The search program is basic, just searches for a word in all my files, I present a list of file names in a ui.TableView. Then if I want to look into a file, I bring up this viewer , to see if it what I was looking for. So for that purpose its good for me. I wanted to update the search program, so I separated this out first. It was a bit of a mess :)

  • Sorry, should have put thin in General not here

  • @ccc, the hotel app idea is dead. My friend that I wrote the Excel/VBA version for is not in the hotel business anymore. We are Actualling sharing a nice big house together now in Pattaya. A Danish guy, we have been friends for many years. It's a little bit like the old show the odd couple, us to living together, but we still have fun :)

    So no real push for me to do booking thing any more. But I still would like to make a pretty good calendar picker( I honestly hate the Apple DateTime Picker). I have made some before, but I should be able to make something better now. At least I hope so. The other thing I will get back to is my voting app. I always go wrong, as I try to make frameworks instead of just getting on and coding something with brute force just to get it done. Pretty or not. It's funny I should have those problems at this age. I didn't have it when I was younger. I was very aware and sensitive to commercial realities, get it done and out the door! I guess without that need, it changes you.

    Hmmm, just after announcing I should be better. I need to ask something embarrassing. I looked at this last night, for some reason I could not get my head around it.

    Below in the generator you modified, I have added x in the return tuple. I can't figure out how to get x to just be a linear counter ie. 0 to (rows * cols)-1.
    I have looked at it too long so I have decided to ask....My feeling it should be something simple that can be done in place and should not be apart of the comp loops....
    just adding x doesn't make much sense as it appears below, but makes more sense if you are creating objects in the generator rather than a tuple.
    Any help appreciated.

    return ((w * j, h * i, w, h, x) for i in range(rows) for j in range(cols))
  • @Phuket2 said:

    Maybe global is ok to use in Python for example, but i would hate myself if I found I had too use it for some reason.

    Why? Sometimes it's perfectly ok to use it. There're other ways how to achieve your goal sometimes. Depends. Globals are here and I'm not fan of globals are evil and also not fan of globals are perfect, let's use them everywhere. Just be pragmatic and use the simplest way.

    The nonlocal seemed to make sense to me when I wanted to start to use closures and be able to interact with the outter scopes vars in a somewhat correct manner (but its possibly also considered spaghetti code, not sure) . But I have been cheating :) eg, i would add a runtime attr to an object to read and write because on not understanding these scope rules.

    In the end the only thing which matters is readability / maintainability. If it's clear what the code is doing, it's fine. Everyone has it's own style, patterns, ... Just don't be too clever or you (or others) will not understand your code after week, month, ...

    I find it a little funny how they say Python is one of the easiest languages to learn. I am sure its correct in some contexts. But the richness of the language makes it somewhat challenging in my mind.

    Yes, it's easy. The problem here is discipline. Python allows you to do everything and you have to maintain discipline to be a good citizen. And sometimes people don't maintain it, stuff brakes, ... Sometimes they have no clue why, because they didn't read documentation, ...

    C was hard, but it was fairly rigid.

    I don't consider C as hard, but I think it's harder compared to Python. Not because it's really hard itself, but because code can contain lot of pointer arithmetics, manual memory management, ... and it's unclear what it does when you look at it for the first time. Anyway it was one of my first languages (when I skip BASIC, ...), I like it and I still use it. Remember good old times with Watcom C, protected mode, ... fun without documentation & internet :)

  • Well, I guess the bigger issue here is that it's worth reading though the modules that @omz has provided in Python. Some other useful stuff can be found.

  • Ok, I did a few updates to make it more useful. Not that it is really that useful unless you need it at runtime as Pythonista has the same but better built fonts picker in in the asset picker.
    But this just shows how hoist the original Custom ui.View Class and place it in another ui.View Custom Class. There is not much happing to make this work, the bulk of the extra lines are creating the views.
    One think I would point out though is that this example is size and orientation friendly. I am finally getting my head around the flex attr from the ui Module. I still sometimes slip up, but it's actually very easy. Shame on me, to take so long to get it. It's designed very well. I just suffer old mans syndrome sometimes. I mention that, because I don't think it's obscure, my brain was just working against myself.
    Anyway, I try to write anything that is not size and orientation friendly anymore. There is no need. And the more you do it, the more natural it is.

    Anyway, below is the update. Pythonista's filter seems to be the same as what I do, but @omz hilites the substring. Also, I am copying the font name to the clipboard where as the asset picker copies the font name into the editor. It's not difficult to do, just decided to copy to the clipboard.

    Again, I am not saying the below is the best way to do things. I am still a beginner. Just saying it's one way.

    # Pythonista Forum - @Phuket2 import ui, clipboard, console from objc_util import * def get_font_list(): # updated version from @dgelessus UIFont = ObjCClass('UIFont') lst = [str(font) for family in UIFont.familyNames() for font in UIFont.fontNamesForFamilyName_(family)] lst.sort() return lst class SimpleListView(ui.View): def __init__(self, items, *args, **kwargs): super().__init__(*args, **kwargs) self.tbl = None self.value = None self.flex = 'wh' self.make_view(items) def make_view(self, items): tbl = ui.TableView(frame=self.bounds) tbl.flex = 'wh' tbl.data_source = tbl.delegate = ui.ListDataSource(items) tbl.data_source.tableview_cell_for_row =\ self.tableview_cell_for_row self.tbl = tbl self.add_subview(tbl) def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = ui.TableViewCell() data = tableview.data_source.items[row] cell.text_label.text = data cell.text_label.font = (data, 16) return cell class FontViewer(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.data = get_font_list() self.tbl = None self.bg_color = 'darkgray' self.flex = 'wh' self.name_str = self.name if self.name else 'Fonts' self.make_view(**kwargs) self.update_name() def make_view(self, **kwargs): # make the containing view margin = kwargs.pop('margin', (0, 0)) cv = ui.View(frame=self.bounds.inset(*margin)) cv.flex = 'wh' # make the search view sv = ui.View(frame=cv.bounds) sv.height = 32 tv = ui.TextField(frame=sv.bounds) tv.placeholder = 'search' tv.clear_button_mode = 'always' tv.autocapitalization_type = ui.AUTOCAPITALIZE_NONE tv.autocorrection_type = False tv.delegate = self tv.flex = 'wh' sv.add_subview(tv) sv.flex = 'w' cv.add_subview(sv) # make the list view lv = ui.View(frame=sv.frame) lv.height = cv.height - sv.frame.max_y - 5 lv.y = sv.frame.max_y + 5 lv.corner_radius = 6 lv.flex = 'wh' cv.add_subview(lv) # create the list slv = SimpleListView(self.data, frame=f) self.tbl = slv.tbl # redirect the action to this class. self.tbl.data_source.action = self.list_action lv.add_subview(slv) self.add_subview(cv) def textfield_did_change(self, textfield): self.filter_data(textfield.text) def filter_data(self, filter_txt): # real poor mans filter. just doing an in-string search to match # but its case insensitive. for this data seems reasonable. txt = filter_txt.lower() # ui.ListDataSource updates itself when the items are changed self.tbl.data_source.items = [item for item in self.data if txt in item.lower()] self.update_name() def update_name(self): self.name = '{} - ({})'.format(self.name_str, len(self.tbl.data_source.items)) def list_action(self, sender): # when a list item is clicked self.value = sender.items[sender.selected_row] clipboard.set(self.value) console.hud_alert('{} - copied'.format(self.value)) self.close() if __name__ == '__main__': w, h = 400, 800 style = 'popover' if style == 'popover': h = ui.get_screen_size()[1] * .6 f = (0, 0, w, h) fv = FontViewer(name='The Fonts', frame=f, margin=(5, 5)) fv.present(style=style)
  • Hmmm, actually, I made a few other small mistakes for it to be all view/orientation friendly. The ui.TextField in search panel and ui.Label in footerpane; did not have their flex attrs set.
    If intrested, I hope this gist Fixes it. a lot of combinations to test

    It's only half import, because can easily change MyDataClass, to point to some other simple data items or with a little effort use it for other things.

  • @uj_jonas said:

    @Phuket2 keeps importing editor without using it

    Favoriting for this 😆

  • @JonB , yeah I know themes are handled in the editor module. At least for now. Themes are very complex, I know you know. So who knows we're they will end up once @omz thinks about it more. There are so many side effects with themes. Or let's say decisions to be made about implementation/API. maybe it will just stay in the editor module.even On my best day, I am glad it's not me deciding... It's very tricky

  • @abcabc , a small update to the gist. Its not suppose to present an ideal case. But combining the views/funcs can start to get something that looks ok. Have numbers around the outer ring in this example, would look more realistic with major and minor tick marks for example. But for me your circular_slider makes this possible.

    Edit: of course the outter ring not even needed

Internal error.

Oops! Looks like something went wrong!