Ken Corey
  • Personal Blog
  • Flippin' Bits
  • Gallery
  • Holidays
  • Flying a Paramotor, Part II

Scientists Discover Shocking Tool to Improve Engineer Performance!

21/2/2023

0 Comments

 
Engineer dreaming up solutions.

Leaders always want the people on their teams to be more productive, more efficient, and perform better at their jobs.

In software, we're constantly trying to improve performance, with all sorts of metrics used to eke just a little more speed out of a team. Here's a few examples for the record in no particular order: agile, scrum, lean development, DevOps, Six Sigma, waterfall, extreme programming, kanban, CI/CD, lean Six Sigma, crystal, feature driven development, rapid application development, capability maturity model, lean startup, design thinking, ITIL, DevSecOps, Lean UX, Six Thinking Hats. (Links explaining these methodologies below.)

Seems lots of people, teams, companies have tried...but have they succeeded?

From the companies I've worked at, the answer seems to be a firm "no".  Companies are focusing on how "hard" people are working. That might be useful when doing a time/motion study on an assembly line, but it doesn't apply when doing creative work like software engineering.

I'd like to propose something radical...but before we talk about that, it's useful to know what an engineer needs to feel "engaged".  

By engaged I mean an engineer who is committed to the work.  They are passionate about the job and care about the success of the projects. More than half of the motivation must come from a desire to learn, grow and contribute to the engineering effort.  They take on new challenges, think creatively, and problem solve in innovative ways.  In short: that's the kind of engineer I want on my team!

To keep that going, an engaged engineer requires care and feeding: Meaningful work, professional development, positive environments, autonomy, work-life balance, recognition, and a diverse work place.  I won't go into those in this article, but they are all key.

Here's the radical bit though: they aren't enough.

An engineer needs to have a bit of breathing room...a bit of time to day-dream.  A bit of time, to...well...be bored.

Yes, that "are we there yet?" kind of boredom.  

I can hear the over-pressured organisations screaming now: "What!?!  We can't have expensive highly-paid engineers GOOFING OFF!?!"

Well, my shouty imaginary organisation...that's *exactly* what I'm proposing.  

Why?  Simple, really.

Boredom (as a tool used by engaged engineers):
1. can spark creativity
2. reduces stress
3. promotes self-discovery
4. encourages movement
5. helps with learning and memory
6. improves sleep
7. enhances mood
8. improves focus

I'm really smart...just take my word for it!  

(Not convinced?  Fair enough...I probably wouldn't be either.  If you want to learn more I mention the "why" for each of these below, and provide references for the studies to back each point up.)

Note that "engaged" part.  This is advanced engineering here.  If your organisation screams "FASTER!" at the teams on a regular basis, you'd probably get more bang for your buck by improving your company culture in the first place.  The engineers have to want to be productive.

Long->short: Make sure you've got the engineers engaged and then let them start to daydream.  Just a little.

Imagine what they'll be coming up with next!

=====================================
A bit of a deeper dive...

Again, I hear the more bellicose companies out there girding for war at the very thought.  Let's talk about each one of these in a little detail, and I'll provide references to studies where people smarter than I figured out each of these items.

Boredom can spark creativity: Research has shown that boredom can lead to creative thinking and problem-solving. A study(S1) published in the Academy of Management Discoveries found that employees who had more boredom in their jobs were more creative and generated more original ideas than those who had less boredom. Encouraging your engineers to take breaks and pursue hobbies or side projects can promote creative thinking and lead to new innovative ideas for your company.

Boredom reduces stress: Chronic stress can have a negative impact on employee well-being and productivity. A study(S2) published in the Journal of Occupational Health Psychology found that brief periods of boredom during the workday can help reduce job-related stress and fatigue. Allowing your engineers to take breaks and participate in activities that help them relax and de-stress can lead to improved job satisfaction, higher productivity, and overall better health.

Boredom promotes self-discovery: Giving your engineers the time and space to reflect on their personal and career goals can have a positive impact on job satisfaction and retention. A study(S3) published in the Journal of Vocational Behavior found that self-reflection can help employees better understand their values and goals, leading to higher job satisfaction and improved performance. Encouraging your engineers to take breaks and explore new interests and hobbies can lead to a more motivated and engaged workforce.

Boredom encourages movement and self-care: A sedentary work environment can have a negative impact on employee health and productivity. A study(S4) published in the American Journal of Preventive Medicine found that taking short breaks during the workday to engage in physical activity can lead to improved mood, reduced fatigue, and increased productivity. Encouraging your engineers to take breaks and engage in physical activity can lead to improved overall health and better productivity.

Boredom helps with learning and memory: Research has shown that boredom can lead to improved cognitive function and memory retention. A study(S5) published in Consciousness and Cognition found that participants who engaged in a boring activity for a short period of time performed better on a subsequent creative task than those who did not engage in the boring activity. Allowing your engineers to take breaks and engage in non-work-related activities that challenge their cognitive abilities can improve memory retention and lead to more efficient and effective problem-solving.

Boredom can improve sleep: Adequate sleep is essential for employee health and productivity. Research has shown that boredom can help promote relaxation and better sleep quality. A study(S6) published in BMC Public Health found that engaging in activities that promote relaxation, such as reading or listening to music, can lead to improved sleep quality. Encouraging your engineers to take breaks and engage in relaxing activities can lead to better sleep quality and improved productivity.

Boredom enhances mood: Positive mood is essential for employee motivation and productivity. Research has shown that boredom can help promote positive mood and reduce negative affect. A study(S7) published in the Journal of Personality and Social Psychology found that engaging in non-demanding activities can lead to improved mood and reduced negative affect. Encouraging your engineers to take breaks and engage in activities that promote positive mood can lead to a more motivated and engaged workforce.

Boredom improves focus: Multitasking and distractions can have a negative impact on employee productivity. Research has shown that boredom can help improve focus and concentration. A study(S8) published in Psychological Science found that exposure to natural environments, which can promote feelings of boredom, can lead to improved focus and cognitive function. Encouraging your engineers to take breaks and engage in activities that promote relaxation and focus, such as meditation or spending time in nature, can lead to better focus and higher-quality work.

=====================================
Methodology links (hover to see link first):
Agile Methodology 
Scrum 
Lean Development 
DevOps 
Six Sigma
Waterfall Methodology
Extreme Programming (XP)
Kanban
Continuous Integration/Continuous Delivery (CI/CD)
Lean Six Sigma
Crystal Methodology
Feature Driven Development (FDD)
Rapid Application Development (RAD)
Capability Maturity Model Integration (CMMI)
Lean Startup
Design Thinking
ITIL
DevSecOps
Lean UX
Six Thinking Hats

=====================================
S1 - "Bored at Work? Try These 3 Things" by Anne Fisher, Fortune, March 15, 2017 - This article discusses a study published in the Academy of Management Discoveries that found that employees who had more boredom in their jobs were more creative and generated more original ideas than those who had less boredom.

S2 - Trougakos, J. P., Hideg, I., Cheng, B. H., & Beal, D. J. (2014). Lunch breaks unpacked: The role of autonomy as a moderator of recovery during lunch. Journal of Occupational Health Psychology, 19(2), 91-103. - This study found that brief periods of boredom during the workday can help reduce job-related stress and fatigue.

S3 - Kooij, D., Jansen, P. G., Dikkers, J. S., & De Lange, A. H. (2014). The influence of age on the associations between self-reflection and work-related outcomes. Journal of Vocational Behavior, 84(2), 235-246. - This study found that self-reflection can help employees better understand their values and goals, leading to higher job satisfaction and improved performance.

S4 - Alkhajah, T. A., Reeves, M. M., Eakin, E. G., Winkler, E. A., & Owen, N. (2012). Sit-stand workstations: A pilot intervention to reduce office sitting time. American Journal of Preventive Medicine, 43(3), 298-303. - This study found that taking short breaks during the workday to engage in physical activity can lead to improved mood, reduced fatigue, and increased productivity.

S5 - Baird, B., Smallwood, J., & Schooler, J. W. (2011). Back to the future: Autobiographical planning and the functionality of mind-wandering. Consciousness and Cognition, 20(4), 1604-1611. - This study found that engaging in a boring activity for a short period of time can improve cognitive function and lead to more efficient and effective problem-solving.

S6 - Kang, J., & Chen, M. H. (2009). Effects of an irregular bedtime schedule on sleep quality, daytime sleepiness, and fatigue among university students in Taiwan. BMC Public Health, 9(1), 248. - This study found that engaging in activities that promote relaxation, such as reading or listening to music, can lead to improved sleep quality.

S7 - Weinstein, N., & Ryan, R. M. (2010). When helping helps: Autonomous motivation for prosocial behavior and its influence on well-being for the helper and recipient. Journal of Personality and Social Psychology, 98(2), 222-244. - This study found that engaging in non-demanding activities can lead to improved mood and reduced negative affect.

S8 - Berman, M. G., Jonides, J., & Kaplan, S. (2008). The cognitive benefits of interacting with nature. Psychological Science, 19(12), 1207-1212. - This study found that exposure to natural environments can lead to improved focus and cognitive function.

0 Comments

Why is software hard business?

14/8/2021

0 Comments

 
Picture
Lots of books, studies, talks, think groups, consultants and more have tried to figure out why software as a business is hard...but they seem all try to look at it from a single viewpoint.

I'm going to give you the secret to why writing software as a business is difficult.  Hard.  Nigh-on impossible.

Why?  Perspective.  Multiple points of view (PoV).

I've attempted to show you why in this chart.  Value from one's point of view tops out at 10 here.  The units are arbitrary.
​
The business folks start this chart on the left.  The absolute best thing they could get is an app that does everything their heart desires and get it /right now/. The longer the project drags on, the farther to the right and down the blue line goes. Why can't developers ever deliver anything?

Either the market opportunity will dry up because a competitor did release an imperfect but on-time project, the sales won't materialise, or the project will run out of money before delivering.

Note that the blue line continues below zero. A below zero value is a very real prospect...it means that the project is losing money for the business.

The developers enter this from the right.  There's almost zero value in giving something to the business on the first day.  We've not had time to scope, research, analyse, plan, divide into user stories, write tests for, fail, refactor, meet, discuss, and eventually deliver some software. Why do the business types always demand software before it's ready?

If the business demands it at the beginning it will have a near-zero value.  As time goes on, the value delivered (red line) slowly ascends.  At the far right, we've hit the perfect software: small, easy to maintain, well documented, maybe multi-platform and a joy to behold...and entirely too late.

By the time we've gotten that far our company has gone out of business.

The real value that a software project delivers is represented by the green line. The maximum value is the MINIMUM of either the red or blue lines.

The best we can hope for is to find the optimal mix: 'enough' software to scratch a business need, delivered fast enough to capitalise on the opportunity.

Admittedly not perfect software, and clearly not delivered on day 1.

There are ways to try to manage both lines to enlarge or prolong the sweet spot.  

You could throw more money at a project (whether that shows up as hardware, software, people, facilities, resources, campaigns, publicity, influencers, whatever...at the end of the day, it's all money) to give you a longer time period before the blue line starts to descend.  However, the farther to the right you go, the less effect throwing money at a project will have.

You can try reuse (internally with code or externally with libraries), or better tech, hardware or people to move the red line to the left.

No matter how passionately I argue that we *must* refactor code or that the project must deliver by Tuesday (even if the software isn't ready), I'm not going to be helping the business.

At the end of the day, we need to swap our points of view. 

If a dev looks at this from the pov of the biz guy, they'll be thinking how to move their bar to the left.  Descope, suggest alternatives, innovate to do things in quicker ways.

If a business guy uses the pov of a developer, he'll see that the quick win never really existed because it wasn't obtainable in the first place, and trying for it might have actually cost us the opportunity that really was obtainable, even if it were smaller.

This is the challenge that makes software difficult, and yet keeps things so painfully interesting.

0 Comments

Keeping with the Trend...

6/5/2019

1 Comment

 
Sometimes the most important thing is to tilt your head and look at the problem differently.  

I usually end up feeling foolish when this happens.  The only thing to do is to own it and move on, lesson learned.

I work on a big app in my day job.  As delivered, it's currently 45MB.

As you can imagine, some size could be sliced off if we could use /this/ technique, or /that/ procedure. Sadly real life doesn't seem to work that way.  Apps, like people, seem to be the sum total of all the events (and corresponding scars) made over their lifetimes.  There are /reasons/ why we can't use app bundling, or other methods to slim down like some other apps might.

So, when I was tasked with creating a carousel effect, though my first thought was to use the 'Android-CoverFlow' library from https://github.com/crosswall/Android-Coverflow, I balked because of the size.

I don't have anything against the code or the library, we just needed the lightest implementation possible.

So I started trying to build the coverflow effect by hand.

I found that the ViewPager is distinctly odd in the Android world.  If you luck into the right point of view, it's a no brainer.

If you, like me, make invalid assumptions, it's a nightmare of code smells: machine-specific code, hooking into the global layout of the widget, strange unexplained offsets being required, etc.

So, instead of being very long winded, I'm going to show you a git repo.  

One branch, "BadCoverflow", is the original code.  It works okay-ish on one size phone (I used the emulator's Nexus s here), but good luck getting it to work across phone sizes (try it on a Nexus 5x for example), or being able to control scrolling, or resizing elements. I couldn't get the scrolling to be reliably 1 page wide on all phones, and strangely the magnification of the transformer wasn't centered and also varied between phones.

I had a simple idea that a 'ViewPager' would fit the full width of the diplay, and it would just somehow 'know' to center the current item, etc.

I am embarrassed to say I lost 3 days to this mess.  To find what was causing the issues for me, I had to completely comment out all the code and uncomment it, bit by bit, to explain to myself what is going on.

In the other branch, "BetterCoverflow", is the simplified code.  Slightly smaller in size, platform-independent, and with fewer code smells.

Note that there's not much difference code-wide between these examples.  The biggest change came in my shifting point of view.

The viewPager is not expected to go the full width of the display and yet manage only a subset.  It's not expected to manage centering etc.  That's the job of the enclosing View.

Many of the smells have been removed (addOnGlobalLayoutListener? Trying to 'kick' the ViewPager as the transformer wasn't, somehow, being used when first laid out...
though I'm sure not all...no tests?  I mean really...).

As with most libraries we automatically reach for, Android-CoverFlow wasn't actually needed in the end, just a better understanding of how ViewPagers work.

I hope this article helps some other poor, lost soul struggling with a ViewPager-based coverflow implementation.
1 Comment

Don't be an Idiot (like me...)

24/9/2018

0 Comments

 
Don't be an Idiot (like me...)

Oh boy.

I don't feel particularly intelligent this evening.

For the last several work days, I've been fighting a bug.  A pernicious bug based around security...which I couldn't find.

I'd go forwards over my code, and then backwards.  Up and down.  I'd check web headers, recompile and run all my tests, etc...  No joy, still couldn't see the bug.

What was it?

Picture that you've got a class like this:

    
​Later on, in another object I instantiated one of these bad boys:

    
​What would you expect to see in the console?  Obviously:

    
​What I'd meant is for the output to be:

    
​Can you see where I went wrong?



The getName method should have been "protected"", at least, or maybe even "public", with a friendly and handy @Override annotation to indicate that we're overriding a method in the ancestor.


I said to myself, "Self," I says, "you done stepped on your crank."


This is an obvious bit of code, right?
​
But what if you had this:

    
​Now, the output is:

    
​How can you tell if that's any different to 
    c2l4OGMzMTk3NmItNWE4MC00YzVlLWE4NmYtOTU3MTJkMjY5OGFk
...or...
    c2V2ZW44NjQzMGI0Zi02MmMwLTQ1NDctOTk2MC1iOWQ2MTY2NGRiMmE=

The fun thing is that there was a third party library handling encryption (that has caused us issues before), as well as a web API that is (by design) rather uncommunicative.

All it would say in this instance is "Bad signature."  Exactly accurate, but not terribly helpful.

All the web request headers, as well as the other 6 arguments as well as those of the other 8 involved web calls were all correct.

The biggest cause (of my stupidity, I'll admit) is that everywhere else in the code, I did this:

    
​You'll notice that I refer back to a common definition of what getRealName is supposed to do.  There were three different encryption methods (each of which overrode getRealName()), and lots of other variables involved...but this was the cause.

Instead of using the common name manufacturing functions, I'd reimplemented them marking them private, for some reason.  Private methods aren't, of course, overridden.  Why would they be?

To make matters worse, I'd done it in a place where I was almost guaranteed to not find the issue.

Damn, another few grey hairs.

Don't be an Idiot (like me)...invent your own way.  This one's mine.
0 Comments

Circus in Motion

23/9/2018

0 Comments

 
I gave a talk to our department at work a week or two ago, and thought that I'd make the talk available here.

The talk is purposefully abstract and simplistic, as I feel that the Circus architecture is simple and applicable to other platforms as well as Android.  I simply didn't want people to get too hung up on the platform-flavour for the talk.

If you have any questions, comments or suggestions, feel free to contact me at ken@kencorey.com.
0 Comments

Let's all go to the Circus!

18/8/2018

0 Comments

 
So, I had a problem.

Like every mobile project before, this project was suffering.

The views (UIViewControllers on iOS or Activities on Android) lifecycles were wreaking havoc with the logic.  The views were like waves....they'd arrive causing my logic to start, and they'd go tearing down the logic sandcastles as they left.

The code invariably had train wrecks scattered throughout: object.attribute.field.method().  On Android it would all crash horribly in a nullPointerException fire.  On iOS, it would just quietly disappear like a mafia hit.

The code was so tightly integrated, you needed testing magic, mocking doubles, stubs, libraries, Robolectric or such to try to test the code.  These often came with limitations that were worse than the untested code.

So, we're back at manual testing bug whack-a-mole: knock one bug down, and another one rises.  Knock the second bug down, and the first one returns.  Squish both, and a yet-undiscovered bug pops up.

The UI state for each view was this flexible thing...when a button was clicked, the textfield was enabled.  Except when the 'Bad Password' screen was showing, because then the cursor would show through.  So we had to special-case that.  Of course, when the requirement came down to show a 'forgotten password' dialog, that had to be catered for as well, and...
Picture

​Enough!

I had to be missing something fundamental here.  

At a previous company, I was floundering towards a solution...   

I had a class called a 'Brain'.  This Brain was a wrapper for the logic states, while the views were the OS-specific visible part.  The brain could be in a different state, and the corresponding views would be shown.

Oh, this raised issues to be sure.  Both iOS and Android want their framework to be the center of your application.  After all, it makes an iOS app near-impossible to translate to Android, and vice-versa, unless you're using a multi-platform framework (Zen, PhoneGap, etc).  I had these states, but the interface was more than 3 methods (it had 5 per state) that people coming to learn it thought it was crazy.

Hrm...time for more research, I guess...  

I ran across this article(http://hannesdorfmann.com/android/model-view-intent) by Hannes Dorfmann.  Brilliant article, and it felt like I was on to something.  It's for Android, obviously, but I'm sure the concepts will translate with a bit of work.

Then I downloaded the code...and felt trapped back in the same box.  Not being completely up-to-speed on RXJava, it felt like there were things just out the corner of my eye that I didn't understand or couldn't even completely see.  I didn't see how it would handle the lifecycle issues I'd been facing.

So, then, I thought: why not rewrite it using the most boring, stupid java possible? 

That's when I arrived at 'Circus'.  (Think Piccadilly, not Big-Top)

Before I tell you what Circus is, let me ask you a question:  What /is/ your app?  

Is it the views?  Is it the database?  Is it the network?

I'd say it's the *logic* of your app that makes it special.  How you choose to do whatever it is your app does.

What are the features I'm looking to implement?
1) Eliminate lifecycle gyrations from my logic.
2) Isolate the storage, network, and all other library calls I'm not writing.
3) Provide an easy event-recording mechanism.
4) Ensure that all of my UI, my logic, and my plugins can be written using TDD /without/ having to use crazy testing frameworks.
5) On Android, ensure that my tests run in the JVM, so they're crazy fast, enabling real TDD again.
6) Split the UI, Logic, and Plugins into pieces so that multiple people can work on the same codebase in a *clean* way.

Sound too good to be true?
Picture

​Okay, so lots of lines.  How's this really a solution for anything?

Well, let's simplify the views...the views only ever do two things: they send an event to the back end, and they render new states.  They do *not* alter global state.  They could be killed, and reconstituted, and still be just as good as before, as they do not maintain their own state.

Okay, let's also simplify the back end things.  In fact, let's break the back-end things into component parts.  There's a 'network' plugin that provides the 20 or so network calls we'll make to the backend.  There's a 'database' call that handles all storage of temporary state.  And so on.  Any code that we aren't writing gets wrapped in a plugin.  All of it.

What's left?  Our logic, of course.  This is the thing that makes each view of our app a view of OUR app.

How do these all talk to each other?  In true Uncle-Bob fashion, though Interfaces (or your language-equivalent).  This means that there's one (and only one) way from a view to send an event to our logic.  There's only one way for our logic to send a new state to the front end for rendering.  There's only one way for our logic to kick off a network call, or for that network call to return its result.

This means that testing is a doddle, as we can simply write any old object that implements this interface, and all of a sudden, it's that kind of object.  We don't need Mockito, Robolectric or any other framework to test...it's all just Our Code!

Our tests can accept events, and send new states to the UI through the UI Interface.  Our tests can send events to the Back classes and see what states pop out.  The plugins can be tested using the Plugin Interface.

And threading?  The UI reports events through a single call.  It receives new states through a single call. When UI events are reported, they're simply put onto a background thread, and when a new state is sent to the views to be rendered, it's shifted to the foreground thread.  That means that our code *never* needs to bother with foreground/background, etc.  Our logic can simply block and wait, as we're by definition on a new background thread for each event, and always on the foreground thread for all UI changes.

Will this be a solution for all ills?  I don't know.

In my next few articles, I'm going to demonstrate these principles, and how I might implement all this and more.  What I'm aiming to deliver is a simple framework that we can use to get our jobs done in a way that allows for full (and easy) TDD in a mobile context.

My needs are a fairly simple Android application, so I'll be writing it in Java.  The concepts would hold on iOS as well with slight variations.

In fact, if I manage the abstractions cleanly enough, the logic won't care a bean what the UI is doing, nor will the UI care what the backend is...

So, enough for today.  Read my next article for first implementations...

-Ken
0 Comments

Why?

18/8/2018

0 Comments

 
Okay, enough's enough.  Why create yet another category?

Well, from time to time I'll have random musings about digital stuff that doesn't seem to fit in anywhere else.
​
0 Comments

    Author

    This is when I'm wearing my IT hat.

    Archives

    February 2023
    August 2021
    May 2019
    September 2018
    August 2018

    Categories

    All

    RSS Feed

  • Personal Blog
  • Flippin' Bits
  • Gallery
  • Holidays
  • Flying a Paramotor, Part II