forked from cerner/cerner.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
1857 lines (1390 loc) · 145 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Engineering Health]]></title>
<link href="http://engineering.cerner.com/atom.xml" rel="self"/>
<link href="http://engineering.cerner.com/"/>
<updated>2017-03-24T15:37:22-05:00</updated>
<id>http://engineering.cerner.com/</id>
<author>
<name><![CDATA[Cerner]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Engineers on the Road for SMART and FHIR (CHC 2016)]]></title>
<link href="http://engineering.cerner.com/blog/engineers-on-the-road-for-smart-and-fhir/"/>
<updated>2017-03-24T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/engineers-on-the-road-for-smart-and-fhir</id>
<content type="html"><![CDATA[<p>Over the past few years, Cerner has been developing a standards-based platform on top of our Cerner Millennium® EHR. Rather than roll our own API, we’ve been using the <a href="http://hl7.org/fhir/overview-dev.html">HL7® FHIR® standard</a>. For app integration, we’ve been using the <a href="http://docs.smarthealthit.org/">SMART® on FHIR specification</a>. If you’re not immediately familiar with those acronyms, you’re definitely not alone.</p>
<p>As we were developing the services, we were also fielding questions from 3rd party developers, answering a lot of questions internally, and trying to keep up with the specifications themselves. We knew that we would need to help provide education around our ecosystem, our implementation of the FHIR and SMART standards to developers since the standards are new and evolving.</p>
<p>This need will become much more pressing because <a href="https://www.healthit.gov/providers-professionals/how-attain-meaningful-use">Meaningful Use 3</a> will trigger deployment of our implementations out to most of our Millennium EHRs. <a href="https://www.cdc.gov/ehrmeaningfuluse/introduction.html">Meaningful Use</a> introduces requirements from the Centers for Medicare and Medicaid (CMS) to modernize the US healthcare infrastructure. This is nothing new, but we’ve been hard at work to support stage 3, which includes the requirement for patients to access their data via an API. In order to attest, most of our clients will then require our implementation of the FHIR API.</p>
<p>This past November offered up two exciting opportunities to provide hands-on instruction and support, which we’ll cover in separate posts. In this first post, we want to highlight the work we did at our annual <a href="https://blogs.cerner.com/blog/CHC16-Summary-UK/">Cerner Health Conference</a>. We decided that this year’s event would be a great opportunity to offer a small Code Learning Lab – providing education for some of the APIs that Cerner has available.</p>
<p>The Code Learning Lab was run from November 14th – 17th in Kansas City with our annual CHC conference. The goal: give developers a hands-on training session with the different APIs that are part of the Cerner Open Developer Experience (<em>code</em>). One of the tracks covered SMART and FHIR specifically, while another went over some of the APIs available with our HealtheIntent and HealtheLife platforms.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2017-03-24-engineers-on-the-road-for-smart-and-fhir/smart-and-fhir-01.jpg"></p>
<p>We saw participation from many of our clients and partners, from both the US and Canada. Over the four days, the lab was in the format of an overview or “lecture” followed by a longer hands-on lab to put what participants were learning to use. During the labs, our engineers would walk around to check on how everyone was doing, answer questions, and help troubleshoot.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2017-03-24-engineers-on-the-road-for-smart-and-fhir/smart-and-fhir-02.jpg"></p>
<p>We received a lot of comments and excitement from everyone participating around the fact that our engineering team itself was involved in the learning lab. It was also very exciting for the engineering team to watch everyone try out our newer developer tools, read our documentation, and then put it to practice. Not only were the participants able to actually see the data coming back, but there were a lot of conversations that occurred that will help us improve the class (and our tooling) in the future to make the event better. In the end, it was a great experience for everyone involved!</p>
<p>If you’re interested, you can check out some of the presentations and labs that were created for the learning lab here: <a href="https://github.com/cerner/ignite-learning-lab">https://github.com/cerner/ignite-learning-lab</a> and our SMART tutorial: <a href="http://engineering.cerner.com/smart-on-fhir-tutorial/#prerequisites">http://engineering.cerner.com/smart-on-fhir-tutorial/#prerequisites</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[One Cerner Associate's Contributions in the Tech Industry]]></title>
<link href="http://engineering.cerner.com/blog/micah-whitacre-recognition-blog/"/>
<updated>2017-03-16T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/micah-whitacre-recognition-blog</id>
<content type="html"><![CDATA[<h3>Background:</h3>
<p>Micah is currently a software architect in Population Health Development in Healthe Intent Development at Cerner. In 2013, Micah Whitacre received committer status on the <a href="https://crunch.apache.org/">Apache Crunch</a> project, and is now a Project Management Committee (PMC) member of the project.</p>
<h3>How has Cerner been been involved in Apache Crunch?</h3>
<p>In 2012 and 2013, Cerner started using this project within several solutions. We also wanted to give back to the community and decided to invest time in helping answer questions and concerns, and overall project needs. We wanted to get involved in small community like <a href="https://crunch.apache.org/">Apache Crunch</a> since it brought great value to our Cerner solutions.</p>
<h3>What does it mean to be receive committer status on Open Source?</h3>
<p>In 2013, I was selected as a committer on <a href="https://crunch.apache.org/">Apache Crunch</a>. In reference to the technical aspect, Apache projects have some form of criteria for when to accept a committer to a project. Election to being a committer is the result of consistent and high quality contributions to the project, through documentation, code, or helping to build the overall community.</p>
<p>Being selected as a committer was an unexpected honor. It’s also an additional responsibility for my involvement with the project. I closely watch for questions and make enhancements and functionality code changes. There are fourteen other committers on the project as well.</p>
<h3>What does it mean to be an Apache Crunch PMC?</h3>
<p>After being a committer for over a year, I was selected as a PMC of <a href="https://crunch.apache.org/">Apache Crunch</a>. The goal of a PMC is to set the pace and the direction of the community, as well as facilitate how the community is interacting. PMCs help drive releases and help grow the committee. Some of my other responsibilities also include participating in discussions about voting people into the community, new releases of code, and which functionalities need to get fixed.</p>
<h3>What are your favorite parts about being a committer?</h3>
<p>One of the coolest parts about being a committer is making new connections with larger tech community. It forces you to build new relationships and talk to people you may have not spoken to before. It’s cool being able to meet new people who don’t work at the company you’re working for. I also enjoy being able to look at the project as a whole and figure out the right way to solve something, rather than solving it right now.</p>
<p>I’ve also spoken I’ve spoken at ApacheCon twice on <a href="https://crunch.apache.org/">Apache Crunch</a>, which have been awesome opportunities.</p>
<h3>How else are you involved in the tech industry?</h3>
<p>I also like to be involved in our development culture at Cerner, helping improve our internal community and increasing awareness of Cerner in the industry. I’ve been a member of the planning committee and have spoken at our internal conference, DevCon, given internal tech talks at Cerner, and have also spoken at industry conferences like Kafka Summit 2016 and Midwest.io 2014. I’ve also written an Engineering Health blog (Scaling People with <a href="https://crunch.apache.org/">Apache Crunch</a>). I am an open source reviewer for Cerner projects, helping review and provide feedback on Cerner open source projects prior to them being published.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Automated Deployment With Apache Kafka]]></title>
<link href="http://engineering.cerner.com/blog/automated-deployment-with-apache-kafka/"/>
<updated>2017-02-16T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/automated-deployment-with-apache-kafka</id>
<content type="html"><![CDATA[<p>It’s likely not a surprise that Cerner would use <a href="http://kafka.apache.org/">Apache Kafka</a>
as we have used a number of related technologies like <a href="http://engineering.cerner.com/2013/02/composable-mapreduce-with-hadoop-and-crunch/">Apache Hadoop</a>
along with its Map/Reduce, HDFS and even <a href="http://engineering.cerner.com/2013/02/near-real-time-processing-over-hadoop-and-hbase/">Apache HBase</a>.
Our team first started using Apache Kafka in 2014
when Kafka 0.8 first came out. Since then we’ve expanded to using Kafka for a
number of different use cases
(<a href="http://blog.cloudera.com/blog/2014/11/how-cerner-uses-cdh-with-apache-kafka/">1</a>, <a href="https://www.confluent.io/kafka-summit-2016-users-ingesting-complex-healthcare-data-with-apache-kafka">2</a>)
and it has become a core piece of Cerner’s infrastructure.</p>
<p>Just like the <a href="http://engineering.cerner.com/blog/deploying-web-services-with-apache-tomcat-and-chef/">applications we create</a>,
we also needed to automate the deployment of Kafka to handle the ever growing
amount of operations work and to ensure a high level of consistency with our
environments. <a href="https://www.chef.io/chef/">Chef</a> was an obvious choice for us since
its been our deployment tool of choice for the last few years. We quickly put together a
<a href="https://github.com/cerner/cerner_kafka">cookbook</a> to help us automate the
deployment of the many Kafka clusters here at Cerner. We have
<a href="https://github.com/cerner/cerner_kafka/blob/master/CHANGELOG.md">continued to support and use this cookbook</a>
after open-sourcing it upgrading it to handle newer versions of Kafka (0.9, 0.10),
handle Kerberos authentication, and <a href="https://github.com/cerner/cerner_kafka/issues?q=is%3Aissue%20is%3Aclosed%20">many other improvements</a>.</p>
<p>If you use Apache Kafka, feel free to <a href="https://github.com/cerner/cerner_kafka">try it out</a>
and let us know how it works for you.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Beadledom - Simple Java Framework for Building REST APIs]]></title>
<link href="http://engineering.cerner.com/blog/beadledom-simple-java-framework-for-building-rest-apis/"/>
<updated>2017-02-15T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/beadledom-simple-java-framework-for-building-rest-apis</id>
<content type="html"><![CDATA[<p>Beadledom is a framework for building Java based web services. It bundles several open sourced components required for building JAX-RS services.</p>
<h3>Why?</h3>
<p>HealtheIntent, Cerner’s population health management platform, started 3.5 years ago. We went through the process of investigating different technologies for the platform. We decided on using Java for building services and arrived on a set of libraries that we believed work well together.</p>
<p>The long history of Java has led to an ocean of libraries that are available to Java developers. Picking up the right set of tools is very important to get the job done the right way. The trickiest part is to know what “the right set of tools” are. This is only the first of many tough decisions that a developer makes during the lifecycle of a project.</p>
<p>If choosing the libraries for a project is a game, then getting them all to play well together is a whole new game. Beadledom not only brings all the awesome java libraries together but also binds them well, making the developer’s life easy. It gives a good head start to the developer by letting them start from a strong foundation.</p>
<p>At Cerner we understand how important and tedious these decisions are and we always want to contribute back to the community. So we open sourced Beadledom because it helped us develop our platform quickly and consistently. We hope that others in the community can also leverage its power.</p>
<h3>What?</h3>
<p>Beadledom uses several open source projects that are widely used and well maintained. Below is a list of a few of the major components that Beadledom uses.</p>
<p>Guice for gluing and bootstrapping components;
Jackson for JSON serialization/deserialization;
Resteasy for JAX-RS implementation;
Stagemonitor for Monitoring and metrics;
Swagger for API Documentation;
Apache Commons-Configuration for handling different types of configurations consistently.
Where?
You can find the source code on GitHub. Please find our documentation at <a href="http://engineering.cerner.com/beadledom/.">http://engineering.cerner.com/beadledom/.</a></p>
<h3>Who?</h3>
<p>Below are the core developers of Beadledom:
John Leacox
Sundeep Paruvu
Nimesh Subramanian
Brian van de Boogaard
Supriya Lal
Here is the complete list of contributors who made Beadledom awesome.</p>
<h3>Cookie Cake Time!</h3>
<p>Cerner takes pride in our open source contributions. When teams contribute to the community Cerner rewards them with a cake. Here is the cookie cake for Beadledom.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2017-02-15-beadledom-simple-java-framework-for-building-rest-apis/beadledom-01.png" title="Beadledom Cookie Cake" ></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[ShipIt VII Day: Winter 2016]]></title>
<link href="http://engineering.cerner.com/blog/shipit-vii-day-winter-2016/"/>
<updated>2017-01-18T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/shipit-vii-day-winter-2016</id>
<content type="html"><![CDATA[<p>Cerner’s 7th ShipIt Day took place on December 8th and 9th. ShipIt is a 24-hour hackathon with the
goal of building something awesome, usable, and value-adding within a single day. The event was
hosted at our DevCenter in the Realization Campus, a large open space that hosts our DevAcademy (to
learn more about our DevAcademy, check out this
<a href="http://engineering.cerner.com/2013/08/devacademy/">earlier post</a>). We had 18 teams made up of
associates from different Cerner organizations. The DevCenter was stocked with all kinds of snacks,
which of course included a traditional drink: Monster Energy. Participants worked hard all day long
and when dinner came around they were ready to dig in. Good thing we ordered 8 twenty-six inch
pizzas and 40 breadsticks from a local Kansas City favorite, <a href="http://www.pizza51.com/">Pizza 51</a>.
Look how big these pizzas were!</p>
<div align="center">
<table>
<tr>
<td><img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-01.jpg"></td>
<td><img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-03.jpg"></td>
</tr>
</table>
</div>
<p>It was predicted we hit a record in Kansas City for the most pizza in an elevator at this time, but
we were not able to get an official count!</p>
<div style="float:left;" >
<img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-04.png">
</div>
<p>When getting pizzas of this size, there was a significant amount to fuel the innovation that was
happening. To break it down:</p>
<p>A = πr<sup>2</sup> = π x 132 ≈ 530.93 square inches = 3.68 square feet x 8 = 29.44 square feet of pizza. Which
is larger than a twin bed size of solid pizza, and slightly smaller than a queen bed. A perfect
amount for a ShipIt event! Teams took a break from their work throughout the evening by playing
Nintendo and cheering on the <a href="http://www.chiefs.com/">Chiefs</a>!</p>
<div align="center">
<table>
<tr>
<td><img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-00.jpg"></td>
<td><img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-07.jpg"></td>
</tr>
</table>
</div>
<p>There were some impressive projects that came out of ShipIt Day VII. <em>Team GLADoS</em>, made up of Kyle
Harper, Sarah Harper, Snehit Gajjar, and Andy Quangvan took first place, and the coveted Golden
Keyboard, with their impressive idea.</p>
<blockquote><p>This ShipIt, we created a new <a href="https://developer.amazon.com/alexa">Alexa skill</a> called Scribe.
With our new skill we integrated the
<a href="https://www.amazon.com/All-New-Echo-Dot-2nd-Generation/dp/B01DFKC2SO/ref=cp_aucc_ods">Amazon Echo and Echo Dot</a>
smart speakers with <a href="https://code.cerner.com/">Cerner’s FHIR implementation</a>. This integration allows
a patient or care provider to access clinical data by simply speaking to the Echo.</p></blockquote>
<p>Judge Sean Griffin was impressed. “Really cool, awesome idea. Great innovation! The applicability
towards data entry could definitely be useful.”</p>
<div align="center">
<img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-08.jpg">
<sub>Team GLADos with the Golden Keyboard</sub>
</div>
<p>Second place went to <em>Team Trogdor</em> (Kyle Lipke, Derek Dobler, Nikki Justice, Mike Harrison,
and Nimesh Subramanain).</p>
<blockquote><p>Troubleshooting errors or misconfigurations in Millennium OAuth can be time consuming. Missing
information or misconfiguration can lead to hours of checking various sources of information. This
web page tool allows us to perform a quick and accurate diagnostic check for what pieces are
available and not available. Built with Ruby on <a href="http://www.sinatrarb.com/">Sinatra framework</a>.
Made to allow for easy additions to various checks that ETS (Emerging Technology Services group)
needs to do.</p></blockquote>
<p>Judge Jim Dwyer noted, “This is a great tool to help drive down operational costs and reduce TCO.”</p>
<div align="center">
<img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-05.jpg">
<sub>Team Trogdor</sub>
</div>
<p>Third place winners, <em>Team 402 Cheeseballs Required</em> (Andy Nelson, Venkatesh Sridharan, Ian Kottman,
Nate Schile, and Anthony Ross) created an application for tracking running mileage for the
<a href="https://www.youtube.com/watch?v=w18fgEcMi7w">Healthe Fitness Center</a>.</p>
<blockquote><p>Our goal was to make the process of submitting running milestones for the Cerner Running Club
easier. The current process involved writing down how far you ran in a binder, and then one of the
gym staff checking that binder occasionally to see when you accomplished a milestone so they could
send a prize. We decided to make a web application that would integrate with Strava that would
simplify tracking how far you’ve run. <a href="https://www.strava.com/">Strava</a> is a platform that
aggregates data from multiple fitness apps, such as <a href="https://www.fitbit.com/">Fitbit</a> and
<a href="https://buy.garmin.com/en-US/US/cIntoSports-cRunning-p1.html">Garmin</a>.
We used the <a href="https://strava.github.io/api/">Strava API</a> to pull a person’s running data so
we could total up their mileage, regardless of what fitness tracker they used. In order to
integrate with Strava’s public API we had to have an externally facing application. We decided to
use an <a href="https://aws.amazon.com/ec2/">Amazon EC2</a> instance to do this, since it was easy and cheap.
We used <a href="http://rubyonrails.org/">Rails</a> to create our web app since that was the web framework
we had the most experience in. First, we would ask a person to connect to their Strava account,
and then we pulled their running data and totaled up their mileage. If a person had reached a
milestone they could press a button to send an email to the gym staff that included their
running log, their total mileage, and what milestones they had achieved.</p></blockquote>
<div align="center">
<img class="center" src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-06.jpg">
<sub>Team 402 Cheeseballs Required</sub>
</div>
<p>By Friday at 10 a.m. the participants were ready to present (for the most part). Cerner associates
from different campuses watched the event via livestream and voted for People’s choice. Those
results are as followed…</p>
<p><strong>Favorite team name</strong>: <em>I Shipped My Pants</em> – Brandon Inman and Steven Goldberg</p>
<blockquote><p>Improvements made to the existing
<a href="http://techblog.netflix.com/2016/08/vizceral-open-source.html">Vizceral-based implementation</a>
of HealtheIntent Intuition
Engineering. Improvements made by the team included features to make it easier to switch between
streaming and batch processing, more timely updates of data, and several cosmetic features to
improve user experience and differentiate the tool from other Vizceral apps. Voice activation was
added as a “fun” feature.</p></blockquote>
<p><strong>Favorite Presentation</strong>: <em>Guys on FHIR</em> – Bhaumik Aniruddha, Bhagat Parthiv, Vetri Selvi Vairamutha,
Neil Pfeiffer, Sai Praveen Gampa</p>
<blockquote><p>Our ShipIt project was a NICU SMART App, intended for the NICU unit. The app will be used to get a
live video of the baby inside an incubator alongside the vitals of the baby. This will prevent
anyone from disturbing the sleeping pattern of the newborn. The live feedback can also be viewed
by the parents which will ease the mental tension. The future scope of this project is to hook up
with an app, which can read the facial expression of the baby.</p></blockquote>
<p><strong>Best Project</strong>: <em>RSA (Readmission Security Admission)</em> – Kristopher Williams, Karthik Nimmagadda, Sai
Inampudi</p>
<blockquote><p>Our project was to create an intuitive dashboard that lets the user visualize the network traffic
for readmission solution’s services for a given time period (hour/day/week/month currently). This
dashboard will allow the user to easily and quickly identify abnormal behavior (e.g. service goes
down, or service experiencing a lot of errors) and is designed in such a way as to return results
extremely fast for longer time spans, compared to ad-hoc splunk queries.</p></blockquote>
<div align="center">
<img src="http://engineering.cerner.com/assets/2017-01-18-shipit-vii-day-winter-2016/shipit-02.jpg">
<sub>People’s Choice Winners</sub>
</div>
<p>ShipIt Day continues to be a great way for Cerner associates to work on projects they don’t normally
have time for, meet people in different organizations and learn something new. Participant
Kristopher Williams said:</p>
<blockquote><p>My favorite part of ShipIt Day was being able to work on something entirely different, and in my
case, with a different group of people. Just a fresh change of pace.</p></blockquote>
<p>Thank you to all our participants and a special thanks to our judges Jenni Syed
(<a href="https://twitter.com/JenniSyed">@JenniSyed</a>), Yegor Hanov, Sean Griffin
(<a href="https://twitter.com/trenchguinea">@trenchguinea</a>), and Jim Dwyer
(<a href="https://twitter.com/episodicdata">@episodicdata</a>).</p>
<p>Check out some additional highlights of our event in this video:</p>
<iframe width="560" height="315" src="//www.youtube.com/embed/iqTp0dmLgUk" frameborder="0" allowfullscreen></iframe>
<p>If you are interested in reading more about previous ShipIt Day events, see these earlier posts:</p>
<ul>
<li><a href="http://engineering.cerner.com/blog/fall-2016-shipit-day/">Fall 2016 ShipIt Day</a></li>
<li><a href="http://engineering.cerner.com/blog/spring-2016-shipit-day/">Spring 2016 ShipIt Day</a></li>
<li><a href="http://engineering.cerner.com/blog/shipit-hackathon-mplus/">ShipIt – 24-hour hackathon for Millennium+ Platform Dev</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Alan and Grace: An Origin Story]]></title>
<link href="http://engineering.cerner.com/blog/alan-and-grace-an-origin-story/"/>
<updated>2016-11-23T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/alan-and-grace-an-origin-story</id>
<content type="html"><![CDATA[<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/alan-grace.png" title="Alan and Grace" ></p>
<p>Meet Alan and Grace. These lighthearted, 8-bit characters were nominated in
early 2014 to become the iconic mascots of Engineering at Cerner. Have you ever
wondered who these 80’s video gaming inspired characters on our Engineering
t-shirts are? Why were they chosen as mascots? What do they represent? The
countless hours spent pondering these questions will be no more. Pull up a
chair as we dive into the mystery behind the dynamic duo known as Alan and
Grace.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/shirt-laptop.png" title="Laptop and t-shirt" ></p>
<p>Believe it or not, the enjoyable pair highlighted on a myriad of our engineering
materials were named after two real life innovators: Alan Turing and Grace
Hopper. Alan and Grace were visionaries in their time, championing advances
that shaped the computer science innovations of today. These icons were chosen
based on their contributions to computer science and the moxie they showed while
doing it.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/alan-8bit.png" title="Alan" ></p>
<p>Alan, our spiky haired friend who embodies an 80’s meets hipster vibe, is named
after the English mathematician Alan Mathison Turing (1912-1954). Turing is
known to some as the father of theoretical computer science and artificial
intelligence. Alan had an unquenchable mind and was in constant pursuit of
knowledge, devoting his life to a vocation in science and mathematics as a
computer scientist, mathematician, logician, cryptanalyst, and theoretical
biologist. Among his many contributions is the notable Alan Turing Enigma
machine. The machine was used to help break the enigma code used in German
naval communications during World War II. The concept of the Turing Enigma
machine has become the foundation of the modern theory of computation and
computability. Alan and his Enigma machine have received some recent fame as
featured in the Imitation Game, a 2014 American historical drama-thriller
loosely based on the biography Alan Turing: The Enigma. It can be argued that
computer science would not be what it is today without the mathematical
imagination of Alan Turing. Cue the mic drop now.</p>
<div align="center">
<img class="left" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/alan-turing.jpg" title="Alan" >
<img class="right" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/turing-machine.jpg" title="Turing Machine" >
<sub>Sources: <a href="http://www.alanturing.net/turing_archive/graphics/photos%20of%20Turing/pages/alan1_psd.htm">alanturing.net</a>, <a href="http://worldnews.nbcnews.com/_news/2013/12/23/22025978-queen-pardons-computing-giant-alan-turing-59-years-after-his-suicide">nbcnews.com</a></sub>
</div>
<hr />
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/grace-8bit.png" title="Grace" ></p>
<p>Cerner Engineering’s jovial female mascot appears as if she’s ready to take on
the world. The fearless spirit of the mascot encompases the nature of its muse
for whom she was named, Grace Brewster Murray Hopper (1906-1992). Grace Hopper
was an American mathematician, computer programmer, military leader, and a woman
clearly ahead of her time. Grace received a Ph.D. in mathematics, one of the
first women to earn this level of education. Grace’s path to computer science
began while serving in the U.S. Naval Reserve as one of the first to program the
Harvard Mark I computer. Grace went on to create the first compiler for
computer languages leading to COBOL, a widely adapted language that would be
used around the world. But Grace wasn’t finished yet. At the age of 60, she
was recalled to active duty where she standardized communication between
different computer languages. When Grace retired at the age of 79 as a rear
admiral, she was the oldest serving officer in the service. In 1991, Grace was
the first women awarded the National Medal of Technology. Throughout her life,
Grace encouraged young people to learn how to program. Grace’s legacy lives on
through the Grace Murray Hopper Award, the Grace Hopper Celebration of Women in
Computing Conference, the University of Missouri’s computer museum “Grace’s
Place”, and now Cerner’s Engineering mascot. Grace continues to serve as an
inspiration to women in tech everywhere. Was there any other choice?</p>
<div align="center">
<img class="left" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/grace-hopper.jpg" title="Grace Hopper" >
<img class="right" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/grace-hopper-2.jpg" title="Grace Hopper" >
<sub>Sources: <a href="http://www.womenatworkmuseum.org/envision-engineering.html">womenatworkmuseum.org</a>, <a href="https://en.wikipedia.org/wiki/Grace_Hopper">wikipedia.org</a></sub>
</div>
<p>Alan and Grace represent a beacon of inspiration, providing icons that
encapsulate and promote a culture of innovation, forward thinking, and just
plain fun. The creation of mascots Alan and Grace has been a big win for the
passionate Cerner engineers dedicated to fostering Cerner’s Engineering culture.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-23-alan-and-grace-an-origin-story/alan-grace-2.png" title="Alan and Grace" ></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Clara Rules Joins Cerner's Open Source]]></title>
<link href="http://engineering.cerner.com/blog/clara-rules-joins-cerner-open-source/"/>
<updated>2016-11-11T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/clara-rules-joins-cerner-open-source</id>
<content type="html"><![CDATA[<p>Sometimes a small experiment on the side can grow into something valuable. We at Cerner have long
used forward-chaining rules engines to express and execute clinical knowledge, but we’ve also had to
extend or work around the capabilities of such engines. Engines targeting business users just
weren’t expressive enough to model some of our logic. To meet this need we are making Clara Rules an
open source project driven by Cerner Engineering.</p>
<p>Clara took an unusual path, starting as a minimal implementation of the
<a href="https://en.wikipedia.org/wiki/Rete_algorithm">Rete algorithm</a> to help my
own understanding. After sharing this with others at Cerner, we started to see an opportunity to
gain the modularity and reasoning advantages of a rules engine, while preserving the expressiveness
and power of a modern programming language. We wanted to combine the best ideas of rules engines
with good software engineering practices. You can see the result of this on the
<a href="http://www.clara-rules.org">Clara Rules home page</a>.</p>
<p><a href="https://github.com/mrrodriguez">Mike Rodriguez</a> has been essential in turning Clara from an
experiment into a valuable system to fill a gap for rules engines which are oriented towards
developers. More recently, <a href="https://github.com/WilliamParker">Will Parker</a>
has also made significant contributions to help make Clara fast and reliable. They made it possible for Clara
to help analyze millions of medical records every day. Therefore Mike and Will are joining as the
initial committers to Cerner Engineering’s Clara project. We will welcome other contributors to make
this step in the future.</p>
<p>You can find project <a href="https://github.com/cerner/clara-rules">source code on GitHub</a>, and the
documentation on the <a href="http://www.clara-rules.org">clara-rules.org</a> site.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Fall 2016 ShipIt Day]]></title>
<link href="http://engineering.cerner.com/blog/fall-2016-shipit-day/"/>
<updated>2016-11-08T00:00:00-06:00</updated>
<id>http://engineering.cerner.com/blog/fall-2016-shipit-day</id>
<content type="html"><![CDATA[<p>Another ShipIt Day was held on September 8th-9th at the Realization Campus at Cerner. ShipIt is a
24-hour hackathon with the goal of building something awesome, usable, and value-adding within a
single day. This fall marked our sixth ShipIt, which has has grown significantly since our first
event.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-08-fall-2016-shipit-day/shipit-sign.jpg" title="Announcement" ></p>
<p>The event kicked off in the morning at the auditorium of our Realization campus. At this point,
teams were already formed, instructions were given, and shirts were handed out. This ShipIt day came
with cool new t-shirts for all participants featuring the ShipIt squirrel (<a href="https://www.quora.com/GitHub-What-is-the-significance-of-the-Ship-It-squirrel">inspired by GitHub</a>)!</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-08-fall-2016-shipit-day/shipit-squirrel-shirt.jpg" title="ShipIt shirt" ></p>
<p>Teams broke out to their work spaces and got to work on their projects. One team, <strong>LearnStack</strong>,
decided to focus their project on associate development. The judges greatly appreciated their
approach to this very real problem, and decided to award them the third place prize.</p>
<p><strong>LearnStack</strong> – Jake LaCombe, Daniel Stucky, Sujay Sudheendra</p>
<blockquote><p>Developers can get to a struggling point when they try to increase their experience level. Sure,
getting started with any language can be very easy to do. Rails for example has their
<a href="https://www.railstutorial.org/">impressive tutorial from Michael Hartl</a> for getting started
with the framework. However, what happens when you
get done with those beginning steps? What does it take to go from a beginner to an intermediate
Rails developer, and then again from Intermediate to Advanced?</p>
<p>The answer here is LearnStack. LearnStack takes a list of resources that are recommended by other
developers, and rated appropriately based on the experience level of the material. Developers can
easily share resources related to beginner, intermediate, and advanced knowledge of a particular
language, process, framework, or whatever it may be. No need to keep doing endless searches online
to figure out how to get to the next level! Let LearnStack point you to the resources you need!”</p></blockquote>
<p>Another team decided to tackle the time it takes to provision a virtual machine. This team called
themselves, “All your base are belong to us,” and they were awarded second place.</p>
<p><strong>All your base are belong to us</strong> – Chris Soukup, Alex Harder, Ben Hemphill</p>
<blockquote><p>The current situation for OS image creation is that it is done infrequently, in an ad-hoc manner,
with little consistency among the various hypervisors. This means that we take the base image and
then use <a href="https://www.chef.io/">Chef</a> to upgrade the image to the desired state. This adds significant
amounts of time to the process of provisioning a virtual machine.</p>
<p>Our project was to use <a href="https://www.packer.io/">Packer</a> to create a generic image with all of the
universal settings that we set with our base OS Chef recipe. This image can then be distributed to all
the hypervisors and made available to consumers. Since the image would be generated regularly, the
provisioning time could be significantly decreased by not having to immediately upgrade the system. Additionally,
since the universal settings are already applied, we save considerable amounts of time on the OS preparation
as well. We took provisioning time for a RedHat 7.2 <a href="https://www.openstack.org/">OpenStack</a> VM from 12 minutes,
50 seconds to 4 minutes, 1 second, a 320% decrease in time!</p>
<p>Future enhancements will allow us to automatically generate these images, distribute them, and make
them available to consumers. This will allow a consuming team to naturally stay current on OS
patches at provisioning time, decrease the human effort in creating these OS images, and provide a
consistent experience for teams across Vagrant, VMWare, OpenStack, EC2, Docker, etc.”</p></blockquote>
<p>For the first time we had a unanimous winner for both the judges and the participant winners. The
<strong>206 Partial Content</strong> team not only won two giant tubs of cheese balls, but also the all important
<a href="http://engineering.cerner.com/blog/shipit-hackathon-mplus/">Golden Keyboard</a> and bragging rights
until the next ShipIt Day. <strong>206 Partial Content</strong> decided to solve a problem to “enable solution designers,
engineers, and grandparents to easily create, stage, and process data for testing scenarios required for
verification without being dependent on upstream processing or rules.”</p>
<p><strong>206 Partial Content</strong> – Madhur Sikri, Ian Kottman, Venkatesh Sridharan, Andy Nelson, Brian van de
Boogard</p>
<blockquote><p>Our project was primarily driven by two rock star engineers on our team, Ian Kottman and Brian van
de Boogaard. We coined our project Sinecure, which means a position requiring little or no work but
giving the holder status or financial benefit. The goal of the project was to find a solution to
creating test data more easily and efficiently for anyone on our team to consume.”</p></blockquote>
<p>Thanks to all who participated and congratulations to our winners. Until next time, at ShipIt VII in
December!</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-11-08-fall-2016-shipit-day/shipit-winners.jpg" title="Winners" ></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Building a Unified UI Component Library: Lessons Learned]]></title>
<link href="http://engineering.cerner.com/blog/building-a-unified-ui-component-library/"/>
<updated>2016-10-13T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/building-a-unified-ui-component-library</id>
<content type="html"><![CDATA[<p>Cerner is building an open source, mobile-first user interface component library for healthcare applications. Pulling years of experience and lessons learned across multiple teams together, we are creating something great. We are very excited to bring this solution to the public and to be contributing back to the community!</p>
<p>We didn’t simply decide to create this library, we started with segmented UI libraries focused on different aspects of the company which had smaller isolated needs. Mistakes were made along the way and we have learned much from them. Let’s take a look at where we started and how we got to where we are now.</p>
<h2>History</h2>
<p>In 2013, a group of engineers with strong front-end skills was put together with the task of creating a reusable component library for Cerner’s HealtheIntent platform. Twitter Bootstrap was used initially, but quickly outgrown as the needs and designs of UX expanded. The project this team built is called Blue Steel. It featured everything from simple typography to interactive data visualizations while adhering to UX guidelines and requirements.</p>
<p>Blue Steel is a Rails gem that provides some basic helpers, CSS, JavaScript, and site templates to simplify layout and correct HTML usage. Blue Steel abstracts complex components to keep things simple and because we didn’t feel it was necessary to abstract native HTML elements.</p>
<p>In its infancy, the project was well received; other platforms saw the value and wanted to take advantage of the work being done. To accommodate the additional platforms, Blue Steel was merged with another internal UI library called Style Guide. The best features of each library were pulled together, sometimes one overriding the other, sometimes merging feature sets. The merged project was called Terra.</p>
<h2>Problems</h2>
<p>The approach of merging existing components saved time up-front, but came with a steep cost. The library was fragmented in the approaches taken during design and development. As such, it became difficult to work on without pre-existing familiarity. It was fairly obvious that we put two frameworks together on a time constraint.</p>
<p>Blue Steel still exists but is comprised primarily of Terra components. It persists to provide HealtheIntent-specific styles and functionality, while also being a Rails wrapper around Terra. Terra has been historically kept below version 1.0.0 for rapid development, while Blue Steel has been above 1.0.0. This strategy has caused a lot of pain for the consumers of both Terra and Blue Steel.</p>
<p>Keeping Terra below version 1.0.0 allowed breaking changes to occur without cutting a major release. Although this made development easier in some aspects, it damaged consumer trust. We always attempted to communicate breaking changes, but it didn’t always happen and it wasn’t always clear. Any time a team had to upgrade, they had to be prepared to fix their application which caused them not to trust us.</p>
<p>The issue was even worse in Blue Steel since it had to accommodate for Terra’s breaking changes. Blue Steel would consume a version of Terra with breaking changes and would still release as a minor update by providing styles and hooks to work around the breaking changes. Deprecation schedules and documentation were written to help keep Blue Steel backwards compatible. Unfortunately, it often wasn’t; sometimes, breaking changes would only manifest in an application.</p>
<p>Blue Steel and Terra were both tested separately with their own documentation sites. These tests were extensive and thorough but could not accommodate the complexity of the various applications consuming them. Breaking changes would creep into applications even when we thought everything was backwards compatible in Blue Steel.</p>
<p>In Terra, the preference was to style on HTML elements, states, and ARIA-roles whenever possible since they carried far more meaning than CSS classes. Unfortunately, this form of styling is somewhat global in nature. It was easy for style collisions to occur between components within Terra, consumer styles, and 3rd party libraries.</p>
<p>Terra was developed in such a way that it discouraged consumers from building custom components. The thinking was that applications would write little to no custom CSS or JavaScript. This didn’t scale well as needs evolved and application developers had to move ahead of the UI library. Terra components had a very high CSS specificity and were difficult to override which forced consumers to write even more complex CSS to override it. In turn, many bugs were introduced to consumer applications.</p>
<p>Terra was also built as a monolith with very little modularity in place. Consumers had the option of taking it all, figuring out how to make a custom build, or not using it. This caused applications which only needed a subset of functionality to become bloated.</p>
<h2>Solutions</h2>
<p>Today, Terra is in the process of being open sourced. We’ve looked extensively at the issues above and are taking measures to address all of them:</p>
<ul>
<li>Each component is in its own repository.</li>
<li>The SUIT CSS convention is being used for all Terra components.</li>
<li>Base componentry is being developed first.</li>
<li>Components are being kept minimal and composable.</li>
<li>Each component is being built to be a minimum viable product and released as 1.0.0 to follow <a href="http://semver.org/">SemVer</a> up front.</li>
<li>Only as components become complex and specific do we introduce framework opinionation. Base components will be framework agnostic.</li>
<li>Everything will have helpers to abstract underlying HTML structures.</li>
</ul>
<p>SUIT CSS bans the use of styling hooks which are considered global and effectively breaks the cascade in a global sense (you can leverage it within a component). At the root node of each component, only classes can be used. As a result, consumers can rest easy knowing that styles will not leak out of components and they have low specificity which allows them to be overridden as needed.</p>
<p>By starting with base components (buttons, images, etc), we effectively create a set of building blocks to build more complex web components. By keeping them small, composable, and framework agnostic, they can be used anywhere with confidence. Following <a href="http://semver.org/">SemVer</a> from the start will boost consumer confidence when using our components.</p>
<p>Introducing opinion into more complex components enables us to build better and more maintainable components with our most common use cases in mind. This does not preclude consumers who do not wish to consume the frameworks and libraries we use. By keeping each component in its own repository, it’s possible to create alternative versions of componentry to meet application needs. Additionally, keeping each component in its own repo allows for individual versioning, limiting scope of change, and makes it very easy for consumers to omit what they don’t need.</p>
<p>Finally, providing helpers for all components will enable easy and consistent development. It will be possible to build complex components solely out of the smaller components leveraging helpers to output the correct HTML. The abstraction also makes it possible to update the implementation in a compatible way while making it so developers don’t have to be aware of complexities like semantic HTML and accessibility. This will enable developers to build solid applications easily and quickly.</p>
<h2>Lessons Learned</h2>
<ul>
<li>When creating a reusable library, avoid global state or styles.</li>
<li>Create an abstraction or facade to the underlying implementation regardless of simplicity.</li>
<li>Keep your library modular.</li>
<li>Start with <a href="http://semver.org/">SemVer</a> and stick to it.</li>
<li>Start simple then reuse and compose.</li>
<li>Keep your library cohesive by developing consistently across components.</li>
<li>Don’t build with any particular framework(s) in mind when you can; the web is constantly evolving.</li>
</ul>
<p>We’ve learned a lot and are excited to open source the results of our work and learning. Keep an eye on <a href="https://github.com/cerner/">github.com/cerner</a> and <a href="http://engineering.cerner.com/">engineering.cerner.com</a> while we build out this new library. It’s going to be great!</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Michelle Brush Receives the Rising Trendsetter STEMMY Award!]]></title>
<link href="http://engineering.cerner.com/blog/michelle-brush-receives-the-rising-trendsetter-stemmy-award/"/>
<updated>2016-10-02T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/michelle-brush-receives-the-rising-trendsetter-stemmy-award</id>
<content type="html"><![CDATA[<p>We are excited to congratulate our own Michelle Brush for receiving the Rising Trendsetter STEMMY award. The Rising Trendsetter Award is given to a woman in STEMM areas with less than 20 years of experience and has demonstrated significant achievements early in their career.</p>
<p>Michelle is a director at Cerner who manages an engineering team in population health as well as a team dedicated to improving Cerner’s development culture. One of Michelle’s most notable career accomplishments was her leadership role in reconstructing Cerner’s software engineer development program in 2013, which she personally oversaw until the end of 2014 (read about the details of this program in her <a href="http://engineering.cerner.com/2013/08/devacademy/">blog</a>). In 2014, she transitioned into an executive role in the Population Health platform, where she fields particularly tricky support issues to help resolve data inconsistencies. Since 2014, Michelle has also managed the Development Culture team at Cerner, a team that focuses on improving associate morale through cultural empowerment, encouraging and providing opportunities for collaboration and innovation, and growing Cerner’s presence in the technical community.</p>
<p>Michelle actively promotes women entering and growing their STEMM careers through her leadership in the community and at Cerner. She is an integral member of Cerner’s women in tech committee, which has the goal to provide development, networking and leadership opportunities to women in technical roles in a supportive and inclusive environment that promotes authenticity and values differences. Additionally, she is a member of several other leadership councils ranging from helping design the new software engineer campus, improving development culture across the company, and intern planning.</p>
<p>In the community, Michelle is also a local chapter leader of <a href="https://www.girldevelopit.com/chapters/kansas-city">Girl Develop It</a>, a nonprofit organization that provides affordable programs for adult women interested in learning web and software development. Michelle is also an organizer of <a href="http://www.midwest.io/">Midwest.io</a>, a two-day industry tech conference in Kansas City that brings together developers across the Midwest for an eclectic collection of talks covering the latest trends, best practices, and research in the field of computing. As a member of the organizing team, she defines the vision for the conference, which includes finding speakers, promoting the conference in the industry, and ensuring diversity is top of mind at the conference.</p>
<p>Michelle also actively speaks at tech conferences, and has spoken at conferences like OSCON, CityCode, O’Reilly’s Software Architecture Conference, and Strange Loop. Michelle is also a MSU Computer Science Board Member.</p>
<p>Congratulations, Michelle!</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[DevCon 2016 Word Cloud]]></title>
<link href="http://engineering.cerner.com/blog/devcon-word-cloud/"/>
<updated>2016-09-28T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/devcon-word-cloud</id>
<content type="html"><![CDATA[<p>Every year we hold an internal developers conference called <a href="http://engineering.cerner.com/2013/08/devcon/">DevCon</a>. This year
we had 295 submissions for talks, ranging from a deep technical dive into the inner workings of Kafka to a reflection on the power of office pranks. I wondered what, if anything, do these submissions have in common? Are there any common themes/topics being discussed? To find out I decided to visualize the talk submissions in a word cloud to create an easily understandable (and hopefully aesthetically pleasing) view of what topics were most common.</p>
<p>The first step was some basic data cleaning so I could get a good set of words to visualize. I used Python to read in the submissions into a single string, lowercase all words, and then remove all common contractions.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># read all submissions into a single string</span>
</span><span class='line'><span class="n">text</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'./submissions.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># lower case</span>
</span><span class='line'><span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># remove all contractions to prevent situations like "we'll" becoming "well" once punctuation is removed</span>
</span><span class='line'><span class="c"># normally a regex tokenizer could be used for this but that assumes single quote is only ever used</span>
</span><span class='line'><span class="c"># in contractions</span>
</span><span class='line'><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"./resources/contractions.txt"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span>
</span><span class='line'> <span class="n">contractions</span> <span class="o">=</span> <span class="nb">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
</span><span class='line'> <span class="k">for</span> <span class="n">contraction</span> <span class="ow">in</span> <span class="n">contractions</span><span class="p">:</span>
</span><span class='line'> <span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">contraction</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="n">Next</span> <span class="n">I</span> <span class="n">replaced</span> <span class="nb">all</span> <span class="n">punctuation</span> <span class="k">with</span> <span class="n">spaces</span><span class="o">.</span> <span class="n">I</span> <span class="n">did</span> <span class="ow">not</span> <span class="n">just</span> <span class="n">remove</span> <span class="n">the</span> <span class="n">punctuation</span> <span class="n">so</span> <span class="n">special</span> <span class="n">cases</span> <span class="n">such</span> <span class="k">as</span> <span class="n">hyphenated</span><span class="o">-</span><span class="n">words</span> <span class="ow">and</span> <span class="n">the</span> <span class="n">phrase</span> <span class="s">"and/or"</span> <span class="n">are</span> <span class="n">preserved</span><span class="o">.</span>
</span><span class='line'>
</span><span class='line'><span class="c"># replace all punctuation with spaces.</span>
</span><span class='line'><span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">punctuation</span><span class="p">):</span>
</span><span class='line'> <span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">char</span><span class="p">,</span> <span class="s">" "</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>
<p>At this point I had 32,987 total words. A word cloud of this dataset was too noisy, predominated by common words like “the” and “talk”. In natural language processing these unwanted common words are called “stop words”. To remove them I made a list out of the submissions and then only kept words that were not in a list of common English words, supplemented by words specific to this data set, such as “Cerner” and “presentation”.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># get list of all words</span>
</span><span class='line'><span class="n">submission_words</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">"[^\w]"</span><span class="p">,</span> <span class="s">" "</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># only keep words that are not in the stop words set</span>
</span><span class='line'><span class="n">stopwords</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'./resources/stopwords.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</span><span class='line'><span class="n">stopwords_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">stopwords</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">))</span>
</span><span class='line'><span class="n">filtered_word_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">w</span> <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">submission_words</span> <span class="k">if</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">stopwords_set</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>This left me with a list of 14,291 words and 4,264 distinct words. When visualized I noticed many similar words were taking the highest spots, such as “team” and “teams” or “technology” and “technologies”. To remove some of this noise I turned to lemmatization. Lemmatization is the process of finding a canonical representation of a word, i.e. its lemma. For example, the lemma for the words “runs” and “running” is run. I used the popular Python library Natural Language Toolkit for lemmatization.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">lemmatizer</span> <span class="o">=</span> <span class="n">WordNetLemmatizer</span><span class="p">()</span>
</span><span class='line'><span class="n">reduced_list</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'><span class="c"># find the lemma of each word</span>
</span><span class='line'><span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">filtered_word_list</span><span class="p">:</span>
</span><span class='line'> <span class="n">reduced_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lemmatizer</span><span class="o">.</span><span class="n">lemmatize</span><span class="p">(</span><span class="n">word</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>
<p>This reduced the dataset to 3,834 distinct words. Now that the dataset was cleaned, common words filtered out, and similar words combined it was time to create the word cloud using a project called <a href="https://github.com/amueller/word_cloud">word_cloud</a>.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">cloud</span> <span class="o">=</span> <span class="n">WordCloud</span><span class="p">(</span><span class="n">relative_scaling</span><span class="o">=.</span><span class="mi">5</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">760</span><span class="p">)</span>
</span><span class='line'><span class="n">cloud</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">submissions</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># write to file</span>
</span><span class='line'><span class="n">cloud</span><span class="o">.</span><span class="n">to_file</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">"cloud.png"</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="c"># show word cloud using matplotlib</span>
</span><span class='line'><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">cloud</span><span class="p">)</span>
</span><span class='line'><span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s">"off"</span><span class="p">)</span>
</span><span class='line'><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-09-28-devcon-word-cloud/word_cloud.png" title="Word Cloud" ></p>
<p>Success! It is obvious what some of the most common themes are, such as “data” and “team”. Possible future steps for cleaning up the data would be grouping noun phrases, such as “software engineer” into single words or possibly removing common spelling mistakes using a spell checking library like <a href="https://pythonhosted.org/pyenchant/">PyEnchant</a>.</p>
<p>You can checkout the full code on <a href="https://github.com/ikottman/devcon-word-cloud">Github</a>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Difficult Debugging: Learning From Utter Nonsense]]></title>
<link href="http://engineering.cerner.com/blog/advanced-debugging/"/>
<updated>2016-07-13T00:00:00-05:00</updated>
<id>http://engineering.cerner.com/blog/difficult-debugging</id>
<content type="html"><![CDATA[<h2>Preface</h2>
<p>As software engineers we invest time into thinking about the problems we are trying to solve every day. Sometimes the problems we face are small or simple. Other times they are large and complex. Either way, we can usually draw from our experience to find a path forward.</p>
<p>While coding, we run into a lot of different bugs. Often, they are simple typos or a misuse of an API. These problems do not bog us down very much, and they are quick and easy to fix. Even complex bugs, while requiring investigation, often follow a familiar pattern(s) that help us identify a path to a solution.</p>
<p>Given this experience, it’s easy for us to think that we are good at debugging.</p>
<p>We are not. We are good at pattern recognition and recognizing similarities to problems we’ve faced in the past. Because we recognize the pattern, we can quickly debug most of the bugs we come across in our day-to-day work.</p>
<p>Which is great. But today, we will be exploring the types of bugs that do not come up in our day-to-day work.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/99-bugs-in-the-code.jpg" title="'Grumpy Cat meme: fixed one bug added 28'" ></p>
<p align="center">
Image source:
<a href="http://weknowmemes.com/2014/04/99-bugs-in-the-code/">weknowmemes.com</a>
</p>
<h2>How Bugs Can Mislead Investigative Efforts</h2>
<p>When a bug is brand new to us, we haven’t had the opportunity to derive a pattern from it yet because we have no experience to draw upon to create that pattern(s). Thus, we must investigate using a limited set of tools:</p>
<ul>
<li>Error messages</li>
<li>Stack traces</li>
<li>Guessing and check debugging</li>
<li>Colleagues</li>
<li>Google</li>
</ul>
<p>Often enough, that set of tools will guide you to a solution within a reasonable amount of time. Be warned, sometimes the solutions online solve a similar problem, but not your root problem. Testing is always in order with new bugs (or any bug more complex than a typo).</p>
<p>Debugging gets even trickier and more time consuming when we encounter a bug that resembles a pattern that we’ve seen before. Once, I came across a bug which looked like two other things, but turned out to be a third unexpected thing.</p>
<h3>Treemaps and IE8, and Fonts, Oh My</h3>
<p>One of our teams created an interactive DOM based treemap which worked in Internet Explorer 8 (IE8) and above. It wasn’t lightning fast in IE8, but it worked sufficiently well with a reasonably complex dataset. That is until the browser started crashing intermittently for some of our users.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/treemap.png" title="'Example treemap'" ></p>
<p align="center">Example treemap with dummy data</p>
<p>There were a few things that we (four engineers) noticed right away:</p>
<ul>
<li>It only crashed in IE8</li>
<li>The presence of a treemap seemed to be a driving factor</li>
<li>Crashing was intermittent</li>
</ul>
<p>Our initial investigation was good. We isolated the problem browser and determined that there was something wrong with the treemap, which was causing the issues, we were on our way to solving this problem – or so we thought.</p>
<p>Given the intermittent nature of the problem, our experiences in the past, and the patterns we had observed, we assumed we had a memory leak, a race condition, or both. In an attempt to rule one of those options out, we tested with small and large datasets for the treemap.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/15k_treemap.png" title="'Treemap with 15,000 cells'" ></p>
<p align="center">Treemap with 15,000 cells in it rendered by Chrome</p>
<p>The above image serves as proof that modern browsers were unaffected by the bug we were experiencing.</p>
<p>Convinced that the treemap was the issue and that it had to be a memory leak or a race condition, we created automated tooling using sIEve, virtual machines, and AutoIt scripts. The automation enabled us to test dozens of scenarios hundreds of times easily to gain metrics which might help illuminate where, in the code, we should look next.</p>
<p>We chose different sized datasets thinking that smaller datasets would not trigger a memory leak while a large one would. Unfortunately, it crashed either way and we were no closer to figuring out what was wrong.</p>
<p>After several more days of investigation we were just as perplexed as the day we started. We had a plethora of information which told us nothing. At this point our capacity had to be reduced down to just one developer – me. Frustrated with the resultless weeks spent investigating the issue, I decided step back and take a completely different approach.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/500_treemap.png" title="'Treemap with 500 cells'" ></p>
<p align="center">IE8 managed to render a 500 cell treemap without crashing</p>
<p>To re-evaluate everything we did, I removed all of the assets from our application to minimize moving parts; regardless of how unlikely a variable was, I wanted to remove it. I ran our test scripts against the application to find that, unsurprisingly, the browser did not crash. I then added JS and CSS assets separately to find that neither alone caused the browser to crash. As a sanity check, I added both back to the application and it would reliably crash. This implied that there was some interplay between CSS and JS which was causing the browser to crash.</p>
<p>In our application, it was easier to add CSS file by file than it was for JS so I went that route. Along the way, I noticed that we were sending the wrong X-UA meta tag so I got sidetracked and fixed that to no avail. Eventually, I added back our Font Awesome CSS which caused the browser to crash. Thinking there was no way that a font could be the issue, I added and removed various pieces of our CSS to determine if it was the cause of the problem. I tried changing selectors, changing the load order, and everything else I could think of to no avail. After a while, frustrated, I commented out every line referencing Font Awesome and the browser stopped crashing. At this point, I just started adding code back line by line until the browser started crashing. What I found made no sense:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&:before {
</span><span class='line'> font-family: 'FontAwesome';
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>
<p>I looked over this for a while and eventually noticed that we were using single quotes when we referenced the font while the font declaration</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>@font-face {
</span><span class='line'> font-family: "FontAwesome";
</span><span class='line'> src: url(@fontAwesomeEotPath);
</span><span class='line'> font-weight: normal;
</span><span class='line'> font-style: normal;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>
<p>was using double quotes.</p>
<p>Having exhausted most other options already, I tried making the quotes match to see if the browser would crash and, to my surprise, it wouldn’t. It didn’t matter whether I used double or single quotes as long as they matched. I added back all of the remaining assets and tested this again; sure enough, the app did not crash even after 200 tests.</p>
<p><strong>Yes, it’s true. It wasn’t a race condition or a memory leak within the treemap, or anything else we thought it might be. It was mismatched quotes.</strong> I would never have guessed this in a million years.</p>
<p>I did not stop here! Although I solved the problem, I needed to understand what was going on. I was also very curious which part of the JS was causing issues with Font Awesome. I reintroduced the old CSS and started testing the JavaScript. The application broke as soon as I re-introduced Modernizr. The treemap was, at this point, seemingly faultless as I was able to reproduce the crashes without it.</p>
<p>I researched mismatched quotes and Modernizr online to try and get a better understanding of what was going on. I found several articles that detailed similar issues, but did not identify the root cause. Eventually I found a post on StackOverflow that enabled me to connect the dots.</p>
<p>Browsers do a lot for developers under the hood and IE8 treats different types of quotes differently and kicks off an error handling subroutine to smooth it over. If that error handling subroutine occurs while Modernizr is attempting to shim the browser for HTML5 compatibility, the browser will crash.</p>
<p>We weren’t wrong in that we were facing a race condition, but we were very wrong about our presumption about the treemap. The only interplay the treemap had was that it caused Modernizr to take longer to apply the shim thus widening the window of opportunity for the race condition to apply.</p>
<p>We worked on this from December 20th to January 9th, a total of twenty days!</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/sad_panda.png" title="'Meme: 20 days of debugging makes me a sad panda'" ></p>
<p align="center">
Image Source:
<a href="https://www.linkedin.com/in/jessicazehring">Jessica Zehring</a>
</p>
<h2>How To Tackle Perplexing Bugs</h2>
<p>Oftentimes, our ability to recognize coding patterns enables us to identify and solve bugs in a timely manner. As the example bug shows, however, following them can lead you down a rabbit hole. At face value, twenty days were spent working on that bug, but when you consider that there were up to four developers involved at a time, the lost time actually equates to one to three months. Once you factor in opportunity cost on top of that, you look at two to six months of time lost to debugging this issue.</p>
<p>That is a disturbingly significant amount of time to have lost on a bug. It was a difficult bug to solve, but it could have been solved faster had we recognized that our past experience was insufficient to solve this problem. There are some key points to take away from debugging something perplexing like the example bug we looked at:</p>
<ol>
<li>Isolate the problem. Find a single way that the bug can be consistently replicated and remove any variance that can trip you up.</li>
<li>Automate as much as you can. There are likely to be many tests; let the computer handle that work for you. While working on the example bug, we ran thousands of tests over those twenty days.</li>
<li>Remove as many variables as possible and keep a list of what’s remaining.</li>
<li>Change one variable at a time. If you change many things simultaneously, you won’t know what yielded which results.</li>
<li>Test, document, and repeat. When you change a single variable, record all of your findings. How did the results change? Eventually new patterns will present themselves.</li>
<li>Narrow the scope. As your testing reveals patterns, narrow down to a smaller area. In the example bug, we went from “somewhere in our static assets” to “something in our CSS and JS” to “something in this particular file” to “it’s this particular line”.</li>
<li>Repeat and keep repeating. Be meticulous in recording your findings. Even if you don’t see a pattern, someone else studying your results might.</li>
</ol>
<p>When you find that past experience is not yielding results in a timely manner (you’ll have to define what that means for yourself), take a step back and follow the steps above. Doing this allows your past experience to help you when it applies and gets it out of the way when it doesn’t. Don’t see how far the rabbit hole goes when you can scientifically figure it out.</p>
<p>Additionally, do not blindly trust answers found online. When working on the example bug, we found several examples of people correctly identifying a similar problems to ours, none of which correctly identified the underlying cause. Treat online resources as what they are – resources. Sometimes they have the answer you seek while other times they are the dots you must connect yourself.</p>
<h2>Tools and Techniques Which Will Help With Day-to-Day Developing and Debugging</h2>
<h3>Linters</h3>
<p>Static analysis, or linting, is a technique to catch common coding mistakes quickly. A linter will evaluate raw source code and give back a report detailing what needs to be fixed. Most languages have some form of linting software available for them. Since this post is front-end oriented, below are a few linters available for JS:</p>
<ul>
<li><a href="http://eslint.org/">ESLint</a></li>
<li><a href="http://jshint.com/">JSHint</a></li>
<li><a href="http://jscs.info/">JSCS</a></li>
</ul>
<p>All of these tools will notify you when you make typos, aren’t using variables, fail to follow a predefined set of coding styles, and more. They are very fast and are your first line of defense against day-to-day bugs. Linters will catch mistakes much faster than a human.</p>
<h4>Example</h4>
<p>I have a friend who is a very talented software engineer and mathematician. One day he called me to see if I could help him debug an issue he had been struggling with for about 19 hours. His Angular application kept spin locking (freezing up) and he couldn’t figure out why. We scrolled through the code and luckily for him, a piece of it caught my eye:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="mi">5</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// logic</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>He had been working on C++ code prior to this project which features block scoping while JavaScript (ES5) only features function scoping. A linter would have immediately caught this mistake and informed him of it, saving 19 hours of debugging.</p>
<p><img class="center" src="http://engineering.cerner.com/assets/2016-07-13-difficult-debugging/semi-colon.jpg" title="'Meme: Semi-colons are the hide and seek champion since 1958'" ></p>
<p align="center">
Image source:
<a href="https://www.reddit.com/r/ProgrammerHumor/comments/3dqj35/several_hours_of_debugging_later/">reddit.com</a>
by Wilsam239
</p>
<h3>Automated Testing Frameworks</h3>
<p>While static analysis is your first line of defense, tests for your code are your second line of defense. Tests should depict the behavior of your codebase and should fail if you deviate from that contract. Just like linters, most languages support automated testing. There are several frameworks that you can leverage for testing JS, a few are:</p>
<ul>
<li><a href="https://mochajs.org/">Mocha</a></li>
<li><a href="http://jasmine.github.io/">Jasmine</a></li>
<li><a href="https://qunitjs.com/">QUnit</a></li>
</ul>
<p>Defining a set of behaviors for your code helps to protect you from unintentional changes and side effects. Tests will take longer to run than a linter, but are still frequently quicker at catching mistakes than a human. Since automated unit tests are like a contract for behavior, they can also help keep developers unfamiliar with the behavioral contract from making mistakes.</p>
<h3>Debugging Tools</h3>
<p>When automated approaches are insufficient, it’s time to start the manual debugging process. Every programming language has a debugging toolset that can be used to work through code with bugs. Since this post is front-end oriented, we’ll look at browser tools.</p>
<p>You could use JS to alert variables at different times, but this is radically inefficient. Today’s modern browsers have a plethora of tools available to you starting with the debugger keyword for JS code. When the browser’s console is open, the debugger statement acts as a breakpoint; it does nothing otherwise. Although simple, it’s very powerful as it gives easy control of adding/removing breakpoints to step through the code.</p>
<p>Atop the debugger keyword lay all of the browser tools. These enable you to step through code, inspect code, profile code runtimes, inject assertions, and even monitor the network traffic relating to the current page. Different browsers have different tools; below are some guides for debugging in different browsers:</p>
<ul>
<li><a href="https://developer.chrome.com/devtools">Chrome</a></li>
<li><a href="https://developer.apple.com/safari/tools/">Safari</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Tools">Firefox</a></li>
<li><a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/f12-devtools-guide/">Edge</a></li>
</ul>
<h4>Automated Robustness Testing</h4>
<p>When you are in the process of manually debugging code, it is useful to automate what you can. For example, when testing the IE8 crashes, we used virtual machines and an AutoIt script to recreate and test the scenario as well as to keep logs of what happened for future reference.</p>
<p>Whenever possible, always automate recreating the scenario(s) for testing purposes as it:</p>
<ul>
<li>Speeds up the process</li>
<li>Removes human error</li>
<li>Ensures consistently gathered metrics</li>
</ul>
<h2>Conclusion</h2>