alexsib

Since
20 Snippets
  • Simple TCP client in Go

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"net"
    	"time"
    )
    
    type Client struct {
    	conn net.Conn
    }
    
    func (c *Client) Write(content string) error {
    	_, err := c.conn.Write([]byte(content + "\n"))
    
    	return err
    }
    
    func (c *Client) Read() (string, error) {
    	reader := bufio.NewReader(c.conn)
    
    	return reader.ReadString('\n')
    }
    
    func (c *Client) Close() error {
    	return c.conn.Close()
    }
    
    // create tcp client
    func getClient(address string) (*Client, error) {
    	// try to resolve address
    	_, err := net.ResolveTCPAddr("tcp", address)
    
    	if err != nil {
    		return nil, err
    	}
    
    	// create tcp connection with 5s timeout 
    	conn, err := net.DialTimeout("tcp", address, 5*time.Second)
    
    	if err != nil {
    		return nil, err
    	}
    
    	conn.SetReadDeadline(time.Now().Add(5 * time.Second))
    	conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
    
    	return &Client{conn: conn}, nil
    }
    
    func main() {
    	// see https://tcpbin.com/
    	client, err := getClient("tcpbin.com:4242")
    
    	if err != nil {
    		panic(err)
    	}
    
    	// close the connection at the end
    	defer client.Close()
    
    	// send request to tcpbin.com echo server
    	err = client.Write("Hello, World!!!")
    
    	if err != nil {
    		panic(err)
    	}
    
    	// read response from tcpbin.com echo server
    	content, err := client.Read()
    
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Print(content)
    }
    
    // $ go run main.go 
    // Hello, World!!!

    This example should give a basic understanding of how to create a TCP client in Go.

  • Parsing YAML Files in Go Without a Struct Definition

    package main
    
    import (
     "fmt"
     "os"
    
     "gopkg.in/yaml.v3"
    )
    
    func main() {
        dataMap := make(map[string]interface{})
        yamlFile, err := os.ReadFile("example.yaml")
     
        if err != nil {
            panic(err)
        }
    
        err = yaml.Unmarshal(yamlFile, dataMap)
        
        if err != nil {
            panic(err)
        }
        
        fmt.Println(dataMap)
    }

    If you want to parse a YAML file into a Go map but are having trouble defining the appropriate struct, there are a couple of alternatives you can use. In Go, you can read a YAML file without needing to define a struct by using the `map[string]interface{}` type. This method lets you load the YAML content into a nested map structure, bypassing the need for a specific struct definition.

  • Pretty Printing Structs in Go

    package main
    
    import (
        "fmt"
        "encoding/json"
    )
    
    type User struct {
        FirstName string `json:"firstname"`
        SecondName string `json:"secondname"`
        Salary int `json:"salary"`
    }
    
    func main() {
        user := User{
            FirstName: "John",
            SecondName: "Doe",
            Salary: 5000,
        }
    
        b, err := json.MarshalIndent(user, "", "  ")
        
        if err != nil {
            fmt.Println(err)
        }
        
        fmt.Print(string(b))
    }

    We can utilize the `json.MarshalIndent` function, which requires the interface we want to marshal, along with a prefix string and an indent string. In this case, we won't use a prefix, but we will set the indent to two empty spaces.

  • Decompress tag.gz file in Go

    package main
    
    import (
    	"archive/tar"
    	"compress/gzip"
    	"fmt"
    	"io"
    	"os"
    	"path/filepath"
    
    	"github.com/unknwon/com"
    )
    
    func ExtractTarGz(file, folder string) error {
    	// open specified file
    	gzipStream, err := os.Open(file)
    
    	if err != nil {
    		return err
    	}
    
    	// create uncompressed stream reader
    	uncompressedStream, err := gzip.NewReader(gzipStream)
    
    	if err != nil {
    		return fmt.Errorf("could not create new targz reader: %v", err)
    	}
    
    	// create tar reader
    	tarReader := tar.NewReader(uncompressedStream)
    
    	for {
    		// read archive header
    		header, err := tarReader.Next()
    
    		if err == io.EOF {
    			break
    		}
    
    		if err != nil {
    			return fmt.Errorf("could not read next entry: %v", err)
    		}
    
    		destPath := filepath.Join(folder, header.Name)
    
    		switch header.Typeflag {
    		case tar.TypeDir:
    			// if a directory already exists skip its creation
    			if com.IsDir(destPath) {
    				continue
    			}
    
    			if err := os.Mkdir(destPath, 0755); err != nil {
    				return fmt.Errorf("could not create directory '%s': %v", destPath, err)
    			}
    		case tar.TypeReg:
    			// if a file already exists skip its creation
    			if com.IsFile(destPath) {
    				continue
    			}
    
    			outFile, err := os.Create(destPath)
    
    			if err != nil {
    				return fmt.Errorf("could not create file '%s': %v", destPath, err)
    			}
    
    			if _, err := io.Copy(outFile, tarReader); err != nil {
    				return fmt.Errorf("could not copy entry '%s': %v", destPath, err)
    			}
    
    			outFile.Close()
    		default:
    			return fmt.Errorf("uknown type: %s in %s", string(header.Typeflag), destPath)
    		}
    	}
    
    	return nil
    }
    
    func main() {
        err := ExtractTarGz("example.tar.gz", "/tmp")
    
        if err != nil {
            panic(err)
        }
    }

    An example of unpacking a tar.gz archive into the specified directory in Go.

  • Filename without extension in Go

    package main
    
    import (
        "fmt"
        "path/filepath"
        "strings"
    )
    
    func main() {
        filePath := "/tmp/file.ext"
    
        // get file name with extension
        fileName := filepath.Base(filePath)
    
        // get file extension
        fileExt := filepath.Ext(filePath)
    
        // truncate file name extension
        fileNameWithoutExt := strings.TrimSuffix(fileName, fileExt)
    
        fmt.Println("File name without extension: " + fileNameWithoutExt)
    }
    
    // $ go run main.go
    // File name without extension: file

    Here is an example of how to get filename without extension in go.

  • Environment variables in Go

    package main
    
    import (
    	"fmt"
    	"os"
    	"strings"
    )
    
    func main() {
    	os.Setenv("FOO", "1")
    	fmt.Println("FOO:", os.Getenv("FOO"))
    	fmt.Println("BAR:", os.Getenv("BAR"))
    
    	fmt.Println("----------------------")
    
    	for _, env := range os.Environ() {
    		pair := strings.SplitN(env, "=", 2)
    		fmt.Println(pair[0])
    	}
    }
    
    // FOO: 1
    // BAR: 
    // ----------------------
    // HOSTNAME
    // PWD
    // HOME
    // LANG
    // SHLVL
    // PATH
    // _
    // FOO

    Here's an example how you can manage environment variables. To assign a value to a key, utilize os.Setenv. Retrieve a value by key using os.Getenv, which will yield an empty string if the key isn't found. Use os.Environ to list all key/value pairs, returned as a string slice formatted as KEY=value. You can split these strings using strings.SplitN to separate keys and values.

  • Removing all files from a folder using PHP

    <?php 
    
    $folderPath = "/tmp/test-folder"; 
    
    // List of files inside the folder 
    $files = glob($folderPath.'/*'); 
     
    foreach($files as $file) { 
    	if(is_file($file)) 
    		// Delete the given file 
    		unlink($file); 
    } 
    
    echo "Files deleted";
    
    // php main.php
    // Files deleted

    PHP program to delete all files from a specified folder.

  • Example of recursion in golang

    package main
    
    import "fmt"
    
    func factorial(n int) int {
    	if n == 0 {
    		return 1
    	}
    
    	return n * factorial(n-1)
    }
    
    func main() {
    	fmt.Println(factorial(5))
    }
    
    // $ go run main.go 
    // 120

    Recursion in Go using the example of factorial calculation.

  • Example of closures in Golang

    package main
    
    import "fmt"
    
    // The function createCounter returns anonymous function defined within its body.
    // The returned function encapsulates the variable count, creating a closure.
    func createCounter() func() int {
    	count := 0
    
    	return func() int {
    		count++
    
    		return count
    	}
    }
    
    func main() {
        // We invoke createCounter, storing the result (a function) in counter variable.
        // This function captures and retains its own count value,
        // which updates with each subsequent invocation of createCounter.
    	counter := createCounter()
    
    	fmt.Println(counter())
    	fmt.Println(counter())
    	fmt.Println(counter())
    
    	newCounter := createCounter()
    	
        fmt.Println(newCounter())
    }
    
    // $ go run main.go 
    // 1
    // 2
    // 3
    // 1

    A simple example of using closures in Go.

  • Panic recovery in Go

    package main
    
    import "fmt"
    
    func main() {
        // Recover function must be called inside a deferred function.
        // When the enclosing function panics, defer is activated and the restore call inside it catches the panic.
        defer func() {
            if r := recover(); r != nil {
                fmt.Printf("recovered: %s\n", r)
            }
        }()
    
        panic("some fatal error")
        
        // This code won't run because of panic.
        // Basic operations stop during a panic and resume during a deferred close.
        fmt.Println("after panic")
    }

    Go allows you to recover from a panic with a built-in recover function. Recovery can prevent a panic from causing the program to abort and instead allow it to continue executing.

  • Example of using mutexes in Go

    package main
    
    import (
    	"fmt"
    	"sync"
    )
    
    // without using mutex the following error can happen: "fatal error: concurrent map writes" while changing the map in multiple goroutines
    type Storage struct {
    	sync.Mutex
    	storage map[string]int // map is not threade-safe
    }
    
    func (s *Storage) Increment(name string) {
    	s.Lock() // lock the mutex before accessing counters
    	defer s.Unlock() // unlock the mutex at the end of the function using a defer statement
        s.storage[name]++
    }
    
    func (s *Storage) Decrement(name string) {
    	s.Lock()
        defer s.Unlock()
    	s.storage[name]--
    }
    
    func main() {
    	s := &Storage{
    		storage: make(map[string]int),
    	}
    
    	wg := sync.WaitGroup{}
    	wg.Add(5)
    
        // increment a named counter in a loop
    	increment := func(name string, count uint) {
    		for i := 0; i < int(count); i++ {
    			s.Increment(name)
    		}
    
    		wg.Done()
    	}
    
        // decrement a named counter in a loop
    	decrement := func(name string, count uint) {
    		for i := 0; i < int(count); i++ {
    			s.Decrement(name)
    		}
    
    		wg.Done()
    	}
    
        // run 5 goroutines concurrently
    	go increment("a", 1000)
    	go decrement("a", 500)
    
    	go increment("b", 1000)
    	go increment("b", 1000)
    	go decrement("b", 1500)
    
    	wg.Wait() // wait for the goroutines to finish
    
    	fmt.Println(s.storage)
    }
    
    // $ go run main.go  
    // map[a:500 b:500]
    
    // without mutex the following error can happen
    // $ go run main.go
    // fatal error: concurrent map writes

    Mutexes can be used to safely access data across multiple goroutines.This example shows how to use mutexes in Go to change a map concurrently and safely.

  • Handle OS signals in Go

    package main
    
    import (
        "fmt"
        "os"
        "os/signal"
        "syscall"
    )
    
    func main() {
        sigs := make(chan os.Signal, 1) // create channel for signal, it should be buffered
        signal.Notify(sigs, syscall.SIGINT) // register the channel to receive notifications of the specified signals
        done := make(chan bool, 1)
    
        go func() {
            sig := <-sigs // wait for OS signal, once received, notify main go routine
            fmt.Printf("\nos signal: %v\n", sig)
            done <- true
        }()
    
        fmt.Println("awaiting signal")
        <-done // wait for the expected signal and then exit
        fmt.Println("exiting")
    }
    
    // $ go run main.go 
    // awaiting os signal
    // ^C
    // os signal: interrupt
    // exiting program

    Here is an example go program for processing Unix signals using channels. Signal processing can be useful, for example, for correct terminating of program when receiving SIGTINT.

  • Binary search algorithm in PHP

    <?php 
      
    function binarySearch(array $arr, int $target): int 
    { 
        $low = 0; 
        $high = count($arr) - 1; 
          
        while ($low <= $high) {          
            // compute middle index 
            $mid = floor(($low + $high) / 2);  
      
            if ($arr[$mid] > $target) { 
                // search the left side of the array 
                $high = $mid -1; 
            } else if ($arr[$mid] < $target) { 
                // search the right side of the array 
                $low = $mid + 1; 
            } else {
                // element found at mid 
                return $mid; 
            }
        } 
          
        // If we reach here element x doesnt exist 
        return -1; 
    } 
      
    // Driver code 
    $arr = [1, 2, 3, 4, 5]; 
    $target = 3;
    $result = binarySearch($arr, $target);
    
    if($result !== -1) { 
        echo "Target '$target' exists at position $result"; 
    } else {
        echo "Target '$target' does not exist";
    }

    Double search is a search method used to find an element in a sorted array.

  • Binary search algorithm in Python

    # Returns index of target in arr if present, else -1
    def binary_search(arr, target):
    	low = 0
    	high = len(arr) - 1
    
    	while low <= high:
    		# Check base case
    		mid = (high + low) // 2
    
    		# If element is smaller than mid, then it can only
    		# be present in left subarray
    		if arr[mid] > target:
    			high = mid - 1
    		# Else the element can only be present in right subarray
    		elif arr[mid] < target:
    			low = mid + 1
    		# If element is present at the middle itself
    		else:
    			return mid
    
    	# Element is not present in the array
    	return -1
    
    # Test array
    arr = [ 2, 3, 4, 10, 40 ]
    target = 10
    
    result = binary_search(arr, target)
    
    if result != -1:
    	print("Element is present at index", str(result))
    else:
    	print("Element is not present in array")

    Binary Search is a searching algorithm for finding an element's position in a sorted array. In this approach, the element is always searched in the middle of a portion of an array.

  • Binary search algorithm in Go

    package main
    
    import "fmt"
    
    // return target index if it exists in arr
    func search(arr []int, target int) int {
        low := 0
        high := len(arr) - 1
    
        for low <= high {
            mid := (low + high) / 2
    
            if arr[mid] < target {
                low = mid + 1
            } else if arr[mid] > target {
                high = mid - 1
            } else {
                return mid
            }
        }
    
        return -1
    }
    
    func main() {
        target := 7
        items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        fmt.Printf("Element '%d' index is %d", target, search(items, target))
    }
    
    // $ output
    // 6

    The binary search algorithm employs a divide-and-conquer approach to locate an item within a sorted array or list. It begins by comparing the target value to the middle element of the array. If they are not identical, the algorithm eliminates the half of the array where the target cannot reside and proceeds the search on the remaining half. This process iterates, with each step narrowing down the search range until the target value is discovered. If the search concludes with an empty remaining half, it indicates that the target is not present in the array.

  • Example of WaitGroup in Go

    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    func main() {
    	wg := &sync.WaitGroup{} // WaitGroup is used to wait for the execution of all running goroutines
    
    	for i := 1; i <= 5; i++ {
    		wg.Add(1) // launch several goroutines and increment the counter in WaitGroup for each running goroutine
    
    		go func(id int) {
    			worker(id, wg)
    		}(i)
    	}
    
    	fmt.Println("waiting for all goroutines to complete")
    	wg.Wait() // block the execution of the program until the WaitGroup counter becomes equal to 0 again
    	fmt.Println("done")
    }
    
    func worker(id int, wg *sync.WaitGroup) {
    	fmt.Printf("worker %d started\n", id)
    	time.Sleep(time.Second) // Sleep simulates a long task
    	
        fmt.Printf("worker %d finished\n", id)
    	wg.Done() // notify WaitGroup that the worker has completed
    }
    
    // $ go run waitgroups.go 
    // waiting for all goroutines finished
    // worker 4 started
    // worker 1 started
    // worker 2 started
    // worker 3 started
    // worker 2 finished
    // worker 4 finished
    // worker 1 finished
    // worker 3 finished
    // done

    To wait for multiple goroutines to execute, you can use the built-in WaitGroup construct.

  • Simple http server in Go

    package main
    
    import (
        "fmt"
        "net/http"
    )
    
    func hello(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "Hello, World!\n")
    }
    
    func headers(w http.ResponseWriter, req *http.Request) {
        for name, headers := range req.Header {
            for _, h := range headers {
                fmt.Fprintf(w, "%v: %v\n", name, h)
            }
        }
    }
    
    func main() {
        http.HandleFunc("/hello", hello)
        http.HandleFunc("/headers", headers)
    
        http.ListenAndServe(":8080", nil) // run http server on port 8080
    }
    

    Basic HTTP server using the net/http package. In the realm of net/http servers, a crucial concept involves handlers. These handlers implement http.Handler interface. A common method for creating a handler is to use http.HandlerFunc, applied to functions that have the required signature. Handlers receive a http.ResponseWriter and a http.Request as parameters. The response writer is employed to populate the HTTP response. Handlers can be registered on server routes by the http.HandleFunc function. This function configures the default router in the net/http package and accepts a function as its parameter. To start the http server, ListenAndServe is called with the specified port and handler. Passing nil as a second paramenter indicates using the default router we recently configured.

  • Implementation of the Quick Sort algorithm in Python

    def quick_sort(arr):
        if len(arr) <= 1:
            return arr
        else:
            pivot = arr[0]
            left = [x for x in arr[1:] if x <= pivot]
            right = [x for x in arr[1:] if x > pivot]
            return quick_sort(left) + [pivot] + quick_sort(right)
    
    # Example usage:
    input_array = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
    sorted_array = quick_sort(input_array)
    
    print("Original Array:", input_array)
    print("Sorted Array:", sorted_array)
    

    In this code, the quick_sort function is a recursive implementation of the Quick Sort algorithm. The pivot element is chosen as the first element of the array, and elements are partitioned into two sub-arrays (left and right) based on their relationship to the pivot. The function is then called recursively on the left and right sub-arrays until the entire array is sorted.

  • Simple implementation of the Quick Sort algorithm in PHP

    <?php
    
    function quickSort(array $array): array
    {
        $length = count($array);
    
        if ($length <= 1) {
            return $array;
        }
    
        $pivot = $array[0];
        $left = $right = [];
    
        for ($i = 1; $i < $length; $i++) {
            if ($array[$i] < $pivot) {
                $left[] = $array[$i];
            } else {
                $right[] = $array[$i];
            }
        }
    
        return array_merge(quickSort($left), [$pivot], quickSort($right));
    }
    
    // Example usage:
    $array = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
    $sortedArray = quickSort($array);
    
    echo "Original Array: " . implode(", ", $array) . "\n";
    echo "Sorted Array: " . implode(", ", $sortedArray) . "\n";
    
    

    Here's a simple implementation of the Quick Sort algorithm in PHP

  • CSV file handling in Python

    import csv
    
    # Writing to a CSV file
    with open('data.csv', 'w', newline='') as csvfile:
        fieldnames = ['name', 'age', 'city']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
        writer.writeheader()
        writer.writerow({'name': 'John', 'age': 30, 'city': 'New York'})
        writer.writerow({'name': 'Alice', 'age': 25, 'city': 'London'})
    
    # Reading from a CSV file
    with open('data.csv', newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            print(row)

    Examples of code for writing to a csv file and reading from a csv file.