Instruction:
Can you implement a function in Python 3 that
names calculate_bestfit_line_through_deagnetization DESCRIPTION calculate_bestfit_line_through_deagnetization is the main function for the demagnetization module.

Response:
def main():
    """
    NAME
       pca.py

    DESCRIPTION
       calculates best-fit line/plane through demagnetization data

    INPUT FORMAT
       takes specimen_name treatment intensity declination inclination  in space delimited file

    SYNTAX
       pca.py [command line options][< filename]

    OPTIONS
        -h prints help and quits
        -f FILE
        -dir [L,P,F][BEG][END] specify direction type, beginning and end
          (L:line, P:plane or F:fisher mean of unit vectors)
          BEG: first step (NRM = step zero)
          END: last step (NRM = step zero)
        < filename for reading from standard input
    OUTPUT:
        specimen_name calculation_type N beg end MAD dec inc
        if calculation_type is 'p', dec and inc are pole to plane, otherwise, best-fit direction

    EXAMPLE:
        pca.py -dir L  1 5 <ex3.3
        will calculate best-fit line through demagnetization steps 1 and 5 from file ex5.1

    """
    if '-h' in sys.argv: # check if help is needed
        print(main.__doc__)
        sys.exit() # graceful quit
    if '-f' in sys.argv:
        ind=sys.argv.index('-f')
        file=sys.argv[ind+1]
        f=open(file,'r')
        data=f.readlines()
    else:
        data=sys.stdin.readlines() # read in data from standard input
    if '-dir' in sys.argv: #
        ind=sys.argv.index('-dir')
        typ=sys.argv[ind+1]
        if typ=='L': calculation_type='DE-BFL'
        if typ=='P': calculation_type='DE-BFP'
        if typ=='F': calculation_type='DE-FM'
        beg_pca = int(sys.argv[ind+2])
        end_pca = int(sys.argv[ind+3])
#
#
    datablock= [] # set up list for data
    s=""
    ind=0
    for line in data:   # read in the data from standard input
        rec=line.split() # split each line on space to get records
        if s=="":
            s=rec[0]
            print(s, calculation_type)
        print(ind,rec[1],rec[3],rec[4],rec[2])
        ind+=1
        datablock.append([float(rec[1]),float(rec[3]),float(rec[4]),float(rec[2]),'0']) # treatment,dec,inc,int,dummy
    mpars=pmag.domean(datablock,beg_pca,end_pca,calculation_type)
    if calculation_type=="DE-FM":
        print('%s %s %i  %6.2f %6.2f %6.1f %7.1f %7.1f' % (s,calculation_type,mpars["specimen_n"],mpars["measurement_step_min"],mpars["measurement_step_max"],mpars["specimen_a95"],mpars["specimen_dec"],mpars["specimen_inc"]))
    else:
        print('%s %s %i  %6.2f %6.2f %6.1f %7.1f %7.1f' % (s,calculation_type,mpars["specimen_n"],mpars["measurement_step_min"],mpars["measurement_step_max"],mpars["specimen_mad"],mpars["specimen_dec"],mpars["specimen_inc"]))


Instruction:
Can you write a function in Python 3 where it
names pt_rot.py DESCRIPTION rotates pt according to specified age and plate SYNTAX pt_rot.py [command line options] OPTIONS -h prints help and quits -f file with lon lat plate age Dplate as space delimited input Dplate is the destination plate coordinates desires - default is "fixed south africa" Dplate should be one of: [nwaf, neaf,saf,aus, eur, ind, sam, ant, grn, nam] -ff file Efile, file has lat lon data file and Efile has sequential rotation poles: Elat Elon Omega -F OFILE, output sites (pmag_results) formatted file with rotated points stored in pole_lon, pole_lat (vgp_lon, vgp_lat). (data_model=2.5) default is to print out rotated lon, lat to standard output -dm [2.5,3] set data model for output. Default is 3

Response:
def main():
    """
    NAME
        pt_rot.py

    DESCRIPTION
        rotates pt according to specified age and plate

    SYNTAX
        pt_rot.py [command line options]

    OPTIONS
        -h prints help and quits
        -f file with lon lat plate age Dplate as space delimited input
           Dplate is the destination plate coordinates desires
           - default is "fixed south africa"
           Dplate should be one of: [nwaf, neaf,saf,aus, eur, ind, sam, ant, grn, nam]
        -ff file Efile,   file  has lat lon data file and Efile has sequential rotation poles: Elat Elon Omega
        -F OFILE, output sites (pmag_results) formatted file with rotated points stored in pole_lon, pole_lat (vgp_lon, vgp_lat).  (data_model=2.5)
           default is to print out rotated lon, lat to standard output
        -dm [2.5,3] set data model for output.  Default is 3
    """
    dir_path='.'
    PTS=[]
    ResRecs=[]
    ofile=""
    data_model=3
    Dplates=['nwaf', 'neaf','saf','aus', 'eur', 'ind', 'sam', 'ant', 'grn', 'nam']
    if '-WD' in sys.argv:
        ind = sys.argv.index('-WD')
        dir_path=sys.argv[ind+1]
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-F' in sys.argv:
        ind = sys.argv.index('-F')
        ofile=dir_path+'/'+sys.argv[ind+1]
    if '-dm' in sys.argv:
        ind = sys.argv.index('-dm')
        data_model=dir_path+'/'+sys.argv[ind+1]
    if '-f' in sys.argv:
        ind = sys.argv.index('-f')
        file=dir_path+'/'+sys.argv[ind+1]
        f=open(file,'r')
        data=f.readlines()
    elif '-ff' in sys.argv:
        ind = sys.argv.index('-ff')
        file=dir_path+'/'+sys.argv[ind+1]
        f=open(file,'r')
        data=f.readlines()
        Efile=dir_path+'/'+sys.argv[ind+2]
        f=open(Efile,'r')
        edata=f.readlines()
        Poles=[]
        for p in edata:
             rec=p.split()
             pole=[float(rec[0]),float(rec[1]),float(rec[2])] # pole is lat/lon/omega
             Poles.append(pole)
    else:
        data=sys.stdin.readlines()
    polelatkey,polelonkey='pole_lat','pole_lon'
    if data_model!=3:
        polelatkey,polelonkey='vgp_lat','vgp_lon'
    for line in data:
        PtRec={}
        rec=line.split()
        PtRec['site_lon']=rec[0]
        PtRec['site_lat']=rec[1]
        if '-ff' in sys.argv:
            pt_lat,pt_lon=float(rec[1]),float(rec[0])
            for pole in Poles:
                ptrot= pmag.pt_rot(pole,[pt_lat],[pt_lon])
                pt_lat=ptrot[0][0]
                pt_lon=ptrot[1][0]
            if ofile=="":
                print(ptrot[1][0], ptrot[0][0])
            else:
                ResRec={polelonkey: '%7.1f'%(ptrot[0][0]),polelatkey:'%7.1f'%( ptrot[1][0])}
                ResRecs.append(ResRec)
        else:
            PtRec['cont']=rec[2]
            if PtRec['cont']=='af':PtRec['cont']='saf' # use fixed south africa
            PtRec['age']=rec[3]
            if len(rec)>4:
               PtRec['dcont']=rec[4]
            PTS.append(PtRec)
    if '-ff' not in sys.argv:
        for pt in PTS:
            pole='not specified'
            pt_lat=float(pt['site_lat'])
            pt_lon=float(pt['site_lon'])
            age=float(pt['age'])
            ptrot=[[pt_lat],[pt_lon]]
            if pt['cont']=='ib':
                pole=frp.get_pole(pt['cont'],age)
                ptrot= pmag.pt_rot(pole,[pt_lat],[pt_lon])
                pt_lat=ptrot[0][0]
                pt_lon=ptrot[1][0]
                pt['cont']='eur'
            if pt['cont']!='saf':
                pole1=frp.get_pole(pt['cont'],age)
                ptrot= pmag.pt_rot(pole1,[pt_lat],[pt_lon])
                if 'dcont' in list(pt.keys()):
                    pt_lat=ptrot[0][0]
                    pt_lon=ptrot[1][0]
                    pole=frp.get_pole(pt['dcont'],age)
                    pole[2]=-pole[2]
                    ptrot= pmag.pt_rot(pole,[pt_lat],[pt_lon])
                if ofile=="":
                    print(ptrot[1][0], ptrot[0][0])
                else:
                    ResRec={polelonkey: '%7.1f'%(ptrot[0][0]),polelatkey:'%7.1f'%( ptrot[1][0])}
                    ResRecs.append(ResRec)
            else:
                if 'dcont' in list(pt.keys()):
                    pole=frp.get_pole(pt['dcont'],age)
                    pole[2]=-pole[2]
                    ptrot= pmag.pt_rot(pole,[pt_lat],[pt_lon])
                    print(ptrot)
                    if ofile=="":
                        print(ptrot[1][0], ptrot[0][0])
                    else:
                        ResRec={polelonkey: '%7.1f'%(ptrot[0][0]),polelatkey:'%7.1f'%( ptrot[1][0])}
                        ResRecs.append(ResRec)
                else:
                    if ofile=="":
                        print(ptrot[1][0], ptrot[0][0])
                    else:
                        ResRec={polelonkey: '%7.1f'%(ptrot[0][0]),polelatkey:'%7.1f'%( ptrot[1][0])}
                        ResRecs.append(ResRec)
    if len(ResRecs)>0:
        if data_model==3:
            pmag.magic_write(ofile,ResRecs,'locations')
        else:
            pmag.magic_write(ofile,ResRecs,'pmag_results')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def requiredUnless(col_name, arg, dm, df, *args):
    # if column name is present, no need to check if it is required
    if col_name in df.columns:
        return None
    arg_list = arg.split(",")
    arg_list = [argument.strip('"') for argument in arg_list]
    msg = ""
    for a in arg_list:
        # ignore validations that reference a different table
        if "." in a:
            continue
        if a not in df.columns:
            msg += "{} column is required unless {} is present.  ".format(col_name, a)
    if msg:
        return msg
    else:
        return None
    return None

Response: Check if a column is required in df unless it is present in dm.


Instruction:
How would you explain what the following Python 3 function does
def requiredUnlessTable(col_name, arg, dm, df, con=None):
    table_name = arg
    if col_name in df.columns:
        return None
    elif not con:
        return None
    elif table_name in con.tables:
        return None
    else:
        return "{} column is required unless table {} is present".format(col_name, table_name)

Response:
This function checks that the given column is present in df unless it is present in contribution
   .


Instruction:
Can you tell what is the following Python 3 function doing
def required(col_name, arg, dm, df, *args):
    if col_name in df.columns:
        return None
    else:
        return '"{}" column is required'.format(col_name)

Response: Check if a column is required in df.


Instruction:
Can you create a Python 3 function that
checks if a value in a column is in another table.

Response:
def isIn(row, col_name, arg, dm, df, con=None):
    """
    row[col_name] must contain a value from another column.
    If not, return error message.
    """
    #grade = df.apply(func, args=(validation_name, arg, dm), axis=1)
    cell_value = row[col_name]
    cell_value = str(cell_value)
    if not cell_value:
        return None
    elif cell_value == 'None':
        return None
    elif cell_value == 'nan':
        return None
    elif not con:
        return None
    # if it's in another table
    cell_values = [v.strip(" ") for v in cell_value.split(":")]
    if "." in arg:
        table_name, table_col_name = arg.split(".")
        if table_name not in con.tables:
            return None
            #return "Must contain a value from {} table. Missing {} table.".format(table_name, table_name)
        if table_col_name not in con.tables[table_name].df.columns:
            return '{} table is missing "{}" column, which is required for validating "{}" column'.format(table_name, table_col_name, col_name)
        possible_values = con.tables[table_name].df[table_col_name].unique()
        for value in cell_values:
            if value not in possible_values:
                trunc_possible_values = [val.replace(' ', '') for val in possible_values if val]
                trunc_cell_value = cell_value.replace(' ', '')
                if trunc_cell_value not in trunc_possible_values:
                    if trunc_cell_value != value:
                        return 'This value (long): "{}" is not found in: {} column in {} table.  Also (short): {} is not in {}'.format(value, table_col_name, table_name, trunc_cell_value, arg)
                    else:
                        return 'This value: "{}" is not found in: {} column in {} table'.format(value, table_col_name, table_name)
                    break
    # if it's in the present table:
    else:
        possible_values = df[arg].unique()
        for value in cell_values:
            if value not in possible_values:
                return 'This value: "{}" is not found in: {} column'.format(value, arg)
                break
    return None


Instruction:
Here you have a function in Python 3, explain what it does
def checkMax(row, col_name, arg, *args):
    cell_value = row[col_name]
    if not cell_value:
        return None
    elif isinstance(cell_value, float):
        if np.isnan(cell_value):
            return None
    try:
        arg_val = float(arg)
    except ValueError:
        if arg in row.index:
            arg_val = row[arg]
        else:
            return None
    if cb.is_null(arg_val):
        return None
    #arg = float(arg)
    try:
        if float(cell_value) <= float(arg_val):
            return None
        else:
            return "{} ({}) must be <= {} ({})".format(str(cell_value), col_name, str(arg_val), str(arg))
    # this happens when the value isn't a float (an error which will be caught elsewhere)
    except ValueError:
        return None

Response: Check that the value of col_name is less than or equal to arg.


Instruction:
Make a summary of the following Python 3 code
def cv(row, col_name, arg, current_data_model, df, con):
    vocabulary = con.vocab.vocabularies
    cell_value = str(row[col_name])
    if not cell_value:
        return None
    elif cell_value == "None":
        return None
    cell_values = cell_value.split(":")
    cell_values = [c.strip() for c in cell_values]
    # get possible values for controlled vocabulary
    # exclude weird unicode
    possible_values = []
    for val in vocabulary[col_name]:
        try:
            possible_values.append(str(val).lower())
        except UnicodeEncodeError as ex:
            print(val, ex)
    for value in cell_values:
        if str(value).lower() == "nan":
            continue
        elif str(value).lower() in possible_values:
            continue
        elif value.lower() == "none":
            continue
        else:
            try:
                if str(float(value)) in possible_values:
                    continue
            except:
                pass
            return '"{}" is not in controlled vocabulary for {}'.format(value, arg)
    return None

Response: This function checks if a controlled vocabulary value is in the appropriate controlled vocabulary for the given arg.


Instruction:
Make a summary of the following Python 3 code
def validate_df(df, dm, con=None):
    # check column validity
    required_one = {}  # keep track of req'd one in group validations here
    cols = df.columns
    invalid_cols = [col for col in cols if col not in dm.index]
    # go through and run all validations for the data type
    for validation_name, validation in dm.iterrows():
        value_type = validation['type']
        if validation_name in df.columns:
            output = df[validation_name].apply(test_type, args=(value_type,))
            df["type_pass" + "_" + validation_name + "_" + value_type] = output
        #
        val_list = validation['validations']
        if not val_list or isinstance(val_list, float):
            continue
        for num, val in enumerate(val_list):
            func_name, arg = split_func(val)
            if arg == "magic_table_column":
                continue
            # first validate for presence
            if func_name in presence_operations:
                func = presence_operations[func_name]
                #grade = func(validation_name, df, arg, dm)
                grade = func(validation_name, arg, dm, df, con)
                pass_col_name = "presence_pass_" + validation_name + "_" + func.__name__
                df[pass_col_name] = grade
            # then validate for correct values
            elif func_name in value_operations:
                func = value_operations[func_name]
                if validation_name in df.columns:
                    grade = df.apply(func, args=(validation_name, arg, dm, df, con), axis=1)
                    col_name = "value_pass_" + validation_name + "_" + func.__name__
                    if col_name in df.columns:
                        num_range = list(range(1, 10))
                        for num in num_range:
                            if (col_name + str(num)) in df.columns:
                                continue
                            else:
                                col_name = col_name + str(num)
                                break
                    df[col_name] = grade.astype(object)
            # last, validate at the column group level
            elif func_name in group_operations:
                func = group_operations[func_name]
                missing = func(validation_name, arg, dm, df)
                if arg not in required_one:
                    required_one[arg] = [missing]
                else:
                    required_one[arg].append(missing)
        # format the group validation columns
        for key, value in list(required_one.items()):
            if None in value:
                # this means at least one value from the required group is present,
                # so the validation passes
                continue
            else:
                # otherwise, all of the values from the required group are missing,
                # so the validation fails
                df["group_pass_{}".format(key)] = "you must have one column from group {}: {}".format(key, ", ".join(value))

    return df

Response: Validate a DataFrame and return a new DataFrame with some required columns.


Instruction:
Can you implement a function in Python 3 that
gets the names of all validation columns in a single node.

Response:
def get_validation_col_names(df):
    """
    Input: validated pandas DataFrame (using validate_df)
    Output: names of all value validation columns,
            names of all presence validation columns,
            names of all type validation columns,
            names of all missing group columns,
            names of all validation columns (excluding groups).
    """
    value_cols = df.columns.str.match("^value_pass_")
    present_cols = df.columns.str.match("^presence_pass")
    type_cols = df.columns.str.match("^type_pass_")
    groups_missing = df.columns.str.match("^group_pass_")
    #
    value_col_names = df.columns[value_cols]
    present_col_names = df.columns[present_cols]
    type_col_names = df.columns[type_cols]
    group_missing_names = df.columns[groups_missing]
    #
    # all validation columns
    validation_cols = np.where(value_cols, value_cols, present_cols)
    validation_cols = np.where(validation_cols, validation_cols, type_cols)
    validation_col_names = df.columns[validation_cols]
    return value_col_names, present_col_names, type_col_names, group_missing_names, validation_col_names


Instruction:
Can you generate the documentation for the following Python 3 function
def print_row_failures(failing_items, verbose=False, outfile_name=None):
    if outfile_name:
        outfile = open(outfile_name, "w")
        outfile.write("\t".join(["name", "row_number", "problem_type",
                                 "problem_col", "error_message"]))
        outfile.write("\n")
    else:
        outfile = None
    for ind, row in failing_items.iterrows():
        issues = row['issues']
        string = "{:10}  |  row number: {}".format(ind, str(row["num"]))
        first_string = "\t".join([str(ind), str(row["num"])])
        if verbose:
            print(first_string)
        #if outfile:
        #    ofile.write("{}\n".format(string))
        for key, issue in list(issues.items()):
            issue_type, issue_col = extract_col_name(key)
            string = "{:10}  |  {:10}  |  {}".format(issue_type, issue_col, issue)
            string = "\t".join([issue_type, issue_col, issue])
            if verbose:
                print(string)
            if outfile:
                outfile.write(first_string + "\t" + string + "\n")
    if outfile:
        outfile.close()

Response: Print the failures of the given DataFrame to a file.


Instruction:
Make a summary of the following Python 3 code
def get_row_failures(df, value_cols, type_cols, verbose=False, outfile=None):
    # set temporary numeric index
    df["num"] = list(range(len(df)))
    # get column names for value & type validations
    names = value_cols.union(type_cols)
    # drop all non validation columns
    value_problems = df[names.union(["num"])]
    # drop validation columns that contain no problems
    failing_items = value_problems.dropna(how="all", subset=names)
    if not len(failing_items):
        if verbose:
            print("No problems")
        return []
    failing_items = failing_items.dropna(how="all", axis=1)
    # get names of the failing items
    bad_items = list(failing_items.index)
    # get index numbers of the failing items
    bad_indices = list(failing_items["num"])
    failing_items['issues'] = failing_items.drop("num", axis=1).apply(make_row_dict, axis=1).values
    # take output and print/write to file
    print_row_failures(failing_items, verbose, outfile)
    return failing_items

Response: Get details on each detected issue in a row by row.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_bad_rows_and_cols(df, validation_names, type_col_names,
                          value_col_names, verbose=False):
    """
    Input: validated DataFrame, all validation names, names of the type columns,
    names of the value columns, verbose (True or False).
    Output: list of rows with bad values, list of columns with bad values,
    list of missing (but required) columns.
    """
    df["num"] = list(range(len(df)))
    problems = df[validation_names.union(["num"])]
    all_problems = problems.dropna(how='all', axis=0, subset=validation_names)
    value_problems = problems.dropna(how='all', axis=0, subset=type_col_names.union(value_col_names))
    all_problems = all_problems.dropna(how='all', axis=1)
    value_problems = value_problems.dropna(how='all', axis=1)
    if not len(problems):
        return None, None, None
    #
    bad_cols = all_problems.columns
    prefixes = ["value_pass_", "type_pass_"]
    missing_prefix = "presence_pass_"
    problem_cols = []
    missing_cols = []
    long_missing_cols = []
    problem_rows = []
    for col in bad_cols:
        pre, stripped_col = extract_col_name(col)
        for prefix in prefixes:
            if col.startswith(prefix):
                problem_cols.append(stripped_col)
                continue
        if col.startswith(missing_prefix):
            missing_cols.append(stripped_col)
            long_missing_cols.append(col)
    if len(value_problems):
        bad_rows = list(zip(list(value_problems["num"]), list(value_problems.index)))
    else:
        bad_rows = []
    if verbose:
        if bad_rows:
            formatted_rows = ["row: {}, name: {}".format(row[0], row[1]) for row in bad_rows]
            if len(bad_rows) > 5:
                print("-W- these rows have problems:\n", "\n".join(formatted_rows[:5]), " ...")
                print("(for full error output see error file)")
            else:
                print("-W- these rows have problems:", "\n".join(formatted_rows))
        if problem_cols:
            print("-W- these columns contain bad values:", ", ".join(set(problem_cols)))
        if missing_cols:
            print("-W- these required columns are missing:", ", ".join(missing_cols))
    return bad_rows, problem_cols, missing_cols

Response: Get bad rows and columns from a validated DataFrame.


Instruction:
Given the following Python 3 function, write the documentation
def validate_table(the_con, dtype, verbose=False, output_dir="."):
    print("-I- Validating {}".format(dtype))
    # grab dataframe
    current_df = the_con.tables[dtype].df
    # grab data model
    current_dm = the_con.tables[dtype].data_model.dm[dtype]
    # run all validations (will add columns to current_df)
    current_df = validate_df(current_df, current_dm, the_con)
    # get names of the added columns
    value_col_names, present_col_names, type_col_names, missing_groups, validation_col_names = get_validation_col_names(current_df)
    # print out failure messages
    ofile = os.path.join(output_dir, "{}_errors.txt".format(dtype))
    failing_items = get_row_failures(current_df, value_col_names,
                                     type_col_names, verbose, outfile=ofile)
    bad_rows, bad_cols, missing_cols = get_bad_rows_and_cols(current_df, validation_col_names,
                                                             value_col_names, type_col_names,
                                                             verbose=True)
    # delete all validation rows
    current_df.drop(validation_col_names, axis=1, inplace=True)
    current_df.drop(missing_groups, axis=1, inplace=True)
    if len(failing_items):
        print("-I- Complete list of row errors can be found in {}".format(ofile))
        return dtype, bad_rows, bad_cols, missing_cols, missing_groups, failing_items
    elif len(missing_cols) or len(missing_groups):
        print("-I- You are missing some required headers")
        if len(missing_cols):
            print("-I- You are missing these required headers: {}".format(", ".join(missing_cols)))
        if len(missing_groups):
            formatted_groups = [group[11:] for group in missing_groups]
            print('-I- You need at least one header from these groups: {}'.format(", ".join(formatted_groups)))
        else:
            formatted_groups = []
        return dtype, bad_rows, bad_cols, missing_cols, formatted_groups, failing_items
    else:
        print("-I- No row errors found!")
        return False

Response: Validate a single table.


Instruction:
Make a summary of the following Python 3 code
def validate_contribution(the_con):
    passing = True
    for dtype in list(the_con.tables.keys()):
        print("validating {}".format(dtype))
        fail = validate_table(the_con, dtype)
        if fail:
            passing = False
        print('--')

Response: Validate a Contribution and return a list of all the tables that are valid.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def split_func(string):
    ind = string.index("(")
    return string[:ind], string[ind+1:-1].strip('"')

Response: Takes a string like requiredIf ( arg_name ) return the function name and the argument


Instruction:
Given the following Python 3 function, write the documentation
def get_degree_cols(df):
    vals = ['lon_w', 'lon_e', 'lat_lon_precision', 'pole_lon',
            'paleolon', 'paleolon_sigma',
            'lon', 'lon_sigma', 'vgp_lon', 'paleo_lon', 'paleo_lon_sigma',
            'azimuth', 'azimuth_dec_correction', 'dir_dec',
            'geographic_precision', 'bed_dip_direction']
    relevant_cols = list(set(vals).intersection(df.columns))
    return relevant_cols

Response: Take in a pandas DataFrame and return a list of columns that are in that DataFrame AND should be between 0 - 360 degrees.


Instruction:
Here you have a function in Python 3, explain what it does
def extract_col_name(string):
    prefixes = ["presence_pass_", "value_pass_", "type_pass_"]
    end = string.rfind("_")
    for prefix in prefixes:
        if string.startswith(prefix):
            return prefix[:-6], string[len(prefix):end]
    return string, string

Response: Takes a string and splits it into a column name and the validation column name.


Instruction:
Explain what the following Python 3 code does
def make_row_dict(row):
    ind = row[row.notnull()].index
    values = row[row.notnull()].values
    # to transformation with extract_col_name here???
    return dict(list(zip(ind, values)))

Response: Takes in a DataFrame row and returns a dictionary with the row s index as key and the row s values as values.


Instruction:
Can you write a function in Python 3 where it
names eq_di. py . py

Response:
def main():
    """
    NAME
        eq_di.py

    DESCRIPTION
      converts x,y pairs digitized from equal area projection to dec inc data

    SYNTAX
        eq_di.py [command line options] [< filename]

    OPTIONS
        -f FILE, input file
        -F FILE, specifies output file name
        -up if data are upper hemisphere
    """
    out=""
    UP=0
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-f' in sys.argv:
        dat=[]
        ind=sys.argv.index('-f')
        file=sys.argv[ind+1]
        f=open(file,'r')
        input=f.readlines()
    else:
        input = sys.stdin.readlines()  # read from standard input
    # NEW
    ofile = ""
    if '-F' in sys.argv:
        ind=sys.argv.index('-F')
        ofile=sys.argv[ind+1]
        out=open(ofile, 'w + a')
    # end NEW
    if '-up' in sys.argv: UP=1
    for line in input:
        rec=line.split()
        x,y=float(rec[1]),float(rec[0])  # swap x,y cartesian for x,y geographic
        #d,i=pmag.doeqdi(x,y)
        r=math.sqrt(x**2+y**2)
        z=1.-r**2
        t=math.asin(z)
        if UP==1:t=-t
        if x==0.:
            if y<0:
                p=3.*math.pi/2.
            else:
                p=old_div(math.pi,2.)
        else:
            p=math.atan2(y,x)
        d,i=p*180./math.pi,t*180./math.pi
        if d<0:d+=360.
        # new
        outstring = '%7.1f %7.1f'%(d,i)
        if ofile == "":
           # print '%7.1f %7.1f'%(d,i)
            print(outstring)
        else:
            out.write(outstring+'\n')


Instruction:
How would you explain what the following Python 3 function does
def main():
    print(main.__doc__)
    if '-h' in sys.argv:sys.exit()
    cont,Int,Top=1,[],[]
    while cont==1:
        try:
            Int.append(int(input(" Enter desired treatment step interval: <return> to quit ")))
            Top.append(int(input(" Enter upper bound for this interval: ")))
        except:
            cont=0
    pmag.chart_maker(Int,Top)

Response: This function is called by the command line for the main function. It is used to generate a new chart for the given data entry.


Instruction:
Can you implement a function in Python 3 that
names s_magic.py DESCRIPTION converts .s format data to measurements format. SYNTAX s_magic.py [command line options] OPTIONS -h prints help message and quits -DM DATA_MODEL_NUM data model number (default is 3) -f SFILE specifies the .s file name -sig last column has sigma -typ Anisotropy type: AMS,AARM,ATRM (default is AMS) -F FILE specifies the specimens formatted file name -usr USER specify username -loc location specify location/study name -spc NUM : specify number of characters to designate a specimen, default = 0 -spn SPECNAME, this specimen has the name SPECNAME -n first column has specimen name -crd [s,g,t], specify coordinate system of data s=specimen,g=geographic,t=tilt adjusted, default is 's' -ncn NCON: naming convention Sample naming convention: [1] XXXXY: where XXXX is an arbitrary length site designation and Y is the single character sample designation. e.g., TG001a is the first sample from site TG001. [default] [2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitary length) [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitary length) [4-Z] XXXXYYY: YYY is sample designation with Z characters from site XXX [5] sample = site [6] sample, site, location info in er_samples.txt -- NOT CURRENTLY SUPPORTED [7-Z] [XXX]YYY: XXX is site designation with Z characters from samples XXXYYY NB: all others you will have to either customize your self or e-mail ltauxe@ucsd.edu for help. DEFAULT FILE: specimens.txt INPUT X11,X22,X33,X12,X23,X13 (.s format file) X11,X22,X33,X12,X23,X13,sigma (.s format file with -sig option) SID, X11,X22,X33,X12,X23,X13 (.s format file with -n option) OUTPUT specimens.txt format file NOTE because .s files do not have specimen names or location information, the output MagIC files will have to be changed prior to importing to data base.

Response:
def main():
    """
    NAME
        s_magic.py

    DESCRIPTION
        converts .s format data to measurements  format.

    SYNTAX
        s_magic.py [command line options]

    OPTIONS
        -h prints help message and quits
        -DM DATA_MODEL_NUM data model number (default is 3)
        -f SFILE specifies the .s file name
        -sig last column has sigma
        -typ Anisotropy type:  AMS,AARM,ATRM (default is AMS)
        -F FILE specifies the specimens formatted file name
        -usr USER specify username
        -loc location specify location/study name
        -spc NUM : specify number of characters to
              designate a  specimen, default = 0
        -spn SPECNAME, this specimen has the name SPECNAME
        -n first column has specimen name
        -crd [s,g,t], specify coordinate system of data
           s=specimen,g=geographic,t=tilt adjusted, default is 's'
        -ncn NCON: naming convention
       Sample naming convention:
            [1] XXXXY: where XXXX is an arbitrary length site designation and Y
                is the single character sample designation.  e.g., TG001a is the
                first sample from site TG001.    [default]
            [2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitary length)
            [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitary length)
            [4-Z] XXXXYYY:  YYY is sample designation with Z characters from site XXX
            [5] sample = site
            [6] sample, site, location info in er_samples.txt -- NOT CURRENTLY SUPPORTED
            [7-Z] [XXX]YYY:  XXX is site designation with Z characters from samples  XXXYYY
            NB: all others you will have to either customize your
                self or e-mail ltauxe@ucsd.edu for help.

    DEFAULT
        FILE:  specimens.txt

    INPUT
        X11,X22,X33,X12,X23,X13  (.s format file)
        X11,X22,X33,X12,X23,X13,sigma (.s format file with -sig option)
        SID, X11,X22,X33,X12,X23,X13  (.s format file with -n option)

    OUTPUT
        specimens.txt format file

    NOTE
        because .s files do not have specimen names or location information, the output MagIC files
        will have to be changed prior to importing to data base.
    """
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    data_model_num = pmag.get_named_arg("-DM", 3)
    data_model_num = int(float(data_model_num))
    sfile = pmag.get_named_arg("-f", reqd=True)
    if data_model_num == 2:
       anisfile = pmag.get_named_arg("-F", "rmag_anisotropy.txt")
    else:
        anisfile = pmag.get_named_arg("-F", "specimens.txt")
    location = pmag.get_named_arg("-loc", "unknown")
    user = pmag.get_named_arg("-usr", "")
    sitename = pmag.get_named_arg("unknown", "")
    specnum = pmag.get_named_arg("-spc", 0)
    specnum = -int(specnum)
    dir_path = pmag.get_named_arg("-WD", ".")
    name = pmag.get_flag_arg_from_sys("-n")
    sigma = pmag.get_flag_arg_from_sys("-sig")
    spec = pmag.get_named_arg("-spn", "unknown")
    atype = pmag.get_named_arg("-typ", 'AMS')
    samp_con = pmag.get_named_arg("-ncn", "1")
    #if '-sig' in sys.argv:
    #    sigma = 1
    #if "-n" in sys.argv:
    #    name = 1
    coord_type = pmag.get_named_arg("-crd", 's')
    convert.s_magic(sfile, anisfile, dir_path, atype,
            coord_type, sigma, samp_con, specnum,
            location, spec, sitename, user, data_model_num, name)


Instruction:
Explain what the following Python 3 code does
def main():
    dir_path = '.'
    sites_file = 'er_sites.txt'
    ocean = 0
    res = 'i'
    proj = 'merc'
    prn_name = 0
    prn_loc = 0
    fancy = 0
    rivers, boundaries = 0, 0
    padlon, padlat, gridspace, details = .5, .5, .5, 1
    fmt = 'pdf'
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-f' in sys.argv:
        ind = sys.argv.index('-f')
        sites_file = sys.argv[ind+1]
    if '-res' in sys.argv:
        ind = sys.argv.index('-res')
        res = sys.argv[ind+1]
    if '-etp' in sys.argv:
        fancy = 1
    if '-n' in sys.argv:
        prn_name = 1
    if '-l' in sys.argv:
        prn_loc = 1
    if '-o' in sys.argv:
        ocean = 1
    if '-R' in sys.argv:
        rivers = 0
    if '-B' in sys.argv:
        boundaries = 0
    if '-prj' in sys.argv:
        ind = sys.argv.index('-prj')
        proj = sys.argv[ind+1]
    if '-fmt' in sys.argv:
        ind = sys.argv.index('-fmt')
        fmt = sys.argv[ind+1]
    verbose = pmagplotlib.verbose
    if '-sav' in sys.argv:
        verbose = 0
    if '-pad' in sys.argv:
        ind = sys.argv.index('-pad')
        padlat = float(sys.argv[ind+1])
        padlon = float(sys.argv[ind+2])
    if '-grd' in sys.argv:
        ind = sys.argv.index('-grd')
        gridspace = float(sys.argv[ind+1])
    if '-WD' in sys.argv:
        ind = sys.argv.index('-WD')
        dir_path = sys.argv[ind+1]
    sites_file = dir_path+'/'+sites_file
    location = ""
    FIG = {'map': 1}
    pmagplotlib.plot_init(FIG['map'], 6, 6)
    # read in er_sites file
    Sites, file_type = pmag.magic_read(sites_file)
    if 'results' in file_type:
        latkey = 'average_lat'
        lonkey = 'average_lon'
        namekey = 'pmag_result_name'
        lockey = 'er_location_names'
    else:
        latkey = 'site_lat'
        lonkey = 'site_lon'
        namekey = 'er_site_name'
        lockey = 'er_location_name'
    lats, lons = [], []
    slats, slons = [], []
    names, locs = [], []
    for site in Sites:
        if prn_loc == 1 and location == "":
            location = site['er_location_name']
        lats.append(float(site[latkey]))
        l = float(site[lonkey])
        if l < 0:
            l = l+360.  # make positive
        lons.append(l)
        if prn_name == 1:
            names.append(site[namekey])
        if prn_loc == 1:
            locs.append(site[lockey])
    for lat in lats:
        slats.append(lat)
    for lon in lons:
        slons.append(lon)
    Opts = {'res': res, 'proj': proj, 'loc_name': locs, 'padlon': padlon, 'padlat': padlat, 'latmin': numpy.min(slats)-padlat, 'latmax': numpy.max(
        slats)+padlat, 'lonmin': numpy.min(slons)-padlon, 'lonmax': numpy.max(slons)+padlon, 'sym': 'ro', 'boundinglat': 0., 'pltgrid': 1.}
    Opts['lon_0'] = 0.5*(numpy.min(slons)+numpy.max(slons))
    Opts['lat_0'] = 0.5*(numpy.min(slats)+numpy.max(slats))
    Opts['names'] = names
    Opts['gridspace'] = gridspace
    Opts['details'] = {'coasts': 1, 'rivers': 1,
                       'states': 1, 'countries': 1, 'ocean': 0}
    if ocean == 1:
        Opts['details']['ocean'] = 1
    if rivers == 1:
        Opts['details']['rivers'] = 0
    if boundaries == 1:
        Opts['details']['states'] = 0
        Opts['details']['countries'] = 0
    Opts['details']['fancy'] = fancy
    pmagplotlib.plot_map(FIG['map'], lats, lons, Opts)
    if verbose:
        pmagplotlib.draw_figs(FIG)
    files = {}
    for key in list(FIG.keys()):
        files[key] = 'Site_map'+'.'+fmt
    if pmagplotlib.isServer:
        black = '#000000'
        purple = '#800080'
        titles = {}
        titles['map'] = 'Site Map'
        FIG = pmagplotlib.add_borders(FIG, titles, black, purple)
        pmagplotlib.save_plots(FIG, files)
    elif verbose:
        ans = input(" S[a]ve to save plot, Return to quit:  ")
        if ans == "a":
            pmagplotlib.save_plots(FIG, files)
    else:
        pmagplotlib.save_plots(FIG, files)

Response: This is the main function for the basemap_magic. py program.


Instruction:
Can you tell what is the following Python 3 function doing
def main():
    inc=[]
    if '-h' in sys.argv: # check if help is needed
        print(main.__doc__)
        sys.exit() # graceful quit
    if '-i' in sys.argv: # ask for filename
        file=input("Enter file name with inc data: ")
        inc=numpy.loadtxt(file)
    elif '-f' in sys.argv:
        ind=sys.argv.index('-f')
        file=sys.argv[ind+1]
        inc=numpy.loadtxt(file)
    else:
        inc = numpy.loadtxt(sys.stdin,dtype=numpy.float)
    ofile=""
    if '-F' in sys.argv:
        ind = sys.argv.index('-F')
        ofile= sys.argv[ind+1]
        out = open(ofile, 'w + a')
    #
    #get doincfish to do the dirty work:
    fpars= pmag.doincfish(inc)
    outstring='%7.1f %7.1f  %i %8.1f %7.1f %7.1f'%(fpars['ginc'],fpars['inc'],fpars['n'],fpars['r'],fpars['k'],fpars['alpha95'])
    if ofile == "":
        print(outstring)
    else:
        out.write(outstring+'\n')

Response:
NAME incfish. py
VIRTUAL. py DESCRIPTION get the fisher parameters from inc only data and return the mean of the fisher parameters.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def sort_diclist(undecorated, sort_on):
    decorated = [(len(dict_[sort_on]) if hasattr(dict_[sort_on], '__len__') else dict_[
                  sort_on], index) for (index, dict_) in enumerate(undecorated)]
    decorated.sort()
    return[undecorated[index] for (key, index) in decorated]

Response:
Sort a list of dictionaries by the value in each
    dictionary for the sorting key


Instruction:
How would you explain what the following Python 3 function does
def get_dictitem(In, k, v, flag, float_to_int=False):
    if float_to_int:
        try:
            v = str(math.trunc(float(v)))
        except ValueError:  # catches non floatable strings
            pass
        except TypeError:  # catches None
            pass
        fixed_In = []
        for dictionary in In:
            if k in dictionary:
                val = dictionary[k]
                try:
                    val = str(math.trunc(float(val)))
                except ValueError:  # catches non floatable strings
                    pass
                except TypeError:  # catches None
                    pass
                dictionary[k] = val
            fixed_In.append(dictionary)
        In = fixed_In
    if flag == "T":
        # return that which is
        return [dictionary for dictionary in In if k in list(dictionary.keys()) and str(dictionary[k]).lower() == str(v).lower()]
    if flag == "F":
        # return that which is not
        return [dictionary for dictionary in In if k in list(dictionary.keys()) and str(dictionary[k]).lower() != str(v).lower()]
    if flag == "has":
        # return that which is contained
        return [dictionary for dictionary in In if k in list(dictionary.keys()) and str(v).lower() in str(dictionary[k]).lower()]
    if flag == "not":
        # return that which is not contained
        return [dictionary for dictionary in In if k in list(dictionary.keys()) and str(v).lower() not in str(dictionary[k]).lower()]
    if flag == "eval":
        A = [dictionary for dictionary in In if k in list(dictionary.keys(
        )) and dictionary[k] != '']  # find records with no blank values for key
        # return that which is
        return [dictionary for dictionary in A if k in list(dictionary.keys()) and float(dictionary[k]) == float(v)]
    if flag == "min":
        A = [dictionary for dictionary in In if k in list(dictionary.keys(
        )) and dictionary[k] != '']  # find records with no blank values for key
        # return that which is greater than
        return [dictionary for dictionary in A if k in list(dictionary.keys()) and float(dictionary[k]) >= float(v)]
    if flag == "max":
        A = [dictionary for dictionary in In if k in list(dictionary.keys(
        )) and dictionary[k] != '']  # find records with no blank values for key
        # return that which is less than
        return [dictionary for dictionary in A if k in list(dictionary.keys()) and float(dictionary[k]) <= float(v)]
    if flag == 'not_null':
        return [dictionary for dictionary in In if dictionary[k]]

Response: returns a list of dictionaries from list In with key k = value v. CASE INSENSITIVE is allowed keywords


Instruction:
Given the following Python 3 function, write the documentation
def get_dictkey(In, k, dtype):

    Out = []
    for d in In:
        if dtype == '':
            Out.append(d[k])
        if dtype == 'f':
            if d[k] == "":
                Out.append(0)
            elif d[k] == None:
                Out.append(0)
            else:
                Out.append(float(d[k]))
        if dtype == 'int':
            if d[k] == "":
                Out.append(0)
            elif d[k] == None:
                Out.append(0)
            else:
                Out.append(int(d[k]))
    return Out

Response: returns list of given key k from input list of dictionaries in data type dtype. uses command get_dictkey


Instruction:
Write a Python 3 function that can
get the orientation of a sample

Response:
def get_orient(samp_data, er_sample_name, **kwargs):
    """
    samp_data : PmagPy list of dicts or pandas DataFrame
    er_sample_name : sample name
    """
    if isinstance(samp_data, pd.DataFrame):
        samp_data = (samp_data.T.apply(dict))
    # set orientation priorities
    EX = ["SO-ASC", "SO-POM"]
    samp_key, az_key, dip_key = 'er_sample_name', 'sample_azimuth', 'sample_dip'
    disc_key, or_key, meth_key = 'sample_description', 'sample_orientation_flag',\
        'magic_method_codes'
    if 'data_model' in list(kwargs.keys()) and kwargs['data_model'] == 3:
        samp_key, az_key, dip_key = 'sample', 'azimuth', 'dip'
        disc_key, or_key, meth_key = 'description', 'orientation_quality',\
            'method_codes'
    orient = {samp_key: er_sample_name, az_key: "",
              dip_key: "", disc_key: ""}
    # get all the orientation data for this sample
    orients = get_dictitem(samp_data, samp_key, er_sample_name, 'T')
    if len(orients) > 0 and or_key in list(orients[0].keys()):
        # exclude all samples with bad orientation flag
        orients = get_dictitem(orients, or_key, 'b', 'F')
    if len(orients) > 0:
        orient = orients[0]  # re-initialize to first one
    methods = get_dictitem(orients, meth_key, 'SO-', 'has')
    # get a list of all orientation methods for this sample
    methods = get_dictkey(methods, meth_key, '')
    SO_methods = []
    for methcode in methods:
        meths = methcode.split(":")
        for meth in meths:
            if (meth.strip() not in EX) and meth.startswith('SO-'):
                SO_methods.append(meth.strip())
    # find top priority orientation method
    if len(SO_methods) == 0:
        print("no orientation data for sample ", er_sample_name)
        # preserve meta-data anyway even though orientation is bad
# get all the orientation data for this sample
        orig_data = get_dictitem(samp_data, samp_key, er_sample_name, 'T')
        if len(orig_data) > 0:
            orig_data = orig_data[0]
        else:
            orig_data = []
        az_type = "SO-NO"
    else:
        SO_priorities = set_priorities(SO_methods, 0)
        az_type = SO_methods[SO_methods.index(SO_priorities[0])]
        orient = get_dictitem(orients, meth_key, az_type, 'has')[
            0]  # re-initialize to best one
    return orient, az_type


Instruction:
Can you implement a function in Python 3 that
gives a mean inclination value of a distribution of directions, this function calculates the expected elongation of this distribution using a best-fit polynomial of the TK03 GAD secular variation model (Tauxe and Kent, 2004). Parameters ---------- inc : inclination in degrees (int or float) Returns --------- elongation : float Examples --------- >>> pmag.EI(20) 2.4863973732 >>> pmag.EI(90) 1.0241570135500004

Response:
def EI(inc):
    """
    Given a mean inclination value of a distribution of directions, this
    function calculates the expected elongation of this distribution using a
    best-fit polynomial of the TK03 GAD secular variation model (Tauxe and
    Kent, 2004).

    Parameters
    ----------
    inc : inclination in degrees (int or float)

    Returns
    ---------
    elongation : float

    Examples
    ---------
    >>> pmag.EI(20)
    2.4863973732
    >>> pmag.EI(90)
    1.0241570135500004
    """
    poly_tk03 = [3.15976125e-06,  -3.52459817e-04,  -
                 1.46641090e-02,   2.89538539e+00]
    return poly_tk03[0] * inc**3 + poly_tk03[1] * inc**2 + poly_tk03[2] * inc + poly_tk03[3]


Instruction:
Implement a Python 3 function for
giving a distribution of directions, this function determines parameters (elongation, inclination, flattening factor, and elongation direction) that are consistent with the TK03 secular variation model. Parameters ---------- data : array of declination, inclination pairs (e.g. np.array([[140,21],[127,23],[142,19],[136,22]])) Returns --------- Es : list of elongation values Is : list of inclination values Fs : list of flattening factors V2s : list of elongation directions (relative to the distribution) The function will return a zero list ([0]) for each of these parameters if the directions constitute a pathological distribution. Examples --------- >>> directions = np.array([[140,21],[127,23],[142,19],[136,22]]) >>> Es, Is, Fs, V2s = pmag.find_f(directions)

Response:
def find_f(data):
    """
    Given a distribution of directions, this function determines parameters
    (elongation, inclination, flattening factor, and elongation direction) that
    are consistent with the TK03 secular variation model.

    Parameters
    ----------
    data : array of declination, inclination pairs
        (e.g. np.array([[140,21],[127,23],[142,19],[136,22]]))

    Returns
    ---------
    Es : list of elongation values
    Is : list of inclination values
    Fs : list of flattening factors
    V2s : list of elongation directions (relative to the distribution)

    The function will return a zero list ([0]) for each of these parameters if the directions constitute a pathological distribution.

    Examples
    ---------
    >>> directions = np.array([[140,21],[127,23],[142,19],[136,22]])
    >>> Es, Is, Fs, V2s = pmag.find_f(directions)
    """
    rad = np.pi/180.
    Es, Is, Fs, V2s = [], [], [], []
    ppars = doprinc(data)
    D = ppars['dec']
    Decs, Incs = data.transpose()[0], data.transpose()[1]
    Tan_Incs = np.tan(Incs * rad)
    for f in np.arange(1., .2, -.01):
        U = old_div(np.arctan((old_div(1., f)) * Tan_Incs), rad)
        fdata = np.array([Decs, U]).transpose()
        ppars = doprinc(fdata)
        Fs.append(f)
        Es.append(old_div(ppars["tau2"], ppars["tau3"]))
        ang = angle([D, 0], [ppars["V2dec"], 0])
        if 180. - ang < ang:
            ang = 180. - ang
        V2s.append(ang)
        Is.append(abs(ppars["inc"]))
        if EI(abs(ppars["inc"])) <= Es[-1]:
            del Es[-1]
            del Is[-1]
            del Fs[-1]
            del V2s[-1]
            if len(Fs) > 0:
                for f in np.arange(Fs[-1], .2, -.005):
                    U = old_div(np.arctan((old_div(1., f)) * Tan_Incs), rad)
                    fdata = np.array([Decs, U]).transpose()
                    ppars = doprinc(fdata)
                    Fs.append(f)
                    Es.append(old_div(ppars["tau2"], ppars["tau3"]))
                    Is.append(abs(ppars["inc"]))
                    ang = angle([D, 0], [ppars["V2dec"], 0])
                    if 180. - ang < ang:
                        ang = 180. - ang
                    V2s.append(ang)
                    if EI(abs(ppars["inc"])) <= Es[-1]:
                        return Es, Is, Fs, V2s
    return [0], [0], [0], [0]


Instruction:
Implement a function in Python 3 to
convert lat to a list of dicts.

Response:
def convert_lat(Recs):
    """
    uses lat, for age<5Ma, model_lat if present, else tries to use average_inc to estimate plat.
    """
    New = []
    for rec in Recs:
        if 'model_lat' in list(rec.keys()) and rec['model_lat'] != "":
            New.append(rec)
        elif 'average_age' in list(rec.keys()) and rec['average_age'] != "" and float(rec['average_age']) <= 5.:
            if 'site_lat' in list(rec.keys()) and rec['site_lat'] != "":
                rec['model_lat'] = rec['site_lat']
                New.append(rec)
        elif 'average_inc' in list(rec.keys()) and rec['average_inc'] != "":
            rec['model_lat'] = '%7.1f' % (plat(float(rec['average_inc'])))
            New.append(rec)
    return New


Instruction:
Can you generate the documentation for the following Python 3 function
def convert_ages(Recs, data_model=3):
    if data_model == 3:
        site_key = 'site'
        agekey = "age"
        keybase = ""
    else:
        site_key = 'er_site_names'
        agekey = find('age', list(rec.keys()))
        if agekey != "":
            keybase = agekey.split('_')[0] + '_'

    New = []
    for rec in Recs:
        age = ''
        if rec[keybase + 'age'] != "":
            age = float(rec[keybase + "age"])
        elif rec[keybase + 'age_low'] != "" and rec[keybase + 'age_high'] != '':
            age = np.mean([rec[keybase + 'age_high'],
                           rec[keybase + "age_low"]])
            # age = float(rec[keybase + 'age_low']) + old_div(
            #    (float(rec[keybase + 'age_high']) - float(rec[keybase + 'age_low'])), 2.)
        if age != '':
            rec[keybase + 'age_unit']
            if rec[keybase + 'age_unit'] == 'Ma':
                rec[keybase + 'age'] = '%10.4e' % (age)
            elif rec[keybase + 'age_unit'] == 'ka' or rec[keybase + 'age_unit'] == 'Ka':
                rec[keybase + 'age'] = '%10.4e' % (age * .001)
            elif rec[keybase + 'age_unit'] == 'Years AD (+/-)':
                rec[keybase + 'age'] = '%10.4e' % ((2011 - age) * 1e-6)
            elif rec[keybase + 'age_unit'] == 'Years BP':
                rec[keybase + 'age'] = '%10.4e' % ((age) * 1e-6)
            rec[keybase + 'age_unit'] = 'Ma'
            New.append(rec)
        else:
            if 'site_key' in list(rec.keys()):
                print('problem in convert_ages:', rec['site_key'])
            elif 'er_site_name' in list(rec.keys()):
                print('problem in convert_ages:', rec['site_key'])
            else:
                print('problem in convert_ages:', rec)
        if len(New) == 0:
            print('no age key:', rec)
    return New

Response: Convert ages to MaTrees


Instruction:
Write a Python 3 function that can
convert items from a list of dicts to a list of dicts.

Response:
def convert_items(data, mapping):
    """
    Input: list of dicts (each dict a record for one item),
    mapping with column names to swap into the records.
    Output: updated list of dicts.
    """
    new_recs = []
    for rec in data:
        new_rec = map_magic.mapping(rec, mapping)
        new_recs.append(new_rec)
    return new_recs


Instruction:
How would you explain what the following Python 3 function does
def convert_directory_2_to_3(meas_fname="magic_measurements.txt", input_dir=".",
                             output_dir=".", meas_only=False, data_model=None):
    """
    Convert 2.0 measurements file into 3.0 measurements file.
    Merge and convert specimen, sample, site, and location data.
    Also translates criteria data.

    Parameters
    ----------
    meas_name : name of measurement file (do not include full path,
        default is "magic_measurements.txt")
    input_dir : name of input directory (default is ".")
    output_dir : name of output directory (default is ".")
    meas_only : boolean, convert only measurement data (default is False)
    data_model : data_model3.DataModel object (default is None)

    Returns
    ---------
    NewMeas : 3.0 measurements data (output of pmag.convert_items)
    upgraded : list of files successfully upgraded to 3.0
    no_upgrade: list of 2.5 files not upgraded to 3.0
    """
    convert = {'specimens': map_magic.spec_magic2_2_magic3_map,
               'samples': map_magic.samp_magic2_2_magic3_map,
               'sites': map_magic.site_magic2_2_magic3_map,
               'locations': map_magic.loc_magic2_2_magic3_map,
               'ages': map_magic.age_magic2_2_magic3_map}
    full_name = os.path.join(input_dir, meas_fname)
    if not os.path.exists(full_name):
        print("-W- {} is not a file".format(full_name))
        return False, False, False
    # read in data model 2.5 measurements file
    data2, filetype = magic_read(full_name)
    # convert list of dicts to 3.0
    NewMeas = convert_items(data2, map_magic.meas_magic2_2_magic3_map)
    # write 3.0 output to file
    ofile = os.path.join(output_dir, 'measurements.txt')
    magic_write(ofile, NewMeas, 'measurements')
    upgraded = []
    if os.path.exists(ofile):
        print("-I- 3.0 format measurements file was successfully created: {}".format(ofile))
        upgraded.append("measurements.txt")
    else:
        print("-W- 3.0 format measurements file could not be created")
    #
    no_upgrade = []
    if not meas_only:
        # try to convert specimens, samples, sites, & locations
        for dtype in ['specimens', 'samples', 'sites', 'locations', 'ages']:
            mapping = convert[dtype]
            res = convert_and_combine_2_to_3(
                dtype, mapping, input_dir, output_dir, data_model)
            if res:
                upgraded.append(res)
        # try to upgrade criteria file
        if os.path.exists(os.path.join(input_dir, 'pmag_criteria.txt')):
            crit_file = convert_criteria_file_2_to_3(input_dir=input_dir,
                                                     output_dir=output_dir,
                                                     data_model=data_model)[0]
            if crit_file:
                upgraded.append(crit_file)
            else:
                no_upgrade.append("pmag_criteria.txt")
        # create list of all un-upgradeable files
        for fname in os.listdir(input_dir):
            if fname in ['measurements.txt', 'specimens.txt', 'samples.txt',
                         'sites.txt', 'locations.txt']:
                continue
            elif 'rmag' in fname:
                no_upgrade.append(fname)
            elif fname in ['pmag_results.txt', 'er_synthetics.txt', 'er_images.txt',
                           'er_plots.txt']:
                no_upgrade.append(fname)

    return NewMeas, upgraded, no_upgrade

Response: Convert 2. 5 measurements file into 3. 0 measurements file.


Instruction:
Implement a function in Python 3 to
convert 2. 5 format data to 3. 0 format data.

Response:
def convert_and_combine_2_to_3(dtype, map_dict, input_dir=".", output_dir=".", data_model=None):
    """
    Read in er_*.txt file and pmag_*.txt file in working directory.
    Combine the data, then translate headers from 2.5 --> 3.0.
    Last, write out the data in 3.0.

    Parameters
    ----------
    dtype : string for input type (specimens, samples, sites, etc.)
    map_dict : dictionary with format {header2_format: header3_format, ...} (from mapping.map_magic module)
    input_dir : input directory, default "."
    output_dir : output directory, default "."
    data_model : data_model3.DataModel object, default None

    Returns
    ---------
    output_file_name with 3.0 format data (or None if translation failed)
    """
    # read in er_ data & make DataFrame
    er_file = os.path.join(input_dir, 'er_{}.txt'.format(dtype))
    er_data, er_dtype = magic_read(er_file)
    if len(er_data):
        er_df = pd.DataFrame(er_data)
        if dtype == 'ages':
            pass
            # remove records with blank ages
            #er_data = get_dictitem(er_data, 'age', '', "F")
            #er_df = pd.DataFrame(er_data)
        else:
            er_df.index = er_df['er_{}_name'.format(dtype[:-1])]
    else:
        er_df = pd.DataFrame()
    #
    if dtype == 'ages':
        full_df = er_df
    else:
        # read in pmag_ data & make DataFrame
        pmag_file = os.path.join(input_dir, 'pmag_{}.txt'.format(dtype))
        pmag_data, pmag_dtype = magic_read(pmag_file)
        if len(pmag_data):
            pmag_df = pd.DataFrame(pmag_data)
            pmag_df.index = pmag_df['er_{}_name'.format(dtype[:-1])]
        else:
            pmag_df = pd.DataFrame()
        # combine the two Dataframes
        full_df = pd.concat([er_df, pmag_df], sort=True)
        # sort the DataFrame so that all records from one item are together
        full_df.sort_index(inplace=True)

    # fix the column names to be 3.0
    full_df.rename(columns=map_dict, inplace=True)
    # create a MagicDataFrame object, providing the dataframe and the data type
    new_df = cb.MagicDataFrame(dtype=dtype, df=full_df, dmodel=data_model)
    # write out the data to file
    if len(new_df.df):
        new_df.write_magic_file(dir_path=output_dir)
        return dtype + ".txt"
    else:
        print("-I- No {} data found.".format(dtype))
        return None


Instruction:
Can you create a Python 3 function that
converts a criteria file from 2. 5 format to 3. 0 format and write it out to file

Response:
def convert_criteria_file_2_to_3(fname="pmag_criteria.txt", input_dir=".",
                                 output_dir=".", data_model=None):
    """
    Convert a criteria file from 2.5 to 3.0 format and write it out to file

    Parameters
    ----------
    fname : string of filename (default "pmag_criteria.txt")
    input_dir : string of input directory (default ".")
    output_dir : string of output directory (default ".")
    data_model : data_model.DataModel object (default None)

    Returns
    ---------
    outfile : string output criteria filename, or False
    crit_container : cb.MagicDataFrame with 3.0 criteria table
    """
    # get criteria from infile
    fname = os.path.join(input_dir, fname)
    if not os.path.exists(fname):
        return False, None
    orig_crit, warnings = read_criteria_from_file(fname, initialize_acceptance_criteria(),
                                                  data_model=2, return_warnings=True)
    converted_crit = {}
    # get data model including criteria map
    if not data_model:
        from . import data_model3 as dm3
        DM = dm3.DataModel()
    else:
        DM = data_model
    crit_map = DM.crit_map
    # drop all empty mappings
    stripped_crit_map = crit_map.dropna(axis='rows')
    # go through criteria and get 3.0 name and criterion_operation
    for crit in orig_crit:
        if orig_crit[crit]['value'] in [-999, '-999', -999.]:
            continue
        if crit in stripped_crit_map.index:
            criterion_operation = stripped_crit_map.loc[crit]['criteria_map']['criterion_operation']
            table_col = stripped_crit_map.loc[crit]['criteria_map']['table_column']
            orig_crit[crit]['criterion_operation'] = criterion_operation
            converted_crit[table_col] = orig_crit[crit]
        else:
            print('-W- Could not convert {} to 3.0, skipping'.format(crit))
    # switch axes
    converted_df = pd.DataFrame(converted_crit).transpose()
    # name the index
    converted_df.index.name = "table_column"
    # rename columns to 3.0 values
    # 'category' --> criterion (uses defaults from initalize_default_criteria)
    # 'pmag_criteria_code' --> criterion (uses what's actually in the translated file)
    converted_df.rename(columns={'pmag_criteria_code': 'criterion', 'er_citation_names': 'citations',
                                 'criteria_definition': 'description', 'value': 'criterion_value'},
                        inplace=True)
    # drop unused columns
    valid_cols = DM.dm['criteria'].index
    drop_cols = set(converted_df.columns) - set(valid_cols)
    converted_df.drop(drop_cols, axis='columns', inplace=True)
    # move 'table_column' from being the index to being a column
    converted_df['table_column'] = converted_df.index
    crit_container = cb.MagicDataFrame(dtype='criteria', df=converted_df)
    crit_container.write_magic_file(dir_path=output_dir)
    return "criteria.txt", crit_container


Instruction:
Can you generate a brief explanation for the following Python 3 code
def orient(mag_azimuth, field_dip, or_con):
    or_con = str(or_con)
    if mag_azimuth == -999:
        return "", ""
    if or_con == "1":  # lab_mag_az=mag_az;  sample_dip = -dip
        return mag_azimuth, -field_dip
    if or_con == "2":
        return mag_azimuth - 90., -field_dip
    if or_con == "3":  # lab_mag_az=mag_az;  sample_dip = 90.-dip
        return mag_azimuth, 90. - field_dip
    if or_con == "4":  # lab_mag_az=mag_az;  sample_dip = dip
        return mag_azimuth, field_dip
    if or_con == "5":  # lab_mag_az=mag_az;  sample_dip = dip-90.
        return mag_azimuth, field_dip - 90.
    if or_con == "6":  # lab_mag_az=mag_az-90.;  sample_dip = 90.-dip
        return mag_azimuth - 90., 90. - field_dip
    if or_con == "7":  # lab_mag_az=mag_az;  sample_dip = 90.-dip
        return mag_azimuth - 90., 90. - field_dip
    print("Error in orientation convention")

Response:
converts user supplied orientations
    to laboratory azimuth and plunge


Instruction:
How would you implement a function in Python 3 that
calculates the Sf for a dataframe with VGP Lat. and optional Fisher s k site latitude and N information can be used to correct for within site scatter.

Response:
def get_sb_df(df, mm97=False):
    """
    Calculates Sf for a dataframe with VGP Lat., and optional Fisher's k, site latitude and N information can be used to correct for within site scatter (McElhinny & McFadden, 1997)

    Parameters
    _________
    df : Pandas Dataframe with columns
        REQUIRED:
        vgp_lat :  VGP latitude
        ONLY REQUIRED for MM97 correction:
        dir_k : Fisher kappa estimate
        dir_n : number of specimens (samples) per site
        lat : latitude of the site
    mm97 : if True, will do the correction for within site scatter

    Returns:
    _______
    Sf : Sf
    """
    df['delta'] = 90.-df.vgp_lat
    Sp2 = np.sum(df.delta**2)/(df.shape[0]-1)
    if 'dir_k' in df.columns and mm97:
        ks = df.dir_k
        Ns = df.dir_n
        Ls = np.radians(df.lat)
        A95s = 140./np.sqrt(ks*Ns)
        Sw2_n = 0.335*(A95s**2)*(2.*(1.+3.*np.sin(Ls)**2) /
                                 (5.-3.*np.sin(Ls)**2))
        return np.sqrt(Sp2-Sw2_n.mean())
    else:
        return np.sqrt(Sp2)


Instruction:
Create a Python 3 function to
return the grade of a specimen given the acceptance criteria

Response:
def grade(PmagRec, ACCEPT, type, data_model=2.5):
    """
    Finds the 'grade' (pass/fail; A/F) of a record (specimen,sample,site) given the acceptance criteria
    """
    GREATERTHAN = ['specimen_q', 'site_k', 'site_n', 'site_n_lines', 'site_int_n', 'measurement_step_min', 'specimen_int_ptrm_n', 'specimen_fvds', 'specimen_frac', 'specimen_f', 'specimen_n', 'specimen_int_n', 'sample_int_n', 'average_age_min', 'average_k', 'average_r', 'specimen_magn_moment',
                   'specimen_magn_volume', 'specimen_rsc', 'sample_n', 'sample_n_lines', 'sample_n_planes', 'sample_k', 'sample_r', 'site_magn_moment', 'site_magn_volume', 'site_magn_mass', 'site_r']  # these statistics must be exceede to pass, all others must be less than (except specimen_scat, which must be true)
    ISTRUE = ['specimen_scat']
    kill = []  # criteria that kill the record
    sigma_types = ['sample_int_sigma', 'sample_int_sigma_perc', 'site_int_sigma',
                   'site_int_sigma_perc', 'average_int_sigma', 'average_int_sigma_perc']
    sigmas = []
    accept = {}
    if type == 'specimen_int':
        USEKEYS = ['specimen_q', 'measurement_step_min', 'measurement_step_max', 'specimen_int_ptrm_n', 'specimen_fvds', 'specimen_frac', 'specimen_f', 'specimen_int_n', 'specimen_magn_moment',
                   'specimen_magn_volume', 'specimen_rsc', 'specimen_scat', 'specimen_drats', 'specimen_int_mad', 'specimen_int_dang', 'specimen_md', 'specimen_b_beta', 'specimen_w', 'specimen_gmax']
        if data_model == 3.0:
            USEKEYS = [map_magic.spec_magic2_2_magic3_map[k] for k in USEKEYS]
    elif type == 'specimen_dir':
        USEKEYS = ['measurement_step_min', 'measurement_step_max', 'specimen_mad',
                   'specimen_n', 'specimen_magn_moment', 'specimen_magn_volume']
        if data_model == 3.0:
            USEKEYS = [map_magic.spec_magic2_2_magic3_map[k] for k in USEKEYS]
    elif type == 'sample_int':
        USEKEYS = ['sample_int_n', 'sample_int_sigma', 'sample_int_sigma_perc']
        if data_model == 3.0:
            USEKEYS = [map_magic.samp_magic2_2_magic3_map[k] for k in USEKEYS]
    elif type == 'sample_dir':
        USEKEYS = ['sample_alpha95', 'sample_n', 'sample_n_lines',
                   'sample_n_planes', 'sample_k', 'sample_r']
        if data_model == 3.0:
            USEKEYS = [map_magic.samp_magic2_2_magic3_map[k] for k in USEKEYS]
    elif type == 'site_int':
        USEKEYS = ['site_int_sigma', 'site_int_sigma_perc', 'site_int_n']
        if data_model == 3.0:
            USEKEYS = [map_magic.site_magic2_2_magic3_map[k] for k in USEKEYS]
    elif type == 'site_dir':
        USEKEYS = ['site_alpha95', 'site_k', 'site_n',
                   'site_n_lines', 'site_n_planes', 'site_r']
        if data_model == 3.0:
            USEKEYS = [map_magic.site_magic2_2_magic3_map[k] for k in USEKEYS]

    for key in list(ACCEPT.keys()):
        if ACCEPT[key] != "" and key in USEKEYS:
            if key in ISTRUE and ACCEPT[key] == 'TRUE' or ACCEPT[key] == 'True':
                # this is because Excel always capitalizes True to TRUE and
                # python doesn't recognize that as a boolean.  never mind
                ACCEPT[key] = '1'
            elif ACCEPT[key] == 'FALSE' or ACCEPT[key] == 'False':
                ACCEPT[key] = '0'
            elif eval(ACCEPT[key]) == 0:
                ACCEPT[key] = ""
            accept[key] = ACCEPT[key]
    for key in sigma_types:
        if key in USEKEYS and key in list(accept.keys()) and key in list(PmagRec.keys()):
            sigmas.append(key)
    if len(sigmas) > 1:
        if PmagRec[sigmas[0]] == "" or PmagRec[sigmas[1]] == "":
            kill.append(sigmas[0])
            kill.append(sigmas[1])
        elif eval(PmagRec[sigmas[0]]) > eval(accept[sigmas[0]]) and eval(PmagRec[sigmas[1]]) > eval(accept[sigmas[1]]):
            kill.append(sigmas[0])
            kill.append(sigmas[1])
    elif len(sigmas) == 1 and sigmas[0] in list(accept.keys()):
        if PmagRec[sigmas[0]] > accept[sigmas[0]]:
            kill.append(sigmas[0])
    for key in list(accept.keys()):
        if accept[key] != "":
            if key not in list(PmagRec.keys()) or PmagRec[key] == '':
                kill.append(key)
            elif key not in sigma_types:
                if key in ISTRUE:  # boolean must be true
                    if PmagRec[key] != '1':
                        kill.append(key)
                if key in GREATERTHAN:
                    if eval(str(PmagRec[key])) < eval(str(accept[key])):
                        kill.append(key)
                else:
                    if eval(str(PmagRec[key])) > eval(str(accept[key])):
                        kill.append(key)
    return kill


Instruction:
Can you tell what is the following Python 3 function doing
def flip(di_block, combine=False):
    ppars = doprinc(di_block)  # get principle direction
    if combine:
        D3 = []
    D1, D2 = [], []
    for rec in di_block:
        ang = angle([rec[0], rec[1]], [ppars['dec'], ppars['inc']])
        if ang > 90.:
            d, i = (rec[0] - 180.) % 360., -rec[1]
            D2.append([d, i])
            if combine:
                D3.append([d, i])
        else:
            D1.append([rec[0], rec[1]])
            if combine:
                D3.append([rec[0], rec[1]])
    if combine:
        return D3
    else:
        return D1, D2

Response: Flips the reverse mode of a single DI block.


Instruction:
Write a Python 3 function for
functioning to convert directional data at a given location to pole position dp dm

Response:
def dia_vgp(*args):  # new function interface by J.Holmes, SIO, 6/1/2011
    """
    Converts directional data (declination, inclination, alpha95) at a given
    location (Site latitude, Site longitude) to pole position (pole longitude,
    pole latitude, dp, dm)

    Parameters
    ----------
    Takes input as (Dec, Inc, a95, Site latitude, Site longitude)
    Input can be as individual values (5 parameters)
    or
    as a list of lists: [[Dec, Inc, a95, lat, lon],[Dec, Inc, a95, lat, lon]]

    Returns
    ----------
    if input is individual values for one pole the return is:
    pole longitude, pole latitude, dp, dm

    if input is list of lists the return is:
    list of pole longitudes, list of pole latitude, list of dp, list of dm
    """
    # test whether arguments are one 2-D list or 5 floats
    if len(args) == 1:  # args comes in as a tuple of multi-dim lists.
        largs = list(args).pop()  # scrap the tuple.
        # reorganize the lists so that we get columns of data in each var.
        (decs, dips, a95s, slats, slongs) = list(zip(*largs))
    else:
        # When args > 1, we are receiving five floats. This usually happens when the invoking script is
        # executed in interactive mode.
        (decs, dips, a95s, slats, slongs) = (args)

    # We send all incoming data to numpy in an array form. Even if it means a
    # 1x1 matrix. That's OKAY. Really.
    (dec, dip, a95, slat, slong) = (np.array(decs), np.array(dips), np.array(a95s),
                                    np.array(slats), np.array(slongs))  # package columns into arrays
    rad = old_div(np.pi, 180.)  # convert to radians
    dec, dip, a95, slat, slong = dec * rad, dip * \
        rad, a95 * rad, slat * rad, slong * rad
    p = np.arctan2(2.0, np.tan(dip))
    plat = np.arcsin(np.sin(slat) * np.cos(p) +
                     np.cos(slat) * np.sin(p) * np.cos(dec))
    beta = old_div((np.sin(p) * np.sin(dec)), np.cos(plat))

    # -------------------------------------------------------------------------
    # The deal with "boolmask":
    # We needed a quick way to assign matrix values based on a logic decision, in this case setting boundaries
    # on out-of-bounds conditions. Creating a matrix of boolean values the size of the original matrix and using
    # it to "mask" the assignment solves this problem nicely. The downside to this is that Numpy complains if you
    # attempt to mask a non-matrix, so we have to check for array type and do a normal assignment if the type is
    # scalar. These checks are made before calculating for the rest of the function.
    # -------------------------------------------------------------------------

    boolmask = beta > 1.  # create a mask of boolean values
    if isinstance(beta, np.ndarray):
        beta[boolmask] = 1.  # assigns 1 only to elements that mask TRUE.
    # Numpy gets upset if you try our masking trick with a scalar or a 0-D
    # matrix.
    else:
        if boolmask:
            beta = 1.
    boolmask = beta < -1.
    if isinstance(beta, np.ndarray):
        beta[boolmask] = -1.  # assigns -1 only to elements that mask TRUE.
    else:
        if boolmask:
            beta = -1.

    beta = np.arcsin(beta)
    plong = slong + np.pi - beta
    if (np.cos(p) > np.sin(slat) * np.sin(plat)).any():
        boolmask = (np.cos(p) > (np.sin(slat) * np.sin(plat)))
        if isinstance(plong, np.ndarray):
            plong[boolmask] = (slong + beta)[boolmask]
        else:
            if boolmask:
                plong = slong + beta

    boolmask = (plong < 0)
    if isinstance(plong, np.ndarray):
        plong[boolmask] = plong[boolmask] + 2 * np.pi
    else:
        if boolmask:
            plong = plong + 2 * np.pi

    boolmask = (plong > 2 * np.pi)
    if isinstance(plong, np.ndarray):
        plong[boolmask] = plong[boolmask] - 2 * np.pi
    else:
        if boolmask:
            plong = plong - 2 * np.pi

    dm = np.rad2deg(a95 * (old_div(np.sin(p), np.cos(dip))))
    dp = np.rad2deg(a95 * (old_div((1 + 3 * (np.cos(p)**2)), 2)))
    plat = np.rad2deg(plat)
    plong = np.rad2deg(plong)
    return plong.tolist(), plat.tolist(), dp.tolist(), dm.tolist()


Instruction:
How would you implement a function in Python 3 that
calculates the parameters of the York regression and Coe parameters

Response:
def int_pars(x, y, vds, **kwargs):
    """
     calculates York regression and Coe parameters (with Tauxe Fvds)
    """
    # first do linear regression a la York
    # do Data Model 3 way:
    if 'version' in list(kwargs.keys()) and kwargs['version'] == 3:
        n_key = 'int_n_measurements'
        b_key = 'int_b'
        sigma_key = 'int_b_sigma'
        f_key = 'int_f'
        fvds_key = 'int_fvds'
        g_key = 'int_g'
        q_key = 'int_q'
        b_beta_key = 'int_b_beta'

    else:  # version 2
        n_key = 'specimen_int_n'
        b_key = 'specimen_b'
        sigma_key = 'specimen_b_sigma'
        f_key = 'specimen_f'
        fvds_key = 'specimen_fvds'
        g_key = 'specimen_g'
        q_key = 'specimen_q'
        b_beta_key = 'specimen_b_beta'

    xx, yer, xer, xyer, yy, xsum, ysum, xy = 0., 0., 0., 0., 0., 0., 0., 0.
    xprime, yprime = [], []
    pars = {}
    pars[n_key] = len(x)
    n = float(len(x))
    if n <= 2:
        print("shouldn't be here at all!")
        return pars, 1
    for i in range(len(x)):
        xx += x[i]**2.
        yy += y[i]**2.
        xy += x[i] * y[i]
        xsum += x[i]
        ysum += y[i]
    xsig = np.sqrt(old_div((xx - (old_div(xsum**2., n))), (n - 1.)))
    ysig = np.sqrt(old_div((yy - (old_div(ysum**2., n))), (n - 1.)))
    sum = 0
    for i in range(int(n)):
        yer += (y[i] - old_div(ysum, n))**2.
        xer += (x[i] - old_div(xsum, n))**2.
        xyer += (y[i] - old_div(ysum, n)) * (x[i] - old_div(xsum, n))
    slop = -np.sqrt(old_div(yer, xer))
    pars[b_key] = slop
    s1 = 2. * yer - 2. * slop * xyer
    s2 = (n - 2.) * xer
    sigma = np.sqrt(old_div(s1, s2))
    pars[sigma_key] = sigma
    s = old_div((xy - (xsum * ysum / n)), (xx - old_div((xsum**2.), n)))
    r = old_div((s * xsig), ysig)
    pars["specimen_rsc"] = r**2.
    ytot = abs(old_div(ysum, n) - slop * xsum / n)
    for i in range(int(n)):
        xprime.append(old_div((slop * x[i] + y[i] - ytot), (2. * slop)))
        yprime.append((old_div((slop * x[i] + y[i] - ytot), 2.)) + ytot)
    sumdy, dy = 0, []
    dyt = abs(yprime[0] - yprime[int(n) - 1])
    for i in range((int(n) - 1)):
        dy.append(abs(yprime[i + 1] - yprime[i]))
        sumdy += dy[i]**2.
    f = old_div(dyt, ytot)
    pars[f_key] = f
    pars["specimen_ytot"] = ytot
    ff = old_div(dyt, vds)
    pars[fvds_key] = ff
    ddy = (old_div(1., dyt)) * sumdy
    g = 1. - old_div(ddy, dyt)
    pars[g_key] = g
    q = abs(slop) * f * g / sigma
    pars[q_key] = q
    pars[b_beta_key] = old_div(-sigma, slop)
    return pars, 0


Instruction:
Can you write a function in Python 3 where it
calculates vector difference sum for demagnetization data

Response:
def dovds(data):
    """
     calculates vector difference sum for demagnetization data
    """
    vds, X = 0, []
    for rec in data:
        X.append(dir2cart(rec))
    for k in range(len(X) - 1):
        xdif = X[k + 1][0] - X[k][0]
        ydif = X[k + 1][1] - X[k][1]
        zdif = X[k + 1][2] - X[k][2]
        vds += np.sqrt(xdif**2 + ydif**2 + zdif**2)
    vds += np.sqrt(X[-1][0]**2 + X[-1][1]**2 + X[-1][2]**2)
    return vds


Instruction:
Given the following Python 3 function, write the documentation
def vspec_magic(data):
    vdata, Dirdata, step_meth = [], [], ""
    if len(data) == 0:
        return vdata
    treat_init = ["treatment_temp", "treatment_temp_decay_rate", "treatment_temp_dc_on", "treatment_temp_dc_off", "treatment_ac_field", "treatment_ac_field_decay_rate", "treatment_ac_field_dc_on",
                  "treatment_ac_field_dc_off", "treatment_dc_field", "treatment_dc_field_decay_rate", "treatment_dc_field_ac_on", "treatment_dc_field_ac_off", "treatment_dc_field_phi", "treatment_dc_field_theta"]
    treats = []
#
# find keys that are used
#
    for key in treat_init:
        if key in list(data[0].keys()):
            treats.append(key)  # get a list of keys
    stop = {}
    stop["er_specimen_name"] = "stop"
    for key in treats:
        stop[key] = ""  # tells program when to quit and go home
    data.append(stop)
#
# set initial states
#
    DataState0, newstate = {}, 0
    for key in treats:
        DataState0[key] = data[0][key]  # set beginning treatment
    k, R = 1, 0
    for i in range(k, len(data)):
        FDirdata, Dirdata, DataStateCurr, newstate = [], [], {}, 0
        for key in treats:  # check if anything changed
            DataStateCurr[key] = data[i][key]
            if DataStateCurr[key].strip() != DataState0[key].strip():
                newstate = 1  # something changed
        if newstate == 1:
            if i == k:  # sample is unique
                vdata.append(data[i - 1])
            else:  # measurement is not unique
                # print "averaging: records " ,k,i
                for l in range(k - 1, i):
                    if 'orientation' in data[l]['measurement_description']:
                        data[l]['measurement_description'] = ""
                    Dirdata.append([float(data[l]['measurement_dec']), float(
                        data[l]['measurement_inc']), float(data[l]['measurement_magn_moment'])])
                    FDirdata.append(
                        [float(data[l]['measurement_dec']), float(data[l]['measurement_inc'])])
                dir, R = vector_mean(Dirdata)
                Fpars = fisher_mean(FDirdata)
                vrec = data[i - 1]
                vrec['measurement_dec'] = '%7.1f' % (dir[0])
                vrec['measurement_inc'] = '%7.1f' % (dir[1])
                vrec['measurement_magn_moment'] = '%8.3e' % (
                    old_div(R, (i - k + 1)))
                vrec['measurement_csd'] = '%7.1f' % (Fpars['csd'])
                vrec['measurement_positions'] = '%7.1f' % (Fpars['n'])
                vrec['measurement_description'] = 'average of multiple measurements'
                if "magic_method_codes" in list(vrec.keys()):
                    meths = vrec["magic_method_codes"].strip().split(":")
                    if "DE-VM" not in meths:
                        meths.append("DE-VM")
                    methods = ""
                    for meth in meths:
                        methods = methods + meth + ":"
                    vrec["magic_method_codes"] = methods[:-1]
                else:
                    vrec["magic_method_codes"] = "DE-VM"
                vdata.append(vrec)
# reset state to new one
            for key in treats:
                DataState0[key] = data[i][key]  # set beginning treatment
            k = i + 1
            if data[i]["er_specimen_name"] == "stop":
                del data[-1]  # get rid of dummy stop sign
                return vdata, treats

Response: Takes average vector of replicate measurements and returns a list of vspecs that are unique


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_specs(data):
    # sort the specimen names
    speclist = []
    for rec in data:
        try:
            spec = rec["er_specimen_name"]
        except KeyError as e:
            spec = rec["specimen"]
        if spec not in speclist:
            speclist.append(spec)
    speclist.sort()
    return speclist

Response: Takes a magic format file and returns a list of unique specimen names


Instruction:
How would you explain what the following Python 3 function does
def vector_mean(data):
    Xbar = np.zeros((3))
    X = dir2cart(data).transpose()
    for i in range(3):
        Xbar[i] = X[i].sum()
    R = np.sqrt(Xbar[0]**2+Xbar[1]**2+Xbar[2]**2)
    Xbar = Xbar/R
    dir = cart2dir(Xbar)
    return dir, R

Response: Calculates the vector mean of a given set of vectors


Instruction:
Implement a Python 3 function for
marking demagnetization data for bad points with measurement_flag

Response:
def mark_dmag_rec(s, ind, data):
    """
    Edits demagnetization data to mark "bad" points with measurement_flag
    """
    datablock = []
    for rec in data:
        if rec['er_specimen_name'] == s:
            meths = rec['magic_method_codes'].split(':')
            if 'LT-NO' in meths or 'LT-AF-Z' in meths or 'LT-T-Z' in meths:
                datablock.append(rec)
    dmagrec = datablock[ind]
    for k in range(len(data)):
        meths = data[k]['magic_method_codes'].split(':')
        if 'LT-NO' in meths or 'LT-AF-Z' in meths or 'LT-T-Z' in meths:
            if data[k]['er_specimen_name'] == s:
                if data[k]['treatment_temp'] == dmagrec['treatment_temp'] and data[k]['treatment_ac_field'] == dmagrec['treatment_ac_field']:
                    if data[k]['measurement_dec'] == dmagrec['measurement_dec'] and data[k]['measurement_inc'] == dmagrec['measurement_inc'] and data[k]['measurement_magn_moment'] == dmagrec['measurement_magn_moment']:
                        if data[k]['measurement_flag'] == 'g':
                            flag = 'b'
                        else:
                            flag = 'g'
                        data[k]['measurement_flag'] = flag
                        break
    return data


Instruction:
How would you explain what the following Python 3 function does
def find_dmag_rec(s, data, **kwargs):
    if 'version' in list(kwargs.keys()) and kwargs['version'] == 3:
        # convert dataframe to list of dictionaries
        data = data.to_dict('records')
        spec_key, dec_key, inc_key = 'specimen', 'dir_dec', 'dir_inc'
        flag_key, temp_key, ac_key = 'flag', 'treat_temp', 'treat_ac_field'
        meth_key = 'method_codes'
        power_key, time_key = 'treat_mw_power', 'treat_mw_time'
        Mkeys = ['magn_moment', 'magn_volume', 'magn_mass', 'magnitude']
        # just look in the intensity column
        inst_key = 'instrument_codes'
    else:
        spec_key, dec_key, inc_key = 'er_specimen_name', 'measurement_dec', 'measurement_inc'
        flag_key = 'measurement_flag'
        flag_key, temp_key, ac_key = 'measurement_flag', 'treatment_temp', 'treatment_ac_field'
        meth_key = 'magic_method_codes'
        power_key, time_key = 'treatment_mw_power', 'treatment_mw_time'
        Mkeys = ['measurement_magn_moment', 'measurement_magn_volume',
                 'measurement_magn_mass', 'measurement_magnitude']
        inst_key = 'magic_instrument_codes'

    EX = ["LP-AN-ARM", "LP-AN-TRM", "LP-ARM-AFD", "LP-ARM2-AFD", "LP-TRM-AFD",
          "LP-TRM", "LP-TRM-TD", "LP-X"]  # list of excluded lab protocols
    INC = ["LT-NO", "LT-AF-Z", "LT-T-Z",
           "LT-M-Z", "LP-PI-TRM-IZ", "LP-PI-M-IZ"]
    datablock, tr = [], ""
    therm_flag, af_flag, mw_flag = 0, 0, 0
    units = []
    spec_meas = get_dictitem(data, spec_key, s, 'T')
    for rec in spec_meas:
        if flag_key not in list(rec.keys()):
            rec[flag_key] = 'g'
        skip = 1
        tr = ""
        meths = rec[meth_key].split(":")
        methods = []
        for m in meths:
            methods.append(m.strip())  # get rid of the stupid spaces!
        for meth in methods:
            if meth.strip() in INC:
                skip = 0
        for meth in EX:
            if meth in methods:
                skip = 1
        if skip == 0:
            if "LT-NO" in methods:
                tr = float(rec[temp_key])
            if "LT-AF-Z" in methods:
                af_flag = 1
                try:
                    tr = float(rec[ac_key])
                except (KeyError, ValueError):
                    tr = 0
                if "T" not in units:
                    units.append("T")
            if "LT-T-Z" in methods:
                therm_flag = 1
                tr = float(rec[temp_key])
                if "K" not in units:
                    units.append("K")
            if "LT-M-Z" in methods:
                mw_flag = 1
                tr = float(rec[power_key]) * float(rec[time_key])
                if "J" not in units:
                    units.append("J")
            # looking for in-field first thellier or microwave data -
            # otherwise, just ignore this
            if "LP-PI-TRM-IZ" in methods or "LP-PI-M-IZ" in methods:
                ZI = 0
            else:
                ZI = 1
            if tr != "":
                dec, inc, int = "", "", ""
                if dec_key in list(rec.keys()) and cb.not_null(rec[dec_key], False):
                    dec = float(rec[dec_key])
                if inc_key in list(rec.keys()) and cb.not_null(rec[inc_key], False):
                    inc = float(rec[inc_key])
                for key in Mkeys:
                    if key in list(rec.keys()) and cb.not_null(rec[key], False):
                        int = float(rec[key])
                if inst_key not in list(rec.keys()):
                    rec[inst_key] = ''
                datablock.append(
                    [tr, dec, inc, int, ZI, rec[flag_key], rec[inst_key]])
    if therm_flag == 1:
        for k in range(len(datablock)):
            if datablock[k][0] == 0.:
                datablock[k][0] = 273.
    if af_flag == 1:
        for k in range(len(datablock)):
            if datablock[k][0] >= 273 and datablock[k][0] <= 323:
                datablock[k][0] = 0.
    meas_units = ""
    if len(units) > 0:
        for u in units:
            meas_units = meas_units + u + ":"
        meas_units = meas_units[:-1]
    return datablock, meas_units

Response: Find demagnetization data for a specimen s.


Instruction:
Write a Python 3 script to
open a file and return a list of the file s lines.

Response:
def open_file(infile, verbose=True):
    """
    Open file and return a list of the file's lines.
    Try to use utf-8 encoding, and if that fails use Latin-1.

    Parameters
    ----------
    infile : str
        full path to file

    Returns
    ----------
    data: list
        all lines in the file
    """
    try:
        with codecs.open(infile, "r", "utf-8") as f:
            lines = list(f.readlines())
    # file might not exist
    except FileNotFoundError:
        if verbose:
            print(
                '-W- You are trying to open a file: {} that does not exist'.format(infile))
        return []
    # encoding might be wrong
    except UnicodeDecodeError:
        try:
            with codecs.open(infile, "r", "Latin-1") as f:
                print(
                    '-I- Using less strict decoding for {}, output may have formatting errors'.format(infile))
                lines = list(f.readlines())
        # if file exists, and encoding is correct, who knows what the problem is
        except Exception as ex:
            print("-W- ", type(ex), ex)
            return []
    except Exception as ex:
        print("-W- ", type(ex), ex)
        return []
    # don't leave a blank line at the end
    i = 0
    while i < 10:
        if not len(lines[-1].strip("\n").strip("\t")):
            lines = lines[:-1]
            i += 1
        else:
            i = 10
    return lines


Instruction:
Can you create a Python 3 function that
reads a MagIC template file and returns a list of dictionaries.

Response:
def magic_read(infile, data=None, return_keys=False, verbose=False):
    """
    Reads  a Magic template file, returns  data in a list of dictionaries.

    Parameters
    ___________
        Required:
            infile : the MagIC formatted tab delimited data file
                first line contains 'tab' in the first column and the data file type in the second (e.g., measurements, specimen, sample, etc.)
        Optional:
            data : data read in with, e.g., file.readlines()
    Returns
    _______
        list of dictionaries, file type
    """
    if infile:
        if not os.path.exists(infile):
            if return_keys:
                return [], 'empty_file', []
            return [], 'empty_file'
    hold, magic_data, magic_record, magic_keys = [], [], {}, []
    if data:
        lines = list(data)
    elif (not data) and (not infile):
        if return_keys:
            return [], 'empty_file', []
        return [], 'empty_file'
    else:
        # if the file doesn't exist, end here
        if not os.path.exists(infile):
            if return_keys:
                return [], 'bad_file', []
            return [], 'bad_file'
        # use custom pmagpy open_file
        lines = open_file(infile, verbose=verbose)
    if not lines:
        if return_keys:
            return [], 'bad_file', []
        return [], 'bad_file'
    d_line = lines[0][:-1].strip('\n').strip('\r').strip('\t')
    if not d_line:
        if return_keys:
            return [], 'empty_file', []
        return [], 'empty_file'
    if d_line[0] == "s" or d_line[1] == "s":
        delim = 'space'
    elif d_line[0] == "t" or d_line[1] == "t":
        delim = 'tab'
    else:
        print('-W- error reading {}. Check that this is a MagIC-format file'.format(infile))
        if return_keys:
            return [], 'bad_file', []
        return [], 'bad_file'
    if delim == 'space':
        file_type = d_line.split()[1]
    if delim == 'tab':
        file_type = d_line.split('\t')[1]
    if file_type == 'delimited':
        if delim == 'space':
            file_type = d_line.split()[2]
        if delim == 'tab':
            file_type = d_line.split('\t')[2]
    line = lines[1].strip('\n').strip('\r')
    if delim == 'space':
        line = line.split()  # lines[1][:-1].split()
    if delim == 'tab':
        line = line.split('\t')  # lines[1][:-1].split('\t')
    for key in line:
        magic_keys.append(key)
    lines = lines[2:]
    if len(lines) < 1:
        if return_keys:
            return [], 'empty_file', []
        return [], 'empty_file'
    for line in lines[:-1]:
        line.replace('\n', '')
        if delim == 'space':
            rec = line[:-1].split()
        if delim == 'tab':
            rec = line[:-1].split('\t')
        hold.append(rec)
    line = lines[-1].replace('\n', '').replace('\r', '')
    if delim == 'space':
        rec = line[:-1].split()
    if delim == 'tab':
        rec = line.split('\t')
    hold.append(rec)
    for rec in hold:
        magic_record = {}
        if len(magic_keys) > len(rec):
            # pad rec with empty strings if needed
            for i in range(len(magic_keys) - len(rec)):
                rec.append('')
        if len(magic_keys) != len(rec):
            # ignores this warning when reading the dividers in an upload.txt
            # composite file
            if rec != ['>>>>>>>>>>'] and 'delimited' not in rec[0]:
                print("Warning: Uneven record lengths detected in {}: ".format(infile))
                print('keys:', magic_keys)
                print('record:', rec)
        # modified by Ron Shaar:
        # add a health check:
        # if len(magic_keys) > len(rec): take rec
        # if len(magic_keys) < len(rec): take magic_keys
        # original code: for k in range(len(rec)):
        # channged to: for k in range(min(len(magic_keys),len(rec))):
        for k in range(min(len(magic_keys), len(rec))):
            magic_record[magic_keys[k]] = rec[k].strip('\n').strip('\r')
        magic_data.append(magic_record)
    magictype = file_type.lower().split("_")
    Types = ['er', 'magic', 'pmag', 'rmag']
    if magictype in Types:
        file_type = file_type.lower()
    if return_keys:
        return magic_data, file_type, magic_keys
    return magic_data, file_type


Instruction:
Can you tell what is the following Python 3 function doing
def magic_read_dict(path, data=None, sort_by_this_name=None, return_keys=False):
    DATA = {}
    #fin = open(path, 'r')
    #first_line = fin.readline()
    lines = open_file(path)
    if not lines:
        if return_keys:
            return {}, 'empty_file', None
        else:
            return {}, 'empty_file'
    first_line = lines.pop(0)
    if first_line[0] == "s" or first_line[1] == "s":
        delim = ' '
    elif first_line[0] == "t" or first_line[1] == "t":
        delim = '\t'
    else:
        print('-W- error reading ', path)
        if return_keys:
            return {}, 'bad_file', None
        else:
            return {}, 'bad_file'

    file_type = first_line.strip('\n').strip('\r').split(delim)[1]

    item_type = file_type
    #item_type = file_type.split('_')[1][:-1]
    if sort_by_this_name:
        pass
    elif item_type == 'age':
        sort_by_this_name = "by_line_number"
    else:
        sort_by_this_name = item_type
    line = lines.pop(0)
    header = line.strip('\n').strip('\r').split(delim)
    counter = 0
    for line in lines:
        tmp_data = {}
        tmp_line = line.strip('\n').strip('\r').split(delim)
        for i in range(len(header)):
            if i < len(tmp_line):
                tmp_data[header[i]] = tmp_line[i].strip()
            else:
                tmp_data[header[i]] = ""
        if sort_by_this_name == "by_line_number":
            DATA[counter] = tmp_data
            counter += 1
        else:
            if tmp_data[sort_by_this_name] != "":
                DATA[tmp_data[sort_by_this_name]] = tmp_data
    if return_keys:
        return DATA, file_type, header
    else:
        return DATA, file_type

Response: Read a magic - formatted tab - delimited file and return a dictionary of the data and file type.


Instruction:
Here you have a function in Python 3, explain what it does
def sort_magic_data(magic_data, sort_name):
    '''
    Sort magic_data by header (like er_specimen_name for example)
    '''
    magic_data_sorted = {}
    for rec in magic_data:
        name = rec[sort_name]
        if name not in list(magic_data_sorted.keys()):
            magic_data_sorted[name] = []
        magic_data_sorted[name].append(rec)
    return magic_data_sorted

Response: Sort magic_data by header name


Instruction:
Make a summary of the following Python 3 code
def upload_read(infile, table):
    delim = 'tab'
    hold, magic_data, magic_record, magic_keys = [], [], {}, []
    f = open(infile, "r")
#
# look for right table
#
    line = f.readline()[:-1]
    file_type = line.split('\t')[1]
    if file_type == 'delimited':
        file_type = line.split('\t')[2]
    if delim == 'tab':
        line = f.readline()[:-1].split('\t')
    else:
        f.close()
        print("only tab delimitted files are supported now")
        return
    while file_type != table:
        while line[0][0:5] in f.readlines() != ">>>>>":
            pass
        line = f.readline()[:-1]
        file_type = line.split('\t')[1]
        if file_type == 'delimited':
            file_type = line.split('\t')[2]
        ine = f.readline()[:-1].split('\t')
    while line[0][0:5] in f.readlines() != ">>>>>":
        for key in line:
            magic_keys.append(key)
        for line in f.readlines():
            rec = line[:-1].split('\t')
            hold.append(rec)
        for rec in hold:
            magic_record = {}
            if len(magic_keys) != len(rec):
                print("Uneven record lengths detected: ", rec)
                input("Return to continue.... ")
            for k in range(len(magic_keys)):
                magic_record[magic_keys[k]] = rec[k]
            magic_data.append(magic_record)
    f.close()
    return magic_data

Response: Reads a MagIC upload or downloaded txt file and puts data in a list of dictionaries