harris1 commited on
Commit
49e113b
1 Parent(s): dbc58fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -86
app.py CHANGED
@@ -285,7 +285,7 @@
285
 
286
  # if __name__ == "__main__":
287
  # iface.launch()
288
- import gradio as gr
289
  import os
290
  from mistralai.client import MistralClient
291
  from mistralai.models.chat_completion import ChatMessage
@@ -298,6 +298,8 @@ if not api_key:
298
  model = "mistral-tiny"
299
  client = MistralClient(api_key=api_key)
300
 
 
 
301
  def generate_goals(input_var):
302
  messages = [
303
  ChatMessage(role="user", content=f"Generate 5 specific, industry relevant goals for {input_var} using Python and Pandas in exam data analysis. Each goal should include a brief name and a one-sentence description of the task or skill.")
@@ -328,11 +330,9 @@ html_content = """
328
  <h1>Exam Data Analysis Goals Generator</h1>
329
  <div id="visualization"></div>
330
  <div id="generatedGoals"></div>
331
-
332
  <script>
333
- const width = 1200;
334
- const height = 800;
335
- const goals = [
336
  { id: 1, x: 100, y: 400, name: "Automate Data Import", description: "Develop scripts to automate exam data extraction from various sources (CSV, Excel, databases) using Pandas read_* functions." },
337
  { id: 2, x: 200, y: 300, name: "Data Cleaning", description: "Implement robust data cleaning processes to handle missing values, outliers, and inconsistencies in exam data using Pandas methods like dropna(), fillna(), and apply()." },
338
  { id: 3, x: 300, y: 200, name: "Data Transformation", description: "Utilize Pandas for complex data transformations such as pivoting exam results, melting question-wise scores, and creating derived features for analysis." },
@@ -407,102 +407,119 @@ html_content = """
407
  { source: 24, target: 17 },
408
  { source: 26, target: 29 }
409
  ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
 
412
- const svg = d3.select("#visualization")
413
- .append("svg")
414
- .attr("width", width)
415
- .attr("height", height);
416
-
417
- const simulation = d3.forceSimulation(goals)
418
- .force("link", d3.forceLink(connections).id(d => d.id))
419
- .force("charge", d3.forceManyBody().strength(-400))
420
- .force("center", d3.forceCenter(width / 2, height / 2));
421
-
422
- const link = svg.append("g")
423
- .selectAll("line")
424
- .data(connections)
425
- .enter().append("line")
426
- .attr("stroke", "#999")
427
- .attr("stroke-opacity", 0.6);
428
-
429
- const node = svg.append("g")
430
- .selectAll("circle")
431
- .data(goals)
432
- .enter().append("circle")
433
- .attr("r", 10)
434
- .attr("fill", d => d.color)
435
- .call(d3.drag()
436
- .on("start", dragstarted)
437
- .on("drag", dragged)
438
- .on("end", dragended));
439
-
440
- const text = svg.append("g")
441
- .selectAll("text")
442
- .data(goals)
443
- .enter().append("text")
444
- .text(d => d.name)
445
- .attr("font-size", "12px")
446
- .attr("dx", 12)
447
- .attr("dy", 4);
448
-
449
  node.on("click", async function(event, d) {
450
- const response = await fetch('generate_goals', {
451
  method: 'POST',
452
  headers: { 'Content-Type': 'application/json' },
453
  body: JSON.stringify({ input_var: d.name })
454
  });
455
  const data = await response.json();
456
- document.getElementById("generatedGoals").innerHTML = `<h2>Generated Goals for ${d.name}</h2><pre>${data}</pre>`;
457
  });
458
 
459
- simulation.on("tick", () => {
460
- link
461
- .attr("x1", d => d.source.x)
462
- .attr("y1", d => d.source.y)
463
- .attr("x2", d => d.target.x)
464
- .attr("y2", d => d.target.y);
465
-
466
- node
467
- .attr("cx", d => d.x)
468
- .attr("cy", d => d.y);
469
-
470
- text
471
- .attr("x", d => d.x)
472
- .attr("y", d => d.y);
473
- });
474
-
475
- function dragstarted(event) {
476
- if (!event.active) simulation.alphaTarget(0.3).restart();
477
- event.subject.fx = event.subject.x;
478
- event.subject.fy = event.subject.y;
479
- }
480
-
481
- function dragged(event) {
482
- event.subject.fx = event.x;
483
- event.subject.fy = event.y;
484
- }
 
 
 
 
 
 
 
485
 
486
- function dragended(event) {
487
- if (!event.active) simulation.alphaTarget(0);
488
- event.subject.fx = null;
489
- event.subject.fy = null;
490
- }
491
  </script>
492
  </body>
493
  </html>
494
  """
495
 
496
- # Gradio interface
497
- iface = gr.Interface(
498
- fn=generate_goals,
499
- inputs=gr.Textbox(visible=False),
500
- outputs=gr.Textbox(visible=False),
501
- title="Exam Data Analysis Goals Generator",
502
- description="Click on a goal in the visualization to generate related goals.",
503
- allow_flagging="never",
504
- css=html_content
505
- )
506
 
507
  if __name__ == "__main__":
508
- iface.launch()
 
285
 
286
  # if __name__ == "__main__":
287
  # iface.launch()
288
+ from flask import Flask, request, jsonify, render_template_string
289
  import os
290
  from mistralai.client import MistralClient
291
  from mistralai.models.chat_completion import ChatMessage
 
298
  model = "mistral-tiny"
299
  client = MistralClient(api_key=api_key)
300
 
301
+ app = Flask(__name__)
302
+
303
  def generate_goals(input_var):
304
  messages = [
305
  ChatMessage(role="user", content=f"Generate 5 specific, industry relevant goals for {input_var} using Python and Pandas in exam data analysis. Each goal should include a brief name and a one-sentence description of the task or skill.")
 
330
  <h1>Exam Data Analysis Goals Generator</h1>
331
  <div id="visualization"></div>
332
  <div id="generatedGoals"></div>
 
333
  <script>
334
+ // Define the goals and connections data
335
+ const goals = [
 
336
  { id: 1, x: 100, y: 400, name: "Automate Data Import", description: "Develop scripts to automate exam data extraction from various sources (CSV, Excel, databases) using Pandas read_* functions." },
337
  { id: 2, x: 200, y: 300, name: "Data Cleaning", description: "Implement robust data cleaning processes to handle missing values, outliers, and inconsistencies in exam data using Pandas methods like dropna(), fillna(), and apply()." },
338
  { id: 3, x: 300, y: 200, name: "Data Transformation", description: "Utilize Pandas for complex data transformations such as pivoting exam results, melting question-wise scores, and creating derived features for analysis." },
 
407
  { source: 24, target: 17 },
408
  { source: 26, target: 29 }
409
  ];
410
+ // Create the SVG container for the goals and connections
411
+ const svg = d3.select("#goalSpace")
412
+ .append("svg")
413
+ .attr("width", width)
414
+ .attr("height", height);
415
+ // Draw connections between goals
416
+ const links = svg.selectAll("line")
417
+ .data(connections)
418
+ .enter()
419
+ .append("line")
420
+ .attr("x1", d => goals.find(g => g.id === d.source).x)
421
+ .attr("y1", d => goals.find(g => g.id === d.source).y)
422
+ .attr("x2", d => goals.find(g => g.id === d.target).x)
423
+ .attr("y2", d => goals.find(g => g.id === d.target).y)
424
+ .attr("stroke", "#999")
425
+ .attr("stroke-width", 1)
426
+ .attr("stroke-opacity", 0.6);
427
+ // Draw goal nodes
428
+ const goalNodes = svg.selectAll("circle")
429
+ .data(goals)
430
+ .enter()
431
+ .append("circle")
432
+ .attr("cx", d => d.x)
433
+ .attr("cy", d => d.y)
434
+ .attr("r", 10)
435
+ .attr("fill", d => {
436
+ if (d.id <= 10) return "blue";
437
+ if (d.id <= 20) return "green";
438
+ return "orange";
439
+ })
440
+ .attr("class", "goal");
441
+ // Add labels to the goals
442
+ const goalLabels = svg.selectAll("text")
443
+ .data(goals)
444
+ .enter()
445
+ .append("text")
446
+ .attr("x", d => d.x + 15)
447
+ .attr("y", d => d.y)
448
+ .text(d => d.name)
449
+ .attr("font-size", "12px");
450
+ // Hover info box
451
+ const hoverInfo = d3.select("#hoverInfo");
452
+ // Add hover effects on goal nodes
453
+ goalNodes.on("mouseover", function(event, d) {
454
+ d3.select(this).attr("r", 15);
455
+ hoverInfo.style("display", "block")
456
+ .style("left", (event.pageX + 10) + "px")
457
+ .style("top", (event.pageY - 10) + "px")
458
+ .html(`<strong>${d.name}</strong><br>${d.description}`);
459
+ }).on("mouseout", function() {
460
+ d3.select(this).attr("r", 10);
461
+ hoverInfo.style("display", "none");
462
+ });
463
 
464
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  node.on("click", async function(event, d) {
466
+ const response = await fetch('/generate_goals', {
467
  method: 'POST',
468
  headers: { 'Content-Type': 'application/json' },
469
  body: JSON.stringify({ input_var: d.name })
470
  });
471
  const data = await response.json();
472
+ document.getElementById("generatedGoals").innerHTML = `<h2>Generated Goals for ${d.name}</h2><pre>${data.goals}</pre>`;
473
  });
474
 
475
+ // Function to update selected goal information
476
+ function updateSelectedGoalInfo(goal) {
477
+ const selectedGoalDiv = d3.select("#selectedGoal");
478
+ selectedGoalDiv.html(`
479
+ <h3>${goal.name}</h3>
480
+ <p>${goal.description}</p>
481
+ `);
482
+ }
483
+ // Function to display the response from the server
484
+ function displayResponse(content) {
485
+ const responseBox = d3.select("#responseBox");
486
+ responseBox.html(`
487
+ <h2>Response</h2>
488
+ <p>${content}</p>
489
+ `);
490
+ }
491
+ // Handle mouse move event to highlight the closest goal
492
+ svg.on("mousemove", function(event) {
493
+ const [x, y] = d3.pointer(event);
494
+ const closest = findClosestGoal(x, y);
495
+ highlightClosestGoal(closest);
496
+ });
497
+ // Function to find the closest goal to the mouse pointer
498
+ function findClosestGoal(x, y) {
499
+ return goals.reduce((closest, goal) => {
500
+ const distance = Math.sqrt(Math.pow(goal.x - x, 2) + Math.pow(goal.y - y, 2));
501
+ return distance < closest.distance ? { goal, distance } : closest;
502
+ }, { goal: null, distance: Infinity }).goal;
503
+ }
504
+ // Function to highlight the closest goal
505
+ function highlightClosestGoal(goal) {
506
+ d3.select("#info").html(`Closest goal: ${goal.name}`);
507
+ }
508
 
 
 
 
 
 
509
  </script>
510
  </body>
511
  </html>
512
  """
513
 
514
+ @app.route('/')
515
+ def index():
516
+ return render_template_string(html_content)
517
+
518
+ @app.route('/generate_goals', methods=['POST'])
519
+ def generate_goals_api():
520
+ input_var = request.json['input_var']
521
+ goals = generate_goals(input_var)
522
+ return jsonify({'goals': goals})
 
523
 
524
  if __name__ == "__main__":
525
+ app.run(debug=True)