New Russian Chronicles
Surviving monotaxocausofilia

May
16

Recently I was working on a python script to backfill a database. The database contains information about a satellite (position, comm signal strength, etc.) and I butted my head against an insidious problem. Hopefully this post saves you a headache!

For context: I am working with a satellite and its database of transmissions. Now, when you want to know the position of a satellite you need two things. First it’s a piece of open-source software called predict. Super cool piece of software, lemme tell you. Second, a Two Line Element or TLE. The TLE gives you updated orbital information about the satellite, easily found here.

Also: I am using anaconda environment. This is important because I do not have this problem if I use python without an environment! :-/ yeah

But, because I am backfilling old data that should be in the database but isn’t, I am using historical TLEs, which the celestrak website very kindly provides. I have those historical TLEs saved in mysql and my script goes over old data, takes a TLE from one table, runs it through predict and updates de appropiate table with the results obtained. Pretty simple, huh?

The problem came with creating a TLE out of a mysql entry. Predict only takes the TLE in txt form, and here is where I encountered a problem.

My script would create a TLE.txt from the table, and try to obtain data from predict. Invariably, predict would return nothing. It does that when you give it, as TLE, a file that is not a TLE.

After experimentation, I discovered two things. The first one was that predict would work just fine with a freshly downloaded TLE from the website. The second, and here is where it gets crazy, was that, if I opened the «wrong» TLE, placed the cursor at the end and pressed «delete» once… the TLE would suddenly be fine and predict would take it.

Mind you, the character count would not change, the text on the screen would not change, the formatting marks in libreoffice would show NOTHING different. IT.DROVE.ME.CRAZY.

So after trying libreoffice, wordcount and many more things, an idea came to me, an idea that could have come straight from my toddler’s mouth: «CAT!»

Although, of course, I meant the linux core util, cat. Yeah, that one that you use to show text on the screen. «Wait, it can do what?» I hear you say. Hold on to your britches.

cat -A bulgariasat1.tle bulgariasat2.tle

The -A argument means «show all» or, as the –help usefully explains, it combines the -vET arguments, in order «show non-printing characters», «show ends» and «show tabs». My objective was to try and see what I was missing, since the word count tool wasn’t helping.

Bulgariasat1.tle is the freshly downloaded one and bulgariasat2.tle is the one that my script produces

Here are the results:

BULGARIASAT-1           ^M$
1 42801U 17038A   22208.61445425  .00000013  00000+0  00000+0 0  9991^M$
2 42801   0.0223  65.5143 0002731  58.7874  44.0702  1.00273279 18580^M$
BULGARIASAT-1           $
1 42801U 17038A   22208.61445425  .00000013  00000+0  00000+0 0  9991$
2 42801   0.0223  65.5143 0002731  58.7874  44.0702  1.00273279 18580$

OK! So what is going on here?

There is something in the fresh TLE that is absent in mine. The answer is, it’s a carriage return.
Without going into boring specifics, the non-printing sign for a new line in windows is «\r\n» , that is, carriage return and new line, and for linux it’s just «\n». The carriage return is represented here as ^M. Everything worked fine when I added \r to \n.

Here is a list of the non-printing characters if you want to take a trip down old computers’ lane.

It’s not the first time I find a similar problem, the same thing caused me quite a headache when I was writing a piece of software to parse European Patent Office’s patent summary files.

I hope that is useful!

May
02

In case you don’t know, I like to program. This program is something a wrote for my bachelor thesis in electrical engineering.

It helps you obtain statistical information from European Patent Office patent summaries. It’s useful in case you are doing technology analysis and want to understand what patents exist of a specific product. It counts, for instance, the appeareance of specific authors, or patent names. It can parse full names or individual words between names.

I hope it’s useful for you, as niche as it is. To run it you need linux and bash and, since wordpress doesn’t let me upload any documents, here’s the code. You need to paste it in a file, make it executable and run it.

It will take any EPO CSV files.

Here’s the Usage, as expressed by running the –help argument

Usage: EPOParser -aCdeiIptu (minimum disaggregation) ||  -axCxdyeyixIxpytxu (maximum disaggregation)

Text options:

	-t	Count the times specific title appears.
	-i	      Count the times each inventor or group of inventors appears.
	-a	      Count the times an applicant or group of applicants appears.
	-I	      Count the times a specific grouping of IPC numbers appears.
	-C	      Count the times a specific grouping of CPC numbers appears.

	The dissagregation modifier "x" after each of the above options tries to split the entries. -Ix, for instance, it will count the number of times each IPC number appears, instead of the groupings of IPC numbers in a specific patent. -tx it will count individual words in titles, and not the appeareance of each full title.

	Exceptions:

	The "x" option does not work with the -a option, and is unreliable with the -i options. The reason is that there is no consistent pattern to dissagreggate inventor and applicant names.

	Date options:

	-d	Count how many patents were published each month of each year.
	-p	Count the priority dates.
	-e	Count the earliest publication dates.
	The modifier "y" after a date option eliminates the month and counts patents per year.
	Exceptions: Some fields of priority or earliest publication dates contain more than one date, which may muddy the results.

	Special options:

	-u	Provides a copy of the original, DOS-formatted Espacenet files that is UNIX-formatted, for easier CSV parsing.
	--help	Displays this help text and exits.
	--version	Displays version information and exits.

Here is the license: Click here

And because I can’t upload a document, here’s the raw source code. I apologize for my mistakes.

#!/bin/bash

: '
EPOParser -  a script that extracts statistical information from Espacenet CSV files.

    Copyright (C) 2021  Pablo Cañamares

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
'


function version
{
printf "\nEPO Parser 1.0.1\nA script to parse statistical information from Espacenet files."
printf "\nEPOParser.sh  Copyright (C) 2021  Pablo Cañamares"
printf "\n\nThis program comes with ABSOLUTELY NO WARRANTY"
printf "\n\nSoftware under GNU GPL v3.0 License."
printf "\nThis is free software, and you are welcome to redistribute it under certain conditions;\nFor details please consult <https://www.gnu.org/licenses/>\n\n"
}


# XXXX
# Constants
# XXXX
# Because this is for the use of the CUT built-in, the first element isn't 0, it's 1.
#
# This is the order of the fields, taken from Espacenet CSV files
#"No";"Title";"Inventors";"applicant";"Publication number";"Earliest priority";"IPC";"CPC";"Publication date";"Earliest publication";"Family number";
declare -ir TITLENUM=2
declare -ir INVENTORNUM=3
declare -ir APPLICANTNUM=4
declare -ir PRIORITYNUM=6
declare -ir IPCNUM=7
declare -ir CPCNUM=8
declare -ir PUBLIDATENUM=9
declare -ir EARLYPUBNUM=10


# XXXX
# Usage function
# XXXX

function usage
{

bold=$(tput bold)
normal=$(tput sgr0)

printf "\nEPOParser will extract information from all of the Espacenet CSV files that are present in the same directory."
printf "\n${bold}Usage:${normal} EPOParser -aCdeiIptu (minimum disaggregation) ||  -axCxdyeyixIxpytxu (maximum disaggregation)"
printf "\n\n${bold}Text options:${normal}"
printf "\n\n\t-t\tCount the times specific title appears."
printf "\n\t-i\t      Count the times each inventor or group of inventors appears."
printf "\n\t-a\t      Count the times an applicant or group of applicants appears."
printf "\n\t-I\t      Count the times a specific grouping of IPC numbers appears."
printf "\n\t-C\t      Count the times a specific grouping of CPC numbers appears."
printf "\n\n\tThe dissagregation modifier \"x\" after each of the above options tries to split the entries. -Ix, for instance, it will count the number of times each IPC number appears, instead of the groupings of IPC numbers in a specific patent. -tx it will count individual words in titles, and not the appeareance of each full title."
printf "\n\n\t${bold}Exceptions: ${normal}"
printf "\n\n\tThe \"x\" option does not work with the -a option, and is unreliable with the -i options. The reason is that there is no consistent pattern to dissagreggate inventor and applicant names."
printf "\n\n\t${bold}Date options:${normal}"
printf "\n\n\t-d\tCount how many patents were published each month of each year."
printf "\n\t-p\tCount the priority dates."
printf "\n\t-e\tCount the earliest publication dates."
printf "\n\tThe modifier \"y\" after a date option eliminates the month and counts patents per year."
printf "\n\t${bold}Exceptions:${normal} Some fields of priority or earliest publication dates contain more than one date, which may muddy the results."
printf "\n\n\t${bold}Special options:${normal}"
printf "\n\n\t-u\tProvides a copy of the original, DOS-formatted Espacenet files that is UNIX-formatted, for easier CSV parsing."
printf "\n\t--help\tDisplays this help text and exits."
printf "\n\t--version\tDisplays version information and exits."
printf "\n"

}


# Function to make error messages more legible in the code
function echoerr { printf "$@\n" 1>&2; }

#Function to check whether there are Espacenet files to process, and places them in a temporary file for easier access later.
function initFileCount
{

    for fileName in *.csv
    do
            if [[ $(head -n 1  "$fileName" | grep '"Espacenet";"";"";"";"";"";"";"";"";') ]] # All Espacenet files start like this, it's
                                                                                             # so they are easy to filter in and count correctly
            then
                echo "$fileName" >> EPOfileList.temp

            fi
    done

    # This check succeeds if EPOfileList.temp is empty at this point. Note the inversion.
    if [[ ! -s EPOfileList.temp ]]
    then
            rm EPOfileList.temp
    	    echoerr "\n\nNo Espacenet CSV files present."
	        exit 127
    fi
}

# Function to transform the EPO files into a format that's easier to parse as a CSV
function win2unix # Don't call it dos2unix, that's a linux utility that already exists.
{
    while read fileName
    do

        outPutName="${fileName%.csv}_unix.csv" # This adds "_unix.csv" at the end of the filename

        perl -pe 's/\r\n//g' "$fileName" > "$outPutName" #This eliminates DOS style newlines
        sed -i '/^[[:space:]]*$/d' "$outPutName" # This eliminates whitespace
        sed -i 's_\"__g' "$outPutName" # This erases double quotes. In a CSV they make a value text and not numbers, but they make parsing difficult. Reinstated later.
        sed -i "s_'__g" "$outPutName" # associative arrays cannot deal with single tildes, so they have to go.
        sed -i '1 i\"File unixed with EPOParser.sh BASH script.\";;;;;;' "$outPutName" # With this line, unixed files wont be modified by subsequent script runs
        echo "$outPutName" >> unixedList.temp # This list will allow us to delete the temporary files at the end if they aren't wanted.

    done < EPOfileList.temp

    rm EPOfileList.temp # No reason to keep this in memory
}

# Arguments parser. Written with GETOPT
argParser()
{
# For this function to work it needs to be fed "$@"

# This instruction returns our arguments in a getopt-friendly way, so it's fed back to it later, after the -- .
parsed_args=$(getopt -n EPOParser -o -aCdeiIptuxy --long version,help -- "$@")
valid_args=$?

if [ "$valid_args" != "0" ]
then
    usage
    exit 1
fi

# The arrays below have to be declared to avoid problems with the display, in the display function.
# -A makes them associative (hash tables), -g makes them global and -i marks that they contain integers.

declare -igA titleCount
declare -igA inventorCount
declare -igA applicantCount
declare -igA publiDateCount
declare -igA priorityCount
declare -igA earliestPubCount
declare -igA IPCcount
declare -igA CPCcount

eval set -- "$parsed_args" # This sets parsed_args as if they had been given as arguments to the script itself
while : # Now the while reads from the script's argument list. This makes it so that arguments are in $n+1 and not $OPTARGS
do
    case "$1" in

    -u)

        if [[ $parsed_args == '-u' ]]
        then
            win2unix # If only a file conversion is desired the rest of the program is skipped.
        exit 0
        fi

        leaveUnixedFiles=0 # With this switch, the temporary files that we created for the program will not be deleted
        shift
        ;;


    -t)
        titleParser='eval fieldParser titleCount TITLENUM'  # If -t is selected, the title parser string will not be empty and thus will be executed.
                                                            # All entries follow the same schematic
        if [[ $2 == '-x' || $2 == '-X' ]]
        then
            titleDisaggregate=0  #With this, the strong that contains the title dissagregation will be expanded. Same for all of the entries below.
            shift # With this being here and the shift at the end, if there's an X we jump straight to the next entry.

        fi

        shift
        ;;

    -i)
        inventorParser='eval fieldParser inventorCount INVENTORNUM'

        if [[ $2 == '-x' || $2 == '-X' ]]
        then
            inventorDisaggregate=0
            shift
        fi

        shift
        ;;

    -a)
        applicantParser='eval fieldParser applicantCount APPLICANTNUM'

        if [[ $2 == '-x' || $2 == '-X' ]]
        then
            applicantDisaggregate=0
            shift
        fi

        shift
        ;;

    -d)
        dateParser='eval fieldParser publiDateCount PUBLIDATENUM'

        if [[ $2 == '-y' || $2 == '-Y' ]]
        then
            publicationMonth=0  # If this is not null, the month will be excised from the date before recounting
            shift
        fi

        shift
        ;;

    -p)
        priorityParser='eval fieldParser priorityCount PRIORITYNUM'

        if [[ $2 == '-y' || $2 == '-Y' ]]
        then
            priorityMonth=0
            shift
        fi

        shift
        ;;

    -e)
        earliestPubParser='eval fieldParser earliestPubCount EARLYPUBNUM'

        if [[ $2 == '-y' || $2 == '-Y' ]]
        then
            earliestPubMonth=0
            shift
        fi

        shift
        ;;

    -I)
        IPCparser='eval fieldParser IPCcount IPCNUM'

        if [[ $2 == '-x' || $2 == '-X' ]]
        then
            IPCdissagregate=0
            shift
        fi

        shift
        ;;

    -C)
        CPCparser='eval fieldParser CPCcount CPCNUM'

        if [[ $2 == '-x' || $2 == '-X' ]]
        then
            CPCdissagregate=0
            shift
        fi

        shift
        ;;

    -x | -X | -y | -Y)

        echo "An $1 option has been read from the arguments. This should not happen. Please take a screenshot of what you were doing and send it to the developer."
        shift
        ;;

    --help)

        usage
        exit 0
        ;;

    --version)

        version
        exit 0
        ;;


    # -- means the end of the arguments; drop this, and break out of the while loop
    --) shift; break ;;

    *) echo "Unexpected option: $1 - this should not happen. Throw away!"
       exit 2

    esac
done
}

# Function to parse fields
function fieldParser
{   #First argument: the array for this piece of data, without $. Second: The associated field number

    declare -n arrayPointer="$1" # -n declares a reference, ie. a sort of pointer
    local -ir FIELDNUM=$2
    local checkString # The entire field we are concerned with.
    local word # Parts of that field, if disaggregated.
    local indexEntry="$(sed -n 9p < "$CSVfileName" | cut -f$FIELDNUM --delimiter=\;)" # This helps eliminate the explanatory line in each file. Unset at the end.

    # Some fields require specific instructions, same for disaggregation, this CASE structure assigns them to a variable that is expanded (or not) at runtime.

    case $FIELDNUM in
        $TITLENUM)
            # For proper comparisons, caps have to be removed from the titles. Plus the title ends with a period sometimes
            indexEntry="${indexEntry,,}"
            local fieldSpecificInstruction='eval checkString=$(tr -d [:punct:] <<< "${checkString,,}")' #punctuation and caps elimination

            if [[ -n $titleDisaggregate ]]
            then
                local disaggregationInstruction='eval checkString=($checkString)'
            fi

            ;;

        $INVENTORNUM)

            local fieldSpecificInstruction='eval tr -d [:punct:] <<< "$checkString" 1> /dev/null' # Output is redirected to the void.

            # to get the name and country later on of the inventors we place a semicolon after the [country code]. This won't be perfect, since some names aren't separated like that, or at all, but it's the best I can come up with.

            if [[ -n $inventorDisaggregate ]]
            then
                local disaggregationInstruction='eval checkString="$(sed -e "s_\(\[..\]\) _\1:_g" <<< "$checkString" )" ;readarray -d : -t checkString <<< "$checkString" 1> /dev/null'
# -e "s/$/ :/"   What was this part of the sed for? What was I thinking?
            fi

            ;;

        $APPLICANTNUM)

            local fieldSpecificInstruction='eval tr -d [:punct:] <<< "$checkString" 1>/dev/null '

            if [[ -n $applicantDisaggregate ]] # The : gives us a reference to later split the names more easily.
            then
                local disaggregationInstruction='eval checkString="$(sed -e "s_\(\[..\]\) _\1:_g" <<< "$checkString" )" ;readarray -d : -t checkString <<< "$checkString" '
            fi

            ;;


        $PRIORITYNUM)

            local fieldSpecificInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}-[[:digit:]]\{2\}\)-.._\1_g" <<< $checkString)'
            # The above sed eliminates the day from the string, leaving only month and year
            # The one below eliminates the month.
            if [[ -n $priorityMonth ]]
            then
                local disaggregationInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}\)-.._\1_g" <<< $checkString)'
            fi

            ;;

        $IPCNUM)

            if [[ -n $IPCdissagregate ]]
            then
                local disaggregationInstruction='eval checkString=($checkString)'
            fi

            ;;

        $CPCNUM)

            # no field specific instruction

            if [[ -n $CPCdissagregate ]]
            then
            # This instruction is similar to the one in the inventor section, it introduces a semicolon
                local disaggregationInstruction='eval checkString="$(sed -e "s_\()\)_\1:_g" -e "s_: _:_g" <<< "$checkString" )" ;readarray -d : -t checkString <<< "$checkString"'
            fi

            ;;

        $PUBLIDATENUM)

            local fieldSpecificInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}-[[:digit:]]\{2\}\)-.._\1_g" <<< $checkString)'
            # The above sed eliminates the day from the string, leaving only month and year
            # The one below eliminates the month.

            if [[ -n $publicationMonth ]]
            then
                local disaggregationInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}\)-.._\1_g" <<< $checkString)'
            fi

            ;;

        $EARLYPUBNUM)

            local fieldSpecificInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}-[[:digit:]]\{2\}\)-.._\1_g" <<< $checkString)'
            # The above sed eliminates the day from the string, leaving only month and year
            # The one below eliminates the month.

            if [[ -n $earliestPubMonth ]]
            then
                local disaggregationInstruction='eval checkString=$(sed "s_\([[:digit:]]\{4\}\)-.._\1_g" <<< $checkString)'
            fi

            ;;

        *)
            echoerr "\n\nCritical error in the field specific instruction selector $1. Aborting.\nHow did that even happen?\nWarn the developer.\n"
            exit 126

            esac
                                                    # XXXXXXXXXXXXXXXXX
                                                    # Parsing starts here
                                                    # XXXXXXXXXXXXXXXXX
    while read 'entry'
        do
            # Entry is an entire line from the input file, that is, an entire patent's information.
            checkString=$(cut -f$FIELDNUM --delimiter=\; <<< "$entry") # This extracts the CSV field

            ${fieldSpecificInstruction[@]} # This expands depending on the field. Check the CASE structure above.

            ${disaggregationInstruction[@]} # This expands if disaggregation has been requested.
            #This makes the string into an array, so it can be dissaggregated. Expand if dissagreggated.
            #The FOR below will treat the string as one single element if this is not expanded, and as an array if it is.

            for word in "${checkString[@]}"
            do

                if [[ -z $word ]] #Empty entries are useless so we don't consider them
                then
        	        continue

                elif [[ -z ${arrayPointer[$word]} ]]
                then
                    (( arrayPointer[$word]=1 )) # If a term hasn't appeared yet, it's added to the hash table and keyed to one.

                else

                   (( arrayPointer[$word]++ )) # The entry is incremented
                fi

            done

        done < "$CSVfileName" # This is specificied in the WHILE loop around this function.

        unset ${arrayPointer/word/indexEntry} # This eliminates the line 8 entry, which contains the field name of each csv.
        # The above doesn't work in all disaggregated cases! Will have to be improved.
}

function longestArray
{
    # This function finds the length of the longest array. It might also be the most inelegant code I have ever written.
    if [[ -n ${titleKeys} && (( ${#titleKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#titleKeys[@]}
    fi

    if [[ -n ${inventorKeys} && (( ${#inventorKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#inventorKeys[@]}
    fi

    if [[ -n ${applicantKeys} && (( ${#applicantKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#applicantKeys[@]}
    fi

    if [[ -n ${dateKeys} && (( ${#dateKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#dateKeys[@]}
    fi

    if [[ -n ${priorityKeys} && (( ${#priorityKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#priorityKeys[@]}
    fi

    if [[ -n ${earliestPubKeys} && (( ${#earliestPubKeys[@]} > $maxLength )) ]]
    then
        maxLength=${#earliestPubKeys[@]}
    fi

    if [[ -n ${IPCkeys} && (( ${#IPCkeys[@]} > $maxLength )) ]]
    then
        maxLength=${#IPCkeys[@]}
    fi

    if [[ -n ${CPCkeys} && (( ${#CPCkeys[@]} > $maxLength )) ]]
    then
        maxLength=${#CPCkeys[@]}
    fi
}


function resultsFileWriter
{
    declare -ar titleKeys=("${!titleCount[@]}") # Thanks to these we get indexed arrays of the keys of the *existing* associative arrays
    declare -ar inventorKeys=("${!inventorCount[@]}")
    declare -ar applicantKeys=("${!applicantCount[@]}")
    declare -ar dateKeys=("${!publiDateCount[@]}")
    declare -ar priorityKeys=("${!priorityCount[@]}")
    declare -ar earliestPubKeys=("${!earliestPubCount[@]}")
    declare -ar IPCkeys=("${!IPCcount[@]}")
    declare -ar CPCkeys=("${!CPCcount[@]}")

    declare -i maxLength=0
    longestArray # Finds the length of the longest array.

    resultsFile="ParsedEPOresults$$.csv" # The name contains the process number. For randomization.
    touch  "$resultsFile"

    {   # This entire block of code has output redirected to the results file XXXXXXXX

        printf "\"Results file created on\";\"%s\";;;;\n" "$(date)" # The first line is the date

        for header in "${headerSpace[@]}" # First we put up the headers in the results file
        do
            printf "\"%s\";;;;;;\n" "$header"
        done

        printf ";;;;;;;;;;;\n" # An empty space for clarity

        # This prints the field headers
        local outPutString='"Titles";"Title count";"Inventors";"Inventor count";"Applicants";"Applicant count";"Publication date";"dates";"First priority";"dates";"Earliest Publication";"dates";"IPC numbers";"IPC count";"CPC numbers";"CPC count";'

        printf "%s\n;;;\n" "$outPutString"  # Space between searches and results


        for (( writeCounter=0 ; writeCounter < maxLength ; writeCounter++ ))
        do
            # If the counter reaches an empty key, it returns an impossible value. That returns an empty array.
            # The reason is that you can ask to print an empty index (it's just empty) but you cannot feed an empty string to an index (between the square brackets).
            printf "\"%s\";%s;" "${titleKeys[$writeCounter]}"       ${titleCount[${titleKeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${inventorKeys[$writeCounter]}"    ${inventorCount[${inventorKeys[$writeCounter]:-'impossible_key-_-'}]}
            printf "\"%s\";%s;" "${applicantKeys[$writeCounter]}"   ${applicantCount[${applicantKeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${dateKeys[$writeCounter]}"        ${publiDateCount[${dateKeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${priorityKeys[$writeCounter]}"    ${priorityCount[${priorityKeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${earliestPubKeys[$writeCounter]}" ${earliestPubCount[${earliestPubKeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${IPCkeys[$writeCounter]}"         ${IPCcount[${IPCkeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\"%s\";%s;" "${CPCkeys[$writeCounter]}"         ${CPCcount[${CPCkeys[$writeCounter]:-'impossible_key^^^'}]}
            printf "\n"

        done
    } >> "$resultsFile" # resultsFile block of code ends here XXXXXXXXXXX
}

function cleanup
{

    if [[ -z $leaveUnixedFiles ]]
    then
        while read 'fileName'
        do
            rm "$fileName"
        done < unixedList.temp
    fi

    rm unixedList.temp
}



# XXXX Main XXXX

initFileCount # We check that there are Espacenet files

win2unix # We transform them to the easy-to-parse format

argParser "$@" # We parse the script arguments. It uses the script's arguments, but they need to be passed on explicitely

trap cleanup EXIT SIGHUP SIGINT SIGTERM ERR # Only after this step does the cleanup function become relevant. Before, the unixed files haven't been created. This activates at EXIT and SIGnal Hung UP or other error conditions

declare -a headerSpace # Array of the file headers
declare -i fileCount=0

while read "CSVfileName"
do

    headerSpace[$fileCount]=$(sed -n '4p' "$CSVfileName") # This records what searches were executed to get to the files that were parsed.
    headerSpace[$fileCount]=$(tr -d \; <<< "${headerSpace[$fileCount]}") # This takes the many semicolons out of the headers

    # Any option that isn't activated will simply expand to nothing
    ${titleParser[@]}
    ${inventorParser[@]}
    ${applicantParser[@]}
    ${dateParser[@]}
    ${priorityParser[@]}
    ${earliestPubParser[@]}
    ${IPCparser[@]}
    ${CPCparser[@]}

    (( fileCount++ ))

done < unixedList.temp

resultsFileWriter

exit 0
Abr
07

Let’s check out the second part of the Ring tetralogy and become Wagner experts. And be super smug.

The action starts when, in the middle of the night, a hobo crashes into a lady’s house and falls exhausted. Instead of calling the guards-of-the-trible, she’s cool, and offers him a glass of whater. He drinks it and IMMEDIATELY throws the lady a wolf-whistle.

She’s cool, it’s the house of Hunding and she’s like «Why don’t you stay and recover? You are wounded?» But he is too much into the toxic masculinity thing, brushes it off and keeps throwing compliments her way. So she brings him a beer. And he’s like «Yeah but did you taste it first?». This dude knows how the ancient French checked whether their wives had been drinking in their absence. (ie. That’s why it’s called a French kiss).

He wants to leave, she kinda wants the opposite, but he’s a troubled soul, pursued by ill fate and stuff. He’s got enemies donchaknow. She insists on him staying, arguing that there’s already plenty of ill fate in her house.

One piece of advice: If someone uses a similar line with you, flee. Seriously. «Your problems are bad but stay because my problems are worse» that’s the mark of Crazy, broadcasted to all frequencies. Run.

They have the hots for each other and almost kiss. But shit’s akward man. They both immediately re-think it, because, surprise surprise, mr. Hunding show’s up in a perfectly timed manner. They immediately start acting all normal, you know what I mean? The husband has one request: my hearth is sacred yo. also «Serve us food biatch.» Oh and they keep acting totally non suspicious with handbrushes and stuff.

But hunding knows something is afoot. Not in the way I have been insinuating until now, no, he detects a similar glint in both their eyes.

Then he questions the hobo. Name, origin, where was he travelling from. He doesnt want to say, so Hunding asks to tell his wife, who’s standing there with them. Because that makes sense. He gives his rapper names «Cheerful», «Peaceful» but says that he has to be called «Woeful». And, totally unasked, tells the story of his life. He was born with a twin sister but some invasion made them apart, and he ended up with another hobo called Wolf in the woods. So he should be called «Woeful the Wolwerine». Wolf cub actually but I had to make that joke. They were chased by the attackers but wolves helped. He lives in the forest but wanted to be among men and specially women. You might think I am exagerating but it’s emphasized. Also his tale is very woey, and tells that discords follows him. People fight to the death and many people accidentally fall on the hobo’s sword by complete accident. Not great optics.

Hundig says «ok, so you bad mojo, you must be pretty cray». The wife tries to defend him. Mr. bum explains he decided to save some lady from being married against her will. So he killed her brothers and she was, unsurprisingly, bummed about that. More relatives came, the girl refuses to leave (she’s busy mourning) so he fights and fights, till she dies and he peaces out. That’s how he lost his weapons. All of this explains his nickname.

Hundig shares his own tale of woe. He was late to a family vengeance. Shame. Then he points out he followed the tracks of the attacker to his own home. And warns him, that hospitality for tonight, and tomorrow, fight to the death.

That’s an honorable man, hell. A male chauvinist one too, since he tells the wife to prepare him a beer and wait in bed. The hobo tries to defend her but he still has a blade, and he doesn’t. This is the most awkward reunion since that last speech at the end of The Big Short. Hobo and wife are left alone while she, explicitly, on the scene, clears the table. There’s sparks, the husband isn’t blind, so there’s more threats of violence.

Mr. Hobo remembers that his dad profesized he’d find a sword when in dire need, and muses about the hot wife. And in very poetic words goes on and on and on about how hot she is.

The wife comes back and reveals she has roofied the husband (the tetralogy has a surprising amount of roofies), and tells the guy that there’s this sword he could use but he needs to be hero-strong. Oh and adds that she was forced to marry Hunding too. In the circumstances, that’s a clear come on.

That weapon was from another hobo who stuck it in a tree during her wedding, and who she recognized because of the glint in his eye, but reveals no more. That sword, by the way, is in the trunk that supports the house. Meaning: it’s right there. Then she sings about that hero who tried to save her during her wedding and stuck the sword there, and asks for his return.

At this point I am super confused because I have no idea if she’s her twin, or if they have the megahots for each other. Or both (ew!) In any case, both are pretty aroused, and sing about it for a while. Springtime of their loving and all that jazz.

He ends up revealing who his father was, the dude who stuck the sword. She gives him a new name, Siegmund. He digs it. And pulls the sword from the tree, and names it Nothung.

It is still ambiguous at this point whether they don’t know they are siblings or they don’t give a fuck. In any case, he’s like «Yeah, why don’t we elope». By this point they figure out they are related, AND don’t give af. Maybe that’s why fate doesn’t like them, because incest is gross? 


And with this gross note, the first act ends.

Second act open in Valhalla where Odin tells Brunhilde the Valkirie, his daugther, that there’s going to be a battle and she should prepare to bring those souls. She says that sure, np, but her mom’s coming and she’s in a foul mood too. So he mans up to face the rage of his wife. She comes and she mad. She maaaaaad.

Here’s the problem: Odin hates Hunding and wants Siegmund to win (spoiler: it’s his one more of his bastard sons), Freya roots for Hundig and wants Siegmund to die. Among other things because she’s the God of wedlock and the lady, Sieglinde, was married legally. I mean, married against her will, but that’s not Freya’s problem.

She mad at Siegmund and Siglinde a lot. Odin wonders why, and she calls his BS. There was a marriage, so she’s on that side. He believes in love, she in marriage. He’s cool with adultery, and, as it turns out, with incest too. (Gross).

Wagner, as usual, doesn’t disappoint with the whole «healthy familiar relationships thing».

She goes further and points out «dude, those are your own kids, and also you are being a deadbeat god. Like wtf, are you just going to let them f***???»

She might be the godess of wedlock, but her husband does not exactly worship her. He’s the cheater type. She pleads. Like ok, this happened, but at least don’t fuck up my godhood, incest is wrong. Which, duh. And asks to just kill all the witnesses.

Odin mentions that yeah, this situation might destroy the gods (apparently that’s what’s at stake) and mentions that the situation cannot be solved by the gods, it must be a hero who doesn’t follow godly design. So he tries to pass it on as if it was his design all along to cheat on his wife and put a bun in some poor lady’s oven.

Odin argues he never extended his protection to the child, and his wife points out that leaving a sword where he’d find it was the same. Freya sure has Odin’s bullshit on speed dial, because she calls it a lot.

Odin unwraps a dead wolf at that point, because why not. His wife wants Siegmund to be on his own, no divine help. Makes Odin swear. Not even Valkirie-y help.

Brunhilde the valkirie shows up. It’s obvious her and her mom don’t get along. Healthy families. Freya knows that if Odin doesn’t do as she says the gods will lose all respect and vanish. Time for Odin to make some hard choices.

«Mom was laughing, so the fight was bad. So, do I kill my bastard brother»? HEALTHY FAMILIES I TELL YOU.

Brunhilde wants orders. Not only she is another bastard daughter from Odin, who like most head gods cannot just keep it in his pants. No, she’s creepy in how much she wants to follow orders. So orders she gets, secret.

Turns out Alberich the giant still has the Ring, so he’s a threat to Odin’s power. Loki made him do it you know. He then reveals that the price for learning more about the Ring from the goddess of earth* was having 8 illegitimate sisters, the Valkiries. Oh and he’s been monging war so he’d have more pals in Valhalla. Sick asshole.

*The frase «Through love I overpowered the woman» is priceless. Oh and at no point are we told when did Odin dump Erda

So yeah, Alberich is looking for the Ring, has an army, and he’s gunning for Valhalla.That’s why he wanted heroes for. With the Ring, Alberich’d rule them all and defeat the gods. Odin needs that Ring. It’s with Fafner, the former giant, that Odin can’t attack because he made a pact with him. Through alliances he became ruler, and alliance now make him slave. That’s why he needs a hero who is free.

Then he makes a point: «As a god, I find myself in everything that I do». That’s fucked up and I bet it gets boring quickly, to only be surrounded by servants to yourself. I guess the other gods are dicks?

That’s when she gets it and tells the public. Fathering mortal children is what will doom the gods. Moral: Keep. It. In. Your. Pants.

Also Alberich paid a woman to have his son, who hates the gods. Because nature, not nurture. Side note.

So (logically!) he renounces his own will and Brunhilde should fight for Freya and kill Siegmund.

But she has a free will and defends her half brother. He’s made about that, almost kills her for her defiance. But she finishes the scene by singing the very well known aria «Nah, I’ll do what I want to.»

Back to the fucking brother and sister. They are married but she’s acting weird. There might be some trauma involved, who knows. She’s having buyer’s regret on the whole incest thing. She’s lived amongst humans after all. And is technically married so she feels guilty. Oh and she now lives in the forest with a hobo.

«Nah, a swipe of this sword to your husbands neck and shit’s fixed» he says.

Said husband, Hunding, is approaching with dogs and armed me. Siegmund decides to go for a pee of something where he’s found and murdered in sight of Sieglinde.

Actually no, she comes back from peeing, Sieglinde is passed out from shock.

Siegmund goes off scene to smoke one or something, when Brunhilde shows up and tells him that he’s a goner, and she’s gonna take him to Valhalla. She’s seen’im after all.

Siengmund is cool with the whole «going to valhalla» business, but not without his sister. She’s so impressed with his passion that decides to help him. I bet this lady heard that BS about «but family is everythiiiiing» a lot of times growing up.

Before Hundig shows up Sieglind has a brief episode of PTSD. Then the men taunt each other and finally, FIGHT SCENE!!

Siegfried loses in the end. He was going to win but Odin sees what Brunhilde is going to do and shows up in person and destroy’s Nothung, and has Siegmund killed Because he spears him. and dies, and Brunhilde flees with a pregnant (EW!) Sieglinde. Odin also kills Hundig disdainfully. He didn’t have it coming.

Second act ends.

Third act starts with dudes machinegunning people from helicopters. You know what I mean.

The valkiries are back from hauling dead heroes to Valhalla, and are now moking them and kicking them around, because frankly, why not. One of the valkiries comments that her mare has already suffered a heroes rage. I want one thing very much: to not thing about what she means.

The valkiries send the men off to Valhalla and wait for her sister. They are shocked to discover she’s carrying a woman, and not a hero (toxic masculinity yo) on her horse. Everyone’s shocked, all the more so because she admits she’s fleeing and defying Odin. He is bearing down on them.

Also, they call him «battlefather». Which…

So yeah, she’s gone rogue and the Valkiries are all WTF?

Sieglinde wakes up and wishes she had just been killed beside Siegmund. She asks for the valkirie to slay her. The Valkirie tells her that she’s preggers and should care for her child. That changes her mind, because you know how bitches are about babies. So she flees. To a cave. Some Valkirie points out that’s a bad place for a lone woman. You don’t say. Oh, and the cave has a Dragon, Fafner (yeah, from the previous episode) with the Ring in it. But Odin won’t go there so….

She flees after the valkiries have a brief debate about where to, and Brunhilde stays to face her dad.

Odin is pissed off, although he admits she was doing what he actually wanted! After a massive rant, Brunhilde shows her mettle and gives herself up. She gets punished by… not being a Valkirie anymore and being cut from the gods. Which I understand, it sucks to lose your trust fund, but she will no longer be her servant so there’s that. But no, he’s putting her to eternal sleep in a mountain, like an asshole. Inside a ring of fire no less.

Before her punishment, she pleads to him. Why so serious? I did what you actually wanted, not your orders! Not only that, but those two are passionately in love. So there. Oh also she fell for him too. Because the call of blood I guess. There’s like a strong theme in all of these, I dunno.

At this point Odin goes on another rant in which he flips from «only you knew what I really wanted» to «Who the fuck are you to presume you know what I want?» inside of the same paragraph They argue back and forth and he’s very ashamed because, as she pointed out, it’s not like he managed the Valkiries well. No training, no support. Anyway so he lovingly puts her in the ring of fire.

By the way, the ring of fire thing is because she’d rather be put there, than with some man that would beat her. No, the ring of fire can only be crossed by awesome heroes, ensuring that whoever wakes her up is not just some deadbeat.

So yeah, another story of a dysfunctional family. Oh and he has to call Loki to do the whole fire thing, because Norse gods, apparently, are specialized. Like insects.

Abr
01

So there’s a quarantine going on and I am stuck at home like everybody else. I think it is the perfect time to sit home and chill and watch the Ring tetralogy. When all of this ends I am going to be able to act VERY superior to everybody else, on account on having watched it.

The first act starts with the nymphs frolicking around. Alberich, the dwarf, shows up for a good time. The nymphs are assholes to the him, because he doesn’t conform to the beauty canons of Heimdall. They are also bitchy.

Then they are terrible at keeping secrets because they just tell the dude that they have been leading on and screwing over all of the magic powers of the Rhinegold. Then they sing about how the desire for love is what keeps everyone going and love is good…. then they try to go for a «we cool, right bro» to the same Nibelung they have been scorning.

Silly Odin, he thought guarding the gold was a task that the dumbest of her daughters could do. What did they expect, for the Nibelung to just take the punishment and not try to get the gold and extort them?

Then the scene changes to Odin and his wife, Frigg. Odin is very excited about having had the Giants build a palace for the gods on top of a mountain. He’s very happy to have built his GottenSuburb, but, in exchange for the palace, the contract has some onerous conditions. Freya, Odin’s sister in law, is to be given to the builders.

Odin’s wife is not supper happy with that, duh. Then Odin is all like «yo, you sis was hot and bothered for that palace too». (Probably for the sweet instagram pics). «And no, I won’t give Freya up because I am into Opera-sized ladies and I wanna tap that ass». Might not be a literal quote.

Then he explains his plan: Loki is going to trick the giants. Yes, get this: Odin trusts Loki. I guess he also thinks that MLMs are profitable.

So that’s the scene: Frigga is sad, Freya is kinda scared because she’s going to be sold into sex slavery to some giants, Odin is acting like a dude. Then the giants show up and the gods pretend to be statues. The Giants are having none of that shit and sing that they want payment.

Poor Freya. I mean, we all like men with tough abs, but the giants are made of stone. Imagine the rugburn.

So yeah, the giants demand payment and point out that the power of the gods is contractual. «You might be very booksmart, but your power depends on honoring contracts. You trick us, shit is going DOWN».
The giants also take a moment to point out that chasing real state and big castles is silly (they leart their lesson in 2009), but mostly insist that they worked hard and now they want payment.

Feeling tricked, the giants insist. Which is a problem for the gods, only Freya can grow the Golden Apples of eternal life. Long term planning: not a nordic god thing.

But then Discount Store Thor, Froh and other gods decide that enough is enough and they can just kick giant ass. Odin stops the fighting and everyone is very upset. But Odin is waiting for Loki. Who shows up just then, pretty sauced up because, hey, it’s 5 o’clock in some Heavenly realm. Odin is like «you bitch better have something up your sleeve», and the other gods are like «You trust this bitch?». Loki whines about ingratitude being his only reward. But in fairness, he IS kind of a dick, and the gods probably have not forgotten the whole «mandrake blowgun» incident. Nor should they, that was super fucked up.

Then Loki goes «Ok, so you know how all dudes want love and womankind right?» The entire cast and public go «^_^ yeeeee». Loki continues: «Ok, so I know the only dude who doesn’t, and he’s a Nibelung that tried to get it on with some nymphs, but they scorned him, he stole the gold and now he wants only gold, not love. So the Nymphs asked me to capture the thief and return the gold to them. Return the gold *chuckle*. I promised them to tell you…. so there.»

At this point gods and giants look at each to see where this is going. But they also kinda hate the Nibelung (Alberich). Oh and Loki reveals he’s also shit at keeping secrets and tells the giant that, with a ring made of Rhine Gold, the bearer would have supreme power. Like, it would be one ring, to rule them all. At this point Frigga asks «Yo, so if a woman had that ring she’d be powerful too right?» And Odin is like «Well, I mean, you have power over my heart, how much more do you want?» And Frigga tickles his vanity and he decides to get the ring for himself. Problem: He doesn’t know any goldsmithing and no rune magic. Loki claims than if you renounce love, you can then learn the runes to make it.

Guess what: Alberich is waaaaay ahead of them because the Nymphs just HAD to toy with his feelings. The gods ask how they can get that ring and he’s like «You steal it obviously». Maybe that’s why he has a shit reputation amongs the gods?
Frigga freaks out that Odin has to deal with the Nymphs too because jealousy and the patriarchate.

But the giants have been hearing all of this and thing, hey, maybe that BLING BLING could be for us. «You keep the bitch and we’ll get the gold. You are a god, that Nibelung is toast» is the gist of it. Odin whines and whines but a contract is a contract. The giants in the meantime take Freya hostage, and set a deadline.

Odin feels bad at that point. All of the gods save Loki. Why? Because they haven’t eaten golden apple lately. And Freya is gone. The gods are boned. Except for Loki who, surprise surprise, has a stash. He’s also quite bitter because Freya used to be stingy with him on the whole Golden Apple front, on account of her being racist against demigods.

So the Odin decides to take a trip to the Underworld, see if he can fix stuff and the first act comes to an end.

When the second act opens we find our friendly Nibelung kickin the ass of Mime the goldsmithing dwarf. Mime tried to get the magic helmet and ring that he forged for himself, but Alberich is taking none of that. He has a ring now. To rule them all.

As Alberich leaves with his treasure, Loki and Odin descend, just in time to be late. They find the beaten up Mime, and Odin is like «that sucks» and Loki is like «LOL, suck it bitch. Give us answers». Turns out Alberich is Mime’s brother, and he beat Mime up to forge the gold. Family, amirite?

Mime spills the goods: Alberich has the face ring but it makes him magically greedy, inviting more lord of the rings comparisons. Also the helmet: It was supposed to be magical but Mime thought he’d fool his brother. He got beaten up for that (family). Apparently he didn’t quite understand the magic of the helmet HE HIMSELF HAD FORGED quite enough. He feels like a fool. Shocker.

Odin is a bit disparaged and Loki, the god of cunning, tells Odin that Odin’s cunning will save the day. The smell of rat intensifies. Then Mime calls on his squad of Miner Dwarven to show Odin that he can get new gold, just, please, don’t hit him no more.

Odin threatens the dwarven if they don’t bring him gold for another ring (I guess to fool Alberich). This guy will make it to middle manager, I tell you.

He also sings about being impressed with the riches of Nibelheim, which is the Underworld. Loki whines again that he does all the bitchwork for no recognition. To which Mime answers «Oh yeah, I understand your plight, it is sooooo baaaaaaaad.» Loki tries to bring him to his (not their!) side, dwarf unimpressed. Odin makes a good point then: «You guys got the gold but living here sucks so what up?». Mime answers that he’ll be megarich and cool one day, you’ll all see. Because he has renounced love too you see. He’s ghetto. And goes on and on about how one day he’ll have all the gold. Then he accusses the gods of living in luxury and despising those from below, and tells them that if only he can he will super dick them over. Odin is not super happy about that, Loki is more like «That Alberich dude has the ring and he’s winning bc he’s cunnin. I dig that guy. Then keeps trying to sweet talk Mime. Mime sees through that bullshit like a blowtorch through butter.

Mime then explains that he has an invisibility helmet and franky, he just wants to be free from the asshole gods. The asshole gods do perceive, though, that he has some awesome forging skillz.

I mean, he shows how cool his helmet is by transforming into a giant snake right there and then. Because hey, why not. Even the gods shit their pants.

Loki then tells him «I bet you can’t become small.» He obviously can, but this was revese psicology and Mime should have seen that coming a mile away. He turns into a toad, so they capture him. I dunno bruh, what if a mugger tells you «I bet you don’t have the cojones to give me your wallet» and you prove him wrong. Just sayin’. In this intelligent, streetwise note the second act comes to an end.

The third act opens with Odin and Loki, with a very hogtied Mime. They take him to his realm and taunt him. «Didn’t you wanna conquer this place? ah? AH?». The gods rub it in a bit. They want his gold. Then they rub it in some more. Mime just wants the ring. And REVENGE.

They untie him somewhat and he summons his hoard. Thing is, with the ring of power he has enslaved the ther Dwarven. He is seen humiliated by his underlings, and he’s salty about that. He wants his helmet back as agreed, but this is Loki we are talking about so LOL. Then they demand his ring, and that’s where Mime, tied and submitted, draws the line. He says he’d rather lose all his limbs. The gods point out that it was made with gold stolen from them. Mime, though, is really into the ring and says that he was the only one who could do things with it. The gods don’t have those jobs skills you see. They are very good at rubbing it in on Alberich, though. They end up taking the ring by force from the very hogtied Alberich. He up shit creek, paddles not included.

Odin is pretty happy, he has The Ring and the gold. They let Alberich go, and before leaving, he curses the ring so that it brings misfortune and a date with the executioner to whoever wears it, and envy to whoever doesn’t.

Odin is enamored with the ring. Loki knows what up, but pretends he doesn’t. He also takes the opportunity to take a bath of gold. That’s when the Giants bring Freya back. The other gods show up too. They are all pretty happy to see Freya back, because, Golden apples. Also they love her a lot too or something.

To recap: Odin and Loki stole from the underworld peepz to give the giants, in a realm above them. A transfer of wealth upwards is what it is.

So they take Freya to measure her, and apportion her weight in gold to the giants. This is unwise, since she’s an opera singer.

They start splitting the gold. Odin, whenever he can get his eyes from the damn ring, expresses his shame. His wife is mad, Thor is mad. The gold isn’t enough to cover Freya, so the giants want the helmet to and… of course the ring. The giant is too enamored with Freya so he wants her TOTALLY covered in gold. And, how funny, the amount of gold missing is a ring’s worth. Odin is just a little upset. Loki insists about the pact: he promised the Nymphs. Anyway they go back and forth. Odin ends up having a melthdown and trying to flee.

The thing is bad enough that Erda, godess of the Earth, makes an appearence to tell Odin to just give up the ring. He does. The Earth godess obviously knows the ring is baaaaaaad. The giants fight over the gold and ring (you can’t share a ring after all, plus show me the money), so one of them, Fafner, kills his brother (another healthy family dynamic) and peaces the fuck out.

Odin makes a speech about how he’d better pay the giants because he wants to be young again. At least he’s aware enough to see that the ring is bad mojo.

Thor is bored, he swings his hammer, brings forth a bridge in the form of a rainbow. Odin makes a speech about the sweet-ass castle he just had built, Valhalla, and all the cool adventures he’s had to pay for it. Then he tells people to go inside to get the party started.

The Nymphs sing a sad song, because the lost the gold, and Loki gets saltier than anybody in the entire opera because he, being a demi-god, is not allowed in Valhalla. He foresees that the Dusk of the Gods is close. By the end of the song the Nymphs realize the gods are deceitful and faint-hearted. (Translation: craven assholes).

And with that, the gods ascent to Valhalla and this combination of Family drama and slapstick comedy comes to an end.

Analysis:

  • Don’t be racist against demi-gods, they’ll take revenge
  • Don’t trust the gods.
  • Stealing from a thief is cool
  • Try to have some guile, because otherwise everyone else will take advantage of you.
  • Don’t trust anybody, but SPECIALLY the damn gods.

 

Ene
23

I have created a very basic Finite State Machine. It makes a buzzer sound, it’s very silly. But the idea might help you implement your own stuff.

The nice thing about a finite state machine is that, by limiting the number of possible states, many errors and invalid values can be avoided. When you close a state and open another you can, for instance, close all the inputs or outputs that are not going to be used in that state. Really convinient for embedded systems, but not only.

And if you make an array of structs, one for each state, and inside those structs you put pointers to functions, you can make fairly fast code.

Why is it fast?

Imagine I make an array of structs, all identical, and a variable StateNumber decides what state we are on exactly.

Because the structs are identical, the offset between variables and function pointers is always the same. If we make it so that only one state can be active at a time then the compiler will see that the offsets are fixed, and optimize.

Also objects

You will notice structs with function pointers. That’s… wait, data, together with code? Isn’t that…. an object?

It is indeed. Objects in C, you can totally make them. They don’t have overload or inheritance (who needs those anyway?) and you need encapsulation to make them private. But so what?

Anyway, enjoy. Oh and here are some resources on encapsulation:

Eric Horner’s blog.

Here it goes! Thoroughly commented. That said, it was a piece of homework on a very specific embedded system, so if some comment doesn’t make sense just ignore it. And the specific registers used, obviously, don’t make sense for you.

 

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
//The possible states
enum eListState
{
    BASE_STATE,
    TIME_INPUT_STATE,
    NOISE_STATE,
    CLEANUP_AND_EXIT,
    NUM_OF_STATES /*This here is one of my favorite 
things. Later one I do a malloc to create as many 
structs as states. If, later, I change the number 
of states I don't have to change the malloc!*/
}eListState;

//This int keeps the current state number. 
It can only be modified by a state_change function.
unsigned short State;

struct SoundStateKeeper *placeholder; /* this forward 
declaration might seem surprising, but it is necessary 
to solve an unusual compiler warning caused
by the scope of a struct declared in a prototype 
being ONLY that prototype.*/

// This is the function pointer that will go into the struct. 
// Typedefed for ease of use.
typedef void (*this_method)(struct SoundStateKeeper *);

// This is the file descriptor we'll use
int fd;

//the array of state structs
/*Each state has its own struct in the array to keep 
track of the values of each state.
//That way there's a single counter to keep track of 
the current state and it gets fed into the array offset.*/

typedef struct SoundStateKeeper
    {
        unsigned short thisStateValue;
        unsigned short nextState;
        this_method current_state_funcP;


    /* Having structs with pointers to code, 
as in this case, is functionally identical
To objects in C++, although with no function overload and 
having to encapsulate to make private structures.
No inheritance either. But objects, in C. Isn't C neat?
    */
    }SoundStateKeeper;

//Function declarations - functions that do stuff.

SoundStateKeeper * init_func(void);
void base_state_choice(SoundStateKeeper *);
void number_getter(SoundStateKeeper *);
void NoiseMaker(SoundStateKeeper *);
void freememAndExit(SoundStateKeeper *);

//This is the change state function 
declaration and definition, the only 
function that touches the State variable.

unsigned short inline state_change_f(SoundStateKeeper *, unsigned short);

/* By inlining we suggest the compiler not to 
keep an object code that points to this function,
but to record it in memory.
It doesn't work on all cases, but it could optimize 
speed of execution by using more memory. Depending on how fast
your memory access is it could be better, or not.
Note that I am not exactly following the GNU C inlining rules,
which call for encapsulation as a prerequisite for inlining
*/

inline unsigned short state_change_f(SoundStateKeeper * state_array, unsigned short currentState)
{
    ///This is a debug function
    //printf("Transitioning from state %hu to state %hu.\nInformation being passed is %hu.", currentState, state_array[currentState]->nextState, state_array[currentState]->thisStateValue);

    unsigned short local_next_state = state_array[currentState].nextState;
    /*This function transmits all the information
 needed to the next state. In some changestates 
this information is, as 7 of 9 would put it, irrelevant.

The reason that I am using identical structs, 
with similar offset, and changing state with always 
the same function, and that function be as small as 
possible, is so I can inline.
*/
    state_array[local_next_state].thisStateValue = state_array[currentState].thisStateValue;

    //Now we return the next state.
    return local_next_state;
}

// Base state working function
void base_state_choice(SoundStateKeeper * state_array)
    {
        if(!state_array[State].thisStateValue)
        {//This only prints the first time
            printf("Welcome to the Cyberdine Industries model T-22 sine wave generator!\n");
        }

        printf("Input 0 to exit and any other number to run it again.\n");
        scanf("%1hu", &state_array[State].thisStateValue);

        /*Here we could accelerate the program 
slightly by creating an array of 10 function pointers, 
where pointer 0 gives back the first result, and all 
the others, the last result. Probably overkill in this case.
*/
        if(!state_array[State].thisStateValue) // Depending on the answer we send to a different state
        {
            state_array[State].nextState = CLEANUP_AND_EXIT;
        }l
        else
        {
            state_array[State].nextState = TIME_INPUT_STATE;
        }
    }

void number_getter(SoundStateKeeper * state_array)
{
    printf("How long do you want the sound to be? Specify in seconds, max is 999 seconds.");
    scanf("%3hu", &state_array[State].thisStateValue);
}

void NoiseMaker(SoundStateKeeper * state_array)
{
    for(unsigned long i = (2000 * state_array[State].thisStateValue); i > 0; i--); //This function is just a buzzer
        {
            write(fd,"FIO0SET 0x04000000",4); // set the pin 0.26
            delay(200); 
            write(fd,"FIO0CLR 0x04000000",4);// reset the pin 0.26
            delay(200); 
        }
}

void freememAndExit(SoundStateKeeper * state_array)
{
    close(fd);

    free(state_array);
    state_array = NULL;
    write(fd,"FIO0DIR 0x0",4);

    printf("Everything cleaned up. Bye!");
    exit(1);
}

SoundStateKeeper * init_func(void)
    {
        SoundStateKeeper *stateArray = calloc(NUM_OF_STATES, sizeof(SoundStateKeeper));
        if(stateArray == NULL)
        {
            printf("Catastrophic memory error");
            exit(1);
        }

//Setup of the initial state, where it just asks to 
//run the operation or quit
        stateArray[BASE_STATE].current_state_funcP = &base_state_choice;

//Setup of time input state, where it asks 
//for the duration of the noise
        stateArray[TIME_INPUT_STATE].nextState = NOISE_STATE; //This is hardcoded, since this state only leads to NOISE_STATE
        stateArray[TIME_INPUT_STATE].current_state_funcP = &number_getter;

        //Setup of noise making function
        stateArray[NOISE_STATE].nextState = BASE_STATE; //hardcoded
        stateArray[NOISE_STATE].current_state_funcP = &NoiseMaker;

        //Setup of the cleanup function.
        stateArray[CLEANUP_AND_EXIT].current_state_funcP = &freememAndExit;

        State = 0; //This is the first state

        //Now we configure the pins
        fd = open("/dev/lpc2478_gpio", O_WRONLY, 0);
        if(fd < 0)
        {
            printf("GPIO ERROR - Could not open file.\n");
            exit(1);
        }

        write(fd,"FIO0DIR 0x04000000",25); //With this we set pin 26, connected to the speaker, to output.

        return stateArray;
    }

int main()
{
    SoundStateKeeper *stateArray = init_func();

    while(1)
    {
        stateArray[State].current_state_funcP(stateArray); // We don't care about what they return so it should be void.
        State = state_change_f(stateArray, State);
    }
}

Ago
07

Preliminary note: Everything in this post has been personally verified by me, it’s safe!

Ok so, the internet sucks more and more these days.

It isn’t quite as bad as TV, obviously. TV means there’s 10-20 kinds of state or corporate run propaganda and you can choose between them.

The internet gives choice. It might be a shit choice, since the state and corporate propaganda is still there, big time, but you can also go to forums and discuss the news directly with folks of different opinions, you can access the propaganda of opposing states and corporations, or, if you want, you can go the crazy route and read about the Time Cube. In short, you can choose.

Will it solve the problems of the world and transform the earth into a magical place of harmony? No, obviously. Will you find capital T truth thanks to the internet? Good luck with that. But at least you can pick your poison. Or mix 20 poisons and find your favorite. Or…. I don’t like where this simile is going.

Note of course that I am talking about news and opinions, and I am leaving aside what really makes the internet good: the enormous amount of technical information that is shared in it, everything from the most obscure old computer systems or how to properly perform robot/human sexy times.

The internet, though, has a massive problem that TV does not. You can’t comment or answer to the TV, iy is a one way thing, which is bad. But, in the age of the internet, TV is a one way thing, and that is good.  In other words: the TV is not watching you.

I mean, until the internet came around.

The internet is full of technology (tracker ads, cookies etc.) out there getting your information. In this post, needless to say, I refer exclusively to advertisers and stuff. I am not discussing anything else, for reasons that should be obvious.

I mean, sure, there are also viruses and stuff that you should be careful of. But did you know that there’s no technical distinction between a cookie and a virus? The difference is purely practical: what they do.

The point of this post is to help you make your computer and your internet browser better, faster, more resilient against all the kinds of bullshit, legal and illegal, that exists.

If you follow all of these steps you will end up with a faster computer that doesn’t become slow and bad overtime. And also you will fortify your browser, meaning that advertisers will not have every single piece of information about you and will not make your browsing slower because your computer has to load 20 advertisements. And that’s without mentioning just how many viruses you’ll block!

Before we start, though, let me pre-empt two pieces of criticism:
– «Without advertisement companies can’t survive»!

That’s the same as saying «Without repression, the poor KGB officers won’t be able to torture anyone and they will be out of a job!» Booo hooo, I say.

-«Without advertisements companies won’t invest in fast servers and there won’t be a fast and colorful internet as we have now!»

That one is probably true, and my answer is, so what? First off, in the beginning the internet was essentially a state and university-run thing. It didn’t support tons of flashy fast graphics. Oh well. But the good thing about it, namely the exchange of technical ideas, and the pure text discussion, would still be possible.

Also, if every single user implemented these guide maybe companies would have to move away from selling our date and manipulating us as business, and would have to, you know, produce stuff people would like to buy.

And now for the good stuff.

A technical note: I will mark the things that apply to windows users and linux users. If you use OSX, then LOL.

All of this will be easy to do, I promise!

The basics: deactivating all of the windows services you will never use.

Linux users please skip this part. Mac users too, obviously.

Ok, so I was planning to organize this in levels of difficulty, but I have to start here.

To make a long story short, windows, as any operative system, is a gigantic program built over many years. It also has tons of legacy services that 90% of users will not use.That is why it is strongly adviced to deactive useless services when you buy a new computer or format it, or, actually, at any point. They consume processing power AND they are attack surfaces for viruses.

You know how you install windows and after a year it works sluggishly? Follow this instructions and it will never happen again.

If you are a beginner you must already be quacking in your boots: Touching the innards of windows? I hear you say But it will bite me, break forever and Bill Gates will send me an angry letter!!

Ok, so someone has made it super easy for you.
I present you The Guide to windows services!

Click here to access this marvelous document!

Choose your windows distribution and then read the instructions. Eh… what’s that? You don’t know exactly which version of Windows you have? No big deal, I got you covered. Click here.

One little note to make applying the above guide even easier: Press windows key + R to open the run box. Then write «services.msc» without the inverted commas and that will open the services window. THERE is where you apply the guide and decide which services should be deactivated, made manual or automatic.

And now for the main course:

Easy level:

 

 

– Quit all social media

No, seriously. If you aren’t paying that means you are the product.

from Ethannonsequitur

If nothing else at least go over the privacy options with a fine-tooth comb. Which you should do in absolutely ANY website you visit.

Privacy Badger or Ad Nauseam

For windows and linux users. Mac users should do it too, although, LOL.

Install Privacy Badger. Or Ad Nauseam. That’s my advice. They are different flavors of ad blocker. Privacy badger blocks them, ad nausem clicks on every single one of them, making them useless. Up to you.

– Change your browser to Firefox.

This applies to y’all.

Opt-out of behavioral advertisement.

For windows and linux users. Mac users should do it too.

Did you know you could do that? There is a sort of platforms for ad companies where you can tell them «I don’t want to see advertisements tailored to what you think I should be buying because I am a woman in my 30’s/ a car enthusiast / have children».

Many companies don’t respect it, and many stop respecting it when enough people do it, sure. But hey, it takes a minute, and costs you nothing.

I think this is important specially if you have ever complained, as many of my friends have, that they get extremely gendered and even sexist advertisements.

For Europe: click here
For the US and Canada: click here

Although frankly I would do all of them. Again, takes a minute.

Note that for the Europe one I’d advise deactivating companies one by one. If you click on «opt out of all» you will opt out of the 10 first companies…. because those are the companies you can see without scrolling down.

Oh, and the US one, do insist and try the different options. It will rebuff your attempts a couple of times just because they can.

Oh and do the same for your google account! Go through the configuration with another fine-tooth comb.

Configure your browser properly.

For all users.

Go to your internet browser’s configuration and deactivate all the telemetry/error reports/help us improve options. Make it so that you do not consent your browser sending any information back to the creators of the browser.

Use Startpage as your default search engine All users
https://startpage.com

If nothing else they are the only search engine that claims not to systematically sell all of your searches to advertising companies.

Intermediate level

Uninstall telemetry updates for windows

For Windows users. Linux users keep being super cool. OSX users… I don’t know what to tell you.

«Telemetry» is one of those modern words. It means «We are getting your data and selling it».

So, uninstall all the updates that do that!
windows 10
https://github.com/10se1ucgo/DisableWinTracking/releases

windows 7/8
https://www.ghacks.net/2016/09/12/ancile-block-spying-on-windows-7-and-8/

Note that this is in the intermediate section only because I advice you to backup your date before you install these. These programs are completely benign in 99.99% of the cases, but hey, just in case.

And finally:

Hard level

Only hard because doing certain things in your computers is scary. But I promise you, this is easy to do and safe! I include it here only because it’s scary.

– Modify your hosts file

For all users

«hosts» is a file in your computer that holds a list of websites. Any website you write and precede with «0.0.0.0» or «127.0.0.1» is essentially blocked. This can be useful to block sites you don’t want your kids to watch!

There exist curated lists of the addresses of spambots, advertisers and stuff. If you include them in your hosts file you will never see them again!

There are two steps you have to follow here.

Go here: Here. Click here.

There are different options for hosts file. Choose the basic one or any other. You can choose to block social media, or not. Porn sites, or not.

Once you choose click on the «raw host» link associated with the file you want. Keep it open.

Then open your hosts file.

For linux: open the terminal and write «sudo gedit hosts». If you get an error install gedit first then try again. The terminal will want your password. Copy the raw hosts file you chose (Yes, copy ALL) and paste it in the hosts file.

For windows users:
The file you are looking for can be found in ../Windows/System32/drivers/etc/

If you try to open it, modify it and save it and it doesn’t let you, you need administrator privileges (as you should, otherwise you are a noob).  Open the start menu, look for the terminal, right-click on it and choose «run with admin privileges». Then do the hosts file.

Mind you, if you use very large hosts files sometimes, upon booting, it takes a minute or two for the computer to read through it and connect to the internet.
For mac users:

Just read this: This

I know this is sounds difficult, but trust me, you cant imagine how much this will improve your internet experience.

Finally:

undocumented_feature

Mar
30

Today I discovered there’s a weird street close to where I live in bulgaria, with yellow pavement.

From Mike Hanson https://flic.kr/p/diHNTo

And as you can see, there’s a yellow taxi. As yellow taxis do, it’s going to take me to the U. S. of A.


From allianz.com

So…. yeah I’m gone for a while. I will take up this blog again. At some point.

Ene
13

Today, I spent the evening together with my italian roomate. And we didn’t spend it chatting, we spent it talking.

Never again, detective Bloch

Unfortunately, I thought he’d be mad at me when I spoilered the shit out of the obscure italian comic that we both happen to like.

From rainews.it

Instead of being mad, he looked at me and said

«It’s ok. More Dharma, less drama.»

🙂

————-
On other news:

Preparing this post I’ve discovered that my dear authors have gotten inspiration from an old Spiderman cover.

from pelapatatecomics.it

Which is cool.
———–
Dylan dog is the obscure n italian comic that I like. He’s the detective of the Nightmare, a private detective that works paranormal cases. It is, needless to say, pulp as fuck.

This film uses the base character and changes a bunch of things, both for copyrights issues and artistic license.

– The dude in the film works in New Orleans, not London (artistic license or al).
– His sidekick is a random guy and not the very Grouch Marx, as in the Italian comics (copyrights issues or c).

– He’s more of an asshole than the comic character.. (al). For instance, his sidekick becomes a literal zombie and is unhappy about it, and Dyland Dog is like, «Suck it, bro!»

– Instead of being just a healthily sceptic (for someone who regularly talks to witches and werewolves) private detective, they make Dylan Dog into a sort of arbiter of the unerworld, mediating the peace between vampires, zombies and werewolves. I can’t believe I’ve just typed that phrase xD. So yeah a guy who’s full blown implicated in the occult. (al)

Not that these are criticism. Film adaptation is difficult. By the way, film adaptation in Russian is «Ekranizatsiya». It’s cool they have a single-word noun for that. You know what I mean.
I didn’t like that they made a prick in the film, Dylan Dog is usually a very well meaning, just guy.
What I liked

– The film is a bit long at the end, but the twists are cool, the vampires look like blade and there are good fight scenes.

– They managed to recreate the flat self- humour of the original. At one point the main character is taking a beating and comments: «Man, for a guy who thinks he’s smart I sure take a lot of beatings all the time!» xD

– Although I didn’t care for the change, I acknowledge the flat humor in the change the introduced when it comes to Dylan Dog’s clarinet. In the comics he can only play one song, G. Tartini’s Devil’s trill.

http://www.youtube.com/watch?v=_e5bgRqdmxI but he plays it often.
In the movie they have him play, off screen, some kid’s practice song, and badly at that. Which meh, but it’s a way of depicting the character so good technique.

– In the movie they made him a much more gung-ho, involved with the supernatural and a gun nut (at one point he remarks: «Plan? I had no plan, just bigger guns!», which meh on the face of it, but it’s hilarious.

I dunno, if you haven’t read the original comics I’m not sure wether to reccomend this movie on its own merits. But if you want an action movie, or the dude in your group of friends who likes experimental Finnish cinema insists you should watch it…. it’s definitely watchable.
Oh the music isn’t bad at all either. Yeah, ok, let’s go with yes, do watch it. Then come here and tell me what you think. Let’s do that ok ?

That said, and before I forget:

If you are a Dylan Dog fan: DON‘T WATCH THIS MOVIE, I repeat, DON‘T WATCH THIS MOVIE.
That is all.

Ah, y otras cosas que se aprenden investigando para este post: QUE BUENA ESTÁ AMY NUTTALL. Esque me vuelvo Nuttall.

Antonio Banderas brings his amazing Malaga accent to a movie that’s a real accentfest. Seriously, every single person has a glorious accent in this movie.

Specially when they are pronounced in robot.

Let’s be straight: the second half is too slow. It’s like a heavy meal that you find yourself still digesting 12h later.

That’s about the only bad thing I can say. The universe is well fleshed, it’s full of sci-fi references in the background.(which I should maybe flesh). The story makes sense. Some of the replies in the movie are awesome. «To die you must first be alive». Or the sadness with which one robot character at the end announces that she’s solved the enigma of the movie, but he wouldn’t understand the answer.

It’s also metaphorical and I think that the robots represent poor people. So…. yeah.

If you are minimally interested in sci fi, watch it.

If you are not, and you’ve seen the trailer I’ve posted above, honestly, you are set, the entire movie is there minus the ending, which you can surely deduce.

Also Melanie Griffit gets shot very suddenly.

Jack Ryan: Shadow Recruit.

Ok, so real american action film about spies and shit.

Did you know that Jack Ryan is the same guy from «Hunt of the Red October» ? It so happens that Jack Ryan is a sort of second rate James Bond. As in, everyone knows James Bond has a series of movies, but no one cares that much about the character Jack Ryan, or Jason Bourne, it’s just movies.

Anyway, so watch it if you like James Bond and Stuff, which I do. Just, don’t believe that Russians are all bad and want to destroy America, it’s very typical in that sense. Like, for instance, there’s Enron imagery at the Russian bad guy’s office.

The film’s ok though, and I liked some quote very much. «Here in Russia we prefer to talk, rather than chat».
And there’s a nice brotherly moment between the good and the bad guy, very John LeCarre in style, in which the two spies realize they come from the same place (actually and metaphorically) and are just actors in the morally equal farce of international politics.

Or I could be overinterpreting.

Ene
09

I’ve been watching moviez.

Dylan Dog: self-contained

Honestly would you think these two guys are the same?

Automata: proletariat

Oh yeah, shake it babe, for Papy Banderas!

Jack Ryan – Shadow Recruit: Déjà Vu. (I honestly wrote «Jason Bourne» on this one. Lapsus)

Enron Imagery. NO ONE is convincing me otherwise.

Ene
01

Did I mention I hate the 1st day of the year? It’s just there, between a massive party and a day where no one is alive and everything is closed. I’ve probably said it a few times.

This is weird. Something I’ve found in Albacete that you might never have heard about.

Sneakers.

A newsletter from the mayor of Los Angeles, California cites fears of many Los Angeles residents that «these shoes indicate sites at which drugs are sold or worse yet, gang turf», and that city and utility employees had launched a program to remove the shoes.[4] However, the practice also occurs along relatively remote stretches of rural highways that are unlikely scenes for gang murders, and have no structures at all to be crack houses.

So yeah, some people toss their shoes over power lines. You can read about that when you read about popular and black culture in the US. It’s part of Arthur Nersessian’s «The Swing Voter».
In that novel, someone destroys new york by placing Cobalt (dirty nuclear) Bombs in sneakers and tossing them around the city.

Anyway, take a look at this picture. It’s taken at the very heart of Albacete, a provincial capital in SE Spain.

This picture above is nothing special, just another act of shoe-tossing. The difference is that I took that picture in that very same provincial capital.  And I wonder, is there a crack kitchen in the center of a central Spain provintial town ?