Spaces:
Sleeping
Sleeping
File size: 8,713 Bytes
c53b63b 7ad44eb 47b49e7 c74b3e5 7ad44eb 47b49e7 7ad44eb c53b63b 7ad44eb 47b49e7 7ad44eb 47b49e7 a7ad55c 98eb0b6 a7ad55c 98eb0b6 a7ad55c 98eb0b6 7ad44eb 47b49e7 7ad44eb 42c790d a7ad55c 42c790d c53b63b 7ad44eb 98eb0b6 7ad44eb 42c790d 47b49e7 7ad44eb 42c790d 47b49e7 7ad44eb 47b49e7 7ad44eb 42c790d 7ad44eb 47b49e7 7ad44eb 47b49e7 98eb0b6 7155478 7ad44eb 42c790d 7ad44eb 42c790d 7ad44eb a7ad55c 7ad44eb 42c790d 7ad44eb 42c790d 7ad44eb 98eb0b6 7ad44eb 98eb0b6 47b49e7 7ad44eb 47b49e7 211f41a 47b49e7 c53b63b 47b49e7 |
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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
import pandas as pd
from pandas.tseries.offsets import MonthEnd
import gradio as gr
import random
# Function to generate a random light color
def generate_random_light_color():
min_brightness = 0.7
while True:
r, g, b = [random.randint(128, 255) for _ in range(3)]
brightness = (r * 0.299 + g * 0.587 + b * 0.114) / 255
if brightness >= min_brightness:
return '#{:02x}{:02x}{:02x}'.format(*(r, g, b))
# Function to set the background color of a specific cell
def set_cell_color(styles_df, index, column, hex_color):
styles_df.at[index, column] = f'background-color: {hex_color}'
return styles_df
# Function to calculate the threshold
def calculate_threshold(value, is_high_price=True):
if 0 <= value <= 200:
return 0.20
elif 201 <= value <= 500:
return 0.70
elif 501 <= value <= 1000:
return 1.0
elif 1001 <= value <= 2000:
return 2.0
elif 2001 <= value <= 3000:
return 3.0
elif 3001 <= value <= 4000:
return 4.0
elif 4001 <= value <= 5000:
return 5.0
else:
return 5.0
def last_thursday(dt):
# Get the last day of the month
last_day_of_month = dt + MonthEnd(0)
# Calculate how many days to subtract to get the last Thursday
offset = (last_day_of_month.weekday() - 3) % 7
return last_day_of_month - pd.Timedelta(days=offset)
def check_condition_passed(df, column_name, max_index, output_value, close_column, value1, value2, is_high = True):
# print(f"Max index: {max_index}")
for index_maybe in range(max_index-1, -1, -1):
# print(f"At index : {index_maybe}")
if is_high:
if df.loc[index_maybe, column_name] > output_value:
close_value = df.loc[index_maybe, close_column]
# print(f"current value: {df.loc[index_maybe, column_name]} - close value {close_value}")
if close_value > value1 and close_value > value2:
return True
break
else:
if df.loc[index_maybe, column_name] < output_value:
close_value = df.loc[index_maybe, close_column]
if close_value < value1 and close_value < value2:
return True
break
return False
# if is_high:
# filtered_df = df[(df.index < max_index) & (df[column_name] > output_value)]
# else:
# filtered_df = df[(df.index < max_index) & (df[column_name] < output_value)]
# if not filtered_df.empty:
# first_valid_row = filtered_df.iloc[0]
# print(f"Respective close row: {first_valid_row}")
# close_value = first_valid_row[close_column]
# print(f"Respective close value: {close_value}")
# if is_high:
# if close_value > value1 and close_value > value2:
# return True
# else:
# if close_value < value1 and close_value < value2:
# return True
# else:
# return False
def get_output_value(value1, value2, is_high=False):
if is_high:
return max(int(value1), int(value2)) + 1
else:
return min(int(value1), int(value2)) - 1
# Function to read CSV and generate Excel with modifications
def process_csv(file):
df = pd.read_csv(file)
df.columns = df.columns.str.strip() # Remove trailing spaces from column names
HIGH_NAME = "HIGH PRICE"
if HIGH_NAME not in df.columns:
HIGH_NAME = "HIGH"
LOW_NAME = "LOW PRICE"
if LOW_NAME not in df.columns:
LOW_NAME = "LOW"
CLOSE_NAME = "CLOSE PRICE"
if CLOSE_NAME not in df.columns:
CLOSE_NAME = "close"
DATE_NAME = "DATE"
if DATE_NAME not in df.columns:
DATE_NAME = "Date"
# Add three empty columns between LOW PRICE and CLOSE PRICE
low_price_index = df.columns.get_loc(CLOSE_NAME)
df.insert(low_price_index + 1, 'HIGH Result', '')
df.insert(low_price_index + 2, 'LOW Result', '')
df.insert(low_price_index + 3, 'Empty Column', '')
# Convert DATE to datetime
df[DATE_NAME] = pd.to_datetime(df[DATE_NAME], format='%d-%b-%Y')
# Detect the last Thursday of each month and insert an empty row after it
df['Last_Thursday'] = df[DATE_NAME].apply(last_thursday)
indices_to_insert = []
for i in range(len(df)):
if df.loc[i, DATE_NAME] == df.loc[i, 'Last_Thursday']:
indices_to_insert.append(i)
df['Separator'] = ''
# Insert empty rows and update the Last_Thursday column
for idx in reversed(indices_to_insert):
# Insert an empty row
df = pd.concat([df.iloc[:idx], pd.DataFrame([{'Separator': 'Separator'}]), df.iloc[idx:]]).reset_index(drop=True)
price_columns = [HIGH_NAME, LOW_NAME, CLOSE_NAME]
df[price_columns] = df[price_columns].replace({',': ''}, regex=True).apply(pd.to_numeric, errors='coerce')
# Calculate global thresholds for HIGH PRICE and LOW PRICE columns
high_price_threshold = calculate_threshold(df[HIGH_NAME].max(), is_high_price=True)
low_price_threshold = calculate_threshold(df[LOW_NAME].min(), is_high_price=False)
# Process HIGH PRICE and LOW PRICE columns
def process_column(df, style_df, column_name, result_column_name, threshold):
element_used = [False] * len(df[column_name])
# for last_thurday_date, group in df.groupby('Last_Thursday', sort=False):
grouped_df = df.groupby((df['Separator'] == 'Separator').cumsum())
for group_name, group in grouped_df:
group = group[group['Separator'] != 'Separator']
rows = group.index.tolist()
print(rows)
for i in range(len(rows) - 1, -1, -1):
if not element_used[rows[i]]:
for j in range(i - 1, -1, -1):
diff = abs(df.loc[rows[i], column_name] - df.loc[rows[j], column_name])
if diff < threshold and not element_used[rows[j]]:
output_value = get_output_value(df.loc[rows[i], column_name], df.loc[rows[j], column_name], 'high' in column_name.lower())
# print(f"i {rows[i]} j {rows[j]} {column_name}")
# print(f"{df.loc[rows[i], column_name]} {df.loc[rows[j], column_name]} diff {diff}, threshold: {threshold}, output value {output_value}")
df.at[rows[j], result_column_name] = output_value
element_used[rows[i]] = True
element_used[rows[j]] = True
color = generate_random_light_color()
style_df = set_cell_color(style_df, index=rows[i], column=column_name, hex_color=color)
style_df = set_cell_color(style_df, index=rows[j], column=column_name, hex_color=color)
# check if there is higher or lower value, if yes, then colorize it
response = check_condition_passed(df, column_name, rows[j], output_value, CLOSE_NAME, df.loc[rows[i], column_name], df.loc[rows[j], column_name], 'high' in column_name.lower())
if response:
style_df = set_cell_color(style_df, index=rows[j], column=result_column_name, hex_color=color)
break
# Create a dictionary to map column names to Excel letters
column_letter_map = {v: k for k, v in enumerate(df.columns, start=1)}
# Save to an Excel file and get the workbook
style_df = pd.DataFrame('', index=df.index, columns=df.columns)
output_file = file.replace(".csv", "_processed.xlsx")
process_column(df, style_df, HIGH_NAME, 'HIGH Result', high_price_threshold)
process_column(df, style_df, LOW_NAME, 'LOW Result', low_price_threshold)
# add an empty row before the new month
df[DATE_NAME] = df[DATE_NAME].dt.strftime('%d-%b-%Y')
# df['Last_Thursday'] = df['Last_Thursday'].dt.strftime('%d-%b-%Y')
styled_df = df.style.apply(lambda _: style_df, axis=None)
styled_df.to_excel(output_file, engine='openpyxl', index=False)
return output_file
# Gradio Interface
def gradio_interface(file):
return process_csv(file)
# Gradio app interface
iface = gr.Interface(
fn=gradio_interface,
inputs=gr.File(label="Upload CSV File (.csv)", file_count="single"),
outputs=gr.File(label="Download Processed Excel File"),
title="CSV to Excel Processor with Cell Highlighting",
description="Upload a CSV file with stock data, and download a processed Excel file with highlighted cells."
)
if __name__ == "__main__":
iface.launch()
|