import csv import io import re from tokenize import String from models.item import Item def csv_to_item(items_csv_reader, solver_run): items = [] headers = [] # get headers and items for key, row in enumerate(items_csv_reader): if key == 0: headers = row else: item = {'attributes': []} # ensure that the b param is formatted correctly if row[len(headers) - 1] != '' and is_float(row[len(headers) - 1]): for key, col in enumerate(headers): if solver_run.irt_model.formatted_b_param() == col: value = float(row[key]) item['b_param'] = value elif solver_run.get_constraint( col) and solver_run.get_constraint( col).reference_attribute.type == 'bundle': if row[key]: item[solver_run.get_constraint( col).reference_attribute.id] = row[key] elif solver_run.get_constraint(col): constraint = solver_run.get_constraint(col) item['attributes'].append({ 'id': col, 'value': row[key], 'type': constraint.reference_attribute.type }) else: if row[key]: item[col] = row[key] # confirm item is only added if it meets the criteria of 100% constraints as a pre-filter items.append(Item.parse_obj(item)) # valid_item = True # item = Item.parse_obj(item) # for constraint in solver_run.constraints: # if item.attribute_exists(constraint.reference_attribute) == False and constraint.minimum == 100: # valid_item = False # if valid_item: items.append(item) return items def solution_to_file(buffer, total_form_items, forms): wr = csv.writer(buffer, dialect='excel', delimiter=',') # write header row for first row utilizing the total items all forms will have # fill the rows with the targets and cut score then the items header = ['status'] for result in forms[0].tif_results: header += [f'tif @ {round(result.theta, 2)}'] for result in forms[0].tcc_results: header += [f'tcc @ {round(result.theta, 2)}'] header += ['cut score'] + [x + 1 for x in range(total_form_items)] wr.writerow(header) # add each form as row to processed csv for form in forms: row = [form.status] for result in form.tif_results + form.tcc_results: row += [ f'target - {result.value}\nresult - {round(result.result, 2)}' ] # provide generated items and cut score row += [round(form.cut_score, 2)] + [item.id for item in form.items] wr.writerow(row) buff2 = io.BytesIO(buffer.getvalue().encode()) return buff2 def error_to_file(buffer, error): wr = csv.writer(buffer, dialect='excel', delimiter=',') wr.writerow(['status']) wr.writerow([error.args[0]]) return io.BytesIO(buffer.getvalue().encode()) def key_to_uuid(key): return re.split("_", key)[0] def solution_items(variables, solver_run): form_items = [] for v in variables: if v.varValue > 0: if 'Item_' in v.name: item_id = v.name.replace('Item_', '') item = solver_run.get_item(int(item_id)) # add item to list and then remove from master item list if item: form_items.append(item) elif 'Bundle_' in v.name: bundle_id = v.name.replace('Bundle_', '') bundle = solver_run.get_bundle(int(bundle_id)) if bundle: for item in bundle.items: if item: form_items.append(item) return form_items def print_problem_variables(problem): # Uncomment this as needed in local dev # print(problem); for v in problem.variables(): print(v.name, "=", v.varValue); # probably a better place for this... def is_float(element: String) -> bool: try: float(element) return True except ValueError: return False