Rob Kraft's Software Development Blog

Software Development Insights

Archive for the ‘Uncategorized’ Category

How To Activate Function Key Lock On Your Lenovo Yoga

Posted by robkraft on June 14, 2019

This post is primarily for myself to find the answer when I need to change the default way function keys behave on my Lenovo computer again.

To do this, launch the “Lenovo Vantage” app in Windows 10.  From there select “Hardware Settings” and then “Input”.

LenovoVantage

Selecting the highlight option will cause your function keys to behave like most software programmers expect them to behave.  Very helpful for a developer like myself that is used to using F8 and F10, not to mention all the helpful Windows function keys:

https://www.computerhope.com/issues/ch000306.htm

Posted in Home Tech, I.T., Uncategorized | Leave a Comment »

Use A Google Sheet To Send Reminder Emails To Your Team For Free

Posted by robkraft on May 26, 2019

A lot of small teams could use reminder emails when it is time for a team member to perform a task, but there are not a lot of products where you can easily set up reminder emails for team members for free.

But you can do it easily with a Google Sheet.

Building on the work of others I created this little script you can copy/paste from https://github.com/RobKraft/GoogleSheetBasedEmailReminders

Open the Script Editor from the Tools menu of your Google Sheet and paste this script in.  The code is simple and documented if you desire to change it.

Then set up 4 columns in your google sheet.  Make row one headers for the 4 columns:

  • Column A: Email Address – this is a single email address or comma separated list of email addresses to send to
  • Column B: Reminder Begin Date – this is the date at which the reminder will start going out daily Column
  • C: Subject – This is the subject of the email
  • Column D: Email Body – This is the body of the email. Also the code adds some extra stuff to the body of the email.

You also need to create a trigger in your google sheet.

To do this, select the Edit menu from the script menu and select Current Project Triggers. You may need to give your project a name and save it at this point. Add a trigger. At the time of this writing in May 2019, you would need to set these values for your trigger:

  • “Choose which function to run” – probably sendEmails
  • “Choose which deployment to run” – probably Head
  • “Select event source” – Time-driven
  • “Select type of time based trigger” – Day Timer – for once per day
  • “Select Time of Day” – During what time frame do you want the trigger to run. (GMT Time)

That is it – save that trigger and it is all yours.  Set up an email to yourself to test it all.  All the emails will be sent from your own @gmail.com account.

Just for fun, I include the script code here that is also in the repo:


function sendEmails() {
  //Set up some variables
  var startRow = 2; // First row of data to process
  var numRows = 100; // Number of rows to process
  var currentDate = new Date();
  var currentYear = currentDate.getFullYear();
  var currentMonth = currentDate.getMonth() + 1;
  var currentDay = currentDate.getDate();
  var emailSubjectPrefix = 'Reminder: ';
  var urlToGoogleSheet = 'https://docs.google.com/spreadsheets/????edit#gid=0';

  var sheet = SpreadsheetApp.getActiveSheet();
  // Fetch the range of cells A2:D100
  var dataRange = sheet.getRange(startRow, 1, numRows, 4);
  // Fetch values for each row in the Range.
  var data = dataRange.getValues();
  for (i in data) {
    var row = data[i]; //Get the whole row
    var emailAddress = row[0]; // First column of row
    if (emailAddress != "") //If there is an email address, do something
    {
      var eventDate = new Date(row[1]); //second column of row
      var yearOfEvent = eventDate.getFullYear();
      var monthOfEvent = eventDate.getMonth() + 1;
      var dayOfEvent = eventDate.getDate();
      if (currentYear >= yearOfEvent && (currentMonth > monthOfEvent || (currentMonth == monthOfEvent 
           && currentDay >= dayOfEvent)))
      {
        var subject = emailSubjectPrefix + row[2];  //third column of row
        var message = row[3]; // fourth column of row
        message = "\r\n\r\n" + message + "\r\n\r\n";
        //Add a link to the spreadsheet in the email so people 
        //can easily go disable the reminder 
        message = message + "\r\nSent on " + currentDate + 
        "\r\nDisable the notification by changing the date on it here: "
        + urlToGoogleSheet;
        message = message + "\r\nReminder Start Date: " + eventDate
        MailApp.sendEmail(emailAddress, subject, message);
      }
    }
  }
}

Posted in Code Design, CodeProject, Uncategorized | Leave a Comment »

How to Upgrade to a Stronger Password Hash. Such as Upgrading from MD5 to BCrypt.

Posted by robkraft on July 23, 2018

Years ago I upgraded the hash algorithm in our database application from a custom algorithm to BCrypt.  Although the implementation went well I lamented the need to retain the old algorithm until such time as all users had logged in and replaced their old hashed password with a new hashed password.  Since that time I have learned there is a better way to upgrade to a stronger password hash so I am sharing it here in case I need to do this again in the future and possibly to help someone else implement a better approach.

In a nutshell, what I should have done is hashed all the existing hashed passwords using BCrypt immediately.

If that does not give you the hint you need to see the solution, allow me to explain in more detail.

Assume you have a database full of user names and passwords, the passwords were all hashed using MD5, and you now want to use BCrypt to hash them.  The approach a lot of us take, including myself, is to add the BCrypt algorithm to the application code.  When users log in to the updated application, the code does the following:

  • Person enters user name and password
  • Application hashes the password using MD5
  • If the MD5 hash matches the hashed MD5 password in the database:
    • The application hashes the password using BCrypt and stores that in the database
  • In the future, the application will use the BCrypt hash for the user instead of the MD5 password.

The problem with this approach, is that that the application must continue to support the old hash algorithm (MD5 in this example), until all users have logged in and converted their password hashes to BCrypt.

There is a better way.

  • Immediately hash all the MD5 hashes using BCrypt.  (Note, this is not hashing the passwords, because we do not know the passwords.  We are hashing the MD5 hash of the passwords.)
    • This allows us to immediately have all the passwords hashed with the stronger BCrypt algorithm.
  • As users log in to the application, hash the password they enter using BCrypt and see if it matches the hash stored in the database.
    • If not, then hash the password they enter using MD5 (your old algorithm), and then hash the result of that operation using BCrypt.  If that hash matches what is stored in the database, allow the user access to the application and also create a new hash of their password directly using BCrypt and update the hash stored in the database.

As mentioned, the benefit of this approach is that you immediately convert all the stored passwords to the stronger algorithm, instead of implementing a gradual process that does not convert all the passwords until all user accounts have eventually logged in, which could be never for some applications.

Posted in Code Design, Security, Uncategorized | Leave a Comment »

iTunes 12.7 Problem – Podcasts missing from Library

Posted by robkraft on October 22, 2017

It seems that most iTunes Upgrades either cause problems or remove features I use for managing the podcasts I listen to and 12.7 was no different.  This one took me an hour to resolve.  Unfortunately Apple has no information about this on their site and it is not easy to submit or get responses to support requests.  But I found the answer on another blog: https://appletoolbox.com/2017/09/apple-releases-new-itunes-12-7-what-you-should-know/#Where_Are_My_Podcasts

I am reposting the resolution on my blog in case I need to again, and maybe to reduce the time it takes for others to resolve the problem.

Posted in Home Tech, Uncategorized | Leave a Comment »

Run Visual Studio As Admin, Without The As Administrator Prompt

Posted by robkraft on July 10, 2016

I run visual studio as admin just by clicking the icon in the task bar:

AA1

If you would like to do this same thing so that it does not prompt you to “run as admin”, and so that you don’t need to right-click and select “Run as administrator”, you can set up a windows task do this using the following steps:

Open Task Scheduler (click start and begin typing:  Task Scheduler).

  • Select “Create Task”.
  • On the General Tab, give the task a name such as “VS as Admin”.
  • Click on the “Run with highest privileges” checkbox to select it.

aa2.png

On the Actions tab:

  • Create a new Action.
  • Action = “Start a Program”.
  • Program/script = “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe”.
    • Note: 14.0 references Visual Studio 2015, use 12.0 for VS 2013
  • Click OK to save the task.

Right click on your desktop and select New, shortcut.

  • Set the value to
    • C:\Windows\System32\schtasks.exe /run /TN “VS as Admin”
      • Replace “VS as Admin” with the name of the task you created above
  • Click Next and enter a name for the shortcut, then click Finish.

Right click on your shortcut and select Pin to Taskbar.  It should be ready to use!

Posted in Coding, Dev Environment, Uncategorized | Leave a Comment »

Robert’s Rules of Coders: #11 Separate User Interface Logic From Business Logic

Posted by robkraft on July 10, 2016

One goal to keep in mind as you write software is to write software that is easy to maintain and enhance in the future. We can do this by organizing code so that things that might change will be easier to change. Consider this example:

CodeArt12-1

CodeArt12-2

In the code above, User Interface (UI) code is mixed together with the business object code. We should try not to pass details about how the UI implements a feature unless the business object really needs to know. In this example, the Products business object really only needs to know three pieces of information from the UI:

  • The Price
  • Should a discount be calculated because this is for a nonprofit agency? (yes or no)
  • Should a discount be calculated because this is a bulk purchase? (yes or no)

If we change the code to pass boolean values to the Products business object instead of the checkboxes, we gain the following benefits:

  • The UI can easily be changed in the future to use something other than checkboxes, and this change will not require also changing code in the Products business object.
  • We increase our potential to use the Products business object with different types of user interfaces. This business object may currently expect a C# WPF checkbox control, which means the business object would not work if someone had a C# Windows checkbox control, or perhaps a C# Silverlight checkbox control. But if the Products business object accepted a boolean, which is a datatype common to more platforms, the business object will more likely work with different user interfaces.
  • Unit tests that we write won’t need to reference the specific UI components needed for building the user interface.

A more common way that developers often entwine UI code with business object code is shown below. This example is the opposite of the case above. Here logic that could, and should, reside in the business object is performed in the UI.

CodeArt12-3

CodeArt12-4

The reason we don’t like this code is that logic to calculate the discounted price should be moved from the UI to the Product business object. In doing so we would gain the following benefits:

  • We could reuse the Product business object in another program without needing to also add logic to the UI of the other program to calculate the discounted price.
  • If we need to change the calculation for the discounted price, we need to make the change in only one place and every program using that business object automatically is affected.
  • We can easily write a unit test on the Product business object to make sure that the code calculating our discounted price works correctly.

A better way to write the code from both examples above so that the UI and business logic is not entwined is shown below. I will admit that this is not the best example, because it does not use TryParse, nor does it have input checking and error handling, and it could use an interface, but those topics are not the point of this article, which is to encourage you to separate the UI logic from the business logic in your applications.

Codeart12-5

CodeArt12-6

It is not bad sometimes to write code that entangles UI code and business logic, knowing that you will refactor the code to move the logic to the correct place before you consider the feature complete. It is often helpful to have all of the code in one big method until you have it correct, then you can improve the code by refactoring it.

As with any of Robert’s Rules of Coding, you don’t need to adhere to them all of the time and there are cases where it is better not to. But most programmers should follow the rules most of the time. I hope you agree.

Go to Robert’s Rules of Coders for more.

 

 

Posted in Code Design, CodeProject, Coding, Uncategorized | 1 Comment »

Robert’s Rules of Coders: #10 Scope minimally, scope private

Posted by robkraft on May 22, 2016

A big ball of mud is a designation for some software programs that are very difficult to maintain. We never set out to create a big ball of mud, but it happens to many programs over time. One technique to reduce the entanglements that lead to a big ball of mud is to expose the functions in your code as little as possible to other parts of your program. In many programming languages the term “scope” is used to determine if your function can be used anywhere within the program, or just within a small area of the code.

The two most common scopes are “public”, which usually means that any part of your program, and perhaps other programs, can call the function; and “private”, which usually means that only other functions within the same region of code, within the same “class” or “namespace”, or perhaps within the same compiled assembly can call the function.

Some languages include additional scopes such as “internal”. .Net allows methods that are scoped private to only be called by other methods within the same “class”; but the use of the “internal” scope allows other classes within the same compiled dll to call the methods with an internal scope, but code in other dlls cannot.

When you write a method that is only used within one class, you should always set the scope of that method to private. This provides the following benefits:

  1. You do not unintentionally provide access to sensitive data.
  2. The code will not be accidentally called from another class, by another developer or yourself, creating an unexpected and undesired entanglement.
  3. The code will not be called by third-party developers, particularly if the class you are writing is part of an API that you expose to third-party developers.
    1. Of course, if you desire that third-party developers have use of the method then scope it public, but do not do so by default because you may be unable to change the method in the future without breaking the third party dependencies on your API.
  4. If you have scoped the method privately, you can be sure that other code is not using the method if you later decide to refactor or rename the method.
    1. This is not entirely true for languages that support alternate methods of calling even private functions from outside of the functions class. For example, the .Net language provides a feature called reflection that can be used to call the private members of another class. Developers using the reflection technique usually understand the risks.
  5. If you have a method that could be accessed by another class, you should spend a few minutes reconsidering the design of your classes instead of quickly and simply making the class public.
    1. Perhaps you should create a new helper class; perhaps you should refactor the code in the method to make accessible just what is needed in the other class.

In the two examples below, the developer desires to use the Base64Decode method in another class.  In the first example the ExampleOfWhatNOTtoDo class is made public as are all of the methods.

CodeArt10-1

But it would be better to move the Base64Decode method out of the ExampleOfWhatNOTtoDo class, so that nothing is made public that does not need tobe public as shown below.

CodeArt10-2

When the language allows a level of scoping besides public and private, such as internal, you should generally consider changing the scope from private to internal if that is sufficient rather than from private to public.

I have two final tips for .Net developers.

Tip 1: You can scope methods internally, yet allow other applications that you write have access to them but using “Friend” assemblies as described here: https://msdn.microsoft.com/en-us/library/mt632254.aspx. The InternalsVisibleTo attribute can be provided to the class in code or to the entire dll in the AssemblyInfo.cs file.

Tip 2: You can use an interface for internal methods, thus making your methods accessible through an interface from other dlls in your solution. You just need to explicitly implement the interface as described here: https://msdn.microsoft.com/en-us/library/ms173157.aspx.

As with any of Robert’s Rules of Coding, you don’t need to adhere to them all of the time and there are cases where it is better not to. But most programmers should follow the rules most of the time. I hope you agree.

Go to Robert’s Rules of Coders for more.

 

Posted in Code Design, Robert's Rules of Coders, Uncategorized | Leave a Comment »

How to prevent foreign language subfolders in Silverlight 5.0 projects

Posted by robkraft on April 17, 2016

This is an update to a blog post I first made in 2011:  https://csharpdeveloper.wordpress.com/2011/04/02/how-to-prevent-foreign-language-subfolders-in-silverlight-projects/

We are still supporting Silverlight applications, though we should have them rewritten in HTML within a year.  Until then, we can put the commands below into a batch file and run it as Admin on developer PCs to stop the creation of all the foreign language versions of the DLLs of our projects.  This speeds up the build time a little bit, and keeps us from distributing, analyzing, virus-checking, and etc. on those DLLS.

c:
cd\
cd \Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\Libraries\Client
rd ar /S /Q
rd bg /S /Q
rd ca /S /Q
rd cs /S /Q
rd da /S /Q
rd de /S /Q
rd el /S /Q
rd es /S /Q
rd et /S /Q
rd eu /S /Q
rd fi /S /Q
rd fr /S /Q
rd he /S /Q
rd hr /S /Q
rd hu /S /Q
rd id /S /Q
rd it /S /Q
rd ja /S /Q
rd ko /S /Q
rd lt /S /Q
rd lv /S /Q
rd ms /S /Q
rd nl /S /Q
rd no /S /Q
rd pl /S /Q
rd pt /S /Q
rd pt-BR /S /Q
rd ro /S /Q
rd ru /S /Q
rd sk /S /Q
rd sl /S /Q
rd sr-Cyrl-CS /S /Q
rd sr-Latn-CS /S /Q
rd sv /S /Q
rd th /S /Q
rd tr /S /Q
rd uk /S /Q
rd vi /S /Q
rd zh-Hans /S /Q
rd zh-Hant /S /Q

cd\
cd \Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0
rd de /S /Q
rd es /S /Q
rd fr /S /Q
rd it /S /Q
rd ja /S /Q
rd ko /S /Q
rd ru /S /Q
rd zh-Hans /S /Q
rd zh-Hant /S /Q

 

 

 

Posted in Silverlight, Uncategorized | Leave a Comment »

Agile Baby Steps: A Parable To Help You Get Started

Posted by robkraft on March 20, 2016

We often hesitate to take the action that shows we are committed to doing something new. We read about it, analyze it, and try to understand it; but real learning requires that we go beyond reading. We must DO. The goal of this article is to get you to take action toward becoming Agile, without understanding or adopting all of the habits of an Agile development team. I am asking you to try out some new processes in your software development life cycle, without considering whether or not you are doing Agile development.

Side bar: Your ability to implement an Agile technique depends upon the process by which your software is implemented. An Agile development technique that works for one process may not work for another, so be cautious of Agile recommendations that state you must do something specific or you will fail at being Agile. Your goal is not to be “Agile” by anyone’s definition. Your goal is to write better software. 

  • Some software developers write code then send it to a quality assurance environment who then push it into production;
  • Some software developers write code for embedded systems where all the software must be completed before it is written to a chip;
  • Some software developers check in code that that runs through automated tests and gets published to a public web site without further human action;
  • And some software developers follow other models for implementation.

The process by which you take code from development into its final environment greatly affects which agile techniques will work for you.

The Parable Begins

Let me share with you a parable of two teams, each tasked with developing the same software, but each using a different methodology.

Team Agile used an agile methodology, and team waterfall used a waterfall method. Both teams were asked to build a web application to allow users to manage data in an existing client-server application.

Team Agile met with the end users, usually known as the product owners in agile, and learned the high level requirements and features desired for the entire application. Because they did not gather detailed requirements, they spent only eight hours on this task.

Side bar: Delaying the gathering of detailed requirements often adds value in several ways:

  1. You don’t spend time gathering and documenting detail requirements for features that later get cancelled or excluded from the project.  If the team spends ten hours detailing the requirements of a feature that management decides not to implement a month later, then the team wasted ten hours. Eliminating waste is the major focus of Lean and Kanban styles of Agile development.

  2. Another reason to delay gathering detailed requirements is that every team member will be smarter in the future than they are today.  Each will know more about the application and may learn that ideas considered early in development are not as effective as new ideas learned since. Perhaps a developer read about a new programming technique or tool; or perhaps the product owner learned about a better way to design a user interface. You can implement these new ideas and techniques even if you documented detail requirements for the old techniques, but that means the time spent gathering and documenting requirements for doing it the old way was wasted time.

Prioritization

Team Agile also asked the product owners which features were most important. The product owners initially said all of the features were necessary and important, but after more discussion the product owners provided this prioritized list of features:

  1. Users need to be able to log in
  2. To view data
  3. To edit data
  4. To add data
  5. To delete data

Prioritizing features is an important, and necessary feature of agile development, as we shall see later. If you do not prioritize the features you are going to work on, you will probably not receive the benefits that agile development can provide.

Meanwhile, in a parallel universe, the Team Waterfall also met with the end users to gather requirements. They spent much more than eight hours on this task because they needed detailed requirements for all the features. They planned for little interaction with the product owner after this meeting until the product was finished. Team Waterfall spent sixty-four hours on requirements.

The Login Feature – Deploy Early

Team Agile next then did some design for the project. They thought about all of the requirements they had learned about, but they only did a detailed design for the first feature they worked on; and that feature was the ability to log in. They spent four hours on the design of this feature.

Then Team Agile coded the login feature. The coding took eight hours. Next, Team Agile turned the application over to the Quality Assurance (QA) team. Even though the entire application was not completed the QA team found a few problems with the login feature. Team Agile fixed those problems, and the QA team could find no more defects.

Side bar: Agile development does not magically prevent programmers from creating bugs, but it does make developers aware of the bugs sooner, so they can fix them while the code is still fresh in their minds and before some errors might get propagated into more of the code.

Team Agile implemented the application in production. Now, this seemed a little silly to some people, because the application did not do anything other than let a user login; but it turned out to be very valuable. They discovered that the software did not work in production. The production environment had an older version of the web server that lacked some features the application depended on. Team Agile met with IT to discuss the problem and decide if the web app should be re-written, or if the production web server could be upgraded to a newer version. They decided the web server could be upgraded, but it did require two weeks for this to be completed.

Agile Manifesto Principle #1: -“Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.”

Side bar: Not all software can be deployed in small pieces, such as software embedded on chips or shrink-wrapped software. But some software, like the software in this parable, can be deployed in pieces. By taking the software as far as possible along the path of implementation you may discover problems. It is always best to know about problems sooner so they can be accounted for in the project schedule and possibly used to correct the product requirements, design, and code. A product developed using a waterfall method has a higher risk of failing to discover some problems until all the code is completed and thus incurs significantly higher costs to correct the problem.

Side bar: Agile methodologies reduce the risk of unknown and unexpected problems by revealing them sooner.

The View Feature

While Team Agile waited for the new web server to be implemented in production, they proceeded to work on the second feature, “Allow users to view data”.   They met with the users to get more detailed requirements about how they would like to view the data. They spent eight hours on this task. Team Agile then created a design, including some mockups and reviewed the mockups with the product owners. After this sixteen hours of work the developers were ready to begin coding.

I have not forgotten about Team Waterfall. During all this time that Team Agile did the activities above, Team Waterfall has been gathering requirements. Team Waterfall is now ready to design the application, and they will spend about forty four hours in design, which is a little less than the total amount of time Team Agile will spend on design. In this parable, Team Waterfall benefitted by designing the entire application all at once because it was all fresh in their minds as they did it. Team Agile, on the other hand, did parts of the design spread out of several months, and had to spend part of that time recalling why some decisions were made. However, the advantage still goes to Team Agile, as we shall see, because Team Waterfall will discover that much of their time spent in design was wasted.

Team Waterfall completed their design then started coding. They chose to code the view and edit features first, and at the same time because they believed them to be the most interesting and fun part of the code to write. For both Team Agile and Team Waterfall, the coding phase(s) of the application take the longest; around three hundred hours. At the same time that Team Waterfall is working on the total application design, Team Agile begins coding their second feature, “Viewing Data”.

Communication With Product Owner

For both teams, the time spent coding is the same for all features except for “Viewing Data”. Team Agile spent one hundred and twenty hours coding this feature, but Team Waterfall is going to spend one hundred and sixty hours coding this same feature for the following reasons.

  • In the first week, a developer attempted to implement a list box on a form as had been requested in the requirements. But the developer found that this data would be difficult to display given the list box features. He realized he could easily do this with a grid though.  So the developer brought this up with the product owner during the daily status meeting, and the product owner said he didn’t care if it was a list box or grid, he barely understands the difference between the two, and he would just prefer to defer that decision to the developer. So the developer used a grid instead of a list box and saved an estimated forty hours of work that would have been needed if he had tried to make the feature work using a list box.

Agile Manifesto Principle #4 – “Business people and developers must work together daily throughout the project.”

  • In the second week, another developer was working on a feature to let users pick their own colors for the forms. The requirement called for a text box in which the user could type a hexadecimal value representing the color, but the developer had recently learned about a component that could just as easily provide a color picker to make it much easier for the end user. Instead of adhering to the requirements the developer showed the product owner liaison an example of the color picker and asked if this change would be acceptable and the product owner liaison loved the idea, so it was implemented.

Agile Manifesto Principle #6 – “The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.”

Side bar: Once again, the ability for frequent interaction between the developers and the end users throughout development facilitates many improvements. Also, developers are often more aware of the capabilities of technology than the end users and can make suggestions for improving the application based on that knowledge. When the discussion for detailed requirements can be delayed and the developer writing the code can be involved, there is a greater chance for a better solution.

Side bar: A good technique for software development, and for many decisions in life, is that it is best to commit to a decision as late as possible because your knowledge later in the life cycle is greater than it will be earlier in the cycle.

Reports Feature – New Requirements

During Team Agile’s development of the “View Data” feature, the product owner realized they had omitted the reports feature from the project. The reports are used by every user and are much more important than the ability to delete, add, or even edit data. The product owner and the developers had a meeting about the omission and decided that the developers would add the report feature next, after they finished View feature.

Agile Manifesto Principle #2 – “Welcome changing requirements, even late in development. Agile processes harness change for the customer’s competitive advantage.” The ability to accept new requirements and to change the priorities of features developed is one of the most noticeable and valuable aspects of agile development.

The development team finished the view feature and easily deployed it into production. The product owners started using the application, even though all of the features were not available.

Agile Manifesto Principle #3 – “Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale. “

Deploying the view feature provided several benefits:

  • The company could begin deriving value from the application. In financial terms, the Return On Investment (ROI) starts occurring sooner in Agile projects than in Waterfall projects.
  • The users became more productive because the web application was easier and faster to use than the client server application. It was also easier for the IT staff to make it available to more users.
  • The users found bugs in the application. Finding some of these bugs may prevent similar bugs from being developed in the remainder of the application. For example:
    • The users found that there were no accessibility keys. So the development team planned to add these to the view screens, and were proactive about adding this feature in future development.
    • The users became more productive because the web application was easier and faster to use than the client server application. It was also easier for the IT staff to make it available to more users.
    • Twenty percent of the users found that some features did not work on the particular browser they used, which was different than the browser used by the developers and most of QA.
    • A few bugs were found causing incorrect data to be displayed.
  • Side bar: Teams often desire to fix bugs right away, but in an Agile environment, especially one with short one-week or two-week iterations, this can be counterproductive. It is generally best to let the team complete what they started in an iteration, then make the fixes to the bugs a top priority for the next iteration.

Waterfall Team Progress

Let’s check in on Team Waterfall. At the same time Team Agile is coding and deploying the “View Data” feature, Team Waterfall chose to code the “View Data” and “Edit Data” features, and they are still in the process of doing this. They have nothing yet to show to the product owners, so let’s turn back to Team Agile, because they have some visible progress that we can check on.

Agile Manifesto Principle #7 – “Working software is the primary measure of progress.”

Team Agile finished the “View Data” feature, and started to develop the “Reports” feature next. The requirements and design only took sixteen hours, and by this time the reports of bugs in the “View Data” feature were coming in. However, the team felt they could and should complete the “Reports” feature before working on the bugs so that they did not incur the cost of switching back and forth between tasks. The product owners accepted this decision because the development iterations were short, and the development team said they could start fixing the bugs next week.

After finishing the “Reports” feature and deploying it to production, the team spent a week fixing the bugs in the “View Data” feature. Some of the bugs had made some views unusable, and other bugs, such as accessibility and support for other browsers, would affect how they developed all subsequent features.

Side bar: Agile development does not magically eliminate bugs, nor does it prevent errors in requirements, design, and communication. But Agile development does reveal most bugs sooner so they can be fixed more quickly and cost less to correct than they would in waterfall development.

Team Waterfall is still coding the “Edit Data” feature at this point in time. It took them longer to code the “View Data” feature than it took Team Agile because Team Waterfall made the list box work as documented in the requirements rather than go back and talk to the product owners about using a grid instead. Team Waterfall also spent time explaining to the product owner that they could not add the “Reports” feature to the product because they had already gathered all of the requirements and done the design and they would need to redo some of that for a new feature. Ultimately, the product owner agreed to increase the product budget and provide proper paperwork for a “Change Request” to the requirements of the system. Team Waterfall then spent eighteen hours gathering the requirements and changing their design, which included changing the design of some database tables they had not started coding against yet. Since Team Waterfall still has nothing to show, we will go back and see what is happening with Team Agile.

More New Feature Requests

Team Agile has started the requirements and design of the “Edit” feature. During development of the edit feature, the product owner realized they had omitted filtering and sorting abilities in the view feature and that filtering and sorting was really necessary to make the views more valuable. Team Agile decided they would add sorting and filtering to views right after they completed the editing feature.

The Cancellation of the Project

But in the next week a new project came in and the developers were asked to suspend this project and work on the new project. The new project was very important, of course, and would probably take the team a year to complete. Team Agile was given one week to wrap up this project and begin work on the new project. For Team Agile, the editing feature was almost done, but the date and time pickers only worked on one browser and the developers estimated it would take them three to five days to get new date and time pickers working on all browsers. Team Agile had to choose between these options:

  1. Add filtering and sorting to views and not release the edit feature
  2. Finish the edit feature so the date picker worked on all browsers and users would not have to type in dates, but not add filtering and sorting to views
  3. Add filtering and sorting to views and release the edit feature without a date picker, requiring users to type in the date.

Team Agile desired to complete the edit feature by making the date picker work because they did not want to provide the end users with a subpar, low quality product; and they thought it would make the developers look bad if the app did not have the simple date pickers. But the product owner said that the filtering and sorting of views was most valuable, and that they would take the editing feature even without the date pickers because the ability to edit data from the web application would provide some value to users even if the feature was not finished perfectly.

Side bar: Agile development often gives the product owner insight into the product development processes and decisions. This is almost always a benefit to the business because the product owner can help guide the product outcome to a solution that provides the best ROI for the business. However it can, occasionally, upset some developers when they feel they are asked to cut quality to get the job done. The developers may feel it will reflect poorly on them. It is up to the management teams to convey to the end user the decisions made in this situation were those of management, and not the developers.       Waterfall teams rarely have this dilemma because the product owner is unaware of all the decisions made.

Speaking of waterfall teams, as in the side note, what is going on with Team Waterfall now that this new project has arrived and they must work on the new project instead. Well, one benefit for Team Waterfall is that they can start on the new project right away instead of spending a week trying to wrap up the old project because there is no way Team Waterfall can deliver anything within one week on the old project; they never even started the Login feature of the application. The obvious enormous downside for Team Waterfall is that they will deliver nothing to the end users, and all the time spent on the application can now be considered waste. That is not the case for Team Agile. Even though the project was terminated early, the agile team delivered something of value that could be further enhanced in the future.

Agile Manifesto Principle #10 – “Simplicity–the art of maximizing the amount of work not done–is essential.”

I provide two summaries to this parable. The first, is a summary specific to the tale, and the second is a summary of general conclusions to be made about agile development.

Specific Summary

  • Team Agile delivered some business value, but all the time spent by Team Waterfall was a waste.
  • Team Agile reduced the development time of some features by frequent interaction with end users and by being open to changing the requirements.
  • Team Agile provided a better way for end users to choose their colors than team waterfall because the UI decision was not made until the feature was developed and in that time the developer had learned of a new component.
  • Team Agile accommodated the “Report” feature because they had a prioritized backlog and could easily queue it up to work on next. Team Waterfall did not prioritize their work, so any new development would probably just be added at the end. Team Waterfall would need to alter their existing requirements and design.
  • Team Waterfall never learned that their app would not work in production due to the older web server. It is probable that the team would be rushing to deliver this product by a deadline, only to discover right at the end that additional time would be required. It could have been even worse if IT was unable to upgrade the web server and the development team had to go back and change code to make the application work on an older web server.

General Summary

  • Agile teams often waste less time than waterfall teams.
  • Frequent interaction with end users can produce a better product with less waste. This is not exclusive to agile development, but it is more common to agile development than to waterfall.
  • The willingness to accept flexible requirements can produce a better product with less waste. This is more difficult to do when all requirements have been gathered up front and have been included in a design.
  • Delaying requirement and design details can lead to better decisions at the time the decision needs to be made.
  • Agile teams accept new requests easily by adding them in the backlog. They do not have a lot of time invested in any features in the backlog because they wait and do the detailed requirements and design for them when they are about to code them.

If you want to become more Agile today:

  • Create a prioritized backlog
  • Select features from the backlog that you will complete during your next iteration. A good iteration length is two weeks.
  • Make sure that you don’t just code the features, but that you include testing and deployment, if possible, to be done within your iteration.
  • Do not work on several things at the same time. Complete each feature as much as possible.
  • Finish what you start each iteration. Do not add interrupt what you started in an iteration by working on something new that came in to the backlog. Wait until the next iteration to start it.
    • Sometimes, something very high priority will come in that must be completed right away. Agile developers understand and accept this.

Posted in CodeProject, Process, Project Management, Uncategorized | Leave a Comment »

Is 2016 the Year to Stop Bundling Javascript and CSS?

Posted by robkraft on December 13, 2015

If you don’t stop bundling your javascript and CSS in 2016, you will probably do so in 2017 or 2018 and the reason for this is the implementation of HTTP2. HTTP2 is a new spec to replace HTTP and requires changes in both browsers and the web servers they connect to. Once each side of the communication supports HTTP2, the improved communications can begin using the new spec. Going into 2016, most major browsers such as Chrome, Firefox, and Edge support it; but I am not sure about IE11.

HTTP2 is not a rewrite of HTTP, but an alteration of a few features. One of the most notable is the ability for the browser to bundle multiple requests together to send them to the server. This is why developers should consider ending the use of bundling javascript and CSS on the server, as it may provide worse performance to clients running HTTP2. For a good podcast about the impact of HTTP2, I recommend show 1224 of .Net Rocks: http://www.dotnetrocks.com/?show=1224

Developers should keep the following in mind regarding HTTP2:

  • Bundling of javascript and CSS may provide worse performance than not bundling for clients using HTTP2.
  • Communications that are not using HTTP2 will still benefit from bundling.
  • Some browsers, notably Chrome and Firefox, may only support HTTP2 when the connection uses TLS/SSL.
  • Proxies in between the client and the server that don’t support HTTP2 may also affect the improvements HTTP2 would otherwise provide.

For a little more about the spec, I recommend this concise post from Akamai: https://http2.akamai.com/. And don’t overlook their awesome demo example of the improvements HTTP2 can provide: https://http2.akamai.com/demo.

Posted in Coding, Dev Environment, I.T., Uncategorized, Web Sites | Leave a Comment »