Author Archives: Jason Knowles

Sprint 6 Retrospective: Capturing and Displaying Specific Categories

We’ve just completed our final working sprint, consisting of six primary objectives.

1.  Maintain communication and collaboration with all other teams.
2.  Create a mock diagram demonstrating our implementation ideas.
3.  Capture the specific data requested by the AMPATH team.
4.  Store this specific data into the PouchDB database.
5.  Write tests for our existing code.
6.  Develop an offline GUI to display specific offline data.


Maintaining communication and collaboration:

Sprint 6 involved substantial communication between ourselves and the other teams. Since this was our last working sprint, our team knew it was imperative to keep up to date on what everyone is working on. Each team is working on a critical part of the offline AMPATH implementation. I like to think of these critical parts as pieces to a puzzle. Eventually we’re all going to have to put these pieces together, and they all have to fit right. Our team agreed that communication is the best way to ensure how the pieces will fit in our final stages of implementation.

Based on our cross-team discussions during this sprint, we began brainstorming how to connect all teams’ implementations as a whole. We’re in the process of designing a mock-up that demonstrates the idea. This ought to be done in time for our final presentation next week.

Creating a mock-up demonstrating our implementation ideas:

We felt that designing a mock diagram was important for the AMPATH team (and our classmates) to see exactly what we envision our final implementation to look like.

Offline Component GUI

We would like to give credit to the offline-storage team for designing the original mock-up above. Small changes were made to reflect the specific information we plan on capturing. After receiving approval from JJ, we began working to implement this overall design.

Capturing the specific data requested by the AMPATH team:

This refers to capturing five specific categories of information to be stored in a PouchDB database:

1. Basic Patient Information
2. Patient Visits
3. Vitals
4. Lab Results
5. HIV Summary

We were able to accomplish updating our offline-data-capture component to include functions that capture the aforementioned data. We were able to accomplish this by using existing OpenMRS services located within the AMPATH app. We made functions where each focuses on capturing and storing one specific category.

Storing the aforementioned categories into PouchDB:

The AMPATH team suggested that we separate the different categories when storing them into PouchDB. This makes a lot of sense; we noticed the original data we were capturing tended to exceed over 3000 lines per patient. The larger the file, the longer it takes to load. We want our offline implementation to load as quickly as possible for the convenience of those using it.

Now that we’re only capturing specific data and storing each category separate, the file sizes are significantly smaller. We opted to store them by name of the category, followed by a given patient’s UUID. For example:

patient-064e419c-ff4e-4a6f-b83f-e1df48e80723
vitals-064e419c-ff4e-4a6f-b83f-e1df48e80723
visits-064e419c-ff4e-4a6f-b83f-e1df48e80723
labs-064e419c-ff4e-4a6f-b83f-e1df48e80723
hivSummary-064e419c-ff4e-4a6f-b83f-e1df48e80723

Writing tests for our existing code:

Ideally, we should have written our tests prior to any actual implementation. Then we could have written our code in a specific fashion to make our tests pass. I am still new to unit testing; this is something I need to work on in future projects (writing tests before implementation). On a positive note, the offline-storage team has made substantial progress writing tests for their component and service. Since they’re using PouchDB as well, our team should be able to easily revise their tests to suit our needs.

Developing a GUI to display specific offline data:

This concerns designing a component with the overall look of the aforementioned mock-up we came up with. We are in the process of implementing this GUI, but we’re having issues getting anything to display to the user. Everything I’ve tried so far hasn’t been working, and it’s pretty frustrating. Here’s the type of errors I am getting:

trying-to-display-pouchdb-data

I think it has something to do with losing the result once leaving the promise. I am hoping to get this working by our project presentation. If anyone wants to see my most recent attempt at getting this working, the commit can be found here.

Overall

I think this was a very eventful sprint. We’ve all done a good job communicating not only with each other, but with other teams as well. Personally, I believe many of my contributions would not have been possible without the communication and support from my teammates, AMPATH, the other teams, and my professor.

 

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

Sprint 5 Retrospective: Capturing Patient Data

As Sprint 5 comes to a close, I believe we are making great progress. Our team’s primary goal is to have a completely functional data capturing service for offline purposes. With the achievements made during this sprint, it seems very realistic that we will have a working module by the end of this semester.

Our main objectives for Sprint 5 were the following:

1.  Decide what would be the most useful data to capture.
2.  Capture raw data to be stored into PouchDB.
3.  Construct ideas presenting captured data in a meaningful way.
4.  Improve cross-team communication.

Deciding what would be the most useful data to capture:
We all agreed that we should begin to focus on storing detailed patient data. Internet connectivity is often unreliable where the AMPATH app is intended on being used. We want to allow medical providers to have offline access to patient data when a given patient is expected to be seen.

Capturing raw data to be stored into PouchDB:
I believe we have made substantial progress concerning this task. We were able to use OpenMRS services (located in the ./src/app/openmrs-api folder) to help us achieve our intended goals.

Originally, we were able to capture data of some 200 patients having the word “test” in their names. This was a great starting point, but we knew we needed to improve upon our results. First, the data was being captured and stored into one large file. This contrasted with our intended capability of having each patient object being stored in its own file. Second, the data being captured was only basic patient information, such as name and address. We wanted to also include more detailed criteria, such as upcoming appointments and other patient encounters.

Initially we were using the PatientResourceService.searchPatient('test') function to capture a given array of patients. We were taking the results from the returned Observable and storing it into PouchDB. The problem we were having was figuring out a way to iterate through these results so we could store each patient in an individual file. Ultimately, we were able to achieve this by using the JavaScript lodash ability. By importing lodash in our component, we were able to use _.each to iterate through the subscribed results from the returned Observable in an array-like fashion. 

Our next step was to try to figure out a way to store patients other than those with “test” in their name. Further, we wanted to capture more meaningful information about the patient (appointments, encounters, etc).

Ultimately, we were able to manipulate an existing component, located in ./src/app/patient-dashboard/common/patient-encounters/patient-encounters.component.ts, to store a patient’s detailed data in PouchDB when it is searched for.

Presenting the captured data in a meaningful way:
This is a topic discussed in great detail during our last working class during Sprint 5. Ultimately we need to decide how we are going to present this to the user. We anticipate the user will be a provider, such as a doctor looking for information about patients to be seen. We are in the process of constructing a mock diagram for a GUI to view and manipulate the captured data.

Improving cross-team communication:
I feel we have made some progress in this area. We seem to have a general idea what everyone is working on. But at the same time, there is definitely room for improvement regarding our communication with other teams. We anticipate a lot of cross-team collaboration in the upcoming sprint. Since all teams are finishing up their work, we need to make sure all implementations are compatible with each other. For this reason, I am confident our cross-team communication will continue to improve during our next sprint.

Overall:
I believe this was an effective sprint. We’ve all done a good job letting each other know what we’re currently working on. I had a lot to do with implementing the offline capturing abilities, but this was only possible due to the support and input from all of my teammates. Regarding participation during this sprint, I think we’ve all done our fair share.

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

The Long Road

I anticipate my career to involve software development for the rest of my life. I need to start preparing for the intense journey to come. That being said, I want to discuss The Long Road apprenticeship pattern. It seems directly relative to the situation I find myself in, which is a soon-to-be entry level software developer.

The Long Road is a portrayed as a direction apprentices should take when new to software development. It is asserted that those looking to journey down this proverbial road should not be looking to become instantaneously rich and famous. Instead, it is suggested that we ought to steadily increase our knowledge and skills throughout the decades to come. We should not feel obligated to accept any promotion that could potentially constrict our quest for knowledge.

I realize applying this pattern will likely mean turning down promotions in favor of strengthening my overall skills. But honestly, I don’t think I’d be comfortable taking a job I didn’t enjoy just because the pay was better. I’d rather spend my professional career looking forward to going to work, instead of potentially dreading it. For that reason, I believe The Long Road is an appropriate pattern for me to follow.

When beginning to apply this pattern, it is suggested to think about where we might end up in the decades ahead when traveling down this “long road.” Personally, it is hard for me to imagine what I’ll be doing ten or twenty years from now. But one of the immediate goals I’ve set for myself after graduation is to learn as many programming languages as possible. This ought to require a lot of reading, programming, and collaboration with other developers. I’m genuinely looking forward to it.

If I were to guess what I’ll be doing many years from now, I am hoping to become well-versed enough in the software development world to have helped others in some substantial way. With all the reading on software development I plan on doing in the decades ahead, perhaps I will have written my own book or two. I guess only time can tell where I’ll end up, but I think I’ll always stay on “The Long Road” in favor of any promotion that might distract me from furthering my overall career. Ultimately, I predict I’ll always be a software developer in one way or another.

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

Sprint 4 Retrospective

It seems that as each sprint goes by, we tend to achieve a substantial amount more than the preceding one. This sprint is no exception. I feel it has a lot to do with us becoming more familiar with the project, as well as the Angular framework.

Our main objectives for Sprint 4 were the following:

1.  Finish refactoring online-tracker to include a service.
2.  Successfully install PouchDB within the AMPATH app.
3.  Research and attempt using the PouchDB API to:
        (a)  perform REST calls.
        (b)  deal with synchronization.
        (c)  encrypt the data within the database.

Refactoring online-tracker to include a service:
We were able to accomplish this. I should point out that the refactoring of online-tracker was a bit more complicated than we anticipated. Initially we thought that just moving around some code would do the trick. But once we attempted to test the code, we realized we had a series of issues that needed addressing. For example, our original service essentially wasn’t returning anything, making it extremely difficult to test. Further, there were some issues with the Observable.timer() that periodically checks for connectivity. Since it wasn’t being properly closed, it was causing potential resource leaks that seemed to slow down the whole app. Felix from the AMPATH team helped us resolve these issues. The end result is that our pull request was accepted, and is officially part of the ng2-amrs repository. I tried to document the whole process the best I could to help others in the future. If you want to check it out, the PDF is located here.

Successfully install PouchDB within the AMPATH app:
We did not expect this to give us so much trouble, but ultimately we were sucessful. We were able to install PouchDB dependancies inside a new standalone Angular app, but every time we would try to install it within our clones of ng2-amrs, the app would no longer compile. With the help of another team working on offline storage, we were able to get it working. Here’s how our team was able to do it:

   1. Clone a clean copy of ng2-amrs, i.e.:  git clone https://github.com//ng2-amrs ng2-amrs-pouchdb
   2. Open ng2-amrs-pouchdb in WebStorm and press ALT-F12 (or Fn-ALT-F12) to start a terminal.
   3. Delete package-lock.json from the Project menu in WebStorm (make sure safe delete is checked)
   4. npm install pouchdb @types/pouchdb
   5. If package-lock.json is recreated, delete it again by following step 3.
   6. npm install webpack webpack-dev-server karma-cli protractor typescript release-it rimraf -g
   7. If package-lock.json is recreated, delete it again by following step 3.
   8. npm install

Research and attempt using the PouchDB API:
I believe our whole team was able to read most (if not all) the chapters in the official PouchDB guide. We were able to make some progress regarding actual implementation within the AMPATH app. For instance, we were able to configure a router for an offline-storage component, and we can now link to it directly within ng2-amrs. Further, we performed some REST calls using the PouchDB API.

Going forward into the next sprint, I think we need to focus on subscribing to data using observables, and then storing that data offline. This will require further experimentation with the PouchDB API. During the next several days, we will look into encryption at a high level, but will focus primarily on data capturing using PouchDB.

Synchronization between an offline database and the AMPATH server is our ultimate goal for this project. Based on our research so far, this task in particular seems pretty advanced. We are likely going to need assistance from the AMPATH team. I have been communicating with Felix regarding these issues.

Overall, I think we worked well as a team, and as a class in general. Everyone seems genuinely interested in completing the tasks we’ve set for ourselves. Communication has been strong for the most part; we always seem to know what each of us is working on.

 

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

Find Mentors

It seems fitting to discuss the Find Mentors apprenticeship pattern this week. I recently finished up a successful refactoring of the AMPATH online-tracker. My pull request was accepted by their development team, and is officially part of the ng2-amrs repository. I am adamant the end result was possible only after receiving the help from a mentor of sorts. I consider Felix from AMPATH a mentor in the sense that he helped clarify many questions I had concerning the online-tracker refactoring, the overall project, and Angular in general. One of the objectives when applying the Find Mentors pattern is to seek someone with knowledge in an area of interest that far exceeds your own. Since Felix’s knowledge of the AMPATH application is leaps and bounds ahead of mine, I think I’ve made a considerable effort to begin applying this pattern.

I have come to the realization I am going to need mentors to gain any sort of momentum in my professional career. My greatest struggles that have been preventing me from reaching out to mentors are intimidation and fear of rejection. But as those describing this pattern point out, the potential payoffs reaching out to mentors far outweigh the risks.

I need to remind myself that the vast majority of open-source communities are very knowledgeable and friendly people, more than willing to help others. I can cite the AMPATH development community as an example here. When I first learned that we would be working with on an actual open-source project with seasoned developers, sure it was intimidating to say the least. It took a little while for me to gain the courage to ask for help from them. But honestly, it was certainly worth it. Not only did I get a pull request accepted, we now have a online tracker service to work with for our offline module implementation. I also gained a whole lot of priceless knowledge concerning the functionality of the overall project.

One of the suggested actions given by those describing the Find Mentors pattern is to actively observe open-source communities. The intention is to, over time, find one or more communities that seem especially helpful and inviting to newcomers. The aspiring apprentice should then reach out to potential mentors from those communities. After I graduate, I plan on finding such a mentor to help me get through the whole job interviewing process. I know I am going to need a lot of help and support for this.

 

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

Breakable Toys

Those describing the Breakable Toys apprenticeship pattern assert the importance of designating a safe-space for failure. But we must accept there is no room for failure on the job. In a professional working environment, many expect us to produce material that works every time. But as depicted in this pattern’s description, failure is necessary in order to grow.

Building breakable toy projects can be a great way to contain, evaluate, and improve upon one’s failure. The idea is to personally design something “on the side” that emulates one or more features you’re working on professionally.

I’ve somewhat already applied this pattern throughout the course of working on the AMPATH project. I’ve developed a few “breakable toys” of my own with the intention of better understanding specific Angular capabilities. My reasoning is as follows: AMPATH uses many Angular functionalities I was previously unfamiliar with. I quickly began to realize I have a whole lot of learning to do.

The concept behind the Breakable Toys pattern seems practical for any Software Developer. In fact, I wouldn’t be surprised if the majority of all programmers have created at least one breakable toy or another. I base this on my personal experience with breakable toys. They have definitely given me a better understanding of the “big picture” behind the AMPATH app. When working on a large project, breaking it down into pieces can give us a better understanding of its overall functionality. We can feel confident evaluating the features in a breakable toy through trial and error. If the toy breaks beyond recognition, its okay. Whereas breakable toys are disposable, large open source projects like AMPATH are not. It seems a lot safer to evaluate functionalities in an isolated space first.

I would also like to mention the specific action suggested by those describing the Breakable Toys pattern. Personally constructing a wiki from scratch is proposed. I feel this will be very beneficial for me in my future endeavors. Building wikis appear to be great breakable toys to experiment with; we can use them to explore fundamentals such as concurrency, HTTP, REST, and general web development. As I begin transitioning to my professional career, these are fundamentals that I certainly need to become more knowledgeable in.

I’ve recently purchased a website domain and hosting space from InMotion. I don’t have anything on it yet, but my eventual goal after I graduate is to build my own “breakable toy” wiki. I want to do this to become more familiar with web development tools and prepare for job interviews. Further, I am hoping to showcase everything I’ve learned about the AMPATH project in this proposed wiki to help others in the future.

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective – Offline Services: Development Stage

We started off this sprint with two primary objectives in mind. Soon I will discuss a bit about our sub-tasks to complement these objectives; i.e. Collaboration, research, complete tutorials, research some more, rinse and repeat…

But first, I want to elaborate on our primary objectives:
1.  Refactor online-tracker-component.ts to include a service.
2. 
Begin the implementation of an offline capture data service.

Our first goal, refactoring the online tracker component, proved to be a lot more simplistic than the second. For the most part, it only took moving around code from one file to another. The end result is the online-tracker-component now calls functions from the new online-tracker-service to determine whether there is an internet connection. Though a simple refactoring modification, this change should be beneficial to all teams in the near future. We can now use our new online tracker service to call functions to check for connectivity status. Since all teams are working towards an offline module for AMRS, we feel this is essential for any of us to go forward.

The good news is the AMPATH development team will likely accept the pull request for our online-tracker modification once we make the tests pass. I should get this done by the end of this weekend, if not later today. In the meantime, if anyone wants to checkout our refactored online tracker implementation, the commit is available on my forked repository here.

Implementing an offline data capture service ultimately proved to be our greatest endeavor. We chose to approach this situation by first evaluating various techniques to achieve an offline capturing ability. PouchDB appeared to be the most promising tool from the start. Our reasoning was that other teams seem to anticipate using PouchDB themselves. We thought it would be best to do the same, so our future implementations would be compatible with other teams.

I initially hit a roadblock understanding the functionality of PouchDB. It appeared that PouchDB tutorials specifically aimed at Angular implementation were either scarce or low quality. Not only that, the AMPATH app seemed to fail every time we would try to import PouchDB directly into it. But other teams report to have had success using PouchDB’s TypeScript installation instructions. I will attempt this installation within the next couple of days, and will ask for feedback if I have any problems.

Fortunately through collaboration, my teammates and others were able to bring me up to speed. Originally I tried to follow the Getting Started guide on PouchDB, but the tutorial seemed not to be geared towards Angular implementation at all. But the Guides page is actually very helpful. The API page is also a great resource for an overview of PouchDB capabilities and syntax.

I had a chance to go through all the mini-chapters last night; PouchDB is making a lot more sense to me now. I will attempt to implement synchronization measures between PouchDB and AMPATH’s OpenMRS data during Spring Break.

It is worth noting that we began to look for alternatives to PouchDB. I actually found an informative tutorial regarding LocalStorage. This seems to be a JavaScript functionality that allows storage of data directly into the user’s browser. With the help of a tutorial geared towards the subject, I put together a simple Angular application implementing the LocalStorage functionality:

captured-objects-todo-app

It’s a simple little ‘breakable toy’ I’ve conjured up with the help of following the aforementioned tutorial. I put it up on GitHub if anyone is interested in looking at it. Ultimately, it looks like we’re going to move forward with PouchDB rather than using LocalStorage. PouchDB just seems like the logical choice; it appears very powerful, flexible and stable, especially in comparison to other alternatives such as LocalStorage. But it was fun experimenting with the functionality. And honestly, exploring all these various Angular capabilities is making me a lot more comfortable working with the framework. It seems like everything I’ve researched thus far regarding Angular has helped me understand the AMPATH application more, either indirectly or directly. So even though we likely won’t be moving forward with LocalStorage implementation, it’s great to know the functionality is there if we never need it in the future! Knowledge is power.

Overall, this sprint was quite eventful. Our collaboration as a team went well; communication is probably the best it’s ever been. We also had some cross-team communication, and all teams seem to be making great progress in enabling offline capabilities for the AMPATH application.

From the blog CS@Worcester – Jason Knowles by Jason Knowles and used with permission of the author. All other rights reserved by the author.