2018 April - Projects Log

Contrary to appearances, I do actually make progress on some of my projects, but not yet enough usually (I think) to write a whole blog post. This might be a good way to post some of those small updates, or even introductions to small projects, but it's just an experiment, so I'll see how it goes.

2018 April 11, Thursday

Today, I started a semi-neat Rust hello-world project to learn the Rust Programming language by trying to use it. I've read the Rust Book, and discovered the different Documentation resources available to learn certain concepts and usage. I'm using
pancurses for terminal UI, even though I
have no idea how ncurses works. I'm mostly using it for screen dimensions and just putting characters where I want them.

The idea of the program is to be a character frequency counter, but in real time; As you type each letter, character counts for letters A-Z display how many times they have been typed since the program was started. I'm also showing stats for space, ., ,, and an other character.

As of today, I have it compiling and echoing characters I type that the program receives one-at-a-time in a loop, all though the ncurses library.

(I also feel I should drop a note about my Neovim setup. Since I'm using vim-polyglot, I have Rust Vim support with syntax highlighting and auto-formatting, with K showing documentation, and a few other commands. I'm using deoplete-rust for intellisense/auto-completion, and ALE for showing compiler errors line by line, and I've got to say: I've never had a language setup work so well and smooth out of the box before! Incremental compilation errors show up right in the status bar, with red >>'s next to the relevant line, and after I fix it and save, it's only 1/2 second later that I see the error go away, and it's very enjoyable discovering the Rust compiler's idea of a safe program. That's all for now!)


2018 April 16, Monday

Today I started a new React Native project as both a learning excercise and a teacher's request - a checkout system for his library books involving Google Sheets, scanning ISBN Bar Codes for book titles, and QR codes for student names, with a focus on ease of use. My last attempt at Android app writing was with Xamarin, which I didn't enjoy much, and I love React.js's declarative functional-style user interface paradigm, so this project has been a long time coming. I'm using create-react-native-app that uses the Expo SDK for an easy cross-platform library, just to try to keep things simple - this app shouldn't be too complicated.

As of today, I have a basic view with a form with four input fields for the ISBN, book title, author, and student name, with 2 buttons. Learning and experimenting with the flexbox layout in a React Native context is... educational, and sometimes unexpected, but it's a common new standard layout worth getting familiar with, so I've no complaints, and feel confident that I can master it and make any layout that I want.


2018 April 17, Tuesday

Some more progress on my React Native library book checkout system - I used the Expo SDK's Camera component to make an in-page preview of the camera, and as I moved the camera over QR codes, it would fire the onBarCodeRead callback with the scanned text within a second (or quicker) as I changed from one qr code the the next, and it read bar codes from the backs of books just fine too. I consider the proof-of-concept for scanning QR codes and bar codes complete at this point, and am ready to move on to using a free REST API to look up ISBN book titles and authors, or perhaps to connecting to a Google Sheets document.

The idea will be to maintain a spreadsheet that has the columns "Book", "Student", "Check Out", "Check In", and "Notes (optional)", that will grow vertically as books are checked in and out, allowing easy reporting on missing books with student accountability.


2018 April 18, Wednesday

More work on the Rust char_count program. The program sort-of does what I wanted for one part - a 5-line tall limited display of what was typed so far, scrolling as it went. It's displaying characters as I type them, but there is currently a bad slowdown whenever the text reaches the end of the line, which gets worse the more text there is. I'm not immediately sure how to fix this - I was experimenting with the functional methods in Rust like map, and slices into String structures.

My impressions of Rust's standard library is that while capable and extensive, it is proving somewhat difficult to navigate and understand, especially when it comes to all the traits and methods that a primitive like slice has available (just take a look at that page, it's huge!). Part of this struggle I attribute to simply me not yet grokking the doc structure, much how like it took me a bit of time to learn cppreference.com, compared to MDN (Mozilla Developer Network) which was much easier, and which I now consider to be the best reference for HTML, CSS, and JavaScript. Rust is complicated, but necessarily so, I believe, because of the power, performance, and safety it gives you. I will definitely keep pushing forward in my understanding of this language, and hopefully reach the point where I can rewrite a certain unnamed C++ program in Rust.


2018 April 19, Thursday

After riding my motorcycle, I pretty much spent the whole evening typing this page! I hope it lives up to my expectations to be able to better document my projects.


2018 April 23, Monday

Tonight, I worked on a pamphlet request page for a church website rewrite. The project uses react-static, which I'm finding to be a nice library that manages things mostly how I would expect, and allows customization for the extra webpack loaders I want.

For a short synopsis - I wanted a solution that allowed content to be changed easily, so I'm using Markdown for most of the content, and components that load in the content (and make Bible verses clickable links), and for special pages, I add custom behavior in React components. I have a webpack loader for markdown files, and use the server side portion of react-static to read the file system to scan for Bible studies, so to add a new bible study, one simply has to upload a new file under a folder, and when re-built, the Bible Studies page will have a new functioning link corresponding to the uploaded file, and order can also be modified as desired.

Tonight's changes involved making a checkbox form selection to actually be functional, and to be used in generating a link with a "mailto" location as documented here that seems to work with generating a pre-filled email asking for the selected pamphlets. I might be able to come up with a better solution with more thought, but I want to avoid having a server if possible, because that will make deployment easier to understand for the people that have to maintain this.


2018 April 24, Tuesday

This evening, I added some navigation to my library checkout react native app, using the react-navigation npm module, in Tab-Navigation mode. The result is below:

Screenshot of Navigation

I'm still very impressed how quickly the development cycle is (the time it takes between making a change and testing it). My dad informs me that the text should be "ISBN", not "ISPN", and after I edit the file and save, about five seconds later, the change is live and visible - only about 15 seconds between wanting a user interface tweak made and seeing it in action. It is a very satisfying development experience, and works with text, layout, and I'm told behavior (though I havn't tested that yet) - it really is one of react-native's killer features - the other, of course, being React itself, which is currently my favorite way of doing user interfaces.

I have a plan as to how I'm going to make the actual data processing really fast. Since the data I'm going to use and update lives in a Google Sheets document, I know (though I haven't looked into it deeply yet) that I need to interact with it over the Internet eventually. I'll need the data as soon as I scan the QR code with a student's name, or the book's ISBN, and having to go on the network before I can show a result would be slow. So, When the page loads, I'm going to try and download a cache of the Sheets data for local processing, nicely wrapped in a thin object-oriented interface. (I could go 100% functional with this, but I'm experimenting a bit.) I'll save the updated data to the server after the user confirms that the check-in/out looks good, but this approach should allow me the quickest feedback from QR scan to the confirmation button being clickable, and ease and pleasantness of use is a strong goal for this simple app.


2018 April 26, Thursday

This evening, I worked on my React Native project - the library checkout sheet. Using the knowledge I obtained with my earlier experiment, I build a CameraScanner component, wrapping my use of the Expo SDK's Camera component behind a small abstraction layer, so I can always change underlying mechanisms without changing a large part of my code. The result is below.

Screenshot of camera scanner

The current behavior is such that the field that gets populated from the scanned text depends on a RegExp match of the scanned text - something with all numbers goes into the ISBN field, and anything else will go into the student name (for now). Eventually, I hope to distinguish between a student name and a custom unique book identifier QR code, to handle multiple books in a library with the same ISBN. I'm showing the actual text received from the camera just to keep representation more indicative of reality, potentially making it easier to debug.

I found out about a nifty behavior of react-native's default setup (the one that's built from create-react-native-app) that seems to be predictable. When I first save a file that I've modified, it tries to hot-reload the component, preserving the app's state (data like the ISBN and Student Name), while replacing the rest of the component while the app is running, including the rendered appearance. This makes it possible to see what happens if you make text bold or not pretty quickly. If I save the file again, and nothing changed, then the app will reload, starting from scratch, so that anything that hot-reloading couldn't apply shows up for sure. Hot-reloading isn't perfect yet, and sometimes, a full refresh is needed to see a change, and this behavior makes it easy to do that.


2018 April 30, Monday

This evening was mostly filled with research into Electron, a way of using web technologies like HTML, CSS, and JavaScript to build desktop applications. I've read and thought about a lot of articles, blog posts, Hacker News flame wars debating on whether this is a good idea, and I side with Electron over against the naysayers primarily because:

  1. The web platform has evolved to become the most wide-reaching user interface platform on the planet
  2. The entire ecosystem is open-source, including major frameworks (React, Angular, Vue, etc...), browser engines (Chrome, Firefox), and tools (NPM, WebPack, Yarn, Babel, etc...), facilitating unrestricted experimentation and innovation.
  3. I believe the benefit of having one application's user interface, front-end as well as back-end, work and behave the same across Windows, Mac, and Linux, is worth the price of bundling Chrome's rendering engine to equalize these Operating Systems.

Mostly the memory use is still a bit of a concern for me, but only if one wants to have dozens of small electron apps with 90 MB runtimes, whereas for serious applications that have a lot of work to do anyway, the overhead becomes more worth it, proportionally.

Tonight's self-education was about how the process architecture is set up, with one main process managing app lifecycle, spawning the actual windows in their own process. Inter-Process Communication (IPC) seems to be best for sending real-time data between processes, which raises questions about how to architect an app that could have more than one window. There may be different ways of doing this that I need to find out a bit yet. I also see strong value in an architecture where Electron as a front-end interoperates with core business and data logic in a safer language than JavaScript, like Rust, maybe C++, or perhaps even .NET Core. I believe I am still in the process of discovering the best way to build applications of all kinds, including applications on the desktop, and will continue researching and experimenting with an open mind.