My new Pythonista dictionary app
I figured some of ya’ll might be interested in this. For the last couple of weeks, I’ve been developing a dictionary app in Pythonista. Here’s the GitHub repo: https://github.com/johnridesabike/WordRoom
Its main difference compared to other dictionary apps is that this is designed for you to write your own notes for the words you look up. It saves your notes and your look-up history. I’ve wanted an app like this for a long time, but I never found one that I liked. I finally decided to dive into Pythonista and make it for myself.
Although I mainly designed the app for my own personal use, I tried to make it user-friendly for anyone else. Also, I did my best to document all of the code so other Pythonista users can take advantage of it. I hope people can find it useful!
This sounds both really useful AND inspiring. I look forward to seeing what it's capable of.
Got this error when trying to run WordRoom.py
Traceback (most recent call last): File "/private/var/mobile/Containers/Shared/AppGroup/AF1E5A27-A567-45C1-A998-655B7A0E2B63/Pythonista3/Documents/projects/from GitHub/WordRoom-master/WordRoom.py", line 10, in <module> from jinja2 import Environment, FileSystemLoader File "/private/var/mobile/Containers/Shared/AppGroup/AF1E5A27-A567-45C1-A998-655B7A0E2B63/Pythonista3/Documents/site-packages/jinja2/__init__.py", line 37, in <module> from jinja2.environment import Environment, Template File "/private/var/mobile/Containers/Shared/AppGroup/AF1E5A27-A567-45C1-A998-655B7A0E2B63/Pythonista3/Documents/site-packages/jinja2/environment.py", line 575 info.external_attr = 0755 << 16L ^ SyntaxError: invalid token
@jsamlarose47 It looks like that error is coming from one of jinja2’s files. WordRoom uses Pythonista’s built-in jinja2 module to format the definition pages.
I don’t know why jinja2 would throw a syntax error, but I did notice something in your error log. Your jinja2 is being loaded from your custom
site-packagesdirectory. When I import it on mine, it loads from the built-in Pythonista library.
If you have a copy of jinja2 in your
site-packages, you could try deleting or updating it and running WordRoom again.
@johnridesabike Wow! Really! Glad it was helpful!
I am currently working on setting up a Flask template project that will work somewhat similar to Pythonista using Bootstrap for the UI elements. I plan to convert that bible app over to a WebApp and maybe an IOS app one day. I followed you on Github as well by the way.
@jsamlarose47 the line
info.external_attr = 0755 << 16Lhas two items that are not Python 3 compatible until it is rewritten as
info.external_attr = 0o755 << 16.
@johnridesabike interesting. Jinja2 is indeed in my site-packages folder and not in either of my Standard Libraries. I'll see what I can do to upgrade...
Later: Okay. Stumped. Tried to update my Jinja2 via pip (stash). Response was that I have the most recent update. Edited jinja2/environment.py (as pointed out by ccc) but got another error:
File "/private/var/mobile/Containers/Shared/AppGroup/AF1E5A27-A567-45C1-A998-655B7A0E2B63/Pythonista3/Documents/site-packages/jinja2/environment.py", line 600 except TemplateSyntaxError, e: ^ SyntaxError: invalid syntax
Fixing the jinja2 errors one by one seems like it could be an exhaustive process, and I'm sure there's a more sensible way to get things up and running— sounds like there's a problem with my install of jinja2. Anyone have any further suggestions?
Based on ccc’s observation, it looks like your Jinja2 is only Python 2 compatible, but my code is all Python 3. Maybe try moving it to
site-packages? Then it should only load when Python 2 code runs.
Pythonista should have a built-in Jina2 module (at least it does for me). It’s located under
Standard Library (3.6)/site-packages/jinja2/. If you don’t have that, then I’m not sure. The most up-to-date Jinja2 is supposedly compatible with 2 and 3. You can check your Jinja2 version by typing this in the console:
import jinja2 jinja2.__version__
Other than that, I’m not sure. If it continues to be a problem, I might look into workarounds that don’t depend on using Jinja2.
I told myself I’d take a break for a bit, but I’ve been having too much fun putting together the iPad UI. I just updated my dev branch with a bunch of changes: https://github.com/johnridesabike/WordRoom/tree/working-copy
I’m posting it now because I want to share my AdaptiveView class I came up with. I really wanted a UI that could dynamically change between compact mode for iPhones and iPad split-view, and regular mode for iPad full-screen. Here’s what it looks like:
class AdaptiveView(ui.View): def __init__(self, nav_column, content_column): # Putting content_column inside a NavigationView is a hack to make its # title bar visible. We never invoke the NavigationView methods. self.add_subview(nav_column) self.add_subview(ui.NavigationView(content_column)) self.content_column = content_column self.nav_column = nav_column # open_words will probably always just have one item, but it's # technically possible to have more than one open. self.open_words =  self.current_layout = None # background color is used as a border between the columns. self.background_color = 'lightgrey' def layout(self): # 678 is the width of an iPad pro app in 1/2 split mode. if self.width >= 678 and self.current_layout != 'regular': self.regular() elif self.width < 678 and self.current_layout != 'compact': self.compact() def compact(self): nav, content = self.subviews nav.x = self.x nav.width = self.width nav.height = self.height nav.flex = 'WH' content.hidden = True for word in self.open_words: compact_word_view.load_word(word) nav.push_view(compact_word_view, False) self.current_layout = 'compact' def regular(self): nav, content = self.subviews nav.width = 320 nav.height = self.height nav.flex = 'H' nav.x = self.x content.hidden = False content.flex = 'WHR' content.x = nav.width + 1 content.width = self.width - nav.width - 1 content.height = self.height if self.current_layout == 'compact': for word in self.open_words: nav.pop_view(False) self.content_column.load_word(word) self.current_layout = 'regular' if __name__ == '__main__': lookup_view = ui.load_view('lookup') nav_view = ui.NavigationView(lookup_view, flex='WH') word_view = ui.load_view('word') compact_word_view = ui.load_view('word') container = AdaptiveView(nav_view, word_view) container.present('fullscreen')
Basically, if you already have two views for navigation and content, you can just load them into an AdaptiveView instance and it will display them according to the window width. You’ll need two instances of the content view (the “word_view” in my code), one to display in the right column and one to push in compact mode. If you open some content and then resize the window, this view will “smartly” move the content from one column to the other.
I also tried making a “regular_narrow” layout for iPads in portrait mode, where just the content is displayed and the menu can slide out with a button. I wasn’t really happy with the way it looked though, and I didn’t take the time to implement features like gestures, so I didn’t include it.
Edit: I’ve since discovered way of checking for the layout class that’s much better than comparing the width. You can use
self.objc_instance.traitCollection().horizontalSizeClass()which returns 1 for compact and 2 for regular.
This is a very interesting and potentially useful app. I obtained a Wordnik API key but, unless I am mistaken, the app makes no real use of the API except to send you to the Wordnik webpage with the word of interest.
@ihf It uses WordNik to download word definitions. However, it also includes a basic offline dictionary that it can fall back on if there's no API key or no internet connection. So depending on what you look up, you may not notice a difference. The offline dictionary is much more limited than WordNik though. If you look at a word definition and it says it came from American Heritage Dictionary or Wikitionary, then that means it downloaded that definition from WordNik.
Just to clarify, here’s an example of a word that requires WordNik to view the definition: https://imgur.com/TGpHJtx
Here’s what it looks like once you add an API key: https://imgur.com/4vSMCCl
And also, I updated the GitHub releases with the latest version. It should have a better UI and some bugfixes.
Following up on this. Reinstalled Pythonista— figured the errors I was seeing might be an indication of some other issues with my set up. All's working fine now. ;)