Cpp size_t 0 is smaller than minus one

Be careful with your loops

size_t zero=0;
long minus_one=-1;
EXCPECT_FALSE( zero < minus_one ); // should be false, but in fact is true

Why that matters?
I got this bug:

long limit = -1; // default value was designed to skip the loop
...
if( .. ) { limit = optionalCalculatedValue; }
...
for( size_t i=0; i<limit; i++) {
    // infinite loop on default limit value
}

Also, there was similar but less obvious situation is same project:

for( size_t i=0; i<parameter-1; i++) {
    // infinite loop if parameter is 0
}

You can fix it like this:

for( size_t i=0; i+1<parameter; i++) {
    // now it's ok
}

IT Management Paradox

  • Effective management practices lead to small teams.
  • Ineffective management practices lead to huge teams.
  • Most people are involved in ineffective practices.
  • Demand for ineffective management practices is higher, than denamd for effective practices.
  • Education system follow the demand of the majority.
  • Education system teach ineffective management practices, because the demand is higher.
  • Effective management practices extinct.

This explains all that billionairs with unfinished education: it’s better to know nothing, then to know wrong.

Example:

“Tick-the-code” and similar practices are widely replaced by “intuition-based-review-of-single-commit” practices. Intuition based review is perfectly useless. Whatever you call it “expert review” or “experience based review” or whatever. Single commit review is also perfectly useless. All commits can be ideal, but together they can, and will, create nonsence. Bare minimum for review is 1 class.

Old-school Agile rule of thumb

If it needs special tools - it’s bullshit.

IMHO, if the tool is just a replacement for pen and paper, but you still can do it with pen and peper - it’s ok. It’s not handy to use pen and paper in the age of remote work. But anything more complex will only make things worse.

Oversimplified prediction 2023

I need to make some .. assumptions about future of IT, it’s not accurate at all, based on personal intuition, but here it is:

  • ChatGPT will replace Alice
  • Kizune AI will reincarnate as Kizune GPT
  • ReactJS will dissapear, leaving JSX templates as the only trace of existance
  • Vue.js and Angular will also dissapear
  • Javascript will dominate desktop application market (just because having trial version in a browser is a huge marketing advantage)
  • Python will replace .NET for server applications
  • Competition between Python and Java Spring will intensify
  • “For Him Who Is Not to be Named” aka “Hydrated Iron Oxide” will dissapear, due to reasons https://www.youtube.com/watch?v=gutR_LNoZw0
  • Amount of desktop apps for Linux will grow
  • Monetization priority will grow, probably we will have nice online market for opensource apps

Why frameworks don't last long?

They are costly to maintain

That’s why we have brand new framework every year.

It’s kind of weird:

  • Framework without components is just a pattern.
  • The more components you have, the more successfull will be your framework.
  • To create competitive minimum of components you need to engage 3rd party devs.

However, for 3rd party component creators situation is different:
the more frameworks use your component - the more succesful your component is.

At the end of the day, we have framework-idependent component + set of wrappers.

So, frameworks tend to dissolve and turn back into patterns. Unless, they have some unique “game changing” features which are hard to replicate, complicated and bloated.

Here is a fork:

  • If fremework creators refactor framework architecture - that lead to simplification of core features, they become replicatabe, they are replicated, and framework turn into design pattern.
  • If they do not refactor their code - that lead to complicated legacy code which is impossible to maintain.

One way or another - all frameworks are doomed 🙄

NEVER trust Trusted Third Party (application signing)

You might had seen complains from Windows Defender, like “unknown publisher”.

And if is a developer, you do not want this message to be displayed, so you have to buy certificate from so called “trusted third party”, and voila.

But.. from end user point of view, does it even make any sence?

This “trusted” companies check NOTHING important for end user

All they do is googling company name. That’s all.

You can do it yourself, you can do it better.

  • Do they check the package for viruses? NO!
  • Will anyone be responsible if the app will damage your data? NO! Every license agreement have a “disclaimer” section.
  • Will “trusted” third party be responsibe? Of cause not.
  • Does it guarantee that the copy is legal and not pirated or modified? NO! In most companies literally everyone has access to this certificates. Why? Because, from the company point of view, the sole purpose of this certificate is to suppress windows defender warning. So, nobody cares. If certificate will leak - company won’t lose anything valuable.

In fact, self-signed applicationas are more secure. At least, no “trusted” third party has access to the certificate.

So if (if!) the company want to prevent supply-chain attacks, it can do it.
Will company benefit from preventing supply-chain attacks? 🤔

Also, checksums will actually work better. Attacker would have to hack both app and company website.

So, there is a good idea to check package for viruses.

For example, here you can check it before download: https://www.virustotal.com/gui/home/url

Especially, if the app is signed by certificate issued by “trusted” third party.

The only argument, “trusted” third pary companies have for trusting this “trusted” certificates is: if company can pay, that company is probably big enouth to trust.

REALLY?

Like we can’t remember any big company which add backdoors, spy on users, collect personal data, sell that data to everyone who ask, make unexpected modifications on your disk etc, etc.

What’s I’m talking about, things like that never happend. That’s just imaginary situation, which has nothing common with reality.

Agile: Why do we use Todo Work Ready Done, instead of Red Green Refactor Deploy?

Looks obvious, right? 🤔

Current setup

In TDD, we use the following sequence:

  • Red: try and fail
  • Green: fix and confirm
  • Refactor: polish solution

That’s 100% solid time-proven sequence. But in Agile/Scrum/Kanban we completely different approach:

  • Todo
  • Work
  • Ready
  • Done

Which is not as good as it looks at first sight. That’s why Trello and Jira had an option to set custom workflow and custom task states.

TDD workflow and Agile task workflow does not map to each other in any aspect! 🥲

So, why are we doing that? To be more “manager friendly”? Is it “positive thinking” which stops as from using the word “fail”?

Well, we can replace “try and fail” with “try and confirm that feature is not implemented / reproduce the bug”, happy?

Suggestion

Maybe we can use sequence like that, for task management:

  • Pick: from heap to sprint backlog
  • Try/Red: Try it and confirm the issue
  • Fix/Green: Fix and confirm solution
  • Polish/Refactor: polish solution
  • Commit: share changes with the team
  • Package: aggregate changes into release package
  • Test: QA team test the package
  • Deploy: publish package for general public
  • Collect feedback: from support team, investors, etc.
  • Fund: get money for next sprint

This looks much closer to reality, you know.. 😎

I suggest using Try/Fix/Polish insteard of Red/Green/Refactor to avoid confusion between task management and coding. But that sets maps to each other perfectly!
Also, that’s closer to the idea behind SMART criteria.

For in-house projects, it can be simplified to just:

  • Pick
  • Try
  • Fix
  • Polish
  • Deploy

Why not?

CLI table draw in Python

Well.. I migrated all my current project to python 😅

Recipie is the same: fill all cells with spaces to maximum column length, then concatenate array representing table row using separator. Flavor with special chars like “├”.

Implemetation changed from Php CLI how to draw table , but not really much:

  • Multibyte string length:
    mb_strlen( cellContent )
    
    become
    len(str( cellContent ))
    
  • Column names:
    $key.str_repeat(" ",$columnWidths[$key] - mb_strlen($key))
    
    become
    key.ljust( maxLenghts[key] )
    
  • Horizontal lines:
    str_repeat("─",$columnWidths[$key])
    
    become
    "".ljust( maxLenghts[key], "─")
    
  • Data cell:
    $cell .= str_repeat(" ", $columnWidths[$key] - mb_strlen($cell))
    
    become
    str(cell).ljust( maxLenghts[key] )
    
    (some cells contain numbers, thats why str(..))
  • Drawing table header:
    echo "╭─".implode("─┬─", $horizontalLines)."─╮\n";
    echo "│ ".implode(" │ ", $columnNames    )." │\n";
    echo "├─".implode("─┼─", $horizontalLines)."─┤\n";
    
    become
    print("╭─"+"─┬─".join(horizontalLines.values())+"─╮");
    print("│ "+" │ ".join(columnNames.values()    )+" │");
    print("├─"+"─┼─".join(horizontalLines.values())+"─┤");
    
    Pho associative key/value arrays are python dictionaries, and join will concatenate dictionary keys, not values in python. So we need .values() to turn it into array of values only.
  • Drawing data row:
    echo "│ ".implode(" │ ", $row)." │\n"; 
    
    bacome
    print("│ "+" │ ".join(row.values())+" │")
    
  • Drawing table footer
    echo "╰─".implode("─┴─", $horizontalLines)."─╯\n";
    
    become
    print("╰─"+"─┴─".join(horizontalLines.values())+"─╯")
    

That’s it 😊

Should I make nice function, like in previous post? 🤔 I doubt that it’s really nesessary, but if you want it - drop me a message with “buy me a coffee” widget in bottom-right corner 🤑

Php CLI how to draw table

The goal

Php shine whenever you work with a lot of text data. So php-cli applications are quite demandable. But for cli (command line interface) we do not have all this fancy html tags and css3 styles. Cli applications are intendent for advanced users, who often want output as stream, which can be directed to next tool in chain. So, in most cases writing results with simple echo works just fine.. unless you need to add a table to the output.

Solution

My first idea was to use ncurses, but.. there is much simpler solution.

All you need is str_repeat()

It’s also possible to use str_pad() in some cases. But, unfortunately, str_pad() does not support unicode.

The idea is to calculate max width for every column, and than fill all cells to this width with spaces. After that, just concatenate array with implode to display each table row.

Example of the following drawTable() function output:

php-cli table

Source code:

<?php

/**
 @param Array data - array of table rows
 @return String representing the table
 @example echo drawTable([
    [ "id"=>1, "name"=>"Test A", "description"=>"short text" ],
    [ "id"=>2, "name"=>"Test B", "description"=>"long text, describing something" ],
    [ "id"=>3, "name"=>"Test C", "description"=>"long text with multibyte string ä ë ï ö ü" ],
    [ "id"=>4, "name"=>"Test ö", "description"=>"myltybyte in name column" ],
    [ "id"=>5, "name"=>"Test E", "description"=>"weeeee!!! äëïöü äëïöü äëïöü äëïöü äëïöü äëïöü" ],
 ]);
 */
function drawTable(Array $data):String {
    // sanity check
    if(empty($data)) { return ""; } 
    // get column names
    $keys = array_keys( reset($data) );
    // calculate maximum width for each column
    $columnWidths = [];
    foreach($keys as $key) {
        $columnWidths[$key] = mb_strlen($key);
        foreach($data as $item) {
            $width = mb_strlen($item[$key]);
            if( $width > $columnWidths[$key] ) {
                $columnWidths[$key] = $width;
            }
        }
    }
    $columnNames = $horizontalLines = [];
    foreach( $keys as $key ) {
        // fill column titles with spaces
        $columnNames[$key] = $key.str_repeat(" ",$columnWidths[$key] - mb_strlen($key)); 
        // prepare horisontal lines
        $horizontalLines[$key] =  str_repeat("─",$columnWidths[$key]); 
    }
    // fill every cell to max column width
    $data = array_map(function($row) use ($columnWidths) {
        array_walk($row, function(&$cell, $key) use ($columnWidths){
            $cell .= str_repeat(" ", $columnWidths[$key] - mb_strlen($cell));
        });
        return $row;
    }, $data);
    ob_start();
    // draw table header
    echo "╭─".implode("─┬─", $horizontalLines)."─╮\n";
    echo "│ ".implode(" │ ", $columnNames    )." │\n";
    echo "├─".implode("─┼─", $horizontalLines)."─┤\n";
    // draw lines
    foreach( $data as $row ) {
        echo "│ ".implode(" │ ", $row)." │\n";        
    }
    // draw bottom line
    echo "╰─".implode("─┴─", $horizontalLines)."─╯\n";
    return ob_get_clean();
}

Note: This solution draw to string buffer, not stdout. For actual display use echo drawTable(...)

Of cause, you can just print it to stdout directly, without ob_start(), ob_get_clean() and use different symbols for table borders.

Here, take some:

    ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏
    ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟
    ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯
    ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿
    ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏
    ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟
    ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯
    ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿

Instant Jun

It’s possible to create artificial junior developer, but does it make any sence?

Artificial solution for artificial problem

Recruiring agencies and recruits stuck in the dillema:

  • Agencies tend to record as much recruis as possible, and ask them to compete for the job.
  • Recruits tend to apply to as much jobs as possible, and ask them to compete for the employee.

Yes, that problem can be easily avoided by “not doing that”, but here we are.

Recruiting agencies try to create at least some funnel for the flood of applications, preferably, automated. And now we have a lot of test systems which make no sence in terms of real IT tasks.

Because, in real life, coding is the tiniest part of software development. Biggest part is interaction with the customer: defining the task details, working with feedback, analysis of limitations etc.

But you are supposed to pass that useless tests anyway, just to reach someone compitent.

So, we have a task defined as a test case. Even more: we are absolutely sure that test is correct.

If the task can be defined as a test case - it can be solved automatically.

Developing tests and developing code is interchangable. We use both in Test Driven Development, because we might have an error in the test itself. We use code to check tests and tests to check the code. And push both parties forward in small steps.

But for recruiting tests thats not the case. We don’t care about bugs in recruiting tests. We can’t fix them anyway. However, that means we should be able to solve that tests automatically.

How?

So let’s check several approaches:

Bruteforce

We can just check all possible combinations of symbols, that will work, but it will take crazy amount of time. My solutions for tests like that are about 500 symbols in size, English alphabet + special symbols will be about 80 letters, so we have 80^500, combinations, thats approximately 3.5*10^931. Build and run tiny test program on my laptop will take about 0.5 second, so that’s not acceptable solution. If I will create a dictionary of words used in actual programs, that can be reduced to, like 10^200 seconds, but that’s too much anyway.

Algorithmic approach

We can reduce choises on each step of generations. For example, if we have { we have to have } later. Also, we can remove some operators like goto or else, as for we do not need them anyway. This way we will have a set of templates, which can be called recursively. That looks more promising, at least if we won’t need to take all possible libraries in consideration.

Neural net

Enter the elephant in the room: https://openai.com/blog/chatgpt/

We can use GAN + additional automated tests (buid + run + check if results match). In GAN we have descriminator, but it has to output “alikeness” of generated solution, which is float, actual tests will gave us boolean. So we need to learn AI by set of examples. Luckely, we have a lot of opensource code everywhere.

Should we?

We definitely can, but should we waste our time on that stupidity? Yes, we can create AI to pass every test that recruiting agency can imagine, and we will bypass all time limitations smoothly and all attempts to check that we are ‘real human beings’ including screen share and cameras etc etc. Because IT is our world, recruiters are aliens here.

But maybe we should teach them how to become native. How to rewiew the code. Learn them to look for methods, not instruments. Make the world better together. Nope, that wont work )

Knockoutjs Is Nice

I used that a while ago, but looks like it still alive 😊

Actually, I still think it’s the best js UI framework, at least for a browser.

Why:

  • MVVM is great, much better than “state” variable like in ReactJS or Vue.
  • It has nice publisher-subscriber implementation inside to serve data to controls, like “normal” ui applications for desktop.
  • Controls are louse coupled, almost independant from each other, yet can communicate
  • It’s tiny!

Latest realse is 2019-11-05, though.. 3 years ago, but just before covid lockdowns.

Link (mostly note for myself): https://knockoutjs.com/