One place for hosting & domains

      How To Install F# and Set Up a Local Programming Environment on Ubuntu 18.04


      The author selected the Free Software Foundation to receive a donation as part of the Write for DOnations program.

      Introduction

      F# is an open-source programming language initially developed at Microsoft Research to extend .NET, Microsoft’s set of tools, libraries, and languages to build applications and services. Besides its remarkably concise syntax, F# supports multiple paradigms, meaning that it can do different types of code structuring, though it was primarily designed to take advantage of the functional programming approach.

      Adopting a specific paradigm, or a style of code, determines the way we will think and organize our programming problem solving. With an imperative approach, the design model used in languages like C++ or Java, a developer describes step-by-step how the computer must accomplish a task. It’s about writing a sequence of statements that will change memory states at the program’s execution. This works fine until we encounter some irregular situations. Consider a shared object for instance, which is used by multiple applications simultaneously. We might want to read its value at the same time that another component is modifying it. These are concurrent actions upon a memory location that can produce data inconsistency and undefined behavior.

      In functional code design, we prevent this kind of problem by minimizing the use of mutable states, or states that can change after we make them. Function is the keyword here, referring to mathematical transformations on some information provided as arguments. A functional code expresses what the program is by composing the solution as a set of functions to be executed. Typically, we build up layers of logic using functions that can return another function or take other functions as inputs.

      Functional programming with F# brings a number of benefits:

      • A more readable and expressive syntax that increases program maintainability.
      • A code less prone to breaking and easier to debug because of stateless functions that can be isolated for testing.
      • Native constructs that facilitate asynchronous programming and safer concurrency.
      • Access to all the existing tools in the .NET world including the community-shared packages.

      Choosing a Runtime

      Since F# is cross-platform, maintaining a similar execution model behavior through different operating systems is essential. .NET achieves this by means of a runtime. A runtime system is a piece of software that orchestrates the execution of a program written with a specific programming language, handling interfacing with the operating system and memory management, among other things.

      There are actually two .NET runtime implementations available on Linux: .NET Core and Mono. Historically, .NET only worked on Windows. In those days, one could resort to the community Mono project to run .NET applications on other platforms like Linux and macOS. Microsoft then launched .NET Core, a faster, modular subset of the original .NET framework, to target multiple platforms.

      At the time of this tutorial’s publication, they both can be used for building web applications or command line utilities. That said, .NET Core does not ship models to create GUI desktop applications on Linux and macOS, while Mono is the only one to support mobile and gaming platforms. It is important to know these differences since the runtime you pick will shape the programs you will build. You could also choose to have both .NET Core and Mono installed in order to account for all use cases and to make a more productive stack.

      In this tutorial, you will set up an F# programming environment on Ubuntu 18.04 using both .NET Core and Mono runtimes. You will then write some code examples to test and review build and compile methods.

      Prerequisites

      To complete this tutorial, you will need basic familiarity with the command line and a computer running Ubuntu 18.04 with a non-root user with sudo privileges.

      Step 1 — Installing F# with .NET Core

      Microsoft provides the .NET Core Software Development Kit (SDK) for F# developers. A Software Development Kit is a set of programming tools that allows programmers to produce specialized applications and adapt them to various operating systems. It traditionally includes a text editor, languages support, a runtime, and a compiler, among other components. In this step, you are going to install this SDK. But first, you will register the Microsoft repository and fetch some dependencies.

      You’ll be completing the installation and setup on the command line, which is a non-graphical way to interact with your computer. That is, instead of clicking on buttons, you’ll be typing in text and receiving feedback from your computer through text as well.

      The command line, also known as a shell or terminal, can help modify and automate many of the tasks you do on a computer every day, and is an essential tool for software developers. There are many terminal commands to learn that can enable you to do more powerful things. For more information about the command line, check out the Introduction to the Linux Terminal tutorial.

      On Ubuntu 18.04, you can find the Terminal application by clicking on the Ubuntu icon in the upper-left hand corner of your screen and typing terminal into the search bar. Click on the Terminal application icon to open it. Alternatively, you can hit the CTRL, ALT, and T keys on the keyboard at the same time to open the Terminal application automatically.

      Ubuntu Terminal

      Once you have opened the terminal, use the wget command to download a package containing some required files, the Microsoft repository configurations, and a key for server communication.

      • wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb

      Now, add the Microsoft repository and install the packages to your system using the dpkg -i instruction.

      • sudo dpkg -i packages-microsoft-prod.deb

      Next, activate the Universe repository, which on Ubuntu is a community-maintained archive of software that is free and open source. This will give you access to apt-transport-https, a dependency for enabling the Ubuntu package manager APT transport over HTTPS.

      • sudo add-apt-repository universe
      • sudo apt install apt-transport-https

      Next, update available downloads:

      Finally, install the current version of the .NET SDK. This tutorial will use version 2.2:

      • sudo apt install dotnet-sdk-2.2

      Now that you have the .NET SDK installed, a quick way to check if everything went well is to try the .NET Core command line interface (CLI), which will be available in the shell once the SDK is downloaded and installed. Display information about your .NET setup by typing this in your terminal:

      When you run a dotnet command for the first time, a text section is displayed as shown below:

      Output

      Welcome to .NET Core! --------------------- Learn more about .NET Core: https://aka.ms/dotnet-docs Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli-docs Telemetry --------- The .NET Core tools collect usage data in order to help us improve your experience. The data is anonymous and doesn't include command-line arguments. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell. Read more about .NET Core CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry ...

      This notification is about collected data, and explains that some .NET CLI commands will send usage information to Microsoft. You will disable this in a moment; for now, look at the output from dotnet --info.

      After a brief moment, the terminal will list information about your .NET installation:

      Output

      .NET Core SDK (reflecting any global.json): Version: 2.2.101 Commit: 236713b0b7 Runtime Environment: OS Name: ubuntu OS Version: 18.04 OS Platform: Linux RID: ubuntu.18.04-x64 Base Path: /usr/share/dotnet/sdk/2.2.101/ Host (useful for support): Version: 2.2.0 Commit: 1249f08fed .NET Core SDKs installed: 2.2.101 [/usr/share/dotnet/sdk] .NET Core runtimes installed: Microsoft.AspNetCore.All 2.2.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.2.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.2.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App] To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download

      Depending on the SDK version, the output may be slightly different, but this confirms that .NET Core is ready to use.

      As mentioned before, the telemetry feature allows some .NET CLI commands to send usage information to Microsoft. It is enabled by default, and can be deactivated by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1. To do so, add a new line to your .profile environment customization file by opening it in your text editor. For this tutorial, we will use nano:

      Add the following line to the end of .profile:

      ~/.profile

      . . .
      export DOTNET_CLI_TELEMETRY_OPTOUT=1
      

      Exit nano by pressing the CTRL and X keys. When prompted to save the file, press Y and then ENTER.

      You can activate the new configuration using the source command:

      From now on, telemetry will be turned off at startup.

      At this point you have .NET Core runtime, languages support, and libraries installed, allowing you to run and build some .NET applications. The dotnet CLI is also available for managing .NET source code and binaries. You could start building F# projects, but as mentioned previously, the .NET Core environment does not provide all the constructs needed to be completely cross-platform. For now you cannot use it to develop mobile applications, for example.

      In order to solve this problem, in the next step you will install F# again, but this time with Mono.

      Step 2 — Installing F# with Mono

      You can use Mono to fill in the remaining gaps in capability left by .NET Core. Mono and .NET Core are both based on the same standard library and both support .NET languages, but that is where the similarity ends. They use different runtimes, different CLIs, and different compilers, making it possible for them to be installed side by side to create a more reliable programming environment. In this section you are going to supplement your environment with the Mono tools for .NET programming and run an F# program from the command line.

      A version of Mono is available in the Ubuntu repositories, but this can be outdated. Instead, add the official Mono package repository to your package manager:

      • sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
      • echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list

      In the preceding commands, you used apt-key to retrieve keys for securing packages transferred from the official Mono repositories. You then added the Mono packages source to your repositories list.

      With a new source list added for APT, update your repositories:

      Next, download the Mono tools. Unlike .NET Core, Mono does not include F# tools, so you will download it as a separate package. Install fsharp and the mono-complete meta-package using the following command:

      • sudo apt install mono-complete fsharp

      Note: Because of the size of this download, the installation process for mono-complete may take a while.

      Once done, you will have the compiler fsharpc and an interactive shell called fsharpi or simply FSI. FSI is an environment, inside the shell, that receives user's input as an expression, evaluates it, then outputs the result and waits for another input. It is just like typing a command in the traditional shell and seeing the result, except here, inputs are F# expressions. FSI provides a fast method to test code or run scripts.

      Activate FSI with the following command:

      This will start the interactive session and replace your regular prompt with the fsharpi prompt:

      Output

      Microsoft (R) F# Interactive version 4.1 Copyright (c) Microsoft Corporation. All Rights Reserved. For help type #help;; >

      You can return to the default shell by running #quit;;. In fsharpi, each command line ends with a double semicolon.

      Let's try a simple operation using the printfn function to render a message passed as a parameter:

      You will receive the following output:

      Output

      Hello World! val it : unit = () >

      From the preceding interaction, fsharpi evaluates the expression as a unit type value. The code is then executed and the result is printed with its type.

      fsharpi can also run a file containing F# code. The script must be named with a .fsx extension and executed from the shell with the command:

      Now that you know the F# installation is working, leave the shell with:

      > #quit;;
      

      With Mono and .NET Core installed, you are now prepared to write any type of F# programs. FSI will allow you to test your code and run some scripts if needed, but executions will be slow. For your F# script to be executed, additional steps are performed to translate the source code into artifacts understandable by the processor, hence the slowness. To remedy this, in the next section you will compile your code with .NET Core, creating standalone binary files that can be immediately run by the machine.

      Step 3 — Writing and Compiling F# Programs with .NET Core

      In this step, you will compile F# source code via command line compilers provided with .NET Core. This will allow you to make your applications faster and to produce preset executable packages for specific systems, making your program easier to distribute.

      Compiling is the transformation process that turns source code into binary file. The software that accomplishes this conversion is called a compiler. .NET Core relies on the dotnet CLI to perform compiling. To demonstrate this, you are going to create a basic F# source to review the compilation cases.

      The dotnet CLI provides a complete application build toolchain. In general, an association of a command and the dotnet driver is used in the shell to complete a task. For example:

      • dotnet new will create a project
      • dotnet build will build a project and all of its dependencies
      • dotnet add package will add a package reference to a project file

      The following will create a new console project called FSharpHello. The -lang option sets the programming language you will code with while the -o option creates a directory in which to place the output.

      • dotnet new console -lang F# -o FSharpHello

      Once this is done, navigate into your newly created project directory:

      This directory contains the FSharpHello.fsproj project configuration file and the obj folder which is used to store temporary object files. There is also the Program.fs file where your default source code exists. Open it in your text editor:

      The file has been automatically filled with a Hello World program:

      Program.fs

      // Learn more about F# at http://fsharp.org
      
      open System
      
      [<EntryPoint>]
      let main argv =
          printfn "Hello World from F#!"
          0 // return an integer exit code
      

      In this code, you start importing the System module with open System, then you define the program entry point, i.e., the place where the program starts when launched from the shell. The main function will call for a Hello World message printing to the console and will stop the program (return an integer exit code).

      Exit out of the file.

      To compile and run this code, use the following from the project directory ~/FSharpHello:

      The program will run, printing the following output to the screen:

      Output

      Hello World from F#!

      Note that it took a while for this program to run, just as with the FSI. As we mentioned before, it's possible to run this faster by generating an executable, i.e., a binary file that can be run directly by the operating system. Here is how to achieve this:

      • dotnet publish -c release -r linux-x64

      This will produce the executable bin/release/netcoreapp2.2/linux-x64/publish/FSharpHello.dll file. This is a shared library that will run on a 64-bit Linux architecture. To export a generic executable for macOS systems, you would replace the linux-x64 runtime identifier (RID) with osx-x64.

      Now execute the file with the following command:

      • dotnet bin/release/netcoreapp2.2/linux-x64/publish/FSharpHello.dll

      This time, you will receive the output much quicker, since the program is already translated into binary.

      Now that you know how to compile in .NET Core, let's see how Mono compiles programs with the dedicated fsharpc command.

      Step 4 — Writing and Compiling F# Programs with Mono

      Mono's compilation process is similar to that of .NET Core, but this time there is a specific command used to compile the program. The fsharpc command is the tool, and it has been created only for compiling.

      This time, create a hello.fs file and write some F# code. First, return to your home directory:

      Next, open up a new file named hello.fs:

      Add the following line to the file:

      hello.fs

      open System
      

      As seen before, this imports the System module or namespace, giving you access to built-in system functions and objects like Console.

      Now, add in some more lines of code:

      hello.fs

      open System
      
      let hello() =
          printf "Who are you? "
          let name = Console.ReadLine()
          printfn "Oh, Hello %s!nI'm F#." name
      

      These new lines define the hello() function to read user input and print a feedback message.

      Now you can add the final lines:

      hello.fs

      open System
      
      let hello() =
          printf "Who are you? "
          let name = Console.ReadLine()
          printfn "Oh, Hello %s!nI'm F#." name
      
      hello()
      Console.ReadKey() |> ignore
      

      Here you are calling the function hello(), then using the ReadKey() method to end the program with a final keystroke.

      Save and exit the file.

      Now with the fsharpc command, use the -o flag to define the output filename and compile your hello.fs source code like this:

      • fsharpc hello.fs -o hello

      The preceding command will generate a hello executable file you can run with the mono command:

      This gives you the following output and awaits user input:

      Output

      Who are you?

      If you type in Sammy, you will get the following.

      Output

      Oh, Hello Sammy! I'm F#.

      Press a final keystroke, and the program will end.

      Congratulations! You have written and compiled your first F# program, both with Mono and .NET Core.

      Conclusion

      In this tutorial, you installed tooling for F# programming, covering both .NET Core and Mono environments. You also tested examples of F# code and built executables. These are the first steps toward learning this practical functional language.

      Next steps could be to learn the language and get in touch with the community. Also, with projects getting more complex, you might need to manage code and resources more efficiently. Package managers like NuGet or Paket are bridges to the strong ecosystem built around .NET and tools-of-choice for organizing large programs.



      Source link

      How To Convert Data Types in Go


      Introduction

      In Go, data types are used to classify one particular type of data, determining the values that you can assign to the type and the operations you can perform on it. When programming, there are times when you will need to convert values between types in order to manipulate values in a different way. For example, you may need to concatenate numeric values with strings, or represent decimal places in numbers that were initialized as integer values. User-generated data is often automatically assigned the string data type, even if it consists of numbers; in order to perform mathematical operations in this input, you would have to convert the string to a numeric data type.

      Since Go is a statically typed language, data types are bound to variables rather than values. This means that, if you define a variable as an int, it can only be an int; you can’t assign a string to it without converting the data type of the variable. The static nature of data types in Go places even more importance on learning the ways to convert them.

      This tutorial will guide you through converting numbers and strings, as well as provide examples to help familiarize yourself with different use cases.

      Converting Number Types

      Go has several numeric types to choose from. Primarily they break out into two general types: integers and floating-point numbers.

      There are many situations in which you may want to convert between numeric types. Converting between different sizes of numeric types can help optimize performance for specific kinds of system architecture. If you have an integer from another part of your code and want to do division on it, you may want to convert the integer to a float to preserve the precision of the operation. Additionally, working with time durations usually involves integer conversion. To address these situations, Go has built-in type conversions for most numeric types.

      Converting Between Integer Types

      Go has many integer data types to pick from. When to use one over the other is typically more about performance; however, there will be times when you will need to convert from one integer type to another. For example, Go sometimes automatically generates numeric values as int, which may not match your input value. If your input value were int64, you would not be able to use the int and the int64 numbers in the same mathematical expression until you converted their data types to match.

      Assume that you have an int8 and you need to convert it to an int32. You can do this by wrapping it in the int32() type conversion:

      var index int8 = 15
      
      var bigIndex int32
      
      bigIndex = int32(index)
      
      fmt.Println(bigIndex)
      

      Output

      15

      This code block defines index as an int8 data type and bigIndex as an int32 data type. To store the value of index in bigIndex, it converts the data type to an int32. This is done by wrapping the int32() conversion around the index variable.

      To verify your data types, you could use the fmt.Printf statement and the %T verb with the following syntax:

      fmt.Printf("index data type:    %Tn", index)
      fmt.Printf("bigIndex data type: %Tn", bigIndex)
      

      Output

      index data type: int8 bigIndex data type: int32

      Since this uses the %T verb, the print statement outputs the type for the variable, and not the actual value of the variable. This way, you can confirm the converted data type.

      You can also convert from a larger bit-size integer to a smaller bit-size integer:

      var big int64 = 64
      
      var little int8
      
      little = int8(big)
      
      fmt.Println(little)
      

      Output

      64

      Keep in mind that when converting integers you could potentially exceed the maximum value of the data type and wraparound:

      var big int64 = 129
      var little = int8(big)
      fmt.Println(little)
      

      Output

      -127

      A wraparound happens when the value is converted to a data type that is too small to hold it. In the preceding example, the 8-bit data type int8 did not have enough space to hold the 64-bit variable big. Care should always be taken when converting from a larger number data type to a smaller number data type so that you do not truncate the data by accident.

      Converting Integers to Floats

      Converting integers to floats in Go is similar to converting one integer type to another. You can use the built-in type conversions by wrapping float64() or float32() around the integer you are converting:

      var x int64 = 57
      
      var y float64 = float64(x)
      
      fmt.Printf("%.2fn", y)
      

      Output

      57.00

      This code declares a variable x of type int64 and initializes its value to 57.

      var x int64 = 57
      

      Wrapping the float64() conversion around x will convert the value of 57 to a float value of 57.00.

      var y float64 = float64(x)
      

      The %.2f print verb tells fmt.Printf to format the float with two decimals.

      You can also use this process on a variable. The following code declares f as equal to 57, and then prints out the new float:

      var f float64 = 57
      fmt.Printf("%.2fn", f)
      

      Output

      57.00

      By using either float32() or float64(), you can convert integers to floats. Next, you will learn how to convert floats to integers.

      Converting Floats to Integers

      Go can convert floats to integers, but the program will lose the precision of the float.

      Wrapping floats in int(), or one of its architecture-independent data types, works similarly to when you used it to convert from one integer type to another. You can add a floating-point number inside of the parentheses to convert it to an integer:

      var f float64 = 390.8
      var i int = int(f)
      
      fmt.Printf("f = %.2fn", f)
      fmt.Printf("i = %dn", i)
      

      Output

      f = 390.80 i = 390

      This syntax would convert the float 390.8 to the integer 390, dropping the decimal place.

      You can also use this with variables. The following code declares b as equal to 125.0 and c as equal to 390.8, then prints them out as integers. Short variable declaration (:=) shortens up the syntax:

      b := 125.0
      c := 390.8
      
      fmt.Println(int(b))
      fmt.Println(int(c))
      

      Output

      125 390

      When converting floats to integers with the int() type, Go cuts off the decimal and remaining numbers of a float to create an integer. Note that, even though you may want to round 390.8 up to 391, Go will not do this through the int() type. Instead, it will drop the decimal.

      Numbers Converted Through Division

      When dividing integer types in Go the result will also be an integer type, with the modulus, or remainder, dropped:

      a := 5 / 2
      fmt.Println(a)
      

      Output

      2

      If, when dividing, any of the number types are a float, then all of the types will automatically be declared as a float:

          a := 5.0 / 2
          fmt.Println(a)
      

      Output

      2.5

      This divides the float 5.0 by the integer 2, and the answer 2.5 is a float that retains the decimal precision.

      In this section, you have converted between different number data types, including differing sizes of integers and floating-point numbers. Next, you will learn how to convert between numbers and strings.

      Converting with Strings

      A string is a sequence of one or more characters (letters, numbers, or symbols). Strings are a common form of data in computer programs, and you may need to convert strings to numbers or numbers to strings fairly often, especially when you are taking in user-generated data.

      Converting Numbers to Strings

      You can convert numbers to strings by using the strconv.Itoa method from the strconv package in the Go standard libary. If you pass either a number or a variable into the parentheses of the method, that numeric value will be converted into a string value.

      First, let’s look at converting integers. To convert the integer 12 to a string value, you can pass 12 into the strconv.Itoa method:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          a := strconv.Itoa(12)
          fmt.Printf("%qn", a)
      }
      

      When running this program, you’ll receive the following output:

      Output

      "12"

      The quotes around the number 12 signify that the number is no longer an integer but is now a string value.

      You used the := assignment operator to both declare a new variable with the name of a and assign the value returned from the strconv.Itoa() function. In this case, you assigned the value 12 to your variable. You also used the %q verb in the fmt.Printf function, which tells the function to quote the string provided.

      With variables you can begin to see how practical it can be to convert integers to strings. Say you want to keep track of a user’s daily programming progress and are inputting how many lines of code they write at a time. You would like to show this feedback to the user and will be printing out string and integer values at the same time:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          user := "Sammy"
          lines := 50
      
          fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
      }
      

      When you run this code, you’ll receive the following error:

      Output

      invalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int)

      You’re not able to concatenate strings and integers in Go, so you’ll have to convert the variable lines to be a string value:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          user := "Sammy"
          lines := 50
      
          fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.")
      }
      

      Now, when you run the code, you’ll receive the following output that congratulates your user on their progress:

      Output

      Congratulations, Sammy! You just wrote 50 lines of code.

      If you are looking to convert a float to a string rather than an integer to a string, you follow similar steps and format. When you pass a float into the fmt.Sprint method, from the fmt package in the Go standard library, a string value of the float will be returned. You can use either the float value itself or a variable:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          fmt.Println(fmt.Sprint(421.034))
      
          f := 5524.53
          fmt.Println(fmt.Sprint(f))
      }
      

      Output

      421.034 5524.53

      You can test to make sure it’s right by concatenating with a string:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          f := 5524.53
          fmt.Println("Sammy has " + fmt.Sprint(f) + " points.")
      }
      

      Output

      Sammy has 5524.53 points.

      You can be sure your float was properly converted to a string because the concatenation was performed without error.

      Converting Strings to Numbers

      Strings can be converted to numbers by using the strconv package in the Go standard library. The strconv package has functions for converting both integer and float number types. This is a very common operation when accepting input from the user. For example, if you had a program that asked for a person’s age, when they type the response in, it is captured as a string. You would then need to convert it to an int to do any math with it.

      If your string does not have decimal places, you’ll most likely want to convert it to an integer by using the strconv.Atoi function. If you know you will use the number as a float, you would use strconv.ParseFloat.

      Let’s use the example of the user Sammy keeping track of lines of code written each day. You may want to manipulate those values with math to provide more interesting feedback for the user, but those values are currently stored in strings:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          lines_yesterday := "50"
          lines_today := "108"
      
          lines_more := lines_today - lines_yesterday
      
          fmt.Println(lines_more)
      }
      

      Output

      invalid operation: lines_today - lines_yesterday (operator - not defined on string)

      Because the two numeric values were stored in strings, you received an error. The operand - for subtraction is not a valid operand for two string values.

      Modify the code to include the strconv.Atoi() method that will convert the strings to integers, which will allow you to do math with values that were originally strings. Because there is a potential to fail when converting a string to an integer, you have to check for any errors. You can use an if statement to check if your conversion was successful.

      package main
      
      import (
          "fmt"
          "log"
          "strconv"
      )
      
      func main() {
          lines_yesterday := "50"
          lines_today := "108"
      
          yesterday, err := strconv.Atoi(lines_yesterday)
          if err != nil {
              log.Fatal(err)
          }
      
          today, err := strconv.Atoi(lines_today)
          if err != nil {
              log.Fatal(err)
          }
          lines_more := today - yesterday
      
          fmt.Println(lines_more)
      }
      

      Because it is possible for a string to not be a number, the strconv.Atoi() method will return both the converted type, as well as a potential error. When converting from lines_yesterday with the strconv.Atoi function, you have to check the err return value to ensure that the value was converted. If the err is not nil, it means that strconv.Atoi was unable to successfully convert the string value to an integer. In this example, you used an if statement to check for the error, and if an error was returned, you used log.Fatal to log the error and exit the program.

      When you run the preceding code, you will get:

      Output

      58

      Now try to convert a string that is not a number:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          a := "not a number"
          b, err := strconv.Atoi(a)
          fmt.Println(b)
          fmt.Println(err)
      }
      

      You will get the following error:

      Output

      0 strconv.Atoi: parsing "not a number": invalid syntax

      Because b was declared, but strconv.Atoi failed to make a conversion, a value was never assigned to b. Notice that b has the value of 0. This is because Go has default values, referred to as zero values in Go. strconv.Atoi provides an error describing why it failed to convert the string as well.

      Converting Strings and Bytes

      Strings in Go are stored as a slice of bytes. In Go, you can convert between a slice of bytes and a string by wrapping it in the corresponding conversions of []byte() and string():

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          a := "my string"
      
          b := []byte(a)
      
          c := string(b)
      
          fmt.Println(a)
      
          fmt.Println(b)
      
          fmt.Println(c)
      }
      

      Here you have stored a string value in a, then converted it to a slice of bytes b, then converted the slice of bytes back to a string as c. You then print a, b, and c to the screen:

      Output

      my string [109 121 32 115 116 114 105 110 103] my string

      The first line of output is the original string my string. The second line printed out is the byte slice that makes up the original string. The third line shows that the byte slice can be safely converted back into a string and printed back out.

      Conclusion

      This Go tutorial demonstrated how to convert several of the important native data types to other data types, primarily through built-in methods. Being able to convert data types in Go will allow you to do things like accept user input and do math across different number types. Later on, when you are using Go to write programs that accept data from many different sources like databases and APIs, you will use these conversion methods to ensure you can act on your data. You will also be able to optimize storage by converting data to smaller data types.

      If you would like a deeper analysis of data types in Go, check out our Understanding Data Types in Go article.



      Source link

      How To Set Up WordPress with MySQL on Kubernetes Using Helm


      Introduction

      As more developers work within distributed environments, tools like Kubernetes have become central to keeping application components standardized across dynamic build and production environments. As Kubernetes is more widely adopted by developers to orchestrate large numbers of containers at scale, it has become increasingly necessary to leverage tools that help manage resources within Kubernetes clusters. Helm is an open-source package manager for Kubernetes that can help you as you define, install, and upgrade your Kubernetes applications.

      In this tutorial, we’ll use Helm for setting up a WordPress site on top of a Kubernetes cluster. We’ll be using an external MySQL server in order to abstract the database component, since it can be part of a separate cluster or managed service for extended availability. After completing the steps described in this tutorial, you will have a fully functional WordPress installation within a containerized cluster environment managed by Kubernetes.

      Prerequisites

      In order to complete this guide, you will need the following available to you:

      Before moving on, make sure you’re able to log into your MySQL server, and that you have connectivity to your Kubernetes cluster. In case you have multiple clusters set up in your kubectl config file, you should make sure that you’re connected to the correct cluster by running the following command from your local machine or development server:

      • kubectl config get-contexts

      This is an example output:

      Output

      CURRENT NAME CLUSTER AUTHINFO NAMESPACE * do-sfo2-wordpress-cluster do-sfo2-wordpress-cluster do-sfo2-wordpress-cluster-admin minikube minikube minikube

      The asterisk sign (*) indicates which cluster is currently the default context. In case you need to change the current context, run:

      • kubectl config use-context context-name

      You should now be ready to follow the rest of the guide.

      Step 1 — Configuring MySQL

      First, we’ll create a dedicated MySQL user and a database for WordPress, allowing connections from external hosts. This is necessary because our WordPress installation will live on a separate server inside the Kubernetes cluster. In case you already have a dedicated MySQL user and database set up for WordPress, you can skip to the next step.

      From the MySQL server, log into MySQL with the following command:

      You will be prompted to provide the password you set up for the root MySQL account when you first installed the software. After logging in, MySQL will give you a command prompt you can use to create the database and user we need for WordPress.

      Note: For this tutorial, we'll be creating a database named wordpress and a user named wordpress_user, identified by the password password. Please note that these are insecure example values, and you should modify them accordingly throughout this guide.

      To create the database, you can use the following statement:

      • CREATE DATABASE wordpress;

      Now, let's create a dedicated MySQL user for this database:

      • CREATE USER wordpress_user IDENTIFIED BY 'password';

      The user wordpress_user was created, but it doesn't have any access permissions yet. The following command will give this user admin access (all privileges) to the wordpress database from both local and external networks:

      • GRANT ALL PRIVILEGES ON wordpress.* TO wordpress_user@'%';

      To update the internal MySQL tables that manage access permissions, use the following statement:

      Now you can exit the MySQL client with:

      To test that the changes were successful, you can log into the MySQL command-line client again, this time using the new account wordpress_user to authenticate:

      • mysql -u wordpress_user -p

      You should use the same password you provided when creating this MySQL user with the CREATE_USER statement. To confirm your new user has access to the wordpress database, you can use the following statement:

      The following output is expected:

      Output

      +--------------------+ | Database | +--------------------+ | information_schema | | wordpress | +--------------------+ 2 rows in set (0.03 sec)

      After confirming the wordpress database is included in the results, you can exit the MySQL command-line client with:

      You now have a dedicated MySQL database for WordPress, and valid access credentials to use within it. Because our WordPress installation will live on a separate server, we still need to edit our MySQL configuration to allow connections coming from external hosts.

      While still on your MySQL server, open the file /etc/mysql/mysql.conf.d/mysqld.cnf using your command-line editor of choice:

      • sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

      Locate the bind-address setting within this file. By default, MySQL listens only on 127.0.0.1 (localhost). In order to accept connections from external hosts, we need to change this value to 0.0.0.0. This is how your bind-address configuration should look:

      /etc/mysql/mysql.conf.d/mysqld.cnf

      
      # Instead of skip-networking the default is now to listen only on
      # localhost which is more compatible and is not less secure.
      bind-address            = 0.0.0.0
      

      When you're done making these changes, save and close the file. You'll need to restart MySQL with the following command:

      • sudo systemctl restart mysql

      To test if you're able to connect remotely, run the following command from your local machine or development server:

      • mysql -h mysql_server_ip -u wordpress_user -p

      Remember to change mysql_server_ip to your MySQL server IP address or hostname. If you're able to connect without errors, you are now ready to proceed to the next step.

      Step 2 — Installing WordPress

      Now that we have the necessary information to connect to the MySQL database, we can go ahead and install WordPress using Helm.

      By default, the WordPress chart installs MariaDB on a separate pod inside the cluster and uses it as the WordPress database. We want to disable this behavior and configure WordPress to use an external MySQL database. This and other configuration options (such as the default WordPress admin user and password) can be set at installation time, either via command-line parameters or via a separate YAML configuration file.

      In order to keep things organized and easily extendable, we are going to use a configuration file.

      From your local machine or development server, create a new directory for your project settings and navigate into it:

      • mkdir myblog-settings
      • cd myblog-settings

      Next, create a file named values.yaml, using your text editor of choice:

      Within this file, we need to set up a few variables that will define how WordPress connects to the database, as well as some basic information about your site and the initial admin user for logging into WordPress when the installation is complete.

      We'll base our configuration on the default values.yaml file from the WordPress Helm chart. The Blog/Site Info section contains general options for your WordPress blog, such as the name of the blog and the initial user credentials. The Database Settings section of this file contains the settings for connecting to the remote MySQL server. MariaDB is disabled in the final section.

      Copy the following contents into your values.yaml file, replacing the highlighted values with your custom values:

      values.yaml

      
      ## Blog/Site Info
      wordpressUsername: sammy
      wordpressPassword: password
      wordpressEmail: [email protected]
      wordpressFirstName: Sammy
      wordpressLastName: the Shark
      wordpressBlogName: Sammy's Blog!
      
      ## Database Settings
      externalDatabase:
        host: mysql_server_ip
        user: wordpress_user
        password: password
        database: wordpress
      
      ## Disabling MariaDB
      mariadb:
        enabled: false
      

      We have just configured the following options:

      • wordpressUsername: WordPress user's login.
      • wordpressPassword: WordPress user's password.
      • wordpressEmail: WordPress user's email.
      • wordpressFirstName: WordPress user's first name.
      • wordpressLastName: WordPress user's last name.
      • wordpressBlogName: Name of the Site or Blog.
      • host: MySQL server IP address or hostname.
      • user: MySQL user.
      • password: MySQL password.
      • database: MySQL database name.

      When you're done editing, save the file and exit the editor.

      Now that we have all settings in place, it is time to execute helm to install WordPress. The following command tells helm to install the most recent stable release of the WordPress chart under the name myblog, using values.yaml as configuration file:

      • helm install --name myblog -f values.yaml stable/wordpress

      You should get output similar to the following:

      Output

      NAME: myblog LAST DEPLOYED: Fri Jan 25 20:24:10 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE myblog-wordpress 0/1 1 0 1s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myblog-wordpress Pending do-block-storage 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE myblog-wordpress-5965f49485-8zfl7 0/1 Pending 0 1s ==> v1/Secret NAME TYPE DATA AGE myblog-externaldb Opaque 1 1s myblog-wordpress Opaque 1 1s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE myblog-wordpress LoadBalancer 10.245.144.79 <pending> 80:31403/TCP,443:30879/TCP 1s (...)

      After the installation is finished, a service named myblog-wordpress is created within your Kubernetes cluster, but it may take a few minutes before the container is ready and the External-IP information is available. To check the status of this service and retrieve its external IP address, run:

      You should get output similar to the following:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 20h myblog-wordpress LoadBalancer 10.245.144.79 203.0.113.110 80:31403/TCP,443:30879/TCP 3m40s

      This command gives you detailed information about services running on your cluster, including name and type of the service, as well as IP addresses used by these services. As you can see from the output, the WordPress installation is being served as myblog-wordpress on the external IP address 203.0.113.110.

      Note: In case you are using minikube to test this setup, you'll need to run minikube service myblog-wordpress in order to expose the container web server so that you can access it from your browser.

      Your WordPress installation is now operational. To access the admin interface, use the public IP address obtained from the output of kubectl get services, followed by /wp-admin in your web browser:

      http://203.0.113.110/wp-admin
      

      Login screen

      You should use the credentials defined in your values.yaml file to log in and start configuring your WordPress site.

      Step 3 — Upgrading WordPress

      Because of its popularity, WordPress is often a target for malicious exploitation, so it's important to keep it updated. We can upgrade Helm releases with the command helm upgrade.

      To list all of your current releases, run the following command from your local machine or development server:

      You should get output similar to this:

      Output

      NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE myblog 1 Fri Jan 25 20:24:10 2019 DEPLOYED wordpress-5.1.2 5.0.3 default

      As you can see from the output, our current WordPress version is 5.0.3 (app version), while the chart version is 5.1.2. If you want to upgrade a release to a newer version of a chart, first update your Helm repositories with:

      You can expect the following output:

      Output

      Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈

      Now you can check if there's a newer version of the WordPress chart available with:

      • helm inspect chart stable/wordpress

      You should see output similar to this:

      Output

      apiVersion: v1 appVersion: 5.1.1 description: Web publishing platform for building blogs and websites. engine: gotpl home: http://www.wordpress.com/ icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png keywords: - wordpress - cms - blog - http - web - application - php maintainers: - email: [email protected] name: Bitnami name: wordpress sources: - https://github.com/bitnami/bitnami-docker-wordpress version: 5.9.0

      As you can see from the output, there's a new chart available (version 5.9.0) with WordPress 5.1.1 (app version). Whenever you want to upgrade your WordPress release to the latest WordPress chart, you should run:

      • helm upgrade -f values.yaml myblog stable/wordpress

      This command will produce output very similar to the output produced by helm install. It is important to provide the same configuration file we used when installing the WordPress chart for the first time, as it contains the custom database settings we defined for our setup.

      Now, if you run helm list again, you should see updated information about your release:

      Output

      NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE myblog 2 Fri May 3 14:51:20 2019 DEPLOYED wordpress-5.9.0 5.1.1 default

      You have successfully upgraded your WordPress to the latest version of the WordPress chart.

      Rolling Back a Release

      Each time you upgrade a release, a new revision of that release is created by Helm. A revision sets a fixed checkpoint to where you can come back if things don't work as expected. It is similar to a commit in Git, because it creates a history of changes that can be compared and reverted. If something goes wrong during the upgrade process, you can always rollback to a previous revision of a given Helm release with the helm rollback command:

      • helm rollback release-name revision-number

      For instance, if we want to undo the upgrade and rollback our WordPress release to its first version, we would use:

      This would rollback the WordPress installation to its first release. You should see the following output, indicating that the rollback was successful:

      Output

      Rollback was a success! Happy Helming!

      Running helm list again should now indicate that WordPress was downgraded back to 5.0.3, chart version 5.1.2:

      Output

      NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE myblog 3 Mon Jan 28 22:02:42 2019 DEPLOYED wordpress-5.1.2 5.0.3 default

      Notice that rolling back a release will actually create a new revision, based on the target revision of the roll-back. Our WordPress release named myblog now is at revision number three, which was based on revision number one.

      Conclusion

      In this guide, we installed WordPress with an external MySQL server on a Kubernetes cluster using the command-line tool Helm. We also learned how to upgrade a WordPress release to a new chart version, and how to rollback a release if something goes wrong throughout the upgrade process.

      As additional steps, you might consider setting up Nginx Ingress with Cert-Manager in order to enable name-based virtual hosting and to configure an SSL certificate for your WordPress site. You should also check the recommended production settings for the WordPress chart we used in this guide.

      If you want to learn more about Kubernetes and Helm, please check out the Kubernetes section of our community page.



      Source link