Generic helper function which takes any enum value and returns that value cast to its integral representation.
template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
Since it is constexpr it can be used as follows:
std::array<int, to_integral(my_fields::field)> b;
http://stackoverflow.com/questions/14589417/can-an-enum-class-be-converted-to-the-underlying-type
This blog serves as a dumping ground for my own interests. On it you will find anything which I want to keep track of; links, articles, tips and tricks. Mostly it focuses on C++, Javascript and HTML, linux and performance.
Thursday, 14 May 2015
Thursday, 9 April 2015
Ubuntu terminal tab colors
This sets dark tab colors, except for the active tab, which is higlighted
$ vim ~/.config/gtk-3.0/gtk.css
TerminalWindow .notebook {
background-color: shade (#333333, 1.02);
background-image: none;
border-radius: 3px;
padding: 2px;
background-clip: border-box;
border-color: shade (#333333, 0.82);
border-width: 1px;
border-style: solid;
/*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/
/*font-weight: 300;*/
}
TerminalWindow .notebook tab {
background-image: none;
background-color: #333333;
border-style: solid;
border-image: -gtk-gradient (linear, left top, left bottom,
from (alpha (shade (#333333, 0.9), 0.0)),
to (shade (#333333, 0.9))) 1;
border-image-width: 0 1px;
border-color: transparent;
border-width: 0;
box-shadow: none;
/*color: shade (@fg_color, 1.2);*/
color: #AEA79F;
}
TerminalWindow .notebook tab:active {
border-color: shade (#333333, 0.82);
border-style: solid;
border-width: 1px;
background-color: shade (#AEA79F, 1.02);
background-image: none;
/*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/
color: #333333;
}
$ vim ~/.config/gtk-3.0/gtk.css
TerminalWindow .notebook {
background-color: shade (#333333, 1.02);
background-image: none;
border-radius: 3px;
padding: 2px;
background-clip: border-box;
border-color: shade (#333333, 0.82);
border-width: 1px;
border-style: solid;
/*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/
/*font-weight: 300;*/
}
TerminalWindow .notebook tab {
background-image: none;
background-color: #333333;
border-style: solid;
border-image: -gtk-gradient (linear, left top, left bottom,
from (alpha (shade (#333333, 0.9), 0.0)),
to (shade (#333333, 0.9))) 1;
border-image-width: 0 1px;
border-color: transparent;
border-width: 0;
box-shadow: none;
/*color: shade (@fg_color, 1.2);*/
color: #AEA79F;
}
TerminalWindow .notebook tab:active {
border-color: shade (#333333, 0.82);
border-style: solid;
border-width: 1px;
background-color: shade (#AEA79F, 1.02);
background-image: none;
/*box-shadow: inset 0 1px shade (#AEA79F, 1.1);*/
color: #333333;
}
Sunday, 15 March 2015
Pandas: merge 2 csv files of market data and plot the spread
import pandas as pd
import numpy as np
from datetime import datetime
%matplotlib inline
# load the csv files into pandas
def read_csv(filename):
return pd.read_csv(
filename,
dtype = {
'bid_vol' : np.float64,
'bid_price': np.float64,
'ask_vol' : np.float64,
'ask_price': np.float64
},
na_values=['nan'],
index_col='time',
parse_dates=['time'],
date_parser=lambda x: datetime.strptime(x[:15], "%H:%M:%S.%f"))
df1 = read_csv('mkt1.best')
df1 = read_csv('mkt2.best')
# since both dataframes have the same column names for price data we
# need to create a multiindex using the instrument id
out = dfs.pop(0)
for df in dfs:
out = out.append(df)
# add 'id' to the index
out = out.set_index('id', append=True)
# sort on timestamp
out = out.sort()
# pivot instr_id from the row index to the column index, leaving only timestamp as the row index
out = out.unstack()
# the times in the dataframes may not match up, so if we add them together, pandas will add NAN
# values for the other columns, so forward fill
out = out.ffill()
# reshuffle the column index so that instr_id is the top level, and the other column labels are the second level
out = out.swaplevel(0,1,axis=1)
# resort the column labels so that columns are grouped by instr_id
out = out.sort(axis=1)
return out
best = create_time_and_id_index([df1, df2])
# create spread columns
best['sell_spread'] = best[mkt2].ask_price - best.[mkt1].bid_price
best['buy_spread'] = best[mkt1].ask_price - best.[mkt2].bid_price
# plot the results!
best.plot(y='sell_spread', figsize=(20, 8))
import numpy as np
from datetime import datetime
%matplotlib inline
# load the csv files into pandas
def read_csv(filename):
return pd.read_csv(
filename,
dtype = {
'bid_vol' : np.float64,
'bid_price': np.float64,
'ask_vol' : np.float64,
'ask_price': np.float64
},
na_values=['nan'],
index_col='time',
parse_dates=['time'],
date_parser=lambda x: datetime.strptime(x[:15], "%H:%M:%S.%f"))
df1 = read_csv('mkt1.best')
df1 = read_csv('mkt2.best')
# since both dataframes have the same column names for price data we
# need to create a multiindex using the instrument id
def create_time_and_id_index(dfs):
# appends all the dataframes into one big dataframeout = dfs.pop(0)
for df in dfs:
out = out.append(df)
# add 'id' to the index
out = out.set_index('id', append=True)
# sort on timestamp
out = out.sort()
# pivot instr_id from the row index to the column index, leaving only timestamp as the row index
out = out.unstack()
# the times in the dataframes may not match up, so if we add them together, pandas will add NAN
# values for the other columns, so forward fill
out = out.ffill()
# reshuffle the column index so that instr_id is the top level, and the other column labels are the second level
out = out.swaplevel(0,1,axis=1)
# resort the column labels so that columns are grouped by instr_id
out = out.sort(axis=1)
return out
best = create_time_and_id_index([df1, df2])
# create spread columns
best['sell_spread'] = best[mkt2].ask_price - best.[mkt1].bid_price
best['buy_spread'] = best[mkt1].ask_price - best.[mkt2].bid_price
# plot the results!
best.plot(y='sell_spread', figsize=(20, 8))
Bash tab completion example
#!/bin/bash
_apps()
{
echo $(cat ${APPS} | awk '{print $1}' | grep -v -e '^#\|^$')
}
_servers()
{
echo $(cat ${SERVERS} | awk '{print $2}' | sort -u | cut -f2 -d@)
}
_options()
{
echo "--help --verbose --validate --quiet --server"
}
_commands()
{
echo "status start stop restart kill version config"
}
_contains()
{
local e
for e in ${@:2}; do
if [[ "$e" == "$1" ]]; then
echo 1
return 0
fi
done
echo 0
return 1
}
_complete()
{
local prev_cmd="${COMP_WORDS[COMP_CWORD-1]}"
local curr_cmd="${COMP_WORDS[COMP_CWORD]}"
if [[ ${prev_cmd} == "--server" ]]; then
COMPREPLY=( $(compgen -W "$(_servers)" -- ${curr_cmd}) )
return 0
fi
if [[ ${curr_cmd} == -* ]]; then
COMPREPLY=( $(compgen -W "$(_options)" -- ${curr_cmd}) )
return 0
fi
# previous command was an app name, so show commands
if [[ $(_contains "${prev_cmd}" "$(_apps)") -eq 1 ]]; then
COMPREPLY=( $(compgen -W "$(_commands)" -- ${curr_cmd}) )
return 0
fi
# otherwise try match an app name
COMPREPLY=( $(compgen -W "$(_apps)" -- ${curr_cmd}) )
}
_main()
{
complete -F _complete cmd
}
_main
_apps()
{
echo $(cat ${APPS} | awk '{print $1}' | grep -v -e '^#\|^$')
}
_servers()
{
echo $(cat ${SERVERS} | awk '{print $2}' | sort -u | cut -f2 -d@)
}
_options()
{
echo "--help --verbose --validate --quiet --server"
}
_commands()
{
echo "status start stop restart kill version config"
}
_contains()
{
local e
for e in ${@:2}; do
if [[ "$e" == "$1" ]]; then
echo 1
return 0
fi
done
echo 0
return 1
}
_complete()
{
local prev_cmd="${COMP_WORDS[COMP_CWORD-1]}"
local curr_cmd="${COMP_WORDS[COMP_CWORD]}"
if [[ ${prev_cmd} == "--server" ]]; then
COMPREPLY=( $(compgen -W "$(_servers)" -- ${curr_cmd}) )
return 0
fi
if [[ ${curr_cmd} == -* ]]; then
COMPREPLY=( $(compgen -W "$(_options)" -- ${curr_cmd}) )
return 0
fi
# previous command was an app name, so show commands
if [[ $(_contains "${prev_cmd}" "$(_apps)") -eq 1 ]]; then
COMPREPLY=( $(compgen -W "$(_commands)" -- ${curr_cmd}) )
return 0
fi
# otherwise try match an app name
COMPREPLY=( $(compgen -W "$(_apps)" -- ${curr_cmd}) )
}
_main()
{
complete -F _complete cmd
}
_main
Tuesday, 10 March 2015
C++11 - Unevaluated operands
Operands of sizeof, typeid, decltype and noexcept are never evaluated
We therefore only need a declaration, not the definition, to use a function or object's name in these contexts
std::declval<T>() returns T&&
std::declval<T&>() returns T&
decltype( foo(std::declval<T>()) ) returns foo's return type when foo is called with T&&
declval allows us to provide a declaration without having to evaluate the expression (ie: in an unevaluated context) - useful for SFINAE etc
Example: testing for copy-assignability
template<class T>
class is_copy_assignable
{
template<class U, class=decltype(declval<U&>()=declval<const U&>())>
static true_type try_assignment(U&&);
template<class U>
static false_type try_assignment(...); // catch-all fallback
public:
using type = decltype(try_assignment(declval<T>()));
};
How this works:
try_assignment(...) will match anything, but is also always the worst match, so if the other try_assignment can match, it will.
type will be the return type of try_assignment, which will either be true_type or false_type
the true_type overload will only work if the expression U& = const U& is valid - ie: if it is copy assignable
We use a second template parameter to allow SFINAE to kick in. It is unnamed because we only use it for SFINAE.
Example: testing for copy-assignability, and requiring an lvalue reference return type
The above example doesn't force a requirement on the copy assignment returning an lvalue reference.
If we assign an alias template to the returned type:
template<class T>
using copy_assignment_t = decltype(declval<T&>() = declval<const T&>());
We can then check whether that is a T& in a SFINAE specialisation
template<class T, class=void>
struct is_copy_assignable
: std::false_type {};
template<class T>
struct is_copy_assignable<T, void_t<copy_assignment_t<T>>>
: std::is_same<copy_assignment_t<T>,T&> {};
We therefore only need a declaration, not the definition, to use a function or object's name in these contexts
std::declval<T>() returns T&&
std::declval<T&>() returns T&
decltype( foo(std::declval<T>()) ) returns foo's return type when foo is called with T&&
declval allows us to provide a declaration without having to evaluate the expression (ie: in an unevaluated context) - useful for SFINAE etc
Example: testing for copy-assignability
template<class T>
class is_copy_assignable
{
template<class U, class=decltype(declval<U&>()=declval<const U&>())>
static true_type try_assignment(U&&);
template<class U>
static false_type try_assignment(...); // catch-all fallback
public:
using type = decltype(try_assignment(declval<T>()));
};
How this works:
try_assignment(...) will match anything, but is also always the worst match, so if the other try_assignment can match, it will.
type will be the return type of try_assignment, which will either be true_type or false_type
the true_type overload will only work if the expression U& = const U& is valid - ie: if it is copy assignable
We use a second template parameter to allow SFINAE to kick in. It is unnamed because we only use it for SFINAE.
Example: testing for copy-assignability, and requiring an lvalue reference return type
The above example doesn't force a requirement on the copy assignment returning an lvalue reference.
If we assign an alias template to the returned type:
template<class T>
using copy_assignment_t = decltype(declval<T&>() = declval<const T&>());
We can then check whether that is a T& in a SFINAE specialisation
struct is_copy_assignable
: std::false_type {};
template<class T>
struct is_copy_assignable<T, void_t<copy_assignment_t<T>>>
: std::is_same<copy_assignment_t<T>,T&> {};
Monday, 19 January 2015
find files older than today and zip them up with the date as part of the extension
1. find files older than today in a given directory with a given extension
$ find -mtime +1 ${DIR} -name "*.${EXT}"
2. calculate the last modified time (seconds since epoch)
$ MOD_SECS=$(stat -c%Y ${FILE})
3. convert the seconds since epoch into a human readable date format
$ MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
4. create a gzip file with the suffix including the date when the file was last modified
$ gzip -S .${MOD_DATE}.gz ${FILE}
5. putting it all together
for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
MOD_SECS=$(stat -c%Y ${FILE})
MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
gzip -S .${MOD_DATE}.gz ${FILE}
done
6. as a script:
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: $0 dir ext"
exit 1
fi
DIR=$1
EXT=$2
for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
MOD_SECS=$(stat -c%Y ${FILE})
MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
gzip -S .${MOD_DATE}.gz ${FILE}
done
$ find -mtime +1 ${DIR} -name "*.${EXT}"
2. calculate the last modified time (seconds since epoch)
$ MOD_SECS=$(stat -c%Y ${FILE})
3. convert the seconds since epoch into a human readable date format
$ MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
4. create a gzip file with the suffix including the date when the file was last modified
$ gzip -S .${MOD_DATE}.gz ${FILE}
5. putting it all together
for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
MOD_SECS=$(stat -c%Y ${FILE})
MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
gzip -S .${MOD_DATE}.gz ${FILE}
done
6. as a script:
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: $0 dir ext"
exit 1
fi
DIR=$1
EXT=$2
for FILE in $(find ${DIR} -mtime +1 -name "*.${EXT}"); do
MOD_SECS=$(stat -c%Y ${FILE})
MOD_DATE=$(date +\%Y-\%m-\%d --date="@${MOD_SECS}")
gzip -S .${MOD_DATE}.gz ${FILE}
done
Tuesday, 6 January 2015
bash command line parsing
We want to be able to mix both optional flags, optional arguments and positional arguments
optional flags: getopts character, not followed by a ':'
optional arguments: getopts character, followed by a ':' (which means "take an argument"
positional arguments: after the getopts, use $OPTIND which is the index of the last option getopts parsed.
$ script.sh [options] ARG1 ARG2
#!/bin/bash
usage()
{
echo "Usage: $0 [-a foo] [-b] ARG1 ARG2" 1>&2;
exit 1
}
while getopts ":a:bh" o; do
case "${o}" in
a) a=${OPTARG};;
b) b=YES;; # turn on flag
h) usage ;; # display help
esac
done
# store positional arguments
ARG1=${@:$OPTIND:1}
ARG2=${@:$OPTIND+1:1}
# check positional arguments have been supplied
if [ -z "${ARG1}" ] || [ -z "${ARG2}" ]; then
usage
fi
# display the results
echo a=${a}
echo b=${b}
echo ARG1=${ARG1}
echo ARG2=${ARG2}
optional flags: getopts character, not followed by a ':'
optional arguments: getopts character, followed by a ':' (which means "take an argument"
positional arguments: after the getopts, use $OPTIND which is the index of the last option getopts parsed.
$ script.sh [options] ARG1 ARG2
#!/bin/bash
usage()
{
echo "Usage: $0 [-a foo] [-b] ARG1 ARG2" 1>&2;
exit 1
}
while getopts ":a:bh" o; do
case "${o}" in
a) a=${OPTARG};;
b) b=YES;; # turn on flag
h) usage ;; # display help
esac
done
# store positional arguments
ARG1=${@:$OPTIND:1}
ARG2=${@:$OPTIND+1:1}
# check positional arguments have been supplied
if [ -z "${ARG1}" ] || [ -z "${ARG2}" ]; then
usage
fi
# display the results
echo a=${a}
echo b=${b}
echo ARG1=${ARG1}
echo ARG2=${ARG2}
Subscribe to:
Posts (Atom)