Showing posts with label management. Show all posts
Showing posts with label management. Show all posts

Tuesday, July 15, 2025

How to write a software issue

If a software problem report or issue describes a large goal or vision, it should be documented as part of a concept of operations or a specification. If you can’t write clear acceptance criteria, or if a developer can’t reasonably complete it in 1–3 working days, it’s probably too big and needs to be split.

Large issues often depend on knowledge of many parts of the system, while smaller ones usually touch just one area. Smaller issues are easier to test, review, and merge. A smaller scope also makes it easier to prioritize and adjust based on feedback. 

Smaller, well-defined tasks are much better candidates as a “first issue” for a newcomer because they feel more approachable. It’s also much clearer when the work is done and what the expected result is. A newcomer can complete the work, submit a pull request, and get feedback quickly — which builds confidence and keeps them engaged.

Monday, June 2, 2025

Non-Functional Requirements

When building software, we define two types of requirements:

  1. Functional: What the system should do (e.g., login, payment).
  2. Non-functional: How well it should do it (e.g., speed, copy protection, security, scalability).

Without this distinction, you risk neglecting important aspects of system quality that don’t show up in features alone. You can implement a feature that works but still fails the user if it’s slow, insecure, or unreliable. Performance is considered non-functional because it affects user experience but doesn’t define what the system does.

It is similar to the frontend-backend layers but not exactly. Frontend-backend is about where things happen. Functional vs. non-functional is about what vs. how well. But there's overlap — non-functional requirements often live in the backend, yet both layers can have them.

In the beginning of a project, non-functional requirements are often forgotten because

  1. They’re abstract and harder to measure
  2. Not visible in UI

But ignoring them leads to rework, failure at scale, and unhappy users. Functional requirements get you a working, minimum viable product. Non-functional requirements make it usable, scalable, and successful.

Monday, December 23, 2024

Why Software Project Estimation Is Difficult

In my experience, the following factors make software project effort/cost estimation difficult:

  1. It is much easier to estimate for the happy path which leaves gaps in specifications for logging, handling edge/error/timeout cases and exceptions.
  2. It is common to overlook non-functional requirements like performance, security, copy protection, scalability. They often become the reason a project fails at scale, even if it succeeds at first. 
  3. Requirement/design changes due to new information after first user (alpha/beta) tests.
  4. Not taking into account code clean up effort as the project complexity increases.
  5. Changes in libraries and frameworks at least once a year, necessitating unplanned rework.

Every if, switch, or loop condition can introduce new paths through the code. If a function has n independent Boolean conditions, the number of possible paths is up to 2^n. If a function takes multiple parameters, the combinations of edge values increase multiplicatively. 1 input has usually at least 3 edge cases, n inputs would have at least 3^n edge case combinations. If the function depends on or alters internal state, interacts with external systems, or uses asynchronous logic, you must test for edge timing, race conditions, resource exhaustion, etc. Edge cases scale faster than linearly with added logic, often closer to exponential or combinatorial growth depending on interaction depth.

Handling error cases and edge conditions often takes much more effort than the happy path due to the need for additional logic, testing, and debugging. If edge cases are not considered early, addressing them later can introduce costly redesign efforts. Unfortunately, the number and complexity of edge cases grow as the project progresses, especially if new scenarios are discovered during development or testing. Handling one error case might introduce or expose others, creating a chain of additional considerations that were not part of the original estimate.

Neglecting regular code cleanup leads to the accumulation of technical debt, which increases the time and effort required to implement similar features later in the project. New developers joining the team may struggle to understand and contribute to the codebase, further slowing development. Additionally, the effort required to fix bugs, integrate new systems, or perform upgrades can grow exponentially over time.

APIs, libraries and frameworks are typically updated every six months, and programming languages undergo significant changes every few years. While these updates bring improvements, they can impact project timelines.

All these factors can make your initial effort/time estimation 10 times less than the actual cost in the end. A rule of thumb you can use is to estimate effort/time for the happy path and multiply that by 10 to get a realistic number.