Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| import numpy as np | |
| import scipy.stats as stats | |
| from fpdf import FPDF | |
| import base64 | |
| import os | |
| from plots import test_profile | |
| import matplotlib.pyplot as plt | |
| from PIL import Image | |
| # Function to calculate z-score | |
| def calculate_z_score(test_score, mean, std_dev): | |
| return (test_score - mean) / std_dev | |
| def z_score_calculator(value, norm_mean, norm_sd): | |
| z_value = (value - norm_mean) / norm_sd | |
| stanine_value = round(1.25 * z_value + 5.5) | |
| z_score = round(z_value, 2) | |
| return z_score, stanine_value | |
| def bnt_calculator(age, education, bnt): | |
| if age <= 60 and education <= 12: | |
| norm_mean = 54.5 | |
| norm_sd = 3.2 | |
| z_score, stanine_value = z_score_calculator(bnt, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age <= 60 and education > 12: | |
| norm_mean = 54.0 | |
| norm_sd = 4.4 | |
| z_score, stanine_value = z_score_calculator(bnt, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age > 60 and education <= 12: | |
| norm_mean = 54.8 | |
| norm_sd = 3.3 | |
| z_score, stanine_value = z_score_calculator(bnt, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age > 60 and education > 12: | |
| norm_mean = 56.2 | |
| norm_sd = 3.4 | |
| z_score, stanine_value = z_score_calculator(bnt, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| else: | |
| print("missing value/ wrong format") | |
| def fas_calculator(age, education, fas): | |
| if age <= 60 and education <= 12: | |
| norm_mean = 42.7 | |
| norm_sd = 13.7 | |
| z_score, stanine_value = z_score_calculator(fas, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age <= 60 and education > 12: | |
| norm_mean = 46.7 | |
| norm_sd = 13.7 | |
| z_score, stanine_value = z_score_calculator(fas, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age > 60 and education <= 12: | |
| norm_mean = 46.9 | |
| norm_sd = 10.4 | |
| z_score, stanine_value = z_score_calculator(fas, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| elif age > 60 and education > 12: | |
| norm_mean = 51.6 | |
| norm_sd = 12.6 | |
| z_score, stanine_value = z_score_calculator(fas, norm_mean, norm_sd) | |
| return norm_mean, norm_sd, z_score, stanine_value | |
| else: | |
| print("missing value/ wrong format") | |
| def generate_graph(BNT_stanine, FAS_stanine): | |
| # Create a plot | |
| fig, ax = plt.subplots() | |
| # Set axis labels and title | |
| ax.set_xlabel('Stanine values') | |
| ax.set_ylabel('Test') | |
| # Set the y-axis to display the tests | |
| ax.set_yticks([1, 2]) | |
| ax.set_yticklabels(['BNT', 'FAS']) | |
| # Set the range of the x-axis | |
| ax.set_xlim([0, 10]) | |
| # Add dots for BNT and FAS scores | |
| ax.scatter(BNT_stanine, 1, s=100, label='BNT') | |
| ax.scatter(FAS_stanine, 2, s=100, label='FAS') | |
| # Add legend | |
| ax.legend() | |
| # Show the plot | |
| # plt.show() | |
| # Save the graph as a png file | |
| fig.savefig('test_profile.png') | |
| return 'test_profile.png' | |
| def create_pdf(z_score, mean, std_dev, logo_path, plot_path): | |
| pdf = FPDF() | |
| pdf.add_page() | |
| pdf.set_xy(0, 0) | |
| pdf.set_font("Arial", size=12) | |
| # Add logos | |
| x_positions = [25, 85, 145] | |
| for i, logo_path in enumerate(logo_paths): | |
| pdf.image(logo_path, x=x_positions[i], y=8, w=40) | |
| pdf.set_xy(10, 50) | |
| # Add title and center it | |
| title = "Z-Score Report" | |
| pdf.set_font("Arial", style="B", size=16) | |
| title_width = pdf.get_string_width(title) + 6 | |
| pdf.cell((210 - title_width) / 2) | |
| pdf.cell(title_width, 10, title, 0, 1, "C") | |
| # Add z-score and center it | |
| pdf.set_font("Arial", size=12) | |
| z_score_text = "Your z-score is: {:.2f}".format(z_score) | |
| z_score_width = pdf.get_string_width(z_score_text) + 6 | |
| pdf.cell((210 - z_score_width) / 2) | |
| pdf.cell(z_score_width, 10, z_score_text, 0, 1, "C") | |
| # Add mean and standard deviation and center it | |
| mean_std_text = "Mean: {}, Standard Deviation: {}".format(mean, std_dev) | |
| mean_std_width = pdf.get_string_width(mean_std_text) + 6 | |
| pdf.cell((210 - mean_std_width) / 2) | |
| pdf.cell(mean_std_width, 10, mean_std_text, 0, 1, "C") | |
| # Add logo | |
| pdf.image(plot_path, x=10, y=80, w=200) | |
| # pdf.set_xy(10, 40) | |
| # Add tool description and center it | |
| pdf.set_xy(10, 230) | |
| pdf.set_font("Arial", size=10) | |
| description = "This PDF report was generated using the Z-Score Calculator Streamlit App." | |
| pdf.multi_cell(0, 10, description, 0, "C") | |
| # Add explanatory text about the collaboration between KI and KTH | |
| pdf.set_xy(10, 255) | |
| pdf.set_font("Arial", size=8) | |
| collaboration_text = ( | |
| "Den här PDF:en är en del av ett samarbetsprojekt mellan Karolinska Institutet (KI) och " | |
| "Kungliga Tekniska Högskolan (KTH) med målsättningen att använda artificiell intelligens (AI) och " | |
| "teknik för att minska administration i sjukhusarbete. Projektet fokuserar på att utveckla och " | |
| "implementera AI-baserade lösningar för att förbättra arbetsflöden, öka effektiviteten och " | |
| "minska den administrativa bördan för sjukvårdspersonal. För frågor om formuläret kontakta Fredrik Sand fredrik.sand-aronsson@regionstockholm.se, för frågor om teknik kontakta Birger Moëll bmoell@kth.se." | |
| ) | |
| line_width = 190 | |
| line_height = pdf.font_size_pt * 0.6 | |
| lines = collaboration_text.split(' ') | |
| current_line = '' | |
| for word in lines: | |
| if pdf.get_string_width(current_line + word) < line_width: | |
| current_line += word + ' ' | |
| else: | |
| pdf.cell(line_width, line_height, current_line, 0, 1) | |
| current_line = word + ' ' | |
| pdf.cell(line_width, line_height, current_line, 0, 1) | |
| return pdf | |
| def pdf_to_base64(pdf): | |
| with open(pdf, "rb") as file: | |
| return base64.b64encode(file.read()).decode('utf-8') | |
| # Title and description | |
| st.title("Z-Score Calculator") | |
| st.write("Enter your test score, age, and education level to calculate the z-score.") | |
| # Input fields | |
| #test_score = st.number_input("Test Score", min_value=0, value=0, step=1) | |
| age = st.number_input("Age", min_value=0, value=18, step=1) | |
| education_level = st.number_input("Education Level in years", min_value=0, value=18, step=1) | |
| isw = st.number_input("ISW", min_value=0, value=0, step=1) | |
| bnt = st.number_input("BNT", min_value=0, value=0, step=1) | |
| fas = st.number_input("FAS", min_value=0, value=0, step=1) | |
| animal = st.number_input("Animal", min_value=0, value=0, step=1) | |
| verb = st.number_input("Verb", min_value=0, value=0, step=1) | |
| repetition = st.number_input("Repetition", min_value=0, value=0, step=1) | |
| logicogrammatic = st.number_input("Logicogrammatic", min_value=0, value=0, step=1) | |
| inference = st.number_input("Inference", min_value=0, value=0, step=1) | |
| reading_speed = st.number_input("Reading Speed", min_value=0, value=0, step=1) | |
| decoding_words = st.number_input("Decoding Words", min_value=0, value=0, step=1) | |
| decoding_non_words = st.number_input("Decoding Non-Words", min_value=0, value=0, step=1) | |
| months_backward = st.number_input("Months Backward", min_value=0, value=0, step=1) | |
| pataka = st.number_input("Pataka", min_value=0, value=0, step=1) | |
| # add all the tests | |
| # Calculate mean and standard deviation based on age and education level | |
| # For simplicity, we will use made-up values for mean and std_dev | |
| mean = np.random.randint(50, 100) | |
| std_dev = np.random.randint(10, 30) | |
| # Calculate z-score and display result | |
| if st.button("Calculate Z-Score"): | |
| profile = test_profile(age, education_level, isw, bnt, fas) | |
| # for each value in the profile, calculate the z-score | |
| bnt_mean, bnt_std, z_bnt, stanine_bnt = bnt_calculator(age, education_level, bnt) | |
| fas_mean, fas_std, z_fas, stanine_fas = fas_calculator(age, education_level, fas) | |
| # z_score = calculate_z_score(test_score, mean, std_dev) | |
| st.write(f"Your bnt z-score is: {z_bnt:.2f}") | |
| st.write(f"Mean: {bnt_mean}, Standard Deviation: {bnt_std}") | |
| st.write(f"Your fas z-score is: {z_fas:.2f}") | |
| st.write(f"Mean: {fas_mean}, Standard Deviation: {fas_std}") | |
| # Create PDF | |
| # logo_path="logo.jpg" | |
| logo_paths = ["logo.jpg", "logo2.jpg", "logo3.jpg"] | |
| # create the plot from the dataframe | |
| # check if education level is more than 12 years, if more than 12, set value to one, otherwise zero | |
| education_level = 1 if education_level > 12 else 0 | |
| plot_path = generate_graph(stanine_bnt, stanine_fas) | |
| # create an image from the plot and add to streamlit display | |
| image = Image.open(plot_path) | |
| st.image(image, caption='Stanine plot', use_column_width=True) | |
| pdf_filename = "z_score_report.pdf" | |
| pdf = create_pdf(z_bnt, bnt_mean, bnt_std, logo_paths, plot_path) | |
| pdf.output(name=pdf_filename) | |
| # Download PDF | |
| with open(pdf_filename, "rb") as file: | |
| base64_pdf = base64.b64encode(file.read()).decode('utf-8') | |
| pdf_display = f'<a href="data:application/octet-stream;base64,{base64_pdf}" download="{pdf_filename}">Download PDF</a>' | |
| st.markdown(pdf_display, unsafe_allow_html=True) | |
| # Remove PDF file after download | |
| if os.path.exists(pdf_filename): | |
| os.remove(pdf_filename) |