Author Archives: orscsblog

Thoughts on “Sustainable Motivations”

The Sustainable Motivations pattern is aimed at apprentices that are having a tough time sticking it out through the more difficult aspects of the craft.  These might not be constrained to the craftwork itself, but could involve management, handling stakeholders (practically it’s own craft, and probably deserving its own book and set of patterns), and just dealing with burnout.  Even if the apprentice hasn’t yet experienced a motivation deficit, they’re likely to encounter one at some point.  They also tell the apprentice to avoid “Golden Locks”, that trap a person in a position because it feels too good to give up, even though it does not contribute to longer-term goals.

Their solution is to commit motivations to writing, spacing some of them out over a few minutes.  They ask the apprentice to determine which of those are externally driven, which internal, and which may not be necessary.  The end result should be a list of five important things that motivate the apprentice, so they can “look at it when times get tough”.

Motivation can be tough for me.  I tend to be energetic at the start of projects or semesters, but struggle to find ways to keep going once the shine wears off.  One of my concerns as making my way in the professional world gets closer and closer to reality is that I won’t be able to sustain motivation.  I’m always worried that a month or two in, I’ll wear down and burn out and not be able to keep going even though I love programming.  As an apprentice software craftsman, finding ways to motivate myself (and the discipline to keep going if and when motivation fails) is probably one of the most important things I can do to set myself up for future success.

I realize while writing this that I don’t actually know for sure what my ambitions are.  I know that I want to spend some time in the software industry, if only to pay off my student loans and ensure that I’m comfortable.  Even if the motivation to do that is the only thing I get out of this pattern, it’s worth it.

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

Thoughts on “Concrete Skills”

This apprenticeship pattern seeks to solve the problem of the apprentice that wants to seek out and join a skilled team to contribute to and learn from (also, it pays the bills).  However, a truly novice software developer may lack the skills needed to contribute, and faces (perhaps fears) rejection.

The writers offer a solution and an action item to assist it.  The solution is to develop and maintain concrete skills, items that can go on a resume, get through HR filters, and convince a hiring manager that it’s worth it to take a shot on the otherwise unproven apprentice.  These include picking up new languages and technologies, and most importantly writing a project in them, especially if it’s something the apprentice can put on a repository site or their own personal site for potential employers to look at.  The action item (short of finishing a half-dozen personal projects) is to look at the CVs of skilled proffessionals, and to figure out which skills they have that the apprentice could learn.  This goes hand-in-hand with keeping one’s own CV up to date and figuring out which parts are likely to catch the attention of hiring managers.

I think that the development of concrete skills is one of the more valuable things that I’ve gotten out of my education, and I wish that I’d had more opportunities to develop some.  I think it’s really important for students to have opportunities to create projects that push not just conceptual learning, but force the development of concrete skills because they’re the best tools for the job.  I have also been lucky to have an employer that’s willing to let me work on software projects for the business which has given me a lot of experience as well.  I would add to this pattern a suggestion to find an external source of pressure to create a project that works and looks professional.

This is, I think, a pattern that seems obvious and is harder to put into practice than it might appear.  It’s easy to commit to doing things by looking over a CV and developing a list of skills, and harder to actually get them done.

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

Sprint 6 Retrospective

This sprint, my team finally got around to the work of dividing up our service into sections and digging into implementation of code and tests.  While it’s frustrating that it took this long, and that we were unable to import either the crypto-js library or Angular’s native crypto library, it does feel good to have something ready to pass on.

My responsibility was to write the portion of the service that generates a private encryption key and stores it locally.  I communicated with our contact at Ampath in order to work out the details of what should be stored and for how long.  I ended up with the following requirements:

  1. The key can only be stored for the duration of a login session.
  2. The key needs to be unique to a user.
  3. The key needs to be generated in a deterministic way — each time the user logs in, the key must be the same so that they can access records encrypted in a previous session.

I chose to use the second iteration of the password-based key derivation function, implemented in crypto-js (Wikipedia link here).  This function generated a key of a set byte length based on a password, an optional salt, and some number of hashing iterations.  Unfortunately, that’s where I hit a bit of a wall.  For reasons that neither I nor anyone else I worked with (my teammates, members of other teams, and Dr. Wurst) could determine, crypto-js does not want to import properly into an Angular app.  We spent time looking for similar problems in various forums, uninstalling/reinstalling the packages, and making sure the proper typings were installed without any success.

I then tried to work around the problem by converting the crypto-js implementation to typescript  (crypto-js file here, on their github page).  However, this required the use of a custom type that I was unable to get to function as well as the use of bitwise operations prohibited by Ampath’s linter.  I know that Erik, one of my teammates, also looked into alternate libraries but was unable to find anything that he could get to work.

I then moved on to writing unit tests, mocking the effects of an actual encryption algorithm in my code.  While getting these tests passing was fairly trivial with mock encryption library calls, I hope that they will be of use to whoever picks up this part of the project next.

I believe that my team did a good job dividing tasks evenly this sprint, but we really needed to be more active on Slack to communicate problems and progress between work classes, even outside of the standups.  We did communicate well enough to make sure we properly handled our team git repository, and on Thursday we should be able to get it ready to integrate into the class repository in addition to dividing up work on the presentation.

I think the biggest takeaway for me from this sprint is that working with external libraries can be somewhat uncertain.  Even after we researched them and got crypto-js functioning in a spike solution, it didn’t work when we tried to import it into the Ampath app.  If I could do something differently (either this past sprint or earlier), I think I would have chosen to try to implement the encryption algorithms ourselves.  While it might have been harder and more work, that would leave a much easier task of integration with the app.

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

Thoughts on Be the Worst

The Be the Worst design pattern seeks to solve the problem of an apprentice’s learning rate leveling off.  Perhaps this is because they have outgrown their team or organization.  Perhaps this is because they are still working through things alone.  Either way, Hoover and Oshineye have a solution in mind.  They suggest that the apprentice seek out a team where they are the weakest developer, so that as many team interactions as possible can lead to learning, and other team members can help them to avoid pitfalls.  They do note that this is somewhat selfish, and the apprentice should be willing to take on whatever menial work comes up in order to balance their lack of experience or skill.  It also means delaying leadership positions or switching jobs and companies for the sake of craftsmanship.

This pattern really speaks to me.  It’s a position I expect to find myself in this summer as I work as an intern.  I will be the least experienced member of my team, and part of my job is to learn as well as to contribute value.  I expect that I will end up with some of the less-desireable work, but that I will be able to learn from my colleagues and that learning will improve my job prospects in the future.

I also have found Being the Worst member of my team to have contributed best to my learning in the past.  As I’ve changed schools and spent more time in school, that position has been less and less frequent.  I don’t mind leading teams if I feel confident in the subject matter or the technology, but I would prefer to be on the less-experienced end of the spectrum.  This isn’t because I want to dodge responsibility; it’s because that’s where I’ve found I do the most real learning.  It also helps me a lot, both in productiveness and confidence, to know I can rely on more-experienced team members to help if I run into problems.

In the future, I want to find more opportunities to Be the Worst (either in classes next semester as I finish my degree, or at work) at least for a while longer.

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

Sprint 5 Retrospective

This sprint we finished our prototype API and had it approved by Ampath.  We also started working through the implementation details for our service as a group.  Finally, we figured out how to repair our local versions of the app and get our group repository in synch with Ampath’s master branch so that we can implement our API over the next sprint.  I learned how to coordinate with other teams to build an API, and how to implement password hashing and data encryption.

I think the biggest takeaway for me this sprint was how to coordinate with other teams on a project to write an API for them to use, and how to integrate details of their implementations into my team’s work.  Because we’re providing a “background” service for the other teams, they can work for now assuming that our service will do what it’s supposed to.  However, this means that we need to understand some details of their implementations so that we can provide them with what they need.  Given the speed with which the semester is coming to a close, the encryption service may not be integrated into other services or components this year.  However, we hope to have something that’s usable for Ampath or another group working on this project to take over in the future.

Our biggest job this sprint was to work on our service’s public API.  We did this primarily through team work periods in class.  This followed a roughly three-step process, which we repeated until we believed our API was in a state where we could send it to Ampath for approval.  First, we spoke with another team to get a handle on their requirements for our service.  Second, we wrote a set of function signatures that we believe filled those requirements.  Third, we discussed implementation of those functions and what other private functions we might need to implement them, as well as which parts of the Crypto-JS API we want to use.

One of the biggest parts of this discussion was to figure out how we want to derive private keys and store hashes in order to provide the best compromise between security and usability.  For password hashing, we decided to store a hash derived from the password with salt derived from the username and timestamp of the offline session creation.  This will be stored with the username in-browser, by the offline login team’s code.  For private key derivation and storage, we spoke with Ampath and agreed on temporary private key storage for the duration of a login session (the key will be generated from the password using a password-to-private-key function and stored in a file that is deleted on logout).  While not optimally secure, this allows encryption/decryption of data without requiring password entry for each data operation.

We followed Jason Knowles’ intructions to rebuild our apps, and used git to update our team repo with Ampath’s latest changes.  For next sprint, our job is to implement and test as much code as we can manage.

I think our team coordination could have been better this week.  It felt like a lot of what we were doing didn’t engage the entire team, although I’m not sure how to manage that better.  Not everyone was present for each work day for varying reasons, although we did keep in touch on Slack we could also probably have kept better notes to send to absent team members.  I think dividing up labor will be easier next sprint since we have actual code to work on.  We will have to make sure we keep our repositories synched, as we don’t have a ton of practice with that.

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

Thoughts on “Craft Over Art”

Craft Over Art seeks to solve the problem of a craftsman wishing to create something beautiful, elegant, or resume-padding at the expense of the party that commissioned the project.  The authors strongly advise that the craftsman deliver a product that is useful, functional, and to specification rather than one that is fancy, inspired, or unique.  The craftsman also cannot wait for inspiration, and must deliver a satisfactory product on time.  Speed is also not the only concern; the product must have at least a minimum of quality even if it takes a little longer.  This is an important concept to introduce to the client as well.

Although I do not fully agree with everything in this pattern, the basic concept speaks to me.  There are a lot of things that need to be balanced in a professional product.  I have run into this firsthand when developing software for my job; my boss obviously wants a quality product, but also does not want me to spend excessive time on it.  I have needed to balance doing things the “right” or “perfect” way with just getting things done.  I do think, however, there is still some room in my work for improvement of quality.  Reading Clean Code and trying to put those ideas into practice from the start of a project has been helpful, although my current project will still likely need a good refactoring, if the time to do so is in the budget.

I don’t necessarily agree with the way that the authors dismiss the art of programming (and the process of art in general; it’s not just waiting for inspiration to strike), although I understand it’s somewhat beyond the scope of the book they’re writing.  I think there is room for the unplayable “million-line game that pushes the frontiers of computer science” — even if the craftsman (or artist, I suppose) that developed it does not benefit directly, the whole field might be inspired or lifted up.  I think there is room for programming as an art, room to make decisions inspired partly by aesthetics rather than purely by utility.  Maybe that’s only in personal projects that don’t have hard deadlines, but I think there’s space to be found for artistic merit in the professional world as well.

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

Thoughts on “Reading List”

“Reading List” is the first in a set of design patterns written to help the apprentice craft a learning curriculum.  As more and more material becomes available, it’s important to carefully select a set of materials that can effectively guide oneself.

This particular pattern is focused on managing material, not necessarily curating it (although it does recommend asking mentors for suggestions).  The recommendation here is to create a list of reading material, and maintain it in a way that lets you see what you have read as well as what you have yet to read.  This allows you to fill in gaps as you go, even if the original list was not particularly comprehensive.  The basic form of the pattern is to keep a text file as a reading list.  In more complex implementations, you can use a version control system to track changes, or use a public form (like a wiki) so that others can benefit.

I am not sure how helpful this pattern will be to me.  While I do understand the need for continued education, and I do enjoy reading, I’ve found that I learn far better from practical, hands-on experience than books, blogs, or powerpoint slides.  While I definitely got a lot out of Clean Code, I got more out of taking Uncle Bob’s suggestions and putting them into practice.  I also tend not to take well to to-do lists, either making or sticking to them — although, perhaps, this pattern would give me an opportunity to expand my horizons in personal organization as well as software craft.

My implementation of this pattern might be a bit more complex than the simple suggestion of keeping a version-controlled text file.  I would prefer to curate a list of resources that contain practical, hands-on components (like Apprenticeship Patterns, although many of those are fairly abstract), or to learn from tutorials that give me room to experiment.

You could even apply this pattern to parts of a book (like Apprenticeship Patterns) that is more fragmented, or easier to digest across multiple readings.  Perhaps also to a video or article series.

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

Sprint 4 Retrospective

This week I got as far as I could with my spike solution before my group reconvened and chose an encryption library to use going forward.  I was finally able to work with PouchDB (creating a database, storing and retrieving data) successfully.  Unfortunately, I wasn’t able to use crypto-pouch to do what we needed to.  It purports to extend PouchDB features, but even when installed and included in dependencies did not actuall appear to add the proper functionality.  Additionally, it does not provide the kind of granular, on-demand encryption that we think will best suit this project’s needs.

Most of what I learned from my spike solution over the last two sprints is that working with multiple packages from different sources can be a challenge.  Also, I had to do some translating between javascript examples and the typescript that I was writing in.  I had to remove and reinstall modules at times, and I also learned that I really should have kept careful track of how I did what I did and in what order, so that if I broke it later I could reinstall more easily.

My group started this sprint with more independent work.  We all had some degree of success with our chosen encryption libraries.  It turns out that, of the libraries we looked at, only bcrypt was suitable.  It has the features we need (password salting and hashing plus on-demand object encryption), and is easy to install and use.  After the group made that determination mid-sprint, we reallocated work.  One person started to figure out how to implement the features we need with bcrypt.  The rest of us started to work out how to test our functions in Angular.  We also created a prototype data flow through our service on Balsamiq.

I think as a group we learned more about how to evaluate external libraries for our needs.  While I think that the way we used this sprint was worth our time both from individual and group learning standpoints, we probably could have saved some time if we’d known going in what to look for in encryption libraries, or written a specification of some kind that we could then look to fill.  We ended up with the following requirements, built from Ampath’s specifications:

  • Need to be able to salt, hash, and store passwords and then compare an entered password to the hash.
  • Need to be able to encrypt arbitrary data objects and decrypt them later.
  • Need to be able to encrypt/decrypt pieces of data on demand, and in a granular way.  This potentially allows more than one user to have data saved on the device, accessible with different keys.

Going forward, I think our biggest challenges will be to make sure each team member is assigned an appropriate amount of work.  I think one or two people may be able to work on the module directly, one or two people can mock a module and write tests, but that still leaves at least one person without a clear task.

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

Thoughts on “Find Mentors” apprenticeship pattern

The problem addressed by this pattern is one that should be familiar to most: needing guidance in unfamiliar ground.  The authors propose that you find a “master craftsperson” to guide you, but recognize a flaw: it is difficult to find true masters in a craft that is still fairly young, and in which the tools evolve very quickly.  Most of all, they emphasize the importance of getting over the anxiety of reaching out, because the upside of success is so high.

This resonates with me and with my experiences.  I find that I am very successful when I have found a mentor of whom I can ask questions and bounce ideas without fear of ridicule or rejection.  Even if my mentor doesn’t respond right away or have the answer, the act of formulating my thoughts enough to send them as a question to someone else can help me find what I’m looking for.

The authors also recommend taking on a mentor role when you have the opportunity.  This is also something that I’ve found helps me learn.  It may be common wisdom at this point, but I’ve found that I don’t know how much I know (or what critical knowledge I lack) until I go to teach it to someone else.  My family members often find themselves in the (hopefully patient) position of listening to me test my knowledge by explaining things to them — doing that by teaching someone that is really invested  in learning the topic is even better!

I can also connect with the anxiety of reaching out, especially to someone with whom I do not have a previous connection.  No matter how beneficial the outcome may be, and no matter what my past experiences have been (overwhelmingly positive) I tend to have trouble taking that first step of making a connection.  In my life in general, the anxiety of reaching out to other people for help is one of the largest obstacles I struggle with and one of the most important for me to work on.

Like with many of the other patterns, I find that this one did not necessarily teach me anything truly novel.  However, it validates what I thought I knew and backed that up, which is just as important.

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

Sprint 3 Retrospective

This sprint, I learned about pouchdb, some about crypto-pouch, about the way that JavaScript handles asynchronous behavior, and how to create typescript classes to wrap objects that return from function calls.  My group worked well to distribute and plan our work for this sprint, but we were interrupted by multiple snow days and found that we work better when we’re all present to bounce ideas off of each other.

At the beginning of this sprint, we found five different encryption services that we could potentially use for the AMPATH app.  We decided to build a spike solution for each one, and each took one of them to work on.  I ended up with crypto-db, which is a small encryption extension for the pouchdb database system that other teams are using for offline data storage.  My plan was to follow the simple setup instructions at the pouchdb site to build a local database with one or two items, display the result of a database access without encryption, display the result of a database access with encryption but without the appropriate key, and display the result of a database access with encryption and with the appropriate key.  I also wanted to find one or two different ways to derive salt to use for additional security.

Unfortunately, it didn’t end up quite that simple.

The first step was setting up an Angular CLI project – it turns out Angular CLI updated recently to remove the ng init command, which made it harder to follow guides for project setup.  I also needed to install the dependencies and types for pouchdb, which was a little tricky — they needed to be installed after a general npm install, otherwise they were overwritten.  Once that hurdle was dealt with, I needed to learn how to actually use pouchdb.  Fortunately, there are instructions (linked above).  However, in order to understand them I needed to dig into what a Promise entails in JavaScript.

A Promise is, as I understand it, an object that allows asynchronous functions to exist.  JavaScript won’t run multithreaded, so in order to keep the scripts running properly a function must return something so that the script can continue, even if that return is delayed by a database access.  When the database access actually does come back, the Promise is able to execute a function of some kind (for example, set some object fields to values pulled from the database).

Once I had figured that out, I ended up stuck at another problem: the data that was returning from the database access could print to the console, but would only print [object Promise] when I tried to convert it to a string and display it.  On Monday, Dr. Wurst showed me how to wrap the return (which, for pouchdb, is a JSON) in a class that has the appropriate fields so that I can copy it to a local instance of that class and then access its fields from my html file.  I did not have time to implement this or get farther with my plan this sprint.

My group also had trouble of various kinds working through our spike solutions, so we decided in our retrospective and planning for the next sprint to push our current set of tasks forward.  Hopefully we will actually be able to meet during our designated work times; if not I think we will need to find a way to meet (or schedule digital meetups) so that we can accomplish our goals.

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