#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
A wrapper for cargo bench
Its numeric output is parsed and dumped to a csv
Pass an an optional independent variable from the command line
And also any other static keys and values

USAGE: python aggregate_bench.py [independent variable]
Writes to measurements.csv in the cwd by default, pass a different filepath to alter this
any other keyword arguments will be written as a header row and value. Be careful with that.

(C) Stephan Hügel 2016
License: MIT
"""
import os
import sys
import csv
from subprocess import check_output
import re
pattern = re.compile(
    r"bench:\s+([0-9,]*)\D+([0-9,]*)"
)

def dump_benchmark(
    pattern,
    filepath="measurements.csv",
    headers=['time', 'error'],
    idep_var=None,
    **kwargs):
    """ If I have to append benchmark output to a CSV once more I'm going
    to drown the world in a bath of fire. This should just work.
    Customise with your own output path and header row.
    idep_var is an optional independent variable.
    """
    # run cargo bench in cwd, capture output
    result = re.search(pattern, check_output(["cargo", "bench"]))
    # get rid of nasty commas, convert to int
    output = [int(group.translate(None, ',')) for group in result.groups()]
    # this one's special because wtf are we measuring without an independent variable
    if idep_var:
        headers.append("independent_variable")
        output.append(idep_var)
    # any other kwargs will be written as a CSV header row and value
    # nothing prevents you from writing rows that don't have a header
    for k, v in kwargs.items():
        headers.append(k),
        output.append(v)
    # check that path and file exist, or create them
    path_wrangle(filepath, headers)
    with open(filepath, 'a') as handle:
        wr = csv.writer(handle)
        wr.writerow(output)

def path_wrangle(filepath, headers):
    """ Check for or create path and output file
    There's no error handling, because noisy failure's probably a good thing
    """
    # check for or create directory path
    directory = os.path.split(filepath)[0]
    if not os.path.exists(directory):
            os.makedirs(directory)
    # if that worked, see if the CSV exists, and create a new one if necessary
    if not os.path.isfile(filepath):
        with open(filepath, 'w') as newhandle:
            wr = csv.writer(newhandle)
            wr.writerow(headers)

if __name__ == "__main__":
    # You know what an independent variable is, of course
    idep_var = None
    # So brittle. Shhh.
    if sys.argv[1] is not None:
        idep_var = sys.argv[1]
    dump_benchmark(pattern, filepath="benches/measurements.csv", idep_var=idep_var)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
A wrapper for cargo bench
Its numeric output is parsed and dumped to a csv
Pass an an optional independent variable from the command line
And also any other static keys and values

USAGE: python aggregate_bench.py [independent variable]
Writes to measurements.csv in the cwd by default, pass a different filepath to alter this
any other keyword arguments will be written as a header row and value. Be careful with that.

(C) Stephan Hügel 2016
License: MIT
"""
import os
import sys
import csv
from subprocess import check_output
import re
pattern = re.compile(
    r"bench:\s+([0-9,]*)\D+([0-9,]*)"
)

def dump_benchmark(
    pattern,
    filepath="measurements.csv",
    headers=['time', 'error'],
    idep_var=None,
    **kwargs):
    """ If I have to append benchmark output to a CSV once more I'm going
    to drown the world in a bath of fire. This should just work.
    Customise with your own output path and header row.
    idep_var is an optional independent variable.
    """
    # run cargo bench in cwd, capture output
    result = re.search(pattern, check_output(["cargo", "bench"]))
    # get rid of nasty commas, convert to int
    output = [int(group.translate(None, ',')) for group in result.groups()]
    # this one's special because wtf are we measuring without an independent variable
    if idep_var:
        headers.append("ivariable")
        output.append(idep_var)
    # any other kwargs will be written as a CSV header row and value
    # nothing prevents you from writing rows that don't have a header
    for k, v in kwargs.items():
        headers.append(k),
        output.append(v)
    # check that path and file exist, or create them
    path_wrangle(filepath, headers)
    with open(filepath, 'a') as handle:
        wr = csv.writer(handle)
        wr.writerow(output)

def path_wrangle(filepath, headers):
    """ Check for or create path and output file
    There's no error handling, because noisy failure's probably a good thing
    """
    # check for or create directory path
    directory = os.path.split(filepath)[0]
    if not os.path.exists(directory):
            os.makedirs(directory)
    # if that worked, see if the CSV exists, and create a new one if necessary
    if not os.path.isfile(filepath):
        with open(filepath, 'w') as newhandle:
            wr = csv.writer(newhandle)
            wr.writerow(headers)

if __name__ == "__main__":
    # You know what an independent variable is, of course
    idep_var = None
    # So brittle. Shhh.
    if sys.argv[1] is not None:
        idep_var = sys.argv[1]
    dump_benchmark(
        pattern,
        filepath="benches/benchmarks.csv",
        idep_var=idep_var,
        num_points=100000,
        cores=2,
        method="crossbeam"
    )

Make function call a bit more readable