3 September 2021

Baby Steps Push Challenge

Earlier this year I met with fellow developers Roland Germ and Bastien David to discuss how we could make coding exercises more engaging and how participants would have more fun. The training formats we use, like Coding Dojo and Coderetreat, were designed for people to have fun (and engage in deliberate practice in order to improve their skills). Ideas like gamification came to mind and we worked on several constraint games to spice up our coding sessions. (A constraint is an artificial challenge during an exercise to make the exercise more interesting, challenging or fun. I like constraints, e.g. my recent Dice Namer Constraint. In this article I will describe another fun constraint: the Baby Steps Push Challenge.)

At the same time I was working with a client who was adopting Continuous Delivery. One of the issues the developers faced was that they were used to work in larger increments. We had worked through several exercises which encouraged smaller steps, e.g. Taking Baby Steps (revert the code if tests are failing after 2 minutes), Test Commit Revert (revert the code if tests are failing at any time) and even Limbo (revert the code if integration with other code fails). I was looking for more exercises to encourage small steps.

Let Slip the Tugs Of WarIdea of Push Championship
Following my discussion with Roland and Bastien I merged some of their ideas into a "Push Championship" - a challenge who would be able to deliver smaller increments.
  • For this exercise I would need some basic TDD or Refactoring exercise.
  • Pairs would work on the same task on their own using version control with branches.
  • While dealing with merge conflicts is part of trunk based development, there should be no artificial branching problems. Participants just try to make more commits.
  • All commits must be green which is tested by CI - actually it is much easier to count the number of successful build actions on each branch.
  • The facilitator ("referee") needs to grade commits afterwards to avoid cheating the game and awards bonus points for good commit messages.
  • Elements of gamification like coins for each commit/push would be nice.
Infrastructure
I created some infrastructure to support the exercise. First there is a central server to count pushes and display the dashboard of positive and negative events during such a "championship": Push Counter Server. It has "Push" in its name but it is more general and can be used to count any form of positive (counting up) or negative (counting down) event. The server application is published on Docker Hub. You can run it with docker run -p4567:4567 codecop/push-counter and the dashboard will be available at http://localhost:4567. You can deploy it to Heroku, which I did. (scripts/heroku_deploy does the job - you need to change the Heroku application name.)

Counting Pushes
The server dashboard displays the current game statistics of all teams - that is the number of positive events - and plays a coin sound (if you allow your browser to do so) when someone scores a point. To notify the server I execute curl at the end of a GitHub build action, e.g. curl -X GET ${{secrets.PUSH_COUNTER_URL}}/​record/team-name?​build=green. Whenever someone pushes to the repository, GitHub runs its build action and the dashboard gets updated.

Distinguishing Pairs
The easiest way to distinguish participant pairs is to use branches. In a scenario where each pair works the same exercise, this works well. I figure out the branch name with some shell and Git commands:
export GIT_BRANCH_NAME=$(git symbolic-ref --short HEAD)
export GIT_BRANCH_NAME=$( echo "$GIT_BRANCH_NAME" | sed 's/ /%20/g' )
curl -X GET ${{ secrets.PUSH_COUNTER_URL }}/record/branch-$GIT_BRANCH_NAME?build=green
The Push Counter Sample Client contains samples with several ways to identify pushes:
  • Using the branch name as shown above. This is dynamic and can be used for pairs working on branches.
  • Hardcoding the branch name in the GitHub action also needs dedicated branches.
  • Reading a team name from a file, i.e. using a lookup file on each branch is also possible.
  • When working trunk based, the GitHub user who pushed can be used (i.e. $GITHUB_ACTOR). This works if pairs do not switch machines.
  • Using a team name lookup by the GitHub user works also when pairs switch machines. Setup of the user name to team name mapping is necessary before the challenge.
  • Using the GitHub user of the last commit is also possible.
  • See the GitHub workflow file.
Test Run
When I tested the setup, I used - you guessed it - my favourite Prime Factors kata. The final score on the dashboard was:
Prime Factors score Choice of Kata
Because of the competition, all participants should be able to finish coding, i.e. it should be possible to finish the exercise in one hour (as part of a workshop or learning hour). Refactoring exercises are a good choice because the given test suite makes sure only working changes/ pushes contribute to the total score. Unfortunately most refactoring exercises are larger than one hour. Then the goal of the refactoring needs to be more specific.

Emily Bache's Parrot Refactoring Kata is a suitable exercise: It is small. (I am able to finish it on my own in less than 20 minutes. In fact - with some practice - I can run through its steps in less than 10 minutes.) And it has many steps, especially if you aim for baby steps. I counted 48 individual changes you can make - and I even missed a few. The concrete task here is to fix the code smell of switch on type code and clean up the code using as many individual, working refactoring steps as possible. Each commit should be delivered (pushed). And then you can repeat the exercise and try to break the score.

Other suitable refactoring exercises might be Top Gear and Promotion Service from my own list of code katas.

Coding Dojo Run
Later I ran the exercise in our local Coding Dojo community. I showed some slides to motivate small increments and gave some hints how to make smaller steps. I prepared a branch of Parrot which reported to my Heroku dashboard. All went as planned and here is some of the feedback I got from participants in the retrospective:
  • The kata (parrot) was the right size, we had plenty of time to work carefully.
  • We had to perform the same change three times - for the three sub-types - and used different approaches for each of them and compared them in the end. That was a bonus.
  • We thought about "How small is small enough?"
  • It is always possible to go smaller - you can commit more often.
  • The constraint encouraged us to take much smaller steps than usually.
  • Very small steps require lots of communication.
  • Very small steps can become confusing due to the pause in between steps.
  • I liked the dashboard and its icons.
  • It would be nice to sit in the same room with the dashboard on a big screen.
  • This notion of scoring works well in teams which have a good relationship.
Your Turn
Now it is your turn to work the exercise. You do not need the server infrastructure if you are on your own. Just clone the parrot and see how many small steps you can make. Then try again and improve your score. Some participants were able to make 52 meaningful, tiny changes to the Parrot using Java. Try to break this high score. Everything above 40 is good and above 50 is very good. If you want to use the exercise for a Coding Dojo, fork the prepared branch of Parrot and set the repository secret PUSH_COUNTER_URL to your dashboard. Have fun!
Final score after review

14 June 2021

The One Thing

Last year, during second lockdown, I watched a message of my guro Jakob where he proposed reading some books in the time when you are not able to practice in the dojo. He specifically recommended two books, The One Thing: The Surprisingly Simple Truth Behind Extraordinary Results and Atomic Habits: An Easy and Proven Way to Build Good Habits and Break Bad Ones. I had seen both books in my Goodreads feed and had not paid attention. But when your master asks, you better follow ;-)

FocusThe Book
The book is about extraordinary results determined by how narrow you can make your focus. Gary Keller insists that it is possible to reach any goal if you focus on it. And by focus he means that you really focus i.e. dedicate four hours of each day to your one goal. It has to be one single goal. And then, by the thousands of hours you have put into your goal, you will see results. Yes obviously, when following this approach, you will see results. In this sense, the One Thing is extraordinary and boring at the same time. I highly recommend reading it.

First I planned to summarise the book for you, and others have done a better job doing that. The book's homepage is a start and you can find many summaries of the book online, like this one on Four Minute Books. While summaries are short and save time, you will not get the benefit of the book without reading it. A book is not only about its content. Here the book is cementing its message by many times the author tells you the same thing in different words, a.k.a. repetition. The total time it takes to read the book is also time you have to reflect on the material.

Impact
Maybe my summary above is a bit lame, so let's discuss the book's impact on my life. And it had a profound impact as you will see. The first and utmost thing I remember from reading the book is the permission to drop stuff from my agenda. Like all developers I know, my daily plan was way too full: work, write a blog post like this one, release an episode of the Coderetreat Facilitation podcast, run a public Coding Dojo for the community, follow up on this cool idea I read about, finish reading SICP and get back playing with Scheme, create more exercises for workshops, keep up to date with Twitter and other feeds, work out, spend time with family, fix this next thing in the flat my wife is complaining about, fight climate change and much more. How was I supposed to allocate 4 (FOUR!) hours each day for the thing I want to do? It was impossible. Obviously Gary was crazy. ;-) Or I had to drop some tasks from my agenda. The idea of focus and dropping tasks was not new to me. I remembered J.B. Rainsberger mentioning a "Not Doing" column in his task list in 2014. I myself have put whole technologies on my blacklist - which I would ignore from this time on, but I have never dropped tasks and ideas so aggressively. I had several TODO lists of low priority where tasks went to die without being honest to myself.

The First Month
I spent the first month following the One Thing on a meta level because I did not work on anything but worked on the process itself. First I increased my focus: I deleted most icons - usually things to do or bookmarks to look at - from my desktop. I removed TODO markers in documents and on my hard drive. Then I reduced my commitments, e.g. I dropped the schedule to blog and record, stopped visiting meetups, reduced the number of learning hours and decided on the maximum number of hours I would work for each client per week. And I was OK with that. Letting go became a mental state and I had been following the Minimalists and Marie Kondo already before I started.

Suddenly I had more time - I even had some unscheduled time to play video games which I almost never did. In hindsight this was not extraordinary at all. If you drop most things you are working on, you will have more time available. It is a matter of focus. Lockdown and home office helped as I saved more than two hours every day. While some colleagues complained that they worked two hours more, I used these two hours - giving me half of my required four hours already. And I used the first month - 80 hours total - to practice the One Thing process. I started each day with a few minutes of mediation to improve my focus. I read more books about focus, e.g. Leo Babauta's book on focus and simplicity, forming habits, e.g. Atomic Habits as mentioned above and learning. I studied these books, taking notes and collecting them. I recommend all of them. I clean up my "office" and spent some time decluttering it, storing stuff in drawers or trashing it to further improve my focus during work.

Books
One example of my achievements since I started using the One Thing methods are the books I have been able to read this year. The Pragmatic Programmers once wrote that you should read at least four technical books a year and the last year I was able to follow their rule was 2016. Since then I have been struggling to read at least one technical book a year. Reading became hard, I had problems focusing and I usually fell asleep after reading a few pages. I decided to add some reading time every day to my four hours of focused work, reading on the topic of focus of course. So including the One Thing, I have read ten books in five months.

ArcherClarity
Spending four hours on focused work each day reduced the time I had available for other things. After some struggle, I had more clarity - and stopped my self-deception. For example, if I see an interesting article linked on Twitter I either read it immediately, or I forget about it. There is no point in adding it to my read-later list, because there is no read later list because there is no extra time for that. I would not read it anyway, my read-later list kept growing and growing. While I was dreaming of doing so much in the past, I have become a naysayer now. For example "this is a good idea. I might try it. (One second later.) No, not really this is not my One thing and I have no time. End of idea." This is refreshing and freeing. Clarity is one of my needs.

Crunch Time
One drawback is that I am always in crunch time. As my time is more limited, I have to prioritize harder and postpone many tasks I know I need to do. This makes me feel uneasy at times. And for the things I still want to do - not as my One thing, but from time to time, e.g. maintaining my blog - I have to live with tiny increments. For example, I was working on this blog post 15 minutes at a time for more than a month. It was a bit frustrating. Still writing and "Public Relations" are not my priority.

Sorrow
Not having time to attend meetups caused some FOMO (fear of missing out) and made me miss the people of the community I had not seen in a while. In general being unable to do things which I liked mad me sad. I have been attending every one of our local, bi-monthly Coderetreats since its inception January 2019. When I was unable to attend for the first time in more than two years, I felt very, very sad. I felt a loss, almost like mourning. Maybe this was the first time in my life when I really let something go. It is easy to let go things you are not attached to.

Crunch Time Summary
Time for a very short summary (as my latest 15 minutes increment is almost spent): Read the book. Find your One Thing. Focus on it. It is possible to allocate four hours each day to focus on your highest priority, though it might be hard to stick to it. I am half a year into the process and did not miss a single day. Keep pushing!

29 April 2021

My Code Katas

Ascending the StairsI run various trainings for software developers, at least one every week. I have used many different exercises - called code katas - most of them curtesy of my fellow coaches, especially Emily Bache who maintains a huge collection of excellent exercises on her GitHub. And I created some exercises myself. I have collected all of them on a page, each with a short description how to use it. Enjoy!

Check out My Code Katas (permanent link).

20 March 2021

11 Years of Prime Factors Kata

In this post I want to celebrate the Prime Factors Code Kata. Prime Factors is a small coding exercise first used by Robert C. Martin in 2005. It is my favourite code kata and it has been almost nine years since I last wrote about it - time to change that. Weird enough, the first code kata I ever worked on - outside of university assignments that turned out to be katas later - was Roman Numerals in 2007. The first time I did the Prime Factors was during Christmas holidays 2009 in Java and Ruby:
import java.util.ArrayList;
import java.util.List;

public class PrimeFactors {
  public static List<Integer> generate(int n) {
    List<Integer> primes = new ArrayList<Integer>();

    for (int candidate = 2; candidate <= n; candidate++) {
      for (; n % candidate == 0; n /= candidate) {
        primes.add(candidate);
      }
    }

    return primes;
  }
}
Now the Java code is exactly the code Robert Martin showed, I was following his example. The Ruby version from back then looks pretty similar, just using while instead of for.
module PrimeFactors
  def generate(n)
    prime_factors = []

    candidate = 2
    while n > 1 do
      while n % candidate == 0 do
        prime_factors << candidate
        n /= candidate
      end
      candidate += 1
      candidate = n if candidate > Math.sqrt(n) # performance fix
    end

    prime_factors
  end
end
If you are wondering how I am still able to find the code, I organise my code katas to allow lookup and comparison. Since then I did the kata 141 times and it has many uses.

Learn a language
Prime Factors is one of the first pieces of code I write - Test Driven of course - when revisiting old languages, like Commodore BASIC or looking at a new language, like Forth, using Gforth 0.7:
: prime_factors ( n -- n1 n2 n3 n4 )
  DUP 1 > IF           \ test for ?DO
    DUP 2 ?DO
      BEGIN
        DUP I MOD 0 =  \ test candidate I
      WHILE
        I SWAP I /     \ add candidate, reduce number
      REPEAT
    LOOP
  THEN
  DUP 1 = IF DROP THEN ;

T{ 1 prime_factors -> }T
T{ 2 prime_factors -> 2 }T
T{ 3 prime_factors -> 3 }T
T{ 4 prime_factors -> 2 2 }T
T{ 6 prime_factors -> 2 3 }T
T{ 8 prime_factors -> 2 2 2 }T
T{ 9 prime_factors -> 3 3 }T
Gforth came with a modified testing framework based on John Hayes S1I's tester.fs, defining the functions T{, -> and }T for testing. Note that the given function prime_factors is not realistic as the number of returned arguments is not known by the caller.

When I had a look at Scala, of course I did Prime Factors:
import java.lang.Math.sqrt

object PrimeFactors {
  def generate(number: Int): List[Int] = {

    def fold(current: Pair[Int, List[Int]], candidate: Int): Pair[Int, List[Int]] = {
      if (current._1 % candidate == 0)
        fold((current._1 / candidate, candidate :: current._2), candidate)
      else
        current
    }

    val (remainder, factors) =
      (2 to sqrt(number).intValue).foldLeft((number, List[Int]()))(fold)

    if (remainder > 1)
      (remainder :: factors).reverse
    else
      factors.reverse
  }
}
This is crazy. The code creates a sequence of all candidate primes and folds it starting from left by dividing by the candidate recursively, appending to the begin of the list, which is cheap. Because of that the list is reversed at the end. I have no idea why I created this, probably I was playing around with foldLeft. This is not a good example, please do not copy it. After all these years, the Forth solution seems easier to grasp. ;-)

So which languages are missing? PowerShell looks much like my PHP (shown below) and my Python Prime Factors looks similar too, just with Python specific range(2, number + 1) and //= inside. And of course JavaScript is missing:
PrimeFactors = function() {
  this.factors = [];
};

PrimeFactors.prototype.generate = function(num) {
  var candidate;
  for (candidate = 2; candidate <= num; candidate += 1) {
    num = this.tryCandidate(num, candidate);
  }
  return this.factors;
};

PrimeFactors.prototype.tryCandidate = function(num, candidate) {
  while (num % candidate === 0) {
    num = this.reduceByFactor(num, candidate);
  }
  return num;
};

PrimeFactors.prototype.reduceByFactor = function(num, factor) {
  this.factors.push(factor);
  return num / factor;
};
Isn't that lovely? Again this is not good code, please do not copy it. At least I showed some creativity using prototype functions.

Learn a testing framework
Using TDD to write some known code is a perfect way to learn more about a testing framework. So I explored XSLTunit using Prime Factors in XSLT or NUnit in C#:
using NUnit.Framework;

[TestFixture]
public class PrimeFactorsTest
{
  [TestCase(new int[0], 1)]
  [TestCase(new int[] { 2 }, 2)]
  [TestCase(new int[] { 3 }, 3)]
  [TestCase(new int[] { 2, 2 }, 4)]
  [TestCase(new int[] { 2, 2, 2 }, 8)]
  [TestCase(new int[] { 3, 3 }, 9)]
  public void TestFactors(int[] expected, int number)
  {
    CollectionAssert.AreEqual(expected, PrimeFactors.Generate(number));
  }

  [Test]
  [Timeout(100)]
  public void TestLarge()
  {
    CollectionAssert.AreEqual(new int[] { int.MaxValue },
                              PrimeFactors.Generate(int.MaxValue));
  }
}
Test your own testing framework
Sometimes, when I need to create my own unit testing framework, e.g. TPUnit for old Turbo Pascal, assert-scm (Scheme R5RS) or ASM Unit for Windows Assembly, I use Prime Factors as test cases:
_prime_factors:
  mov     esi, 0          ; esi = number of factors
  mov     edi, ebx        ; edi = address of factors
  mov     ecx, eax        ; ecx = current number
  mov     ebx, 1          ; ebx = candidate

  jmp .not_diviseable

.loop_over_candidates:
  inc     ebx             ; next candidate

.break_if_candidate_is_larger_than_square:
; if candidate * candidate <= number then try candidate
  mov     eax, ebx
  mul     ebx
  cmp     eax, ecx
  jbe     .try_candidate

; else number is a (large) prime and we are done
  mov     [edi + esi * register_size], ecx
  add     esi, 1
  jmp     .done

.try_candidate:
; if number % candidate == 0 then add candidate
  mov     eax, ecx
  xor     edx, edx
  div     ebx
  cmp     edx, 0          ; remainder is 0
  jne     .not_diviseable

.is_diviseable:
  mov     [edi + esi * register_size], ebx
                          ; store candidate in factors
  add     esi, 1          ; we found a factor
  mov     ecx, eax        ; number is remainder of division
  jmp     .try_candidate  ; try current candidate again

.not_diviseable:
; if number > 1 then try next candidate
  cmp     ecx, 1
  jne     .loop_over_candidates

.done:
; return number of factors
  mov     eax, esi
  ret
This piece of assembly calcultes the prime factors of the number passed in EAX into in the dword array address EBX.

TDD Demo
In 2012 I started practising Prime Factors as kata performance, minimising the number of keys I pressed. I ran it around 50 times. In the end I used the practice to calm down when I was anxious - it was like mediation. I still have to perform it somewhere, adding music and all... I have used it demoing TDD in uncounted presentations - actually around 40: during my university guest lectures, user group meetings and at my clients. Most demos were in Java and some in PHP,
<?php
class PrimeFactors {
  static function generate($n) {
    $factors = [];
    for ($candidate = 2; $candidate <= $n; $candidate += 1) {
      while ($n % $candidate == 0) {
        $factors[]= $candidate;
        $n /= $candidate;
      }
    }
    return $factors;
  }
}
and a single demo of test driving R code,
primeFactors <- function(number) {
  factors <- vector(mode="integer")

  candidate <- 2
  while (candidate <= sqrt(number)) {
    while (number %% candidate == 0) {
      factors <- c(factors, candidate)
      number <- number / candidate
    }
    candidate = candidate + 1
  }

  if (number > 1) {
    factors <- c(factors, number)
  }

  factors
}
It seems, most programming languages look the same. The last sentence is not true for NATURAL, Cobol's cousin, which is ugly. I will not show it here as it would destroy this lovely post.

Conclusion
By writing this post, I learned that I still need to create Prime Factors in the programming languages Go, Kotlin, OpenOffice Basic, Oracle PL/SQL and of course TypeScript - I could - and I will, it is just a matter of time. So Prime Factors - in fact any small enough code kata - is a great tool for exploring, studying and practising programming languages, testing frameworks, IDE tools and Test Driven Development in general. I will leave you with my latest addition to my collection of Prime Factors, using C99. Have fun!
#include <math.h>

typedef struct {
  unsigned char count;
  unsigned int values[31];
} PrimeFactors;

void PrimeFactors_init(PrimeFactors* factors)
{
  (*factors).count = 0;
}

void PrimeFactors_add(PrimeFactors* factors, const unsigned int factor)
{
  int count = (*factors).count;
  (*factors).values[count] = factor;
  (*factors).count = count + 1;
}

void generate(const unsigned int number, PrimeFactors* factors)
{
  PrimeFactors_init(factors);

  unsigned int remaining = number;
  for (unsigned int candidate = 2; candidate <= sqrtl(remaining); candidate += 1) {
    while (remaining % candidate == 0) {
      PrimeFactors_add(factors, candidate);
      remaining /= candidate;
    }
  }

  if (remaining > 1) {
    PrimeFactors_add(factors, remaining);
  }
}

17 February 2021

Dice Namer Constraint

A constraint is an artificial challenge during an exercise to make the exercise more interesting, challenging or fun. I like constraints and wrote about some of them. The Dice Namer is such a constraint: Everything but the names of test methods is named using random dices. The French company Arolla created some really nice dices using random, enterprise-y useless names like Processor, Dummy or Factory. I managed to get several sets and to use them in my coding exercises after discussing naming in code. Now with the remote work due to Covid, I had to come up with something new. And here it is, the

Arolla Dice Namer Application

Press the buttons and see the random dices for your name, together with some dices-like sound (if you allow your browser to play it). This is a real fun and it will help you create amazing code like this one using viciously named functions...
What does this code do?

1 February 2021

Working with AI Surveillance

Since several years I am exploring ethics and meaning of my work as software engineer. While it is not a clear cut topic, it lies in the core of our work, similar to all the tech and engineering stuff. Last year Artur Meyster, CTO of Career Karma, contacted me about cooperating on a guest blog post here on my site. (Thank you Artur for your patience.) While guest blogging seems mainly SEO related, I do not mind a fresh perspective on a topic I have been thinking about, much like the series of interviews I am conducting from time to time. This post was mostly written by Maria Elena Gonzalez. Maria is a broadcast journalist and has been working as a tech writer for three years. During this time, her work has been published by companies like TechAccute, Trip University, and Entrepreneur - and now by the Code Cop ;-)

Heavy SurveillanceAI Surveillance
The recent evolution of technology has resulted in many new areas, such as data science, virtual reality or machine learning. As a developer, these are the new and cool topics to explore and dive into. (Maybe start with a data science boot camp.) Applications in these areas have improved our quality of life. They serve the same purpose as AI surveillance: to improve our quality of life. However, as is the case with any invention, AI surveillance has a dark side: we might be losing our right to privacy.

You may think this is a problem only for famous people, but that is not the case. It can also be a problem for you. According to a recent report from the Carnegie Endowment for International Peace, 75 out of 176 countries are using Artificial Intelligence (AI) for surveillance purposes, which makes it hard to know who is safe from AI surveillance. If you would like to know more about the impact of AI surveillance on our daily life, read on.

What is AI Surveillance?
AI surveillance goes beyond AI-driven security cameras. Companies and governmental organizations have been using this technology to track trends and transitions to make better business decisions.

How is it Affecting Us?
AI surveillance has many benefits. For example, it can improve traffic. Have you ever waited for traffic lights to turn green even though there are no cars around? This could be improved by using AI surveillance. AI algorithms can detect movement and change traffic lights phasing based on real-time activity. Financial companies can use AI surveillance to spot malicious activities and minimize fraud. This has the potential to revolutionize the financial industry. The possibilities are endless, and we could continue to show you the positive aspects of AI surveillance, but let's take a look at the darker side.

With the amount of data collected increasing rapidly, the possibility of privacy invasion is rocketing. While some AI surveillance activity falls within the law, others represent privacy violations. Privacy International points out that AI surveillance can be very delicate when it comes to data privacy: "With the proliferation of surveillance cameras, facial recognition, open-source and social media intelligence, biometrics, and data emerging from smart cities, the police now have unprecedented access to massive amounts of data." Governments that take advantage of this technology have access to citizens' personal data, a situation that can quickly turn into a violation of privacy rights if left unchecked.

Which Countries are Adopting AI Surveillance Technology?
Among the leaders in the use of AI surveillance are China and the United States. Out of the two, China is implementing the technology more widely. According to the Carnegie Endowment for International Peace, the organizations that most often use AI surveillance are part of the government. China is not only using the technology to improve traffic, it is also applying AI surveillance to track the activities of the Uighurs, in the northwestern province of Xinjiang, according to LiveWithAI. By using facial recognition based on race and ethnicity characteristics, the Chinese government can easily detect when a Uighur attempts to flee Xinjiang.

Is the US Government using AI surveillance? Yes, of course. Common applications of governmental AI surveillance include military activity and security. For example Palantir might have helped to power Trump's "extreme vetting" of immigrants. However, there are other applications that target improving the performance of cities.

James, I think your cover's blown!Which Companies Provide These Kind of Service?
According to the report from the Carnegie Endowment for International Peace, some of the leading companies providing AI surveillance are Huawei, ZTE and Hikvision. These companies provide AI-powered surveillance to more than 60 countries. A particularly controversial case involving AI surveillance and facial recognition technology is that of Clearview. This company collects and stores publicly available data on every person on the planet. Scraping from social media platforms such as Facebook and Instagram, Clearview has collected more than 3 billion images from social media platforms, making it the largest such library in the world. Using its enormous library of pictures, Clearview has created a search engine for faces that can be used to recognize anyone. This tool has already been used by more than 600 law enforcement agencies, including the FBI and the US Department of Justice. Clearview's willingness to do what no one else dared to do - scrape freely available data and exploit it for profit - has put it in the centre of a moral debate.

Should You Apply at Such Companies?
Now we are getting to the meat of the discussion: As a software professional, should you work for a company that is working on this type of solution? How do you navigate the moral implications of your work? These are complex questions that seem to require deep introspection. However, at the end of the day - at least for the extreme cases mentioned above - the answer is simpler than you expect.

On the personal level, whether working for a company like Clearview is a good idea depends on your values and what you prioritize in life. Some people abhor the whole concept of using free data to spy on people, while others would simply see nothing wrong with this idea. If you are more like the former, then working for a company like Clearview is a bad idea. It goes against your principles - you will simply not be happy in the long run, regardless of the size of that pay check. If, on the other hand, you don't see anything wrong with these practices and everything else about the job looks good, you might think it is OK to do the job. It is not.

In his famous keynote Not just code monkeys Martin Fowler identified two areas where most of our impact and responsibility as a developer lie at the moment: Privacy and avoiding the creation of an alienating atmosphere at our workplaces.

Conclusion
AI surveillance can be beneficial if used wisely and without violating privacy rights. However, there are some organizations that are using this technology to invade our privacy. The key to avoiding this is to create new policies that protect our privacy rights. As a developer, you must be aware of the implication of your work on privacy and steer clear of such violations.