Spaces:
Build error
Build error
File size: 5,239 Bytes
441d880 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | from pydantic import BaseModel
from typing import List, Dict, Optional
from collections import defaultdict
import datetime
import json
import os
import pandas as pd
import re
import numpy as np
import pprint
import math
from UserProfile import *
class PVEntry(BaseModel):
Num: int
Value: str
Question: str
Criteria: Optional[str]
Rating_Definition: Optional[str]
Adjacent_Values: Optional[List[str]]
Opposite_Values: Optional[List[str]]
Answer: Optional[str]
Score: Optional[int]
Assessment: Optional[str]
def parse_values(value_str: Optional[str], delimiter: str = ",") -> List[str]:
"""
Parses a delimited string into a list of strings.
If the value is None or NaN, return an empty list.
Args:
value_str (Optional[str]): The input string to parse.
delimiter (str): The delimiter to use for splitting. Defaults to ','.
Returns:
List[str]: A list of trimmed strings.
"""
if pd.isna(value_str) or not isinstance(value_str, str):
return []
return [v.strip() for v in value_str.split(delimiter)]
def extract_values_from_assessment_file(assessment_file):
"""
Extracts and aggregates Value and Score pairs from an Excel file by summing scores.
Args:
assessment_file (str): Path to the Excel file.
Returns:
list: A list of dictionaries with Value and total Score.
"""
# Read the Excel file
df = pd.read_excel(assessment_file)
# Ensure required columns are present
if "Value" not in df.columns or "Score" not in df.columns:
raise ValueError("The file must contain 'Value' and 'Score' columns.")
# Clean the data
df_clean = df[["Value", "Score"]].dropna()
df_clean["Score"] = pd.to_numeric(df_clean["Score"], errors="coerce")
# Group by Value and sum the scores
aggregated = df_clean.groupby("Value", as_index=False).sum()
# Convert to list of dictionaries
return aggregated.to_dict(orient="records")
class PVAssessment(BaseModel):
Entries: dict[str, list[PVEntry]]
@staticmethod
def generate_personality_assessment(personality_file):
df = pd.read_excel(personality_file)
# Use defaultdict to allow appending multiple PVEntries per value
entries = defaultdict(list)
for _, row in df.iterrows():
pv_entry = PVEntry(
Num=row["Num"],
Value=row["Value"],
Question=row["Assessment_Question"],
Criteria=row["Assessment_Criteria"],
Rating_Definition=row["Rating_Definition"],
Adjacent_Values=parse_values(row["Adjacent_Values"]),
Opposite_Values=parse_values(row["Opposite_Values"]),
Answer=None,
Score=None,
Assessment=None
)
entries[row["Value"]].append(pv_entry)
return PVAssessment(Entries=dict(entries))
@staticmethod
def get_score_definition(value, score, pv_assessment):
"""
Converts a numerical score (1-50) into a corresponding rating definition.
Args:
value (str): The personality value key.
score (int): A numerical score between 1 and 50.
pv_assessment (PVAssessment): The personality assessment object.
Returns:
str: The corresponding rating definition, or an empty string if not found.
"""
if not isinstance(pv_assessment, PVAssessment):
print("Error: Expected a PVAssessment object.")
return ""
if not isinstance(score, int) or score < 1 or score > 50:
print(f"Error: Invalid score '{score}' for '{value}'. Expected a number between 1 and 50.")
return ""
entry_list = pv_assessment.Entries.get(value)
if not entry_list or not isinstance(entry_list, list) or len(entry_list) == 0:
print(f"Error: No entries found for value '{value}'.")
return ""
# Use the first PVEntry in the list
pv_entry = entry_list[0]
rating_definition = pv_entry.Rating_Definition
if not isinstance(rating_definition, str) or not rating_definition:
print(f"Error: No valid rating definition found for '{value}'.")
return ""
rating_definition_list = parse_values(rating_definition, delimiter=";")
# Find the corresponding description based on the score range
for definition in rating_definition_list:
try:
range_part, description = definition.split(":", 1)
range_part = range_part.strip()
if "-" in range_part:
range_lower, range_upper = map(int, range_part.split("-"))
else:
range_lower = range_upper = int(range_part)
if range_lower <= score <= range_upper:
return description.strip()
except ValueError:
print(f"Error: Invalid rating definition format for '{value}': {definition}")
continue
print(f"Error: No matching rating definition found for score {score} in '{value}'.")
return "" |