How to write technical specifications for a simple program (calculator)

Let's consider what the work of creating technical specifications for a simple program might look like.

Let's take a calculator that will perform basic arithmetic operations (+, -, *, /).

The work can be built in 2 stages:

  1. Searching for positive facts about what exactly we want from a calculator;

  2. Searching for negative facts that can go wrong (in the broad sense of the word) when working with both the program and the technical specifications – and formulating requirements that prevent them.

Using our understanding of the subject area, we can formulate the following positive facts:

The calculator must perform arithmetic operations.

By and large, the positive facts end there, since almost everything else falls into the realm of “it’s obvious that… – yes? but it’s not entirely obvious to me.”

Difficulty level: I'm too young to die

What can go wrong:

What about tetration?

Let's play it safe and check that we correctly understand the number of arithmetic operations. But no, there are not 4 of them, and at least 10. We are unlikely to need a super root tomorrow, and neither will a logarithm with simple roots, if we are talking about a simple program. So let's explicitly indicate which 4 operations we are talking about:

The calculator must perform 4 basic arithmetic operations: addition, subtraction, multiplication, division.

(from the point of view of classic requirements engineering, there are 4 requirements in one, but at this stage this is not so important)

We haven't specified the user interface

As we understand now, the interface may well be at least voiceif not tactile in Braille.

Since we are writing technical specifications for a simple (both for development and for the user) program, we will choose the graphical interface.

The calculator should display the numbers being calculated in a graphical user interface.

How much will MCMXII + VII be?

Further, if you dig a little deeper, Roman numerals are good in their own way, but it will definitely be easier for us with the usual ones.

The calculator must operate in Arabic numerals in the user interface.

Number reading direction

Oddly enough, in the modern world there are people who read words not only from left to right, but also in other directions. Numbers are usually read from left to right, but since we are not ready to undertake ethnographic research on every issue, it is better to play it safe:

The calculator must operate in the user interface with numbers that are read from left to right.

Polish notation

Those who studied to be a programmer may know that there are different forms of notation for arithmetic and logical expressions, and the school and university mathematical infix form we are used to is not the only one.

The calculator must allow you to enter and process arithmetic expressions in infix notation.

So far, so good

What we've got so far:

The calculator must perform 4 basic arithmetic operations: addition, subtraction, multiplication, division.

The calculator should display the numbers being calculated in a graphical user interface.

The calculator must operate in Arabic numbers in a graphical user interface.

The calculator must operate in a graphical user interface with numbers that are read from left to right.

The calculator must allow you to enter and process arithmetic expressions in infix notation.

Classify it immediately

Anyone with even a little system knowledge – … analyst, … programmer or … administrator will probably have a desire to classify this list for ease of analysis and work with it. At a minimum, we clearly see a subset of requirements about the user interface:

Functional Requirements

The calculator must perform 4 basic arithmetic operations: addition, subtraction, multiplication, division.

Interface requirements

The calculator should display the numbers being calculated in a graphical user interface.

The calculator must operate in Arabic numbers in the user interface.

The calculator must operate in the user interface with numbers that are read from left to right.

The calculator must allow you to enter and process arithmetic expressions in infix notation.

Hmm, the last requirement contains functions too, which seems to make it both a functional requirement and an interface requirement. And this is called technical specification for a simple program? We got confused in 3 pines, that is, in 5 requirements – we wanted to simplify our future life by classification, but it only got worse – well, typical grief from the mind! 🙂

Okay, let's go back to the classic type of structure that we skipped over – hierarchical, in the spirit of functional decomposition. In it, under each function, you can stuff both a functional sub-requirement and any other. For convenience and generalization, any other can be called a “constraint”, because all they do is limit the behavior of the function and nothing more!

At the same time, you can change the order of recording requirements to a more chronological one, similar to a session of working with the program, if not testing it:

The calculator should allow enter arithmetic expressions.

> The calculator should allow enter arithmetic expressions in infix records.

The calculator should demonstrate numbers with which calculations take place, in graphic user interface.

> The calculator must operate in the user interface Arabic numbers.

> The calculator must operate in the user interface with numbers that can be read from left to right.

The calculator should fulfill 4 basic arithmetic operations: addition, subtraction, multiplication, division.

> The calculator must perform arithmetic expressions in infix records.

About the infix record it turned out 2 times, which again is not comme il faut from the point of view of DRY, making changes to the program, modularity, etc. But here, as usual with architecture (in our case, with the structure of requirements), compromises have to be made, because There are no forms that are equally suitable for everything. Well, oddly enough, you can actually enter expressions in one form, store them in another, and execute them in a third – it would be stupid, but technically possible.

Now this is a script!

Since we have practically a script, and not just a hierarchy, we can already check it for closedness and completeness – will such a set of operations, expressed by functions, allow us to obtain the result we need?

It seems like yes, but a person with a tester’s eye will easily tell you that allowing you to enter, demonstrate the input and calculate the results of operations does not mean showing the results of the calculations!

So let's add one last explicit function:

The calculator should show results of calculation of arithmetic operations.

Let us separately note how our vocabulary floats around here. Either we write the bookish “demonstrate”, then we switch to the more informal “show”. That is “perform arithmetic expressions” (hmm, is this even possible? they execute commands and requests, but expressions can probably only be processed), then “calculations”. During the development of technical specifications, this is completely acceptable, because we want to express the meaning briefly, clearly and unambiguously, and for this we look for and try different words. But when finalizing the requirements, it will be useful to streamline the vocabulary and make it more homogeneous.

In fact, we ended up with a typical minimal proto-use case consisting of 4 steps:

  1. The program provides the ability to enter initial data and issue commands

  2. The user enters the initial data and gives the command

  3. The program executes the requested command on the data

  4. The program tells the user the result of the command

What about the input interface?

Well, it seems we forgot something. The GUI user interface shows the numbers and operations, it's ok. But you also need an interface to enter numbers and commands. And also not voice, but there are at least 2 options:

  1. Keyboard input

  2. Mouse input…

You can request both interfaces at once, at least this is the option we see in a typical desktop calculator. Wait, why did we decide that we have a desktop and not a mobile? Is it really necessary to take into account the application context for the simplest program? It turns out, yes. Or not?

The calculator should allow enter arithmetic expressions via a graphical interface.

Is it possible to have 7 hats?

And so, from the question about the input interface, we return to a more general question – for what category of devices do you need a calculator? And by the way, what about tablets? (We didn’t even notice the elephant)

It seems that you can cheat here and demand that the program be cross-platform and adaptive. Phew, a load off my shoulders…

But wait, wait, on what categories of devices will the developer demonstrate and hand over the program? Android devices, for example, have many versions of the devices, and even on different generations of the OS.

If we demand abstract cross-platform and adaptability, then we cannot say that we are making a simple program, because In general, it is impossible to achieve such qualities without restrictions on versions of devices and operating systems.

Therefore, it is necessary to specify specific subclasses of devices and operating systems. If we want simplicity for the developer and user, it makes sense to choose the most popular device configurations on the market.

Considering that a desktop computer almost always has at least 2 input interfaces (keyboard and mouse), and on a smartphone the touchscreen still dominates, we decided to make a program specifically for the smartphone.

In total, you can take the most popular device based on sales results over the last year in our region, for example, Redmi 9A (32 GB).

What would the requirement-constraint look like for this case:

The calculator should work on Redmi 9A (32 GB) devices.

Chief, everything's broken.

Things break, software can also break or not work. You can’t expect 100% reliability; it’s important to choose some reasonable compromise. In general, it is useful to make reliability consistent with user expectations. In the case of a complex and expensive program, it is worth studying the performance of competitors and making calculations of the cost of failure for users and the business.

In our case, a simple estimate will suffice – in how many cases out of 100 can the program fail? We don't have any additional information about the context of use, so we can expect 1-2 failures per 100 commands.

The calculator must perform calculations on expressions with a reliability of at least 98%.

Let's talk about dimensions…

In the physical world, the dimensions and form factor of a product or device greatly influence its consumer qualities.

In the digital world, the analogue of dimensions can, with some stretch, be considered the size of a program in memory and on disk.

Imagine that our program weighs 1 GB when downloaded. Is this acceptable? Hardly.

Here you can rely on benchmarking, i.e. measuring the characteristics of typical programs of this class on the market. Or take into account in which country, with which Internet and on which phones it will be used.

However, for example, Google Play has its own recommendations and restrictions that can be directly used:

The calculator must be supplied as a distribution kit no larger than 200 MB in size.

…and efficiency

The next question is: is it normal for the program to take up 2 GB of RAM in the phone during use? It also looks too much for our program.

If you look for information about best practices, you can come up with recommendations so that the program takes up no more than 50 MB in memory. Let's stop there:

The calculator should use no more than 50 MB of phone RAM.

Don't slow down!

Let's consider another not entirely obvious, but quite possible case of a negative event – imagine that we enter 2 + 2 into the calculator and the calculator thinks for 14 hours. Well, or at least 7 minutes. Okay, let it be 15 seconds. What can you say about such a calculator? We need to limit this madness!

And in matters of computational speed, not only the ubiquitous benchmarking can come to our aid, but also Jakob Nielsen’s cognitive heuristics – for example, about the fact that a reaction of less than 0.1 seconds is perceived by most people as instantaneous. Well, let's write it down like this:

The calculator should calculate an arithmetic expression in no more than 0.1 second.

How much does it weigh in grams?

If we return to the issue of calculations, we can remember that they are carried out with a certain accuracy, not always absolute.

Again, we are looking for the best practices for household calculators and reaching the level:

The calculator must perform calculations with an accuracy of at least 8 decimal places.

Infinity sign

On the other hand, you can try to operate in calculations with very large or very small numbers. Making a universal device is not very easy and most likely not necessary. It is necessary to choose a reasonable range of calculation limits.

Search says that the typical range of most household calculators is from 10^-99 to 10^99, but to enter numbers with exponents you need the ability to specify the exponent with a separate command, which you want to avoid for a simple calculator.

In addition, here we return to the question about the interface – how many numbers do we want to see on the screen at the same time? A typical pocket calculator has 8-10 digits on the screen. Then you can limit yourself to a range of 10 digits – i.e. 10 billion as the maximum number. But this is not even enough to show Russia’s annual budget (18 trillion in 2024).

However, a software calculator differs from a physical calculator in that it can control the size of the displayed numbers and generally do line breaks. After some experiments, we can establish that numbers presented in the form of 5 lines of x 3 digits x 7 triples of zeros, those ~= 100 digits, can be quite readable.

Thus, we can return to the range of a typical calculator a couple of paragraphs above:

The calculator should perform calculations with numbers from 10^-99 to 10^99.

Our fingers are tired

So, what else do we have left, what are the risks, what could go wrong?

Let's imagine that we enter an expression in the form of a long chain with a large number of different operations. How many operations does it make sense to support?

For a computer program, we can say that it doesn’t matter – as long as the person is not tired of entering numbers and signs, the program can process everything. But does this mean that the length of the expression can be infinite? From a practical point of view, this makes little sense, so here too it’s worth agreeing on the point when your program will finally say ERROR….

Oh, by the way, what about errors that are not a crash? For example, division by 0? We need to somehow respond to this:

The calculator should report impossibility perform an operation if it is mathematically impossible.

This is how adding just the “divide” operation complicates the behavior of the program.

Well, at the same time, let’s describe what to do with failures:

The calculator should report failure during the operation.

And so until the very end it’s all turtles

I'm guessing that having read this far, you've been at least horrified by the number of things and aspects that need to be thought about when creating a seemingly simple software calculator. And we haven’t touched on the questions yet:

– graphic design,

– what buttons will the calculator have, except for digital and operations,

— speed of reaction of the calculator to pressing buttons 🙂

The good news is that in large programs there are more of these aspects (for example + information security), but not by much. Plus, some aspects, which I call macro-constraints, need to be thought about and understood once for the entire program (okay – for a subsystem, service, microservice), and not for each of its functions again.

In addition, as you gain experience, you can make your own “calculators” of various program characteristics listed above, because the mathematics of such calculations is as elementary as that of our calculator here.

Let's look at the final assembly of requirements

Let's put it together and see what we ended up with:

Functions and their micro-limitations

The calculator should allow enter arithmetic expressions.

The calculator should allow enter arithmetic expressions via a graphical interface.

The calculator should allow enter arithmetic expressions in infix records.

The calculator should demonstrate numbers with which calculations take place, in graphic user interface.

The calculator must operate in the user interface Arabic numbers.

The calculator must operate in the user interface with numbers that can be read from left to right.

The calculator should fulfill 4 basic arithmetic operations: addition, subtraction, multiplication, division.

The calculator must perform arithmetic expressions in infix records.

The calculator should show results of calculation of arithmetic operations.

The calculator should report impossibility perform an operation if it is mathematically impossible.

The calculator should report failure during the operation.

Macro restrictions

Compatibility

The calculator should work on devices Redmi 9A (32 GB).

Reliability

The calculator must perform calculations on expressions with reliability no less than 98%.

Efficiency

The calculator must be supplied as distribution no more than 200 MB in size.

The calculator should use no more than 50 MB operational phone memory.

Performance

The calculator should carry out calculation expressions in no more than 0.1 second.

Accuracy

The calculator must calculate with accuracy no worse than 8 decimal places.

Frontiers of Computing

The calculator should perform calculations with numbers from 10^-99 to 10^99.


What other holes do you see in this requirements specification? 🙂

Thanks for the pictures neuroartist Alina Bogacheva.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *