Spaces:
Sleeping
Sleeping
Commit
·
a089b0d
1
Parent(s):
5e37e32
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
import csv
|
4 |
+
import io
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
import numpy as np
|
7 |
+
|
8 |
+
def preprocess_csv(input_bytes):
|
9 |
+
text = input_bytes.decode() # Decode bytes to text
|
10 |
+
output = io.StringIO()
|
11 |
+
writer = csv.writer(output)
|
12 |
+
|
13 |
+
for row in csv.reader(io.StringIO(text)): # Read text as csv
|
14 |
+
if len(row) > 5:
|
15 |
+
row = row[0:5] + [','.join(row[5:])] # Combine extra fields into one
|
16 |
+
writer.writerow(row)
|
17 |
+
|
18 |
+
output.seek(0) # go to the start of the StringIO object
|
19 |
+
return output
|
20 |
+
|
21 |
+
def load_data(file):
|
22 |
+
column_names = [
|
23 |
+
'Functional area',
|
24 |
+
'Scenario name',
|
25 |
+
'Start datetime',
|
26 |
+
'End datetime',
|
27 |
+
'Status',
|
28 |
+
'Error message'
|
29 |
+
]
|
30 |
+
data = pd.read_csv(file, header=None, names=column_names)
|
31 |
+
return data
|
32 |
+
|
33 |
+
def fill_missing_data(data, column_index, value):
|
34 |
+
data.iloc[:, column_index] = data.iloc[:, column_index].fillna(value)
|
35 |
+
return data
|
36 |
+
|
37 |
+
|
38 |
+
def single_main(uploaded_file):
|
39 |
+
# st.title('Single CSV Analyzer')
|
40 |
+
|
41 |
+
# uploaded_file = st.file_uploader("Upload CSV file", type="csv")
|
42 |
+
|
43 |
+
if uploaded_file is not None:
|
44 |
+
# Process the csv file
|
45 |
+
column_names = ["Functional area", "Scenario name", "Start datetime", "End datetime", "Status", "Error message"]
|
46 |
+
|
47 |
+
filet = uploaded_file.read()
|
48 |
+
processed_output = preprocess_csv(filet)
|
49 |
+
processed_file = io.StringIO(processed_output.getvalue())
|
50 |
+
data = load_data(processed_file)
|
51 |
+
|
52 |
+
data = fill_missing_data(data, 4, 0)
|
53 |
+
data['Start datetime'] = pd.to_datetime(data['Start datetime'], errors='coerce')
|
54 |
+
data['End datetime'] = pd.to_datetime(data['End datetime'], errors='coerce')
|
55 |
+
data['Time spent'] = (data['End datetime'] - data['Start datetime']).dt.total_seconds()
|
56 |
+
|
57 |
+
# st.write(data)
|
58 |
+
|
59 |
+
# Display scenarios with status "failed" grouped by functional area
|
60 |
+
failed_scenarios = data[data['Status'] == 'FAILED']
|
61 |
+
passed_scenarios = data[data['Status'] == 'PASSED']
|
62 |
+
# selected_status = st.selectbox("Select a status", ['Failed', 'Passed'])
|
63 |
+
# Use radio buttons for selecting status
|
64 |
+
selected_status = st.radio("Select a status", ['Failed', 'Passed'])
|
65 |
+
|
66 |
+
# Determine which scenarios to display based on selected status
|
67 |
+
if selected_status == 'Failed':
|
68 |
+
unique_areas = np.append(failed_scenarios['Functional area'].unique(), "All")
|
69 |
+
selected_scenarios = failed_scenarios
|
70 |
+
selected_functional_area = st.selectbox("Select a functional area", unique_areas, index=len(unique_areas)-1)
|
71 |
+
elif selected_status == 'Passed':
|
72 |
+
unique_areas = np.append(passed_scenarios['Functional area'].unique(), "All")
|
73 |
+
selected_scenarios = passed_scenarios
|
74 |
+
selected_functional_area = st.selectbox("Select a functional area", unique_areas, index=len(unique_areas)-1)
|
75 |
+
else:
|
76 |
+
selected_scenarios = None
|
77 |
+
|
78 |
+
if selected_scenarios is not None:
|
79 |
+
# st.write(f"Scenarios with status '{selected_status}' grouped by functional area:")
|
80 |
+
st.markdown(f"### Scenarios with status '{selected_status}' grouped by functional area:")
|
81 |
+
|
82 |
+
# Handle the "All" option
|
83 |
+
# Filter scenarios based on selected functional area
|
84 |
+
if selected_functional_area != "All":
|
85 |
+
filtered_scenarios = selected_scenarios[selected_scenarios['Functional area'] == selected_functional_area]
|
86 |
+
else:
|
87 |
+
filtered_scenarios = selected_scenarios
|
88 |
+
|
89 |
+
# Calculate the average time spent for each functional area
|
90 |
+
average_time_spent_seconds = filtered_scenarios.groupby('Functional area')['Time spent'].mean().reset_index()
|
91 |
+
|
92 |
+
# Convert average time spent from seconds to minutes and seconds format
|
93 |
+
average_time_spent_seconds['Time spent'] = pd.to_datetime(average_time_spent_seconds['Time spent'], unit='s').dt.strftime('%M:%S')
|
94 |
+
|
95 |
+
# Group by functional area and get the start datetime for sorting
|
96 |
+
start_datetime_group = filtered_scenarios.groupby('Functional area')['Start datetime'].min().reset_index()
|
97 |
+
|
98 |
+
# Merge average_time_spent_seconds and start_datetime_group
|
99 |
+
average_time_spent_seconds = average_time_spent_seconds.merge(start_datetime_group, on='Functional area')
|
100 |
+
|
101 |
+
# Filter scenarios based on selected functional area
|
102 |
+
|
103 |
+
grouped_filtered_failed_scenarios = filtered_scenarios.groupby('Functional area')[['Scenario name', 'Error message']].apply(lambda x: x.reset_index(drop=True))
|
104 |
+
st.dataframe(grouped_filtered_failed_scenarios)
|
105 |
+
|
106 |
+
|
107 |
+
# Display total count of failures
|
108 |
+
fail_count = len(failed_scenarios)
|
109 |
+
st.write(f"Failing scenarios Count: {fail_count}")
|
110 |
+
# Display total count of Passing
|
111 |
+
pass_count = len(passed_scenarios)
|
112 |
+
st.write(f"Passing scenarios Count: {pass_count}")
|
113 |
+
|
114 |
+
# Sort the average time spent table by start datetime
|
115 |
+
average_time_spent_seconds = average_time_spent_seconds.sort_values(by='Start datetime')
|
116 |
+
|
117 |
+
# Display average time spent on each functional area in a table
|
118 |
+
st.markdown("### Average Time Spent on Each Functional Area")
|
119 |
+
st.dataframe(average_time_spent_seconds)
|
120 |
+
|
121 |
+
# Create and display bar graph of errors by functional area
|
122 |
+
st.write("### Bar graph showing number of failures in each functional area:")
|
123 |
+
error_counts = failed_scenarios['Functional area'].value_counts()
|
124 |
+
plt.figure(figsize=(10, 6))
|
125 |
+
plt.bar(error_counts.index, error_counts.values)
|
126 |
+
plt.xlabel('Functional Area')
|
127 |
+
plt.ylabel('Number of Errors')
|
128 |
+
plt.title('Number of Errors by Functional Area')
|
129 |
+
plt.xticks(rotation=45, ha='right')
|
130 |
+
plt.tight_layout() # Add this line to adjust layout
|
131 |
+
st.pyplot(plt)
|
132 |
+
|
133 |
+
else:
|
134 |
+
st.write("### No scenarios with status 'failed' found.")
|
135 |
+
pass
|
136 |
+
|
137 |
+
def main():
|
138 |
+
st.title('CSV Analyser')
|
139 |
+
|
140 |
+
uploaded_file = st.file_uploader("Upload CSV file", type="csv")
|
141 |
+
|
142 |
+
if uploaded_file is not None:
|
143 |
+
single_main(uploaded_file) # Load the main app when the file is uploaded
|
144 |
+
|
145 |
+
if __name__ == "__main__":
|
146 |
+
main()
|