How Do You Write a Tic-Tac-Toe Program in Golang?

Problem scenario
You want to play TicTacToe. You have a Golang compiler installed. What should you do?

Solution
Prerequisites
This assumes that you have installed Go. If you need assistance, see this posting.

Procedures
1. Name this program tictactoe.go.

package main

import (
  "strings"
  "bufio"
  "fmt"
  "os"
)

func mapper(letter string) int{
  if strings.TrimRight(letter, "\n") == "a" { return 0 }
  if strings.TrimRight(letter, "\n") == "b" { return 1 }
  if strings.TrimRight(letter, "\n") == "c" { return 2 }
  if strings.TrimRight(letter, "\n") == "d" { return 3 }
  if strings.TrimRight(letter, "\n") == "e" { return 4 }
  if strings.TrimRight(letter, "\n") == "f" { return 5 }
  if strings.TrimRight(letter, "\n") == "g" { return 6 }
  if strings.TrimRight(letter, "\n") == "h" { return 7 }
  if strings.TrimRight(letter, "\n") == "i" { return 8 }
  return 99
}

func bprinter (board [9]string) {
  fmt.Println("The board now looks like this:")
  fmt.Println("-------")
  fmt.Println("|" + board[0] + "|" + board[1] + "|" + board[2] + "|")
  fmt.Println("|" + board[3] + "|" + board[4] + "|" + board[5] + "|")
  fmt.Println("|" + board[6] + "|" + board[7] + "|" + board[8] + "|")
  fmt.Println("-------")
  fmt.Println("")
 }

func legendprinter () {
  fmt.Println("Here is the legend for you to make a mark:")
  fmt.Println("_______")
  fmt.Println("|a|b|c|")
  fmt.Println("|d|e|f|")
  fmt.Println("|g|h|i|")
  fmt.Println("-------")
}


func step1(board [9]string, player string) [9]string {
  boardpos := requestor(player)
  newboard := marker(board, player, boardpos)
  tflag := islistsame(board, newboard)
  if (tflag) {
     fmt.Println("No change was made. The same player must make a valid selection. Player " + player + " please try again.")
     newboard = step1(board, player)
  }
  return newboard
}


func boardwinchecker(board [9]string) string {
  lastmessage := "nowinner"
  if board[0] == board[4] { // check the diagonal from left top to right bottom corner
    if board[4] == board[8] {
      if board[4] != " " {
        lastmessage = "Player " + board[0] + " wins!"
        }
    }
  }
  if board[2] == board[4] { // check the diagonal from right top to left bottom corner
    if board[4] == board[6] {
      if board[6] != " " {
        lastmessage = "Player " + board[2] + " wins!"
      }
    }
  }
  if board[0] == board[3] { // check the left column
    if board[3] == board[6] {
      if board[6] != " " {
        lastmessage = "Player " + board[0] + " wins!"
      }
    }
  }
  if board[0] == board[1] { // check the top row
    if board[1] == board[2] {
      if board[0] != " " {
        lastmessage = "Player " + board[0] + " wins!"
      }
    }
  }
  if board[2] == board[5] { // check right column
    if board[5] == board[8] {
      if board[2] != " " {
        lastmessage = "Player " + board[2] + " wins!"
      }
    }
  }
  if board[6] == board[7] { // check bottom row
    if board[7] == board[8] {
      if board[8] != " " {
        lastmessage = "Player " + board[6] + " wins!"
      }
    }
  }
  if board[1] == board[4] { // check middle column
    if board[4] == board[7] {
      if board[1] != " " {
        lastmessage = "Player " + board[1] + " wins!"
      }
    }
  }
  if board[3] == board[4] { // check middle row
    if board[4] == board[5] {
      if board[3] != " " {
        lastmessage = "Player " + board[3] + " wins!"
      }
    }
  }
return lastmessage
}

func marker(board [9]string, player string, position string) [9]string {
  x := mapper(position)
  if (board[x] != " ") {
    fmt.Println("That square has already been marked.  Please try again.")
  } else {
    board[x] = player
  }
  return board
 }

func requestor(player string) string {

fmt.Println("Player", player, "it is your turn.")
fmt.Println("Please enter a letter for the square you want to mark (a through i):")
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
if strings.TrimRight(text, "\n") != "a" {
  if strings.TrimRight(text, "\n") != "b" {
    if strings.TrimRight(text, "\n") != "c" {
      if strings.TrimRight(text, "\n") != "d" {
        if strings.TrimRight(text, "\n") != "e" {
          if strings.TrimRight(text, "\n") != "f" {
            if strings.TrimRight(text, "\n") != "g" {
              if strings.TrimRight(text, "\n") != "h" {
                if strings.TrimRight(text, "\n") != "i" {
                  fmt.Println("*** WARNING ***")
                  fmt.Println("That was an invalid entry. Please try again player " + player)
                  fmt.Println(" ")
                  text = requestor(player)
                  }
                }
              }
            }
          }
        }
      }
    }
  }
return text
}

func islistsame(board1 [9]string, board2 [9]string) bool {
  var j = true
  for i := 0; i < 9; i++ {
    if board1[i] == board2[i] {
    } else {
      j = false
    }
 }
  return j
}

func main() {

  var tttb [9]string
  tttb[0] = " "
  tttb[1] = " "
  tttb[2] = " "
  tttb[3] = " "
  tttb[4] = " "
  tttb[5] = " "
  tttb[6] = " "
  tttb[7] = " "
  tttb[8] = " "

legendprinter()

a := step1(tttb, "X")
bprinter(a)
b := step1(a, "O")
bprinter(b)
c := step1(b, "X")
bprinter(c)
d := step1(c, "O")
bprinter(d)
e := step1(d, "X")
bprinter(e)
legendprinter()
be := boardwinchecker(e)
if be == "nowinner" {
  f := step1(e, "O")
  bprinter(f)
  bf := boardwinchecker(f)
  if bf == "nowinner" {
    bprinter(f)
    g := step1(f, "X")
    bg := boardwinchecker(g)
    if bg == "nowinner" {
      bprinter(g)
      h := step1(g, "O")
      bh := boardwinchecker(h)
      if bh == "nowinner" {
        bprinter(h)
        i := step1(h, "X")
        bi := boardwinchecker(i)
        if bi == "nowinner" {
            legendprinter()
            lastmessage := "CAT's GAME. (It was a draw aka a tie game.)"
            bprinter(i)
            fmt.Println(lastmessage)
        } else {
            bprinter(i)
            fmt.Println(bi) }
      } else {
           bprinter(h)
           fmt.Println(bh) }
     } else {
          bprinter(g)
          fmt.Println(bg) }
   }  else {
          bprinter(f)
          fmt.Println(bf) }
  } else {
       bprinter(e)
       fmt.Println(be) }
 }

2. You can run it one of two ways:

Method 1
go run tictactoe.go

Method 2
Run these two commands:
go build tictactoe.go
./tictactoe

How Do You Scale Out the Nodes of an AKS Cluster?

Problem scenario
You are using AKS (Azure Kubernetes Service). You have a cluster that you want to have more nodes. (Please do not confuse nodes with pods; see this posting if you are not sure about the difference.) What should you do?

Solution
You need to know the name of the cluster and the resource group it is in. Draft a command like this:

az aks scale --name foocluster --node-count 5 --resource-group barrg

-Replace "5" with the number of nodes you want to scale up.
-Replace "foocluster" with the name of the cluster
-Replace "barrg" with the name of the resource group

Run the command you drafted above.

Why is Docker Popular with Jenkins?

Question
You have noticed that Docker and Jenkins are regularly used together. Why is this?

Answer
1. The docker build command produces one artifact. Jenkins lends itself to well-defined tasks.

2. The logic and dependencies of the build can usually be completely contained in the Dockerfile (page 20 of Docker Up and Running). Simple lines of text can standardize many aspects of a given build (e.g., Java) (page 20 of Docker Up and Running). This can be shared company-wide (page 20 of Docker Up and Running). Deployments are consistent and simple which is excellent for testing. A big part of the CI/CD pipeline is testing. Lower environments are made for testing before production. The concept of Docker is a container that is transportable like a whale (Docker's icon).

What is Cargo Cult Systems Engineering?

Question
What is cargo cult systems engineering?

Answer
Cargo cult systems engineering: vestige stanzas are included in a given configuration file for no functional benefit. Such irrelevant, or environment-inappropriate, stanzas exist either because the systems engineer was not given sufficient time to analyze every line of configuration or because the systems engineer failed to understand why the lines were included in the template (or working system) he/she copied from. Some businesses are not supportive of systems engineers spending time analyzing every stanza (because of business reasons that mitigate the problems or due to sheer market pressure).

This term is an off-shoot of the Steve McConnell term "cargo cult software engineering." (This is taken from his website here.)

Some proofs-of-concept scripts and step-by-step directions include "cargo cult systems engineering." This does not mean that they are useless. They may serve a practical goal (of illustrating an application of a technology) as opposed to a "best practice" goal. Some "best practice" achievements are not as secure or as performant as other solutions. Certain I.T. projects necessitate scrutinizing individual configuration files. Such projects include hardening systems (given the number of recent hackings that have brought negative publicity to companies), optimizing performance (for high volume websites or busy transactional databases), reducing the footprint of files (e.g., in Docker containers), and others to save money as inefficient operations in public clouds can be very expensive.

The term "cargo cult systems engineering" helps acknowledge the complexity of the I.T. world. Many generalist professionals (including competent ones) may rely on solutions from the internet without understanding what each character means or does. It seems the DevOps movement embraces deviation from "best practices" as it accepts fuzzy logic and transdisciplinarity for rapid development of software or platforms. One potential benefit transcending specializations is the adoption of bleeding edge security practices. This can mitigate the negative effects of a "move fast and break stuff" culture.

How Do You Create a Build Pipeline in Azure?

Problem scenario
You want to use an Azure pipeline. You want it to perform a build. What should you do?

Solution
Prerequisites
i. You must have a supported code versioning system with certain files. As of 10/7/19 the options are Azure Repos Git, Bitbucket Cloud, GitHub, GitHub Enterprise Server, other Git repositories or Subversion. If you follow steps 1 through 4 of How Do You Build a Java Program with Maven?, and put them in to Azure Repos Git (see "How Do You Use Azure Repositories?" if you need assistance with that), you will have satisfied the Prerequisites and can proceed directly to the procedures.

ii. You have a .yaml file in the supported code versioning system. Here is an example azure-pipelines.yml file (taken from this external site).

steps:
- task: Maven@3
  inputs:
    mavenPomFile: 'pom.xml'
    mavenOptions: '-Xmx3072m'
    javaHomeOption: 'JDKVersion'
    jdkVersionOption: '1.11'
    jdkArchitectureOption: 'x64'
    publishJUnitResults: false
    testResultsFiles: '**/TEST-*.xml'
    goals: 'package'

If you want assistance with Azure Repos Git, see this posting.

iii. You have a pom.xml file in the code versioning system in the same directory as the azure-pipelines.yml file.

iv. You have .java files in directories in your code versioning system that correspond with your pom.xml file.

Procedures
1. Log into Azure. Go here: https://dev.azure.com
2. Click on the project that has the repository you will use. If necessary, create a project and add a repository with the files you need.
3. Click "Pipelines" and go to "Builds"
4. Go to "New" -> "New Build Pipeline" or click "New pipeline" if you see that.
5. Click where your YAML file is (as described in the prerequisites above). If you used Azure Repos Git, click the corresponding button.
6. Click the repository name as you should see it listed.
7. For "Configure your pipeline" click "Show More"
8. Click "Maven"
9. Click "Save and run"
10. You can modify the "Commit message" if you want. Then click "Save and run".

How Do You Write a Python Program to Test If Two Words Are Anagrams?

Problem scenario
You want a program to test if two words are anagramous with each other. You want the test to be case insensitive. How do you write a program that will interactively prompt the user for two different words and test if they are anagrams?

Solution
Use this Python 3 program (and it will interactively prompt you to enter two words):

word1 = input("Enter one word: ").lower()
word2 = input("Enter a second word: ").lower()

wL1 = list(word1)
wL2 = list(word2)

wL1.sort()
wL2.sort()

if (wL1 == wL2):
  print("The two programs are anagrams!")
else:
  print("The two words are NOT anagrams!")

It will not work with Python 2.

How Do You Build a Java Program with Maven?

Problem scenario
You want to use Maven to build a Java program from source code. The code is in at least two different .java files. How do you run Maven to compile a .java file?

Solution
Prerequisites
This assumes that you have installed Maven. If you need assistance, see this posting.

Procedures
1. Run this command: mkdir -p src/main/java/contint
2. Create this file: src/main/java/contint/Helloer.java

package contint;

public class Helloer {
    public static void main(String[] args) {
        ContInt helloer = new ContInt();
        System.out.println(helloer.produceMessage());
    }
}

3. Create this file: src/main/java/contint/ContInt.java

package contint;

public class ContInt {
    public String produceMessage() {
        return "This program was written by Continual Integration";
    }
}

4. Create this pom.xml file with the following content

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.continualintegration</groupId>
    <artifactId>contint</artifactId>
    <packaging>jar</packaging>
    <version>0.1.0</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>contint.Helloer</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

5. Run these commands:

mvn compile
mvn package
java -jar target/contint-0.1.0.jar

How Do You Use Azure Repositories?

Problem scenario
You want to use Git in an Azure Repository. What do you do?

Prerequisites
You have a Linux VM with Git installed.

Procedures
1. Log into Azure.
2. Go to https://dev.azure.com/
3. Click on "New Project"
4. Enter a project name. For your first project, you should probably have "Project visibility" set to "Private."
5. For the prompt "What service would you like to start with?" Choose "Repos".
6. You should see the project name and at the top of the page it will say "is empty." Click "Generate Git Credentials".
7. You will see a username and password. You will only get one opportunity to store this password. Copy it now.
8. Copy the HTTPS URL for your Git repository.
9. Go to your server with Git. Run these commands:

git clone https://URL_COPIED_FROM_ABOVE
cd
date > file.txt
git add .
git commit -m "Added a file"
git push origin master

How Do You Install Spring Framework with Docker?

Problem scenario
You want to deploy the Spring framework with Docker. How do you do this?

Solution
Warning: The last step in this is not a security "recommended practice." Only follow these directions (with sudo docker run…), if the server is not that important or you are in a very secure network. One published book says you can use "sudo docker …" as long as the server is not in production (page 43 of Docker Up and Running).

Prerequisites
This assumes that you have installed Docker. If you need assistance, see this posting.

Procedures
1.a. Install Spring framework with these directions.
1.b. Run these commands:

sudo ln -s /home/ec2-user/gs-spring-boot-docker/complete/target/dependency/BOOT-INF /home/ec2-user/gs-spring-boot-docker/complete/BOOT-INF

sudo ln -s /home/ec2-user/gs-spring-boot-docker/complete/target/dependency/META-INF /home/ec2-user/gs-spring-boot-docker/complete/META-INF

2. Move into the "complete" directory. (To find it, use sudo find / -name complete -type d )
Here is an example: cd /home/jdoe/gs-spring-boot-docker/complete/target/dependency/BOOT-INF/lib/

3. Run this command: docker build -t "ricepaper:contint" .

4. Mentally obtain the image ID with this command: docker images

5. Create the container with this command, but substitute abcd1234 with the image ID (found in step #4):
docker create -it abcd1234 bash

6. Find the container ID with this command: docker ps -a

7. Start the container with a command like this, but substitute efgh5689 with the container ID:
docker start efgh5678

8. Run this command:

sudo docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

9. From a web browser, go to the server's IP address over port 8080. That is compose a URL like this where x.x.x.x is the external IP address of the server: http://x.x.x.x:8080

Place that URL that you just created in a web browser. Go to the link. You should see the browser window displaying "Hello Docker World".

How Do You Troubleshoot the HDFS Error “failed on connection exception: java.net.ConnectException: Connection refused;”?

Problem scenario
You have a multi-node Hadoop cluster running Hadoop version 3. You run this command: hdfs dfsadmin -report

You receive an error that includes this message: "failed on connection exception: java.net.ConnectException: Connection refused; "

What should you do?

Potential Solution
Run these three commands:

bash /usr/local/hadoop/sbin/stop-dfs.sh
hdfs namenode -format
bash /usr/local/hadoop/sbin/start-dfs.sh