Spaces:
Running
Running
import pandas as pd | |
import numpy as np | |
import plotly.graph_objs as go | |
from plotly.subplots import make_subplots | |
import streamlit as st | |
from scipy.stats import norm | |
def is_matching_pattern(column, prefix): | |
""" | |
بررسی میکند که آیا نام ستون با الگوی prefix-number (1 تا 3 رقم) مطابقت دارد یا خیر. | |
پارامترها: | |
- column: نام ستون برای بررسی. | |
- prefix: پیشوندی که باید قبل از خط فاصله باشد. | |
بازگشت: | |
- True اگر مطابقت دارد، در غیر این صورت False. | |
""" | |
if not str(column).startswith(prefix + '_'): | |
return False | |
suffix = column[len(prefix) + 1:] | |
if 1 <= len(suffix) <= 3 and suffix.isdigit(): | |
return True | |
return False | |
def analyze_single_column(df, column_name, type_option): | |
""" | |
تابع 1: تحلیل یک ستون بر اساس گزینه انتخاب شده. | |
پارامترها: | |
- df: DataFrame پانداس. | |
- column_name: نام ستون یا پیشوند. | |
- type_option: 1 یا 2. | |
بازگشت: | |
- table: DataFrame شامل فراوانیها و درصدها. | |
- fig: شیء Figure از Plotly. | |
""" | |
total_rows = len(df) | |
if type_option == 1: | |
if column_name not in df.columns: | |
st.error(f"❌ ستون '{column_name}' در فایل Excel یافت نشد.") | |
return None, None | |
# محاسبه فراوانی | |
frequency = df[column_name].value_counts(dropna=False).sort_index() | |
percentage = (frequency / total_rows) * 100 | |
table = pd.DataFrame({ | |
column_name: frequency.index, | |
'Frequency': frequency.values, | |
'Percentage': percentage.values | |
}) | |
st.subheader("📊 جدول فراوانی و درصد:") | |
st.dataframe(table) | |
# ترسیم هیستوگرام تعاملی | |
fig = go.Figure(data=[go.Bar( | |
x=table[column_name].astype(str), | |
y=table['Percentage'], | |
marker=dict(color='rgba(173, 216, 230, 0.6)', | |
line=dict(color='rgba(173, 216, 230, 1.0)', width=1)), | |
width=0.4 | |
)]) | |
fig.update_layout( | |
title=f"📈 هیستوگرام '{column_name}'", | |
xaxis_title=column_name, | |
yaxis_title='Percentage', | |
bargap=0.2, | |
template='plotly_white' | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
return table, fig | |
elif type_option == 2: | |
# انتخاب ستونها مطابق الگوی name-number | |
selected_columns = [col for col in df.columns if is_matching_pattern(col, column_name)] | |
if not selected_columns: | |
st.error(f"❌ هیچ ستونی مطابق الگوی '{column_name}-<number>' در فایل Excel یافت نشد.") | |
return None, None | |
results_freq = {} | |
results_pct = {} | |
for col in selected_columns: | |
unique_values = df[col].dropna().unique() | |
if len(unique_values) > 2: | |
st.warning(f"⚠️ ستون '{col}' بیش از دو مقدار یکتا دارد و نادیده گرفته شد.") | |
continue | |
value_counts = df[col].value_counts(dropna=False) | |
results_freq[col] = sum(list(value_counts)) | |
if not results_freq: | |
st.error("❌ هیچ ستون معتبری با دقیقاً دو مقدار یکتا یافت نشد.") | |
return None, None | |
# ایجاد جدول فراوانی | |
freq_table = pd.DataFrame(results_freq).fillna(0).astype(int) | |
freq_table.insert(0, column_name, freq_table.index) | |
st.subheader("📊 جدول فراوانی:") | |
st.dataframe(freq_table) | |
# محاسبه درصدها | |
# برای هر ستون، درصدها بر اساس تعداد سطرهای فیلتر شده محاسبه میشوند | |
pct_table = freq_table.copy() | |
for col in selected_columns: | |
pct_table[col] = pct_table[col] / freq_table[col].sum() * 100 | |
st.subheader("📊 جدول درصدها:") | |
st.dataframe(pct_table) | |
# ترسیم هیستوگرام تعاملی برای درصدها | |
fig = go.Figure() | |
for col in selected_columns: | |
fig.add_trace(go.Bar( | |
x=pct_table[column_name].astype(str), | |
y=pct_table[col], | |
name=col, | |
width=0.4 | |
)) | |
fig.update_layout( | |
title=f"📈 هیستوگرام درصدها برای ستونهای '{column_name}-<number>'", | |
xaxis_title=column_name, | |
yaxis_title='Percentage', | |
barmode='group', | |
bargap=0.2, | |
template='plotly_white' | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
return freq_table, pct_table, fig | |
else: | |
st.error("❌ گزینه 'Type Option' باید 1 یا 2 باشد.") | |
return None, None | |
def read_excel_sheets(file): | |
"""خواندن یک فایل Excel با چندین شیت و بازگشت دیکشنری از DataFrameها.""" | |
try: | |
xls = pd.ExcelFile(file) | |
sheets_data = {sheet: xls.parse(sheet) for sheet in xls.sheet_names} | |
return sheets_data | |
except Exception as e: | |
st.error(f"❌ خطا در خواندن فایل Excel: {e}") | |
return None | |
def z_testes(n1, n2, p1, p2): | |
"""انجام Z-test برای نسبتها و بازگشت p-value.""" | |
try: | |
pooled_p = (n1 * p1 + n2 * p2) / (n1 + n2) | |
se = np.sqrt(pooled_p * (1 - pooled_p) * (1 / n1 + 1 / n2)) | |
z = (p1 - p2) / se | |
p_value = 2 * (1 - norm.cdf(abs(z))) | |
return p_value | |
except ZeroDivisionError: | |
return np.nan | |
def Z_test_dataframes(sheets_data): | |
"""پردازش DataFrame هر شیت و محاسبه DataFrameهای جدید با نتایج Z-test.""" | |
result_dataframes = {} | |
for sheet_name, df in sheets_data.items(): | |
if df.empty: | |
st.warning(f"⚠️ شیت '{sheet_name}' خالی است. نادیده گرفته شد.") | |
continue | |
df = df.set_index(df.columns[0]) # استفاده از اولین ستون به عنوان ایندکس | |
rows, cols = df.shape | |
if cols < 2: | |
st.warning(f"⚠️ شیت '{sheet_name}' ستونهای کافی برای تحلیل ندارد. نادیده گرفته شد.") | |
continue | |
new_df = pd.DataFrame(index=df.index[:-1], columns=df.columns[1:]) | |
for i, row_name in enumerate(df.index[:-1]): | |
for j, col_name in enumerate(df.columns[1:]): | |
try: | |
n1 = df.iloc[-1, 0] # x_I1 | |
n2 = df.iloc[-1, j+1] # x_Ij | |
p1 = df.iloc[i, 0] # x_1J | |
p2 = df.iloc[i, j+1] # x_ij | |
p_value = z_testes(n1, n2, p1, p2) | |
new_df.iloc[i, j] = p_value | |
except Exception as e: | |
st.error(f"❌ خطا در پردازش شیت '{sheet_name}', ردیف '{row_name}', ستون '{col_name}': {e}") | |
new_df.iloc[i, j] = np.nan | |
result_dataframes[sheet_name] = new_df | |
return result_dataframes | |
def analyze_z_test(file): | |
""" | |
تابع 3: انجام تحلیل Z-Test بر روی فایل Excel بارگذاری شده. | |
پارامترها: | |
- file: فایل Excel بارگذاری شده | |
بازگشت: | |
- result_dataframes: دیکشنری از DataFrameها با p-value | |
""" | |
sheets_data = read_excel_sheets(file) | |
if sheets_data is None: | |
return None | |
result_dataframes = Z_test_dataframes(sheets_data) | |
if not result_dataframes: | |
st.error("❌ هیچ شیت معتبری برای تحلیل Z-Test یافت نشد.") | |
return None | |
st.write("### 📈 جداول پردازش شده با نتایج Z-Test") | |
for sheet_name, df in result_dataframes.items(): | |
st.write(f"#### شیت: {sheet_name}") | |
# اعمال رنگبندی بر اساس p-value | |
def color_p_value(val): | |
try: | |
if pd.isna(val): | |
return 'background-color: lightgray' | |
elif val < 0.05: | |
return 'background-color: lightgreen' | |
else: | |
return 'background-color: lightcoral' | |
except: | |
return 'background-color: lightgray' | |
styled_df = df.style.applymap(color_p_value) | |
# نمایش DataFrame رنگی | |
st.dataframe(styled_df, use_container_width=True) | |
return result_dataframes | |
def analyze_multiple_columns(df, first_name, second_name, first_type, second_type): | |
""" | |
تابع 2: تحلیل دادهها بر اساس ترکیب انواع اول و دوم. | |
پارامترها: | |
- df: DataFrame پانداس | |
- first_name: نام یا پیشوند ستون اول | |
- second_name: نام یا پیشوند ستون دوم | |
- first_type: 1 یا 2 | |
- second_type: 1 یا 2 | |
بازگشت: | |
- freq_table: DataFrame شامل فراوانیها | |
- pct_table: DataFrame شامل درصدها | |
- fig: شیء Figure از Plotly | |
""" | |
total_rows = len(df) | |
# توابع کمکی برای انتخاب ستونها بر اساس نوع | |
def select_columns_type1(name): | |
if name in df.columns: | |
return [name] | |
else: | |
st.error(f"❌ ستون '{name}' در فایل Excel یافت نشد.") | |
return [] | |
def select_columns_type2(name): | |
selected = [col for col in df.columns if is_matching_pattern(col, name)] | |
if not selected: | |
st.error(f"❌ هیچ ستونی مطابق الگوی '{name}-<number>' در فایل Excel یافت نشد.") | |
return selected | |
# انتخاب ستونها بر اساس نوع | |
first_columns = select_columns_type1(first_name) if first_type == 1 else select_columns_type2(first_name) | |
second_columns = select_columns_type1(second_name) if second_type == 1 else select_columns_type2(second_name) | |
if not first_columns or not second_columns: | |
st.error("❌ انتخاب ستونها ناموفق بود.") | |
return None, None, None | |
figs = [] | |
if first_type == 1 and second_type == 1: | |
# هر دو نوع 1 | |
if len(first_columns) != 1 or len(second_columns) != 1: | |
st.error("❌ وقتی هر دو نوع 1 هستند، دقیقاً یک ستون برای هر کدام انتخاب کنید.") | |
return None, None, None | |
col1 = first_columns[0] | |
col2 = second_columns[0] | |
contingency = pd.crosstab(df[col1], df[col2]) | |
freq_table = contingency.copy() | |
st.subheader("📊 جدول فراوانی مشترک:") | |
st.dataframe(freq_table) | |
# محاسبه درصدها | |
pct_table = contingency.div(contingency.sum().sum()) * 100 | |
st.subheader("📊 جدول درصدها:") | |
st.dataframe(pct_table) | |
# ترسیم Heatmap | |
fig = go.Figure(data=go.Heatmap( | |
z=pct_table.values, | |
x=pct_table.columns, | |
y=pct_table.index, | |
colorscale='Blues', | |
colorbar=dict(title='Percentage') | |
)) | |
fig.update_layout( | |
title=f"📈 Heatmap بین '{col1}' و '{col2}'", | |
xaxis_title=col2, | |
yaxis_title=col1, | |
template='plotly_white' | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
figs.append(fig) | |
elif first_type == 1 and second_type == 2: | |
# نوع اول 1 و نوع دوم 2 | |
if len(first_columns) != 1: | |
st.error("❌ وقتی نوع اول 1 است، دقیقاً یک ستون انتخاب کنید.") | |
return None, None, None | |
col1 = first_columns[0] | |
col2_list = second_columns | |
unique_values_col1 = df[col1].dropna().unique() | |
freq_results = {} | |
pct_results = {} | |
for val in unique_values_col1: | |
filter_df = df[df[col1] == val] | |
freq_table = {} | |
pct_table = {} | |
for col2 in col2_list: | |
freq = filter_df[col2].value_counts(dropna=False) | |
freq_table[col2] = freq.to_dict() | |
pct = (freq / len(filter_df)) * 100 | |
pct_table[col2] = pct.to_dict() | |
freq_results[val] = freq_table | |
pct_results[val] = pct_table | |
# ایجاد DataFrameهای فراوانی | |
freq_df = pd.DataFrame(freq_results).T.fillna(0).astype(int) | |
freq_df.insert(0, col1, freq_df.index) | |
st.subheader("📊 جدول فراوانی بر اساس گروه:") | |
st.dataframe(freq_df) | |
# ایجاد DataFrameهای درصد | |
pct_df = pd.DataFrame(pct_results).T.fillna(0).round(2) | |
pct_df.insert(0, col1, pct_df.index) | |
st.subheader("📊 جدول درصد بر اساس گروه:") | |
st.dataframe(pct_df) | |
# ترسیم نمودارهای بار برای درصدها | |
for val, data in pct_results.items(): | |
st.subheader(f"📈 درصدها برای '{col1}' = {val}") | |
fig = make_subplots(rows=1, cols=len(col2_list), subplot_titles=col2_list) | |
for i, col2 in enumerate(col2_list, 1): | |
categories = list(data[col2].keys()) | |
values = list(data[col2].values()) | |
fig.add_trace(go.Bar( | |
x=categories, | |
y=values, | |
marker=dict(color='rgba(173, 216, 230, 0.6)', | |
line=dict(color='rgba(173, 216, 230, 1.0)', width=1)), | |
width=0.4 | |
), row=1, col=i) | |
fig.update_xaxes(title_text=col2, row=1, col=i) | |
fig.update_yaxes(title_text='Percentage', row=1, col=i) | |
fig.update_layout( | |
title=f"📈 درصدها برای '{col1}' = {val}", | |
template='plotly_white', | |
showlegend=False | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
figs.append(fig) | |
elif first_type == 2 and second_type == 1: | |
# نوع اول 2 و نوع دوم 1 | |
if len(second_columns) != 1: | |
st.error("❌ وقتی نوع دوم 1 است، دقیقاً یک ستون انتخاب کنید.") | |
return None, None, None | |
col2 = second_columns[0] | |
col1_list = first_columns | |
unique_values_col2 = df[col2].dropna().unique() | |
freq_results = {} | |
pct_results = {} | |
for val in unique_values_col2: | |
filter_df = df[df[col2] == val] | |
freq_table = {} | |
pct_table = {} | |
for col1 in col1_list: | |
freq = filter_df[col1].value_counts(dropna=False) | |
freq_table[col1] = freq.to_dict() | |
pct = (freq / len(filter_df)) * 100 | |
pct_table[col1] = pct.to_dict() | |
freq_results[val] = freq_table | |
pct_results[val] = pct_table | |
# ایجاد DataFrameهای فراوانی | |
freq_df = pd.DataFrame(freq_results).T.fillna(0).astype(int) | |
freq_df.insert(0, col2, freq_df.index) | |
st.subheader("📊 جدول فراوانی بر اساس گروه:") | |
st.dataframe(freq_df) | |
# ایجاد DataFrameهای درصد | |
pct_df = pd.DataFrame(pct_results).T.fillna(0).round(2) | |
pct_df.insert(0, col2, pct_df.index) | |
st.subheader("📊 جدول درصد بر اساس گروه:") | |
st.dataframe(pct_df) | |
# ترسیم نمودارهای بار برای درصدها | |
for val, data in pct_results.items(): | |
st.subheader(f"📈 درصدها برای '{col2}' = {val}") | |
fig = make_subplots(rows=1, cols=len(col1_list), subplot_titles=col1_list) | |
for i, col1 in enumerate(col1_list, 1): | |
categories = list(data[col1].keys()) | |
values = list(data[col1].values()) | |
fig.add_trace(go.Bar( | |
x=categories, | |
y=values, | |
marker=dict(color='rgba(173, 216, 230, 0.6)', | |
line=dict(color='rgba(173, 216, 230, 1.0)', width=1)), | |
width=0.4 | |
), row=1, col=i) | |
fig.update_xaxes(title_text=col1, row=1, col=i) | |
fig.update_yaxes(title_text='Percentage', row=1, col=i) | |
fig.update_layout( | |
title=f"📈 درصدها برای '{col2}' = {val}", | |
template='plotly_white', | |
showlegend=False | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
figs.append(fig) | |
elif first_type == 2 and second_type == 2: | |
# هر دو نوع 2 | |
col1_list = first_columns | |
col2_list = second_columns | |
freq_results = {} | |
pct_results = {} | |
for col2 in col2_list: | |
for val in df[col2].dropna().unique(): | |
filter_df = df[df[col2] == val] | |
frequency = {} | |
percentage = {} | |
for col1 in col1_list: | |
count = filter_df[col1].count() | |
frequency[col1] = count | |
percentage[col1] = (count / len(filter_df)) * 100 if len(filter_df) > 0 else np.nan | |
freq_results[(col2, val)] = frequency | |
pct_results[(col2, val)] = percentage | |
if not freq_results: | |
st.error("❌ هیچ ترکیب معتبری برای هر دو نوع 2 یافت نشد.") | |
return None, None, None | |
# ایجاد DataFrameهای فراوانی | |
freq_df = pd.DataFrame(list(freq_results.values()), index=pd.MultiIndex.from_tuples(freq_results.keys(), names=['Second Column', 'Second Column Value'])) | |
st.subheader("📊 جدول فراوانی چندبعدی:") | |
st.dataframe(freq_df) | |
# ایجاد DataFrameهای درصد | |
pct_df = pd.DataFrame(list(pct_results.values()), index=pd.MultiIndex.from_tuples(pct_results.keys(), names=['Second Column', 'Second Column Value'])) | |
st.subheader("📊 جدول درصد چندبعدی:") | |
st.dataframe(pct_df.round(2)) | |
# ترسیم نمودارهای بار برای درصدها | |
for (col2, val), data in pct_results.items(): | |
st.subheader(f"📈 درصدها برای '{col2}' = {val}") | |
fig = go.Figure(data=[go.Bar( | |
x=list(data.keys()), | |
y=list(data.values()), | |
marker=dict(color='rgba(173, 216, 230, 0.6)', | |
line=dict(color='rgba(173, 216, 230, 1.0)', width=1)), | |
width=0.4 | |
)]) | |
fig.update_layout( | |
title=f"📈 درصدها برای '{col2}' = {val}", | |
xaxis_title=first_name, | |
yaxis_title='Percentage', | |
template='plotly_white' | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
figs.append(fig) | |
else: | |
st.error("❌ 'First Type' و 'Second Type' باید هر کدام 1 یا 2 باشند.") | |
return None, None, None | |
return freq_table, pct_table, fig | |
def Z_test_dataframes(sheets_data): | |
"""پردازش DataFrame هر شیت و محاسبه DataFrameهای جدید با نتایج Z-test.""" | |
result_dataframes = {} | |
for sheet_name, df in sheets_data.items(): | |
if df.empty: | |
st.warning(f"⚠️ شیت '{sheet_name}' خالی است. نادیده گرفته شد.") | |
continue | |
df = df.set_index(df.columns[0]) # استفاده از اولین ستون به عنوان ایندکس | |
rows, cols = df.shape | |
if cols < 2: | |
st.warning(f"⚠️ شیت '{sheet_name}' ستونهای کافی برای تحلیل ندارد. نادیده گرفته شد.") | |
continue | |
new_df = pd.DataFrame(index=df.index[:-1], columns=df.columns[1:]) | |
for i, row_name in enumerate(df.index[:-1]): | |
for j, col_name in enumerate(df.columns[1:]): | |
try: | |
n1 = df.iloc[-1, 0] # x_I1 | |
n2 = df.iloc[-1, j+1] # x_Ij | |
p1 = df.iloc[i, 0] # x_1J | |
p2 = df.iloc[i, j+1] # x_ij | |
p_value = z_testes(n1, n2, p1, p2) | |
new_df.iloc[i, j] = p_value | |
except Exception as e: | |
st.error(f"❌ خطا در پردازش شیت '{sheet_name}', ردیف '{row_name}', ستون '{col_name}': {e}") | |
new_df.iloc[i, j] = np.nan | |
result_dataframes[sheet_name] = new_df | |
return result_dataframes | |
def analyze_z_test(file): | |
""" | |
تابع 3: انجام تحلیل Z-Test بر روی فایل Excel بارگذاری شده. | |
پارامترها: | |
- file: فایل Excel بارگذاری شده | |
بازگشت: | |
- result_dataframes: دیکشنری از DataFrameها با p-value | |
""" | |
sheets_data = read_excel_sheets(file) | |
if sheets_data is None: | |
return None | |
result_dataframes = Z_test_dataframes(sheets_data) | |
if not result_dataframes: | |
st.error("❌ هیچ شیت معتبری برای تحلیل Z-Test یافت نشد.") | |
return None | |
st.write("### 📈 جداول پردازش شده با نتایج Z-Test") | |
for sheet_name, df in result_dataframes.items(): | |
st.write(f"#### شیت: {sheet_name}") | |
# اعمال رنگبندی بر اساس p-value | |
def color_p_value(val): | |
try: | |
if pd.isna(val): | |
return 'background-color: lightgray' | |
elif val < 0.05: | |
return 'background-color: lightgreen' | |
else: | |
return 'background-color: lightcoral' | |
except: | |
return 'background-color: lightgray' | |
styled_df = df.style.applymap(color_p_value) | |
# نمایش DataFrame رنگی | |
st.dataframe(styled_df, use_container_width=True) | |
return result_dataframes | |
def read_excel_sheets(file): | |
"""خواندن یک فایل Excel با چندین شیت و بازگشت دیکشنری از DataFrameها.""" | |
try: | |
xls = pd.ExcelFile(file) | |
sheets_data = {sheet: xls.parse(sheet) for sheet in xls.sheet_names} | |
return sheets_data | |
except Exception as e: | |
st.error(f"❌ خطا در خواندن فایل Excel: {e}") | |
return None | |
def main(): | |
st.title("📊 Data Analysis Application") | |
st.write(""" | |
خوش آمدید به **Data Analysis Application**! این ابزار به شما امکان میدهد یک فایل Excel بارگذاری کنید و بر اساس انتخاب خود، تحلیلهای مختلفی را انجام دهید. | |
""") | |
# File uploader | |
uploaded_file = st.file_uploader("📂 فایل Excel خود را بارگذاری کنید", type=["xlsx", "xls"]) | |
if uploaded_file is not None: | |
try: | |
df = pd.read_excel(uploaded_file) | |
st.success("✅ فایل با موفقیت بارگذاری شد!") | |
st.subheader("🗂️ پیشنمایش دادههای بارگذاری شده:") | |
st.dataframe(df.head()) # نمایش چند ردیف اول | |
except Exception as e: | |
st.error(f"❌ خطا در خواندن فایل Excel: {e}") | |
return | |
st.markdown("---") | |
# Function Selection | |
st.header("🔍 انتخاب تابع تحلیل") | |
analysis_function = st.radio("Choose Function", ("Analyze Single Column", "Analyze Multiple Columns", "Run Z-Test Analysis")) | |
if analysis_function == "Analyze Single Column": | |
st.header("📈 تحلیل یک ستون") | |
column_name = st.text_input("🔍 نام ستون یا پیشوند را وارد کنید:", "") | |
type_option = st.selectbox("📊 انتخاب گزینه نوع تحلیل", ("1", "2")) | |
if st.button("▶️ اجرای تحلیل"): | |
if column_name.strip() == "": | |
st.error("❗ لطفاً نام ستون معتبر وارد کنید.") | |
else: | |
type_option_int = int(type_option) | |
result = analyze_single_column(df, column_name, type_option_int) | |
if result is not None: | |
if type_option_int == 1: | |
table, fig = result | |
else: | |
freq_table, pct_table, fig = result | |
st.success("✅ تحلیل با موفقیت انجام شد!") | |
elif analysis_function == "Analyze Multiple Columns": | |
st.header("📊 تحلیل چندین ستون") | |
first_name = st.text_input("🔍 نام ستون اول یا پیشوند آن را وارد کنید:", "") | |
second_name = st.text_input("🔍 نام ستون دوم یا پیشوند آن را وارد کنید:", "") | |
first_type = st.selectbox("📊 انتخاب نوع تحلیل برای ستون اول", ("1", "2"), key='first_type') | |
second_type = st.selectbox("📊 انتخاب نوع تحلیل برای ستون دوم", ("1", "2"), key='second_type') | |
if st.button("▶️ اجرای تحلیل"): | |
if first_name.strip() == "" or second_name.strip() == "": | |
st.error("❗ لطفاً نام ستونهای معتبر وارد کنید.") | |
else: | |
first_type_int = int(first_type) | |
second_type_int = int(second_type) | |
result = analyze_multiple_columns(df, first_name, second_name, first_type_int, second_type_int) | |
if result is not None: | |
if first_type_int ==1 and second_type_int ==1: | |
freq_table, pct_table, fig = result | |
else: | |
freq_table, pct_table, fig = result | |
st.success("✅ تحلیل با موفقیت انجام شد!") | |
elif analysis_function == "Run Z-Test Analysis": | |
st.header("📉 اجرای تحلیل Z-Test") | |
st.write(""" | |
این تحلیل Z-Test برای نسبتها را روی هر شیت از فایل Excel شما انجام میدهد. | |
اطمینان حاصل کنید که هر شیت به درستی ساختاربندی شده باشد: | |
- **ستون اول** باید ایندکس باشد (مثلاً دستهبندیها). | |
- **آخرین ردیف** باید شامل تعداد کلها (`n1`, `n2`, ...) باشد. | |
- **ردیفهای قبلی** باید شامل تعدادها (`p1`, `p2`, ...) باشند. | |
""") | |
if st.button("▶️ اجرای تحلیل Z-Test"): | |
result_dataframes = analyze_z_test(uploaded_file) | |
if result_dataframes is not None: | |
st.success("✅ تحلیل Z-Test با موفقیت انجام شد!") | |
else: | |
st.info("ℹ️ لطفاً یک فایل Excel بارگذاری کنید تا تحلیل شروع شود.") | |
if __name__ == "__main__": | |
main() | |