## lib/stuff.ex

``````
defmodule Stuff do
@moduledoc"""
Useful functions
"""

import Type.PTypeOf

@doc"""
Converts a number to a string, with the particularity that if the number is one digit, it adds the zero before it

### Parameter:

- n: Integer. Number to convert.

### Return:

- String.

"""
def integer_to_string_with_2_digits(n) when 1 <= n and n <= 9 do
"0" <> Integer.to_string(n)
end

def integer_to_string_with_2_digits(n) do
Integer.to_string(n)
end

@doc"""
Converts a time in seconds to the understandable format hh:mm:ss

###Parameter:

- time: Integer. Time in second.

### Return:

- String

"""
def convert_seconds_to_humans(time)
when is_integer(time) and time >= 0 do
hours = div(time, 3600)
minutes = time - hours * 3600 |> div(60)
seconds = time - hours * 3600 - minutes * 60

"#{hours}h #{minutes}m #{seconds}s"
end

@doc"""
Subtract between lists. It generalizes, and uses, the one implemented by Kernel.--/2.
The difference is for when a term to "subtract" is a map; in this case its values are obtained and it is transformed into lists of tuples, applying the subtraction to them.

### Parameters:

- l1: List of tuples of size 2. List of items.

- l2: List of tuples of size 2. List of elements used to compare in `l1`. Those tuples that are the same are removed from `l1`.

### Return:

- List of tuples of size 2

"""
def list_subtraction(l1, l2) do
l1 = Enum.sort(l1)
l2 = Enum.sort(l2)
recursive_list_subtraction(l1, l2, [])
end

defp recursive_list_subtraction([], _, acc) do
acc
end

defp recursive_list_subtraction(l1, [], acc) do
acc ++ l1
end

defp recursive_list_subtraction([{k, v} | r1], [{k, v} | r2], acc) do
recursive_list_subtraction(r1, r2, acc)
end

defp recursive_list_subtraction([{k, v1} | r1], [{k, v2} | r2], acc) do
v1 = case type_of(v1) do
:map -> Enum.sort(v1) |> Map.new()
:list -> Enum.sort(v1)
_ -> v1
end
v2 = case type_of(v2) do
:map -> Enum.sort(v2) |> Map.new()
:list -> Enum.sort(v2)
_ -> v2
end

if v2 == v1 do
recursive_list_subtraction(r1, r2, acc)
else
recursive_list_subtraction(r1, r2, acc ++ [{k, v1}])
end
end

defp recursive_list_subtraction([{k1, v1} | r], [{k2, _v} | _] = l, acc) when k1 < k2 do
recursive_list_subtraction(r, l, acc ++ [{k1, v1}])
end

defp recursive_list_subtraction(l, [{_k, _v} | r], acc) do
recursive_list_subtraction(l, r, acc)
end

@doc"""
Takes the first elements of the list

### Parameters:

- list: List. List.

- n: Integer. Number of elements to be taken consecutively, starting with the first.

### Return:

- {A, B} (A + B = list) where

A List the first `n` elements of `list`

B List of the remaining elements of `list`

"""
def get_firsts(list, n)
when is_list(list) and is_integer(n) and n >= 0 do
get_firsts(list, n, [], 0)
end

defp get_firsts([], _, acc, _) do
{acc, []}
end

defp get_firsts(list, n, acc, n) do
{acc, list}
end

defp get_firsts([elem | r], n, acc, count) do
get_firsts(r, n, acc ++ [elem], count + 1)
end

@doc"""
Generates a random string with the symbols '0123456789abcdefghijklmnopqrstuvwxyz'

### Parameter:

- len: Integer. Chain length.

### Return:

- String.

"""
def random_string_generate(len)
when is_integer(len) and len > 0 do
symbols = '0123456789abcdefghijklmnopqrstuvwxyz'
symbol_count = Enum.count(symbols)
for _ <- 1..len, into: "", do: <<Enum.at(symbols, :crypto.rand_uniform(0, symbol_count))>>
end

end
``````