PSF GSoC students blogs: GSoC Weekly Check-in

Hello everyone!

This is 7th week of GSoC 2019, just one week away from 2nd Evaluations. Here’s what I did this week.

What did I do this week?

This week was a bit relaxing. I didn’t do much except making changes in my old PR for improvement of Icons Picker API. Added some features like zipping folders, providing a separate route for download of files and improved file structure. There were a few changes my mentors told me to make in that PR so that the code matches all the other repos. Except that I started working on the current version of EOS-icons while the new version is still in development.

What is coming up next week?

In one or two days the code base for new version of EOS-icons will be ready which brings some major changes like moving to pug from HTML templates, using Gulp instead of Grunt and a lot more. Once that is done, I’ll make the icons-picker and connect it with API.

Did I get stuck anywhere?

Yes, I am still stuck on some error with heroku deployment. I tested it locally and the solution seems to work. Once my PR is merged I’ll try to make the changes in it.

Till next time,
Cheers!

Planet Python

Understanding Arrays in Go

Introduction

An array in Go is an ordered sequence of elements that has its capacity defined at creation time. Once an array has allocated its size, the size can no longer be changed. Because the size of an array is static, the data structure only needs to allocate memory once, as opposed to a variable length data structure that must dynamically allocate memory so that it can become larger or smaller in the future.

Although the fixed length of arrays can make them somewhat rigid to work with, the one-time memory allocation can increase the speed and performance of your program. Because of this, developers typically use arrays when optimizing programs. In Go, slices are the variable length version of arrays. Slices provide more flexibility and constitute what you would think of as arrays in other languages.

In this article, you will learn how to declare an array, how to call individual elements using indexing, how to slice the array into smaller sets, and the difference between an array and a slice in Go.

Defining an Array

Arrays are defined by declaring the size of the array in brackets [ ], followed by the data type of the elements. An array in Go must have all its elements be the same data type. After the data type, you can declare the individual values of the array elements in curly brackets { }.

The following is the general schema for declaring an array:

[capacity]data_type{element_values} 

Note: It is important to remember that every declaration of a new array creates a distinct type. So, although [2]int and [3]int both have integer elements, their differing capacities make their data types incompatible.

If you do not declare the values of the array’s elements, the default is zero-valued, which means that the array elements of the array will be empty. For integers, this is represented by 0, and for strings this is represented by an empty string.

For example, the following array numbers has three integer elements that do not yet have a value:

var numbers [3]int 

If you printed numbers, you would recieve the following output:

Output
[0 0 0]

If you would like to assign the values of the elements when you create the array, place the values in curly brackets. An array of strings with set values looks like this:

[4]string{"blue coral", "staghorn coral", "pillar coral", "elkhorn coral"} 

You can store an array in a variable and print it out:

coral := [4]string{"blue coral", "staghorn coral", "pillar coral", "elkhorn coral"} fmt.Println(coral) 

Running a program with the preceding lines would give you the following output:

Output
[blue coral staghorn coral pillar coral elkhorn coral]

Notice that there is no delineation between the elements in the array when it is printed, making it difficult to tell where one element ends and another begins. Because of this, it is sometimes helpful to use the fmt.Printf function instead, which can format strings before printing them to the screen. Provide the %q verb with this command to instruct the function to put quotation marks around the values:

fmt.Printf("%q\n", coral) 

This will result in the following:

Output
["blue coral" "staghorn coral" "pillar coral" "elkhorn coral"]

Now each item is quoted. The \n verb instructs to the formatter to add a line return at the end.

With a general idea of how to declare arrays and what they consist of, you can now move on to learning how to specify elements in an array with indexes.

Indexing Arrays

Each element in an array can be called individually through indexing. Each element corresponds to an index number, which is an int value starting from the index number 0 and counting up.

For the coral array from the earlier example, the index breakdown looks like this:

“blue coral” “staghorn coral” “pillar coral” “elkhorn coral”
0 1 2 3

The first element, the string 'blue coral', starts at index 0, and the list ends at index 3 with the item 'elkhorn coral'.

You can call a discrete element of the array by referring to its index number in brackets after the variable in which the array is stored:

fmt.Println(coral[2]) 

This will print the following:

Output
pillar coral

The index numbers for this array range from 03, so to call any of the elements individually and assign them a value, you could refer to the index numbers like this:

coral[0] = "blue coral" coral[1] = "staghorn coral" coral[2] = "pillar coral" coral[3] = "elkhorn coral" 

If you call the array coral with an index number greater than 3, it will be out of range, and Go will consider the action invalid:

fmt.Println(coral[22]) 
Output
invalid array index 22 (out of bounds for 4-element array)

When indexing an array, you must always use a positive number. Unlike some languages that let you index backwards with a negative number, doing that in Go will result in an error:

fmt.Println(coral[-1]) 
Output
invalid array index -1 (index must be non-negative)

Now that you know how to work with individual elements in an array, you can learn how to slice arrays to select a range of elements.

Slicing Arrays

By using index numbers to determine beginning and endpoints, you can call a subsection of the values within an array. This is called slicing the array. You can do this by creating a range of index numbers separated by a colon, in the form of [first_index:second_index].

Let’s say you would like to just print the middle items of coral, without the first and last element. You can do this by creating a slice starting at index 1 and ending just before index 3:

fmt.Println(coral[1:3]) 

Running a program with this line would yield the following:

Output
[staghorn coral pillar coral]

When creating a slice, as in [1:3], the first number is where the slice starts (inclusive), and the second number is the sum of the first number and the total number of elements you would like to retrieve:

array[starting_index : (starting_index + length_of_slice)] 

In this instance, you called the second element (or index 1) as the starting point, and called two elements in total. This is how the calculation would look:

array[1 : (1 + 2)] 

Which is how you arrived at this notation:

coral[1:3] 

If you want to set the beginning or end of the array as a starting or end point of the slice, you can omit one of the numbers in the array[first_index:second_index] syntax. For example, if you want to print the first three items of the array coral — which would be "blue coral", "staghorn coral", and "pillar coral" — you can do so by typing:

fmt.Println(coral[:3]) 

This will print:

Output
[blue coral staghorn coral pillar coral]

This printed the beginning of the array, stopping right before index 3.

To include all the items at the end of an array, you would reverse the syntax:

fmt.Println(coral[1:]) 

This would give the following:

Output
[staghorn coral pillar coral elkhorn coral]

This section discussed calling individual parts of an array by slicing out subsections. Next, you’ll learn a specific function that Go uses for arrays: len().

Array Functions

In Go, len() is a built-in function made to help you work with arrays. Like with strings, you can calculate the length of an array by using len() and passing in the array as a parameter.

For example, to find how many elements are in the coral array, you would use:

len(coral) 

If you print out the length for the array coral, you’ll receive the following output:

Output
4

This gives the length of the array 4 in the int data type, which is correct because the array coral has four items:

coral := [4]string{"blue coral", "staghorn coral", "pillar coral", "elkhorn coral"} 

If you create an array of integers with more elements, you could use the len() function on this as well:

numbers := [13]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} fmt.Println(len(numbers)) 

This would result in the following output:

Output
13

Although these example arrays have relatively few items, the len() function is especially useful when determining how many elements are in very large arrays.

Now that you know how to use len() to output the length of arrays, you can learn how arrays differ from another common data structure: slices.

How Arrays Differ from Slices

As mentioned before, the primary way in which arrays are different from slices is that the size of an array cannot be modified. This means that while you can change the values of elements in an array, you can’t make the array larger or smaller after it has been defined. A slice, on the other hand, can alter its length.

Let’s consider your coral array:

coral := [4]string{"blue coral", "staghorn coral", "pillar coral", "elkhorn coral"} 

Say you want to add the item "black coral" to this array. If you try to use the append() function with the array by typing:

coral = append(coral, "black coral") 

You will receive an error as your output:

Output
first argument to append must be slice; have [4]string

If you create an array and decide that you need it to have a variable length, you can convert it to a slice. To convert an array to a slice, use the slicing process you learned in the Slicing Arrays step of this tutorial, except this time select the entire slice by omitting both of the index numbers that would determine the endpoints:

coral[:] 

Keep in mind that you can’t convert the variable coral to a slice itself, since once a variable is defined in Go, its type can’t be changed. To work around this, you can copy the entire contents of the array into a new variable as a slice:

coralSlice := coral[:] 

If you printed coralSlice, you would receive the following output:

Output
[blue coral staghorn coral pillar coral elkhorn coral]

Now, try to use append() with the newly converted slice:

newSlice := append(coralSlice, "black coral") fmt.Printf("%q\n", newSlice) 

This will output the slice with the added element:

Output
["blue coral" "staghorn coral" "pillar coral" "elkhorn coral" "black coral"]

Conclusion

In this tutorial, you learned that the array data type is a sequenced data type with a fixed length, which makes it faster for Go to process at the cost of flexibility. Arrays also can help with communication on a team of developers: When others collaborate with you on your code, your use of arrays will convey to them that you don’t intend for their lengths to be changed.

With this data type in your tool box, you can now go more in-depth learning the variable length version of this structure: slices.

DigitalOcean Community Tutorials

How To Install Go on Debian 10

Introduction

Go, also known as golang, is a modern, open-source programming language developed by Google. Go tries to make software development safe, fast and approachable to help you build reliable and efficient software.

This tutorial will guide you through downloading and installing Go from source, as well as compiling and executing a “Hello, World!” program on a Debian 10 server.

Prerequisites

To complete this tutorial, you will need access to a Debian 10 server and a non-root user with sudo privileges, as described in Initial Server Setup with Debian 10.

Step 1 — Downloading Go

In this step, we’ll install Go on your server.

First, ensure your apt package index is up to date using the following command:

  • sudo apt update

Now install curl so you will be able to grab the latest Go release:

  • sudo apt install curl

Next, visit the official Go downloads page and find the URL for the current binary release’s tarball. Make sure you copy the link for the latest version that is compatible with a 64-bit architecture.

From your home directory, use curl to retrieve the tarball:

  • curl -O https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz

Although the tarball came from a genuine source, it is best practice to verify both the authenticity and integrity of items downloaded from the internet. This verification method certifies that the file was neither tampered with nor corrupted or damaged during the download process. The sha256sum command produces a unique 256-bit hash:

  • sha256sum go1.12.7.linux-amd64.tar.gz
Output
go1.12.7.linux-amd64.tar.gz 66d83bfb5a9ede000e33c6579a91a29e6b101829ad41fffb5c5bb6c900e109d9 go1.12.7.linux-amd64.tar.gz

Compare the hash in your output to the checksum value on the Go download page. If they match, then it is safe to conclude that the download is legitimate.

With Go downloaded and the integrity of the file validated, let’s proceed with the installation.

Step 2 — Installing Go

We’ll now use tar to extract the tarball. The following flags are used to instruct tar how to extract, view, and operate on the downloaded tarball:

  • The x flag tells it that we want to extract files from a tarball
  • The v flag indicates that we want verbose output, including a list of the files being extracted
  • The f flag tells tar that we’ll specify a filename to operate on

Now let’s put things all together and run the command to extract the package:

  • tar xvf go1.12.7.linux-amd64.tar.gz

You should now have a directory called go in your home directory. Recursively change the owner and group of this directory to root, and move it to /usr/local:

  • sudo chown -R root:root ./go
  • sudo mv go /usr/local

Note: Although /usr/local/go is the officially-recommended location, some users may prefer or require different paths.

At this point, using Go would require specifying the full path to its install location in the command line. To make interacting with Go more user-friendly, we will set a few paths.

Step 2 — Setting Go Paths

In this step, we’ll set some paths in your environment.

First, set Go’s root value, which tells Go where to look for its files:

  • nano ~/.profile

At the end of the file, add the following lines:

export GOPATH=$  HOME/work export PATH=$  PATH:/usr/local/go/bin:$  GOPATH/bin 

If you chose a different installation location for Go, then you should add the following lines to this file instead of the lines shown above. In this example, we are adding the lines that would be required if you installed Go in your home directory:

export GOROOT=$  HOME/go export GOPATH=$  HOME/work export PATH=$  PATH:$  GOROOT/bin:$  GOPATH/bin 

With the appropriate lines pasted into your profile, save and close the file.

Next, refresh your profile by running:

  • source ~/.profile

With the Go installation in place and the necessary environment paths set, let’s confirm that our setup works by composing a short program.

Step 3 — Testing Your Installation

Now that Go is installed and the paths are set for your server, you can ensure that Go is working as expected.

Create a new directory for your Go workspace, which is where Go will build its files:

  • mkdir $ HOME/work

Then, create a directory hierarchy in this folder so that you will be able to create your test file. We’ll use the directory my_project as an example:

  • mkdir -p work/src/my_project/hello

Next, you can create a traditional “Hello World” Go file:

  • nano ~/work/src/my_project/hello/hello.go

Inside your editor, add the following code to the file, which uses the main Go packages, imports the formatted IO content component, and sets a new function to print “Hello, World!” when run:

~/work/src/my_project/hello/hello.go
package main  import "fmt"  func main() {    fmt.Printf("Hello, World!\n") } 

When it runs, this program will print Hello, World!, indicating that Go programs are compiling correctly.

Save and close the file, then compile it by invoking the Go command install:

  • go install my_project/hello

With the program compiled, you can run it by executing the command:

  • hello

Go is successfully installed and functional if you see the following output:

Output
Hello, World!

You can determine where the compiled hello binary is installed by using the which command:

  • which hello
Output
/home/sammy/work/bin/hello

The “Hello, World!” program established that you have a Go development environment.

Conclusion

By downloading and installing the latest Go package and setting its paths, you now have a system to use for Go development. To learn more about working with Go, see our development series How To Code in Go. You can also consult the official documentation on How to Write Go Code.

DigitalOcean Community Tutorials

Moving to zsh, part 06 – Customizing the zsh Prompt

Apple has announced that in macOS 10.15 Catalina the default shell will be zsh.

I will be giving a half-day ‘Moving to zsh’ class at our offices in Amsterdam on September 6! Visit the website for details!

In this series, I will document my experiences moving bash settings, configurations, and scripts over to zsh.

As I have mentioned in the earlier posts, I am aware that there are many solutions out there that give you a pre-configured ‘shortcut’ into lots of zsh goodness. But I am interested in learning this the ‘hard way’ without shortcuts. Call me old-fashioned. (“Uphill! In the snow! Both ways!”)

The default bash prompt on macOS is quite elaborate. It shows the username, the hostname, and the current directory.

Calypso:~ armin$   

On the other hand, the default bash prompt doesn’t show the previous command’s exit code, a piece of information I find very useful. I have written before how I re-configured my bash prompt to have the information I want:

Of course, I wanted to recreate the same experience in zsh.

Minimal Zsh Prompt

The only difference to my bash prompt is the % instead of the $ .

Note: creating a file ~/.hushlogin will suppress the status message at the start of each Terminal session in zsh as well as in bash (or any other shell).

Basic Prompt Configuration

The basic zsh prompt configuration works similar to bash, even though it uses a different syntax. The different placeholders are described in detail in the zsh manual.

zsh uses the same shell variable PS1 to store the default prompt. However, the variable names PROMPT and prompt are synonyms for PS1 and you will see either of those three being used in various examples. I am going to use PROMPT.

The default prompt in zsh is %m%#. The %m shows the first element of the hostname, the %# shows a # when the current prompt has super-user privileges (e.g. after a sudo -s) and otherwise the % symbol (the default zsh prompt symbol).

The zsh default prompt is far shorter than the bash default, but even less useful. Since I work on the local system most of the time, the hostname bears no useful information, and repeating it every line is superfluous.

Note: you can argue that the hostname in the prompt is useful when you frequently have multiple terminal windows open to different hosts. This is true, but then the prompt is defined by the remote shell and its configuration files on the remote host. In your configuration file, you can test if the SSH_CLIENT variable is set and show a different prompt for remote sessions. There are more ways of showing the host in remote shell sessions, for example in the Terminal window title bar or with different window background colors.

In our first iteration, I want to show the current working directory instead of the hostname. When you look through the list of prompt placeholders in the zsh documentation, you find %d, %/, and %~. The first two do exactly the same. The last substitution will display a path that starts with the user’s home directory with the ~, so it will shorten /Users/armin/Projects/ to ~/Projects.

Note: in the end you want to set your PROMPT variable in the .zshrc file, so it will take effect in all your zsh sessions. For testing, however, you can just change the PROMPT variable in the interactive shell. This will give you immediate feedback, how your current setup works.

% PROMPT='%/ %# ' /Users/armin/Projects/dotfiles/zshfunctions %   % PROMPT='%~ %# ' ~/Projects/dotfiles/zshfunctions %  

Note the trailing space in the prompt string, to separate the final % or # from the command entry.

I prefer the shorter output of the %~ option, but it can still be quite long, depending on your working directory. zsh has a trick for this: when you insert a number n between the % and the ~, then only the last n elements of the path will be shown:

% PROMPT='%2~ %# ' dotfiles/zshfunctions %                        

When you do %1~ it will show only the name of the working directory or ~ if it is the home directory. (This also works with %/, e.g. %2/.)

Adding Color

Adding a bit of color or shades of gray to the prompt can make it more readable. In bash you need cryptic escape codes to switch the colors. zsh provides an easier way. To turn the directory in the path blue, you can use:

PROMPT='%F{blue}%1~%f %# ' 

The F stands for ‘Foreground color.’ zsh understands the colors black, red, green, yellow, blue, magenta, cyan and white. %F or %f resets to the default text color. Furthermore, Terminal.app represents itself as a 256-color terminal to the shell. You can verify this with

% echo $  TERM xterm-256color 

You can access the 256 color pallet with %F{0} through %F{255}. There are tables showing which number maps to which color:

So, since I want a dark gray for my current working dir in my prompt, I chose 240, I also set it to bold with the %B code:

PROMPT='%B%F{240}%1~%f%b %# ' 

You can find a detailed list of the codes for visual effects in the documentation.

Dynamic Prompt

I wrote an entire post on how to get bash to show the color-coded exit code of the last command. As it turns out, this is much easier in zsh.

One of the prompt codes provides a ‘ternary conditional,’ which means it will show one of two expressions, depending on a condition. There are several conditions you can use. Once again the details can be found in the documentation.

There is one condition for the previous commands exit code:

%(?.<success expression>.<failure expression>) 

This expression will use the <success expression> when the previous command exited successfully (exit code zero) and <failure expression> when the previous command failed (non-zero exit code). So it is quite easy to build an conditional prompt:

% PROMPT='%(?.√.?%?) %1~ %# '  √ ~ % false ?1 ~ %  

You can get the character with option-V on the US or international macOS keyboard layout. The last part of the ternary ?%? looks confusing. The first ? will print a literal question mark, and the second part %? will be replaced with previous command’s exit code.

You can add colors in the ternary expression as well:

PROMPT='%(?.%F{green}√.%F{red}?%?)%f %B%F{240}%1~%f%b %# '  

Another interesting conditional code is ! which returns whether the shell is privileged (i.e. running as root) or not. This allows us to change the default prompt symbol from % to something else, while maintaining the warning functionality when running as root:

% PROMPT='%1~ %(!.#.>) '  ~ > sudo -s ~ # exit ~ >  

Complete Prompt

Here is the complete prompt we assembled, with all the parts explained:

PROMPT='%(?.%F{green}√.%F{red}?%?)%f %B%F{240}%1~%f%b %# ' 
%(?.√.?%?) if return code ? is 0, show , else show ?%?
%? exit code of previous command
%1~ current working dir, shortening home to ~, show only last 1 element
%# # with root privileges, % otherwise
%B %b start/stop bold
%F{...} text (foreground) color, see table
%f reset to default textcolor

Right Sided Prompt

zsh also offers a right sided prompt. It uses the same placeholders as the ‘normal’ prompt. Use the RPROMPT variable to set the right side prompt:

% RPROMPT='%*' √ zshfunctions %                    11:02:55 

zsh will automatically hide the right prompt when the cursor reaches it when typing a long command. You can use all the other substitutions from the left side prompt, including colors and other visual markers in the right side prompt.

Git Integration

zsh includes some basic integration for version control systems. Once again there is a voluminous, but hard to understand description of it in the documentation.

I found a better, more specific example in the ‘Pro git’ documentation. This example will show the current branch on the right side prompt.

I have changed the example to include the repo name and the branch, and to change the color.

autoload -Uz vcs_info precmd_vcs_info() { vcs_info } precmd_functions+=( precmd_vcs_info ) setopt prompt_subst RPROMPT=$  vcs_info_msg_0_ zstyle ':vcs_info:git:*' formats '%F{240}(%b)%r%f' zstyle ':vcs_info:*' enable git 

In this case %b and %r are placeholders for the VCS (version control system) system for the branch and the repository name.

There are git prompt solutions other than the built-in module, which deliver more information. There is a script in the git repository, and many of the larger zsh theme projects, such as ‘oh-my-zsh’ and ‘prezto’ have all kinds of git status widgets or modules or themes or what ever they call them.

Summary

You can spend (or waste) a lot of time on fine-tuning your prompt. Whether these modifications really improve your productivity is a matter of opinion.

In the next post, we will cover some miscellaneous odds and ends that haven’t yet really fit into any of preceding posts.

Scripting OS X