This week I was mostly working in checking the functionality of the system, looking at UI elements, following method calls related to surgery CRUD operations etc.
I found a few cases where a surgery validation failed when trying to enter a emergency procedure. The problem was that the surgery associated with the emergency procedure was not properly initialized, which caused it to fail validation. A few breakpoints with IntelliJ IDEA helped to solve that. Special thanks to Gayan Weerakutti for helping me to setup debugging.
Then there were some UI elements that didn’t appear properly. Checked through files and came across a set of JSON files that were apparently used for configuring the UI, but I couldn’t understand exactly how they interacted with the other files. They aren’t imported anywhere. I’m guessing the OpenMRS classloader is specially configured to look at the path they exist and read them if they’re there.
I’m gonna keep this one short, at least for now. You know the reason.
Last week, we decided to replace the Joda Time library with java.time and ThreeTen-Extra library. And that’s exactly what I did this week.
There were 3 steps to what I did.
Identifying the replacement classes.
Understanding the class structure to start the migration from the base classes.
Figuring out the best match for a given instance of replacement.
It might not look like much, but there was quite a bit of work once I got into it. I had already started off the replacement without much thought in the previous week. But as I later realized, it’s better to first look exactly where and how the base classes are used later.
Identifying the Replacement classes
The first step was figuring out which class of Joda Time maps to which of java.time or ThreeTen-Extra (henceforth known as TTX). Some of the classes like DateTime could be replaced with ZonedDateTime from the built-in library, while others like Interval needed the help of TTX.
There were some concepts like Hours, Minutes etc. that were replaced with Duration and Period. These were used in some calculations of the scheduling algorithm.
Understanding the class structure
It’s so much easier to start from the base classes and replace the library from inside out. This is because of our lovely IDEs that continuously parse the classes and perform semantic analysis to see if we’re using methods correctly. This is quite useful as then we can clearly see if and when we’re using a method wrong somewhere, use the IDE to suggest replacements and continue our work happily.
More importantly, it helps to understand why a particular type was used in the first place. Then I can make an informed decision for the next step.
Figuring out the best match
You can’t just blindly start replacing Joda Time with whatever fits. You need to look into the context. What’s the best way to replace DateTime used in an instance where it’s used to record the available times of an operation theater? I could go with a ZonedDateTime, or use a LocalDateTime that dropped the timezone. Heck, I could record them in Instants.
For recording the available times, I went with LocalDateTime. That’s because the available times are mostly for the scheduling work done locally. I could just add a timezone later if someone from Brazil wants to see when an operation theater in Rwanda operates.
What else? Oh yeah, we talked more about moving to an official repo under OMRS. It was agreed that it’s best to move at the end of the summer, when we have a concrete, ready-to-deploy module that others can also work on. So how could I show the world that I was working, making a contribution to the open source world, with those all-important green boxes on my GitHub profile?
I could make my fork into a standalone project! Just had to contact GitHub Support center. A kind lady there resolved the issue in hours. 👌
That’s it for last week. I hope you’ll excuse the brevity, at least for now. Do check out the repo and comment on my choices. Please, I may have made mistakes. You get the joy of pointing out mistakes, I get some of dat free code inspection.
First, exams got postponed a week because Sri Lanka was hit with the heaviest floods since 2003. The lower part of the country was basically washed off into the sea. Our thoughts and prayers are with those affected. Exams getting postponed meant I need to cover as much work as I can in this week.
Second, a weird error kept coming up out of nowhere. Some errors, you just gotta erase from your code.
Errors, Errors Everywhere
You know the best part of Java Exceptions? It’s how specific they are. You know the worst part? It’s how specific they are.
I was working on checking UI functionality of the Operation Theater module and there were errors as functions didn’t fire up properly. First there was a UI element that was incorrectly configured – a text area was given to be loaded from the EMR module, while it should have been from the UI Commons.
Then I started looking into the unit tests. If a unit test failed, that meant there was a difference between the older dependencies and newer ones. So I ran them, and of course, there they were.
The first set of errors all said that they could not autowire some beans of the Serialization Xstream module. I checked the POM files and that module was being loaded properly. But then it hit me – maybe the OT module needs the older APIs of the Xstream module. I had seen multiple APIs of the same module being loaded in a POM when looking through certain OpenMRS modules. So it occurred to me that I should first try loading the older API versions of the Xstream module.
And I did just that. Off went the autowiring issues. In came a different set of Hibernate issues. This time it said this.
GenericJDBCException: could not prepare statement
I looked around for this error and Stack Overflow said it could due to mixing newer and older versions of DB tools. Apparently there was a point in the DB call chain that didn’t work well with the rest of it which was newer. Or so I guess.
I checked to see if we were using HSQLDB but couldn’t find a mention of it. I was looking around when all of a sudden, everything just stopped loading.
Well, it went like this.
Previously, the module could be loaded to the Ref App 2.6 through the web interface. OpenMRS refreshed context and loaded classes without any problem.
But once I shut down the server, restarting it would throw an error saying the following:
... nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/openmrs/util/OpenmrsClassLoader) previously initiated loading for a different type with name "org/joda/time/DateTime"
Apparently, the class loader encounters a conflict with multiple Joda time versions. The class loader constraint violation would come up whenever I restarted the server. However, I could delete the module from the server’s folder manually, start the server and then load the module via the web interface for testing.
But now, I could not load the module even in a fresh server. When I try to load it via the web interface, the server would crash while refreshing the context, throwing ^that error. What the $%#*? How come it worked before and now doesn’t? Oh well.
How would I solve it?
I tried a few things.
Use Joda Time version mentioned in the other modules and give scope as provided.
Give dependency with compile scope.
Neither could put an end to my worry. Next step, ask the community!
Asked about this on the IRC channel but people could not help me. Then I looked at alternatives. Could we replace the whole thing? It’s Joda Time that causes the error. So let’s stop depending on it.
My mentors came to aid. We discussed the issue and I got to know that Joda Time had given trouble before as well. They were more than happy to stop relying on it.
It’s Time to move on.
Java 8 has a new library for Time related concepts, and I looked at comparisons between them. The new library was built-in, but it didn’t have many of the features that Joda Time had. The worst part was that we depended on some exclusive features like intervals. I realized this after I started working on replacing Joda.
Then, I found another library called ThreeTen-Extra that has just what we need – intervals. I asked if the mentors were okay with replacing one dependency with another and got the green light. I’m working on the replacement now, in a new branch.
We also decided that it’s best to bring the OT module to a repository under the OpenMRS org in GitHub. Right now, I’m working on a fork from the original GSoC student’s repo. He doesn’t seem to be active there anymore.
That’s about it for this week. Next one’s gonna be tough. Exams. You can find the discussion with mentors here.
This is the official blog for my Google Summer of Code 2017 project. I am going to be working for OpenMRS, an open source project that supports healthcare delivery around the world. It feels great to have been awarded this opportunity, thank you @Team OpenMRS! 😁
My project is to work on the Operation theater module, which has been made as part of GSoC 2014. It’s used to schedule surgeries and other operation theater activities in multiple theaters. The module was written for an older OpenMRS version, so my first task is to migrate it to the latest platform.
The next steps would be to make enhancements to the workflow. There are 3 stages in any operation theater activity – pre-theater, in-theater and post-theater. The enhancements will focus on the data collection procedures during the entire workflow of an activity.
Coding officially kicks off on the 30th of May. It’s the community bonding period right now, so I’m using this time to learn more about OpenMRS. It’s a wonderful community with people willing to help and share knowledge.
After discussions with my mentor, we decided to start early. So here I’ll be posting on my progress.
Setting Up the Dev Environment
OpenMRS has a nifty tool for working on their projects – the OpenMRS SDK. It allows you to run multiple instances of OpenMRS at the same time. Hence you can easily test something on different OpenMRS versions concurrently.
The original OT module had been written for platform version 1.9.7, and the current version is 2.0.5. I used the SDK to set up the OpenMRS Reference Application 2.6, which is built on that platform and has a slew of modules bundled with it. The idea is to migrate the OT module to the latest stable release first, then provide backward compatibility if and where necessary.
I use IntelliJ IDEA as the IDE as it has great documentation and support both within the OpenMRS community and outside.
Work so far
When submitting the proposal, I had identified database changes as a key point of consideration when migrating the module. So I decided to start with that.
Out of sheer curiosity, I first tried changing just the target platform version of the module and building against that. The module got compiled successfully, but failed some tests written for the older platform. Then I skipped the tests, and imported the built module to the Ref App via the web interface. Just for the kick of it. Well, the error logs weren’t pretty. But they taught me where to look.
Specifically, they taught me that the changes of Hibernate were causing trouble. The OT module was built for Hibernate 3.x, while OpenMRS currently uses Hibernate 4.x. SessionFactory was now used in place of DbSessionFactory.
The next step was changing the module dependencies to the ones included in the latest Reference Application. Reporting, ID Generation and many other modules had come a long way forward from their older versions used in the OT module.
Then I tried building the module again. It wasn’t going to be that easy of course. Tests failed, so I skipped them again. Imported the module again, but as expected, the module couldn’t start. Database errors were all over the place.
I perused the error logs and it seemed the bean definitions in the module application context were causing the errors. Looking into the file, the errors were caused by a set of beans defined for the Appointment Scheduling module, as it apparently didn’t have its own bean definitions at that time. The current version probably does.
So I commented off those beans, and rebuilt the module. Imported the module to the Ref App and voila! The module started! 😁
Right now the Operation theater module correctly appears in the UI, with scheduling and other functionality. Next step is to verify that it works properly, going through each action one by one. There’ll be lots of errors, lots of bug hunts. I can already feel the thrill of the hunt. Or the dread, you choose.
So yeah, we’re making progress. I plan to use the tests written before to identify the API calls and learn what has changed. The other option is to read the logs when errors come up.
So this started as an assignment but turned out to be quite fun by the end of it. We were asked to make a biometric identification system with Java using any biometric identifier. There was one restriction – no libraries were allowed. Out went OpenCV and pretty much anything that could be made to work reliably within the time-frame of a week.
My first thought was to make a voice identifier – a system in which the distinct features of someone’s voice would be saved in order to identify them uniquely. But that turned out to be far more time-consuming than I thought and involved libraries which I could not adopt. There wasn’t much time to write them myself. So after 3 days of struggling, I switched to keystroke dynamics.
What’s keystroke dynamics? It’s the official term for the unique way you type on a keyboard. Turns out that each of us use a keyboard differently – with more than just a change in overall speed. We spend different amounts of time pressing each key and moving onto another, have our own favourites among the Shift keys and have this unique patterns while moving from one key to another. I’m sure you’ve noticed these things. And these little things add up to a relatively strong set of features that can uniquely identify someone.
To make things more organized, let’s start with biometrics in general. A biometric identifier is a distinct, measurable characteristic that can be used to label and describe individuals. You’ve probably used the most popular one – that fingerprint scanner on your iPhone or Android. There are two main categories of biometric identifiers.
Physiological – relating to your body
Fingerprints, iris recognition, face recognition, DNA, hand geometry, body smell and more
Behavioural – involving the way you behave
Voice, typing rhythm, gait (basically the way you move)
Intro’s done. In our case, keystroke dynamics has the features I mentioned before, with some fancy technical terms for most of them. Here are some definitions to make our lives easier.
Dwell time – the time a key is kept pressed down.
Flight time – period between pressing times or releasing times of two keys. Sometimes measured as time between releasing one key and pressing another.
Digraphs & trigraphs – pairs & trios of letters that frequently appear together. In English, these inclue th, sh, tr, wh for digraphs and nth, sch, scr, spl, spr, str, thr for trigraphs. More generally, these are known as n-graphs.
Take a moment to think about these, especially the flight times and n-graphs. You would realize how each of us have different latencies associated with each n-graph. I myself type (a,s) and (i,o) within 50 milli seconds.
The verification methodology of this prototype application is quite crude at the moment, as mentioned below.
I first let the user type an arbitrary text and measured the dwell times for each key in a conventional US keyboard – the time each letter in English alphabet is kept pressed down. For example, user X dwells on key “Q” for 120 ms. This is taken as the average of all dwell times of occurrences of “Q” in the text. Then when a user, say Y, tries to identify himself as X, Y’s dwell time of “Q” is measured and let’ say it turns out to be 90 ms. The system checks whether the time difference for “Q” is within a range of 20 ms – did Y type within a safe range of 100 to 140 ms? If not, the system counts that Y failed to pass “Q”. If 10 or more such failures occur, Y is identified to be different from X.
Obviously, this is a very rough and arbitrary measurement. Test it with your friends and you’ll realize that the dwell times are more common than expected. But it was considerably accurate, given that only one parameter was being used. This is more of a proof-of-concept (and a last-moment assignment submission) to be fair. The system is to be extended with flight times and n-graphs in the future. Maybe.
You can find the code in GitHub. Give it a test run, why don’tcha?
When Achala asked me to help him out with an electronics class for kids, I didn’t know what I was signing up for. It was in June 2016 – I was free procrastinating uni work, and this seemed like a good distraction. I mean, it was kids. Plus electronics. Kids are fun(!). How hard could it get?
But no, oh no. Joining Igniter Space (formerly KidsIgnite) changed quite a few of things in my life, including some life goals. I’ve seen most, if not all, kinds of kids from angels to brats. I’ve had the chance to teach basic calculus & programming, and clean up snot. I’ve cuddled the cutest of kids, and had my hair pulled off with a plier.
Okay, a little background first for the less fortunate of you who haven’t heard about Igniter Space. Essentially, it’s a makerspace – a place where people gather and work on computing or other technological projects. From the outside, you’re forgiven for mistaking it for an electronics class.
Igniter Space is a place where children learn the basics of robotics, electronics, programming, mechanical engineering and other skills that make an engineer. They start off with carefully planned activities that make them familiar with small electronic components, basic concepts of computer programming, building mechanical structures and so on. While doing all this, they’re encouraged to make use of the knowledge they gather and build stuff on their own. Think it’s a little far-fetched? Try their Facebook page. The little minds have come up with things that will make you feel little.
So yeah, now that intros are done, back to my story. We have classes on weekends, and I am one of the instructors guiding the kids with their activities. On a normal day, I meet a group of 6 to 12 kids each from the Tech Beginner, Master & Leader classes. Oh okay, the title might be misleading but hey, I’m a responsible daddy. Numbers don’t matter if you take care of ’em all. I help them to understand the principles of machinery and coding that miraculously lands them a toy (or game) to take home at the end of the class.
The first thing to note here is that the children are encouraged to do the activity on their own. Let it be a vibrating Ladybird bug or the classic Atari Breakout block breaker game, it has to be their own work. But being the curious new followers of the path they are, the kids ask for our help more often than not. It could be for a tip on soldering the wires to the small vibro motor, or how to keep track of the blocks broken with a variable on Scratch – the programming tool we use. So we teach them where to heat up or what variables to use and watch them do it for themselves.
We make every effort to make sure the children understand what they’re doing, and most of them do. But due to karma or decisions of the divine being reigning supreme, not all kids are created equal. Some need a little push in the right direction. A lot do the activities with normal supervision and a question now and then. A few finish it early, and make modifications that make us go “wow, how did you come up with this?”
Looking around the table, I can see the hyper-intelligent, the curious, and the ones with special needs. We nurture them all. It’d have been a perfect, spiritually satisfying experience if not for the nagging voices that go “sir, can you help me with this?” every few milli seconds. Okay okay, I’m kidding. It’s not that bad. The beginners don’t ask a lot of questions. They usually wander off on their own trails of thought and build different things. At the end they’re shouting to each other saying his or her toy is the most beautiful or colourful. They want to prove they’re the best. Sounds familiar, parents? These little things love to pull my hair or t-shirt and get a comment on their progress.
The intermediate are the noisiest. Being curious pre-teens, they have a lot of questions about the mechanics, the electronics and the programming blocks in Scratch. Plus they’re keen on making friends with the other kids and exchanging ideas, or complaining when someone else copies their exact design. Copyrights are a thing with the coming generations.
And the elder children. They’re mostly teens with hints of growing self-esteem. Questions are comparatively rare, for they usually try to figure out things on their own – either because they don’t want to seem ignorant in front of others or because they truly desire the joy of self-discovery. Probably both. Most questions are quite intelligent too, usually asking about different outcomes if they change something here or there. Sometimes they come in front of the class and answer questions. I feel most connected with this group. I’m not exactly a saint with the beginner rug rats.
So yeah, I feel like a father teaching the wonders of the world while showing a kid how to light a bulb with a battery or make a ball move on a computer screen. There’s a special kind of satisfaction in seeing their faces go “oh” when comprehension strikes them hard. Juggling a full table of them is no small feat, and you’ve probably had a tinge of the experience if you’re a parent. Just a tinge, yeah. You didn’t cope with my lot.
My lot. Love em or hate em, I own a little piece of them. Now let me go thank my parents for putting up with this particular rascal.
At the time of writing this article, Materialize CSS framework’s Autocomplete widget didn’t work properly with AJAX calls. So I gave it a go myself.
Ideally, the autocomplete widget should have the following features.
AJAX calls must be made only after a certain minimum number of characters are entered.
Requests must not be sent until the user stops typing into the box. This means setting a reasonable timeout to check end of typing.
If a request is already on its way when the user enters more characters, the existing request must be cancelled before sending a new one.
Clicking a result or outside the results list must close the list.
Certain keys should not trigger AJAX calls.
The results must be scrollable with arrow keys and selectable with Enter.
The code looks something like this. A few important things are explained below it.
You can remove the timeout or escape fewer keys if you want. I used GSMArena’s search function to make a working demo, which you can test here. Note that you need to enable loading scripts from unauthenticated sources, so better try it with Chrome . Even with Chrome you need to allow loading such scripts with a teeny tiny notification that appears at the end of the address bar. The demo has images and the results link to other pages. Open the developer tools in your browser and notice how requests get cancelled if you type with small intervals. Try scrolling through the results with arrow keys. You probably don’t need to add an image to the list item or link it to another page. The idea is that you can, if you want to.
The code is pretty much self-explanatory, but let me point out a few important things.
I’m getting all the results from the AJAX call and appending them to a single, long string, and then appending that string to the autocomplete dropdown in one go as a single jQuery object. This is more efficient than appending each result individually, taking full advantage of the ability of jQuery to insert a chunk of html in a string. This article has a great analysis of jQuery append() method to explain why I did this.
Control keys such as Shift, Ctrl, Alt etc. are escaped conditionally. The conditional check uses the or operator for this, which kind of makes it long. Better alternative approaches are more than welcome.
Please suggest if you have any improvements to this code.