#!/usr/bin/env bash

read_stdin() {
    # Desc: Consumes stdin; outputs as stdout lines
    # Input: stdin (consumes)
    # Output: stdout (newline delimited)
    # Example: printf "foo\nbar\n" | read_stdin
    # Depends: GNU bash (version 5.1.16)
    # Version: 0.0.1
    local input_stdin output;

    # Store stdin
    if [[ -p /dev/stdin ]]; then
        input_stdin="$(cat -)";
    fi; 
    
    # Store as output array elements
    ## Read in stdin
    if [[ -n $input_stdin ]]; then
        while read -r line; do
            output+=("$line");
        done < <(printf "%s\n" "$input_stdin");
    fi;

    # Print to stdout
    printf "%s\n" "${output[@]}";
}; # read stdin to stdout lines
get_median() {
    # Desc: Gets the median from integers or floats read from stdin
    # Input:  stdin   newline-delimited integers or floats
    # Output: stdout  float
    # Depends: GNU Coreutils 8.32 (sort), bc 1.07.1
    # Depends: BK-2020-03: read_stdin() 0.0.1,
    # Version: 0.0.1

    # Read stdin
    list="$(read_stdin)";

    # Sort list
    list="$(printf "%s\n" "$list" | sort -n)";

    # Get list length
    list_lc="$(printf "%s\n" "$list" | wc -l)";

    # Get number of lines to trim from start and end
    if [[ $((list_lc % 2)) -eq 0 ]]; then
        # If even
        trim=$(( list_lc / 2 - 1 ));
        flag_even="true";
    else
        # If odd
        trim=$(( list_lc / 2 ));
    fi;

    # Trim lines
    list="$(printf "%s\n" "$list" | tail -n+$((trim+1)) | head -n-$((trim)) )";

    # Get median
    if [[ "$flag_even" == "true" ]]; then
        ## Average remaining two lines
        l1="$(printf "%s\n" "$list" | head -n1)";
        l2="$(printf "%s\n" "$list" | tail -n1)";
        median="$( echo "( $l1 + $l2 ) / 2" | bc -l; )";
    else
        ## Median is simply remmaining line
        median="$list";
    fi;

    # Output median
    printf "%s" "$median";
    
    # Author: Steven Baltakatei Sandoval
    # License: GPLv3+
}; # Returns median float from a list

# Test
shuf -i1-100 -n49 | get_median; printf "\n";
printf "17\n5\n11.1111\n3.141592\n2\n343.4343434343434343\n" | get_median; printf "\n";