File size: 11,771 Bytes
257e8f6
 
 
 
 
 
 
 
b4f80a1
257e8f6
b4f80a1
257e8f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ee33ea8
257e8f6
ee33ea8
 
 
 
 
 
 
 
 
 
257e8f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ee33ea8
257e8f6
 
 
 
 
 
 
 
 
ee33ea8
257e8f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823c8d5
257e8f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823c8d5
 
 
 
257e8f6
 
 
 
 
 
820635d
ee33ea8
820635d
257e8f6
 
ee33ea8
 
 
 
257e8f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
820635d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257e8f6
 
 
ee33ea8
257e8f6
 
 
 
 
 
 
 
 
 
 
 
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
from openai import OpenAI
import gradio as gr
import os
import base64
import numpy as np
from PIL import Image
import io
import pandas as pd
from dotenv import load_dotenv

load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
client = OpenAI(
    # This is the default and can be omitted
    api_key = api_key,
)

def analyze_feedback(feedback_text):
    """Analyzes feedback text and returns a summary.

    Args:
        feedback_text (str): The text of the feedback to analyze.

    Returns:
        str: A summary of the feedback.
    """
    chat_completion = client.chat.completions.create(
    messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": feedback_text}
        ]
    ,
    model="gpt-3.5-turbo"
    )
    return chat_completion.choices[0].message.content

def process_files(uploaded_files, text_data):
    results = [["File Name", "Summary", "Areas of Improvement", "Actionable Objectives","Sentiment", "Themes"]]
    if text_data == "":
        for file_path in uploaded_files:
            # Extract file name from the file path
            file_name = os.path.basename(file_path)
            # Open and read the file content
            with open(file_path, 'r', encoding='utf-8') as file:
                feedback_text = file.read()
                #print(feedback_text)
    else:
        feedback_text = text_data
        # Process the feedback text
        processed_feedback = process_feedback(feedback_text)
        
        #print ('processed', processed_feedback)
        # Example result format for each file
        file_result = {
            "summary": processed_feedback['summary'],
            "areas_of_improvement": processed_feedback['areas_of_improvement'],
            "actionable_objectives": processed_feedback['actionable_objectives'],
            "sentiment": processed_feedback['sentiment'],
            "themes": processed_feedback['themes']
        }
        
        #print(file_result)
        #print (type(file_result))

    return feedback_text, file_result


def process_feedback(feedback_text):
    # Example processing steps
    # You need to replace these with your actual feedback analysis logic
    #print (feedback_text)
    summary = analyze_feedback("Provide the summary of the feedback first and then after the summary, analyze and list down the top achievements in this Feedback and pull out any key themes from the Feedback: " + feedback_text)
    
    # Simple sentiment analysis
    sentiment = analyze_feedback("What are the overall sentiment score and reasons for the score in this feedback, if 1 is negative and 10 is rated as positive. Provide responses as colon delimeted format: Who gave the Feedback:What was the sentiment score:why was the score given for this feedback: " + feedback_text)

    # Theme identification (implement your logic)
    themes = analyze_feedback("What are the key recurring positive and negative themes in this feedback: " + feedback_text)
    
    #print ("Summ",summary)
    #strengths = analyze_feedback("What are the key strengths in this feedback: " + feedback_text)
    areas_of_improvement = analyze_feedback("Which hard and soft skills may need development according to this Feedback: " + feedback_text)
    actionable_objectives = analyze_feedback("Suggest actionable objectives based on this feedback and steps to accomplish these objectives: " + feedback_text)

    # This depends on how the response is formatted. You may need to adjust the parsing logic
    sentiment_data = []  # This will be a list of dictionaries
    print (sentiment)
    # Example of processing (you'll need to adjust this based on actual response format)
    for line in sentiment.split('\n'):
        if line.strip():
            parts = line.split(':')
            if len(parts) >= 3:
                sentiment_data.append({
                    "Giver": parts[0].strip(),
                    "Score": parts[1].strip(),
                    "Reason": parts[2].strip()
                })
    # Assign the results to analysis_results
    analysis_results = {
        "summary": summary,
        "themes": themes,
        "areas_of_improvement": areas_of_improvement,
        "actionable_objectives": actionable_objectives,
        "sentiment": sentiment_data  
    }
    #print (analysis_results)

    return analysis_results

def display_results(uploaded_files, text_data):
    """
    Processes uploaded feedback files and displays the results.

    Args:
        uploaded_files (list): A list of file paths to uploaded feedback files.

    Returns:
        tuple: A tuple containing various analysis results or an empty string if no files were uploaded.
    """
    feedback, results = process_files(uploaded_files, text_data)
    if results:
        # Extract each area of feedback from the dictionary
        summary = results['summary'] if 'summary' in results else ""
        areas_of_improvement = results['areas_of_improvement'] if 'areas_of_improvement' in results else ""
        actionable_objectives = results['actionable_objectives'] if 'actionable_objectives' in results else ""
        themes_text = results['themes'] if 'themes' in results else ""
        #sentiments_text = results['sentiment'] if 'sentiment' in results else ""
        sentiment_table=[]
        if results:
            for sentiment_entry in results['sentiment']:
                entry_as_list = [sentiment_entry['Giver'], sentiment_entry['Score'], sentiment_entry['Reason']]
                sentiment_table.append(entry_as_list)
                
        # Create a Pandas DataFrame
        df = pd.DataFrame(sentiment_table, columns=["Giver", "Score", "Reason"])
        df = df.iloc[1:]
        return summary, themes_text, areas_of_improvement, actionable_objectives,df
    else:
        return "","","","",[], None

def image_to_base64(image_path):
    """
    Reads an image file and returns its base64 encoded representation.

    Args:
        image_path (str): The path to the image file.

    Returns:
        str: The base64 encoded representation of the image data.
    """

    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")


# Encode the logo image into base64
logo_base64 = image_to_base64("pixelpk_logo.png")


markdown_content = f"""
<img src="data:image/png;base64,{logo_base64}" alt="Feedback Logo" style="width: 100px; height: 100px; margin-top: 10px;" />
<h1>Employee OR Student Feedbcak Analyzer</h1>
<p style="margin-top: 5px;">Feedback analyzer give employee/students feedback, providing key insights into strengths, areas for improvement, and overall sentiments.</p>
"""

# Custom CSS for styling the interface
custom_css = """
<style>
  .gradio-container {
    font-family: 'Helvetica Neue', Arial, sans-serif;
  }
  .gradio-accordion {
    border-radius: 5px;
  }
  .gradio-accordion .gradio-tab {
    padding: 10px;
  }
  .gradio-textbox {
    height: auto;
    min-height: 50px;
    max-height: 300px; /* Adjust as needed */
    overflow-y: auto; /* Enables vertical scrolling */
  }
  h1 {
    text-align: center;
    display:block;
}
</style>
"""


with gr.Blocks(gr.themes.Monochrome(), css=custom_css) as demo:
    # Display introductory markdown content
    gr.Markdown(f"""<center>{markdown_content}</center>
                <p>**NOTE**: Below some txt examples given. Makesure to uploaded file content OR input text should be as given below.</p>
                """)
    # Layout elements in a row
    with gr.Column():
        with gr.Row():
            # Upload button for selecting files
            upload_button = gr.File(file_types=[".txt"], file_count = "multiple")
            upload_text = gr.TextArea(placeholder = "enter your text here")
        # Button to trigger analysis
        submit_button = gr.Button("Submit")

    # Accordion to display analysis results
    with gr.Accordion("Analysis Results"):
        # Tab for summary information
        with gr.Tab("Summary"):
            output_summary = gr.Textbox(label="Summary", lines = 4, placeholder="Summary will appear here...")
        # Tab for key insights
        with gr.Tab("Key Insights"):
            output_improvement_areas = gr.Textbox(label="Key Insights", lines = 15, placeholder="Themes will appear here...")
        # Tab for specific improvement areas
        with gr.Tab("Improvement Areas"):
            output_themes = gr.Textbox(label="Analysis", lines = 15, placeholder="Analysis will appear here...")
        # Tab for actionable objectives
        with gr.Tab("Objectives"):
            output_actionable_objectives = gr.Textbox(label="Actionable Objectives", lines = 15, placeholder="Objectives will appear here...")
        # Tab for sentiment analysis results
        with gr.Tab("Sentiments"):
            output_sentiment_table = gr.Dataframe(label="Sediment Analysis")
    with gr.Column():
        gr.Markdown(f"""
                <p>
                    From a teacher: Aamir is an attentive student who actively participates in class discussions and demonstrates a strong understanding of the subject matter. However, there is room for improvement in completing assignments on time.
                    From a incharge: As an in-charge, I have noticed that Aamir is well-disciplined and follows instructions diligently. However, I encourage Aamir to seek clarification whenever necessary to ensure complete understanding of tasks.
                    From a co_supervisor: In my role as a co-supervisor, I have observed Aamir's dedication to their projects and their willingness to seek assistance when needed. I recommend Aamir to continue developing their research skills and explore more innovative approaches.
                    From a principal: Aamir has shown commendable progress in both academic and extracurricular activities. However, I would like to see Aamir take on more leadership roles and actively contribute to school initiatives.
                    </p>
                    <h3> OR </h3>
                    <p>
                    From a Supervisor: ABC shows remarkable attention to detail in their work, consistently delivering high-quality results. However, I've observed a need for improvement in time management, as some projects have missed deadlines.
                    From a Team Member: ABC is a great team player, always ready to lend a hand. Their collaborative spirit boosts our team's morale. On the downside, there are times when ABC seems hesitant to take initiative on new tasks.
                    From a Client: In our interactions, ABC has displayed excellent customer service skills. He is always polite and helpful. However, there's been an instance where he promised a follow-up but failed to do so in the agreed timeframe.
                    From a Department Head: ABC innovative approach to problem-solving has been a significant asset to our department. He need to work on their presentation skills, though, as they tend to be a bit unclear during departmental briefings.
                    From an Internal Service Provider (like IT Support): ABC is always respectful and appreciative of the support services. However, he often submit requests at the last minute, making it challenging to provide timely assistance.
                    </p>
                """)
    # Connect button click to analysis function
    submit_button.click(
        display_results,
        inputs = [upload_button, upload_text],
        outputs = [
            output_summary,
            output_themes,
            output_improvement_areas,
            output_actionable_objectives,
            output_sentiment_table
        ]
    )

    # Launch the Gradio interface
    demo.launch(share = True)