Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WikidataAPI improved and working #83

Merged
merged 4 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
408 changes: 407 additions & 1 deletion .gitignore

Large diffs are not rendered by default.

405 changes: 405 additions & 0 deletions wikidata_service/.gitignore

Large diffs are not rendered by default.

136 changes: 17 additions & 119 deletions wikidata_service/WikiDataTest/Controllers/WikiDataController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using WikiDataTest.Models;
using WikiDataTest.Services;

namespace WikiDataTest.Controllers
{
Expand All @@ -8,138 +10,34 @@ namespace WikiDataTest.Controllers
public class WikiDataController : ControllerBase
{
private readonly ILogger<WikiDataController> _logger;
private readonly QueryService _queryService;
private readonly WikiDataService _wikiDataService;
private readonly QuestionService _questionService;

public WikiDataController(ILogger<WikiDataController> logger)

public WikiDataController(ILogger<WikiDataController> logger,
QueryService queryService, WikiDataService wikiDataService, QuestionService questionService)
{
_logger = logger;
_queryService = queryService;
_wikiDataService = wikiDataService;
_questionService = questionService;
}

[HttpGet("GetQuestions")]
public async Task<IActionResult> GetQuestions()
{
string endpointUrl = "https://query.wikidata.org/sparql?query=";
string sparqlQuery = "SELECT ?capitalLabel ?countryLabel WHERE { ?capital wdt:P1376 ?country. ?capital wdt:P31 wd:Q5119. ?country wdt:P31 wd:Q3624078. SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\". }} LIMIT 400";
RootObject jsonQuestions = await _wikiDataService.GetQuestions(_queryService.GetCapitalsQuery());

var fullUrl = endpointUrl + sparqlQuery;
Question[] questions = _questionService.GenerateQuestionsCapitalsOf(jsonQuestions.results.bindings.ToArray<CapitalCountry>());

using (var client = new HttpClient())
foreach (var item in questions)
{
client.DefaultRequestHeaders.Add("User-Agent", "Sergiollende/1.0");
client.DefaultRequestHeaders.Add("Accept", "application/sparql-results+json");

HttpResponseMessage response = await client.GetAsync(fullUrl);

string responseBody = await response.Content.ReadAsStringAsync();

RootObject jsonResult = JsonConvert.DeserializeObject<RootObject>(responseBody);
foreach(CapitalCountry c in jsonResult.results.bindings)
{
Console.WriteLine(c.ToString());
}

Question[] questions = GenerateQuestionsCapitalsOf(jsonResult.results.bindings.ToArray<CapitalCountry>());

foreach (var item in questions)
{
Console.WriteLine(item.ToString());
}

return Ok(jsonResult);
Console.WriteLine(item.ToString());
}

}

private Question[] GenerateQuestionsCapitalsOf(CapitalCountry[] capitalCountries)
{
Question[] questions = new Question[10];

ISet<int> ids = new HashSet<int>();
Random r = new Random();

while (ids.Count < 10) {
ids.Add(r.Next(capitalCountries.Length));
}

int[] idsList = new int[10];
int i = 0;
foreach (int id in ids)
{
idsList[i++] = id;
}

for (int j = 0; j < idsList.Length; j++)
{
string text = "What is the capital of " + capitalCountries[idsList[j]].countryLabel.value;
string[] answers = new string[4];
answers[0] = capitalCountries[idsList[j]].capitalLabel.value;
int[] wrongIds = new int[3];
for (int w = 1; w < 4; w++)
{
int wrongId = r.Next(capitalCountries.Length);
while (idsList.Contains(wrongId) || wrongIds.Contains(wrongId) )
{
wrongId = r.Next(capitalCountries.Length);
}
answers[w] = capitalCountries[wrongId].capitalLabel.value;
}
int correctAnswer = 0;

questions[j] = new Question(text, answers, correctAnswer);
}

return questions;
}

return Ok(questions);
}
}

public class CapitalCountry
{
public Label capitalLabel { get; set; }
public Label countryLabel { get; set; }

public string ToString()
{
return countryLabel.value + ": " + capitalLabel.value;
}
}

public class Label
{
public string value { get; set; }
}


public class Results
{
public List<CapitalCountry> bindings { get; set; }
}

public class RootObject
{
public Results results { get; set; }
}

public class Question
{
public string text { get; set; }
public string[] answers;
public int correctAnswer;

public Question(string text, string[] answers, int correctAnswer)
{
this.text = text;
this.answers = answers;
this.correctAnswer = correctAnswer;
}

public string ToString()
{
string aux = "text: " + text;
aux += "\ncorrectAnswer: " + answers[0];
aux += "\nAnswer: " + answers[1];
aux += "\nAnswer: " + answers[2];
aux += "\nAnswer: " + answers[3];
return aux ;
}
}
}
14 changes: 14 additions & 0 deletions wikidata_service/WikiDataTest/Models/CapitalCountry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace WikiDataTest.Models
{

public class CapitalCountry
{
public Label capitalLabel { get; set; }
public Label countryLabel { get; set; }

public string ToString()
{
return countryLabel.value + ": " + capitalLabel.value;
}
}
}
8 changes: 8 additions & 0 deletions wikidata_service/WikiDataTest/Models/Label.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace WikiDataTest.Models
{
public class Label
{
public string value { get; set; }
}

}
26 changes: 26 additions & 0 deletions wikidata_service/WikiDataTest/Models/Question.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace WikiDataTest.Models
{
public class Question
{
public string text { get; set; }
public string[] answers { get; set; }
public int correctAnswer { get; set; }

public Question(string text, string[] answers, int correctAnswer)
{
this.text = text;
this.answers = answers;
this.correctAnswer = correctAnswer;
}

public string ToString()
{
string aux = "text: " + text;
aux += "\ncorrectAnswer: " + answers[0];
aux += "\nAnswer: " + answers[1];
aux += "\nAnswer: " + answers[2];
aux += "\nAnswer: " + answers[3];
return aux;
}
}
}
7 changes: 7 additions & 0 deletions wikidata_service/WikiDataTest/Models/Results.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace WikiDataTest.Models
{
public class Results
{
public List<CapitalCountry> bindings { get; set; }
}
}
7 changes: 7 additions & 0 deletions wikidata_service/WikiDataTest/Models/RootObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace WikiDataTest.Models
{
public class RootObject
{
public Results results { get; set; }
}
}
6 changes: 6 additions & 0 deletions wikidata_service/WikiDataTest/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using WikiDataTest.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
Expand All @@ -6,6 +8,10 @@
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton(new QueryService());
builder.Services.AddSingleton(new WikiDataService());
builder.Services.AddSingleton(new QuestionService());


var app = builder.Build();

Expand Down
10 changes: 10 additions & 0 deletions wikidata_service/WikiDataTest/Services/QueryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace WikiDataTest.Services
{
public class QueryService
{
public string GetCapitalsQuery()
{
return "SELECT ?capitalLabel ?countryLabel WHERE { ?capital wdt:P1376 ?country. ?capital wdt:P31 wd:Q5119. ?country wdt:P31 wd:Q3624078. SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\". }} LIMIT 400";
}
}
}
68 changes: 68 additions & 0 deletions wikidata_service/WikiDataTest/Services/QuestionService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using WikiDataTest.Controllers;
using WikiDataTest.Models;

namespace WikiDataTest.Services
{
public class QuestionService
{
/// <summary>
/// Generate the questions from the capital/countries passed as parameter
/// </summary>
/// <param name="capitalCountries"> all the countries obtained </param>
/// <param name="numberQuestions"> number of questions to generate </param>
/// <returns></returns>
public Question[] GenerateQuestionsCapitalsOf(CapitalCountry[] capitalCountries, int numberQuestions = 10)
{
Question[] questions = new Question[numberQuestions];

ISet<int> ids = new HashSet<int>();
Random r = new Random();

while (ids.Count < numberQuestions)
{
ids.Add(r.Next(capitalCountries.Length));
}

int[] idsList = new int[numberQuestions];
int i = 0;
foreach (int id in ids)
{
idsList[i++] = id;
}

// Generate questions
for (int j = 0; j < idsList.Length; j++)
{
// Generate the questions
string countryName = capitalCountries[idsList[j]].countryLabel.value;
string questionText = $"What is the capital of {countryName}?";
string[] answers = new string[4];

// Place of the correct answer
int correctAnswer = 0;

// Save the capital of the specific country on first place
answers[correctAnswer] = capitalCountries[idsList[j]].capitalLabel.value;

// Get 3 random wrong answers from all the capitals
int[] wrongIds = new int[3];
for (int w = 1; w < 4; w++)
{
int wrongId = r.Next(capitalCountries.Length);
while (idsList[j] == wrongId || wrongIds.Contains(wrongId))
{
wrongId = r.Next(capitalCountries.Length);
}
// Adding the id of the wrongAnswer to the array
wrongIds[w - 1] = wrongId;
answers[w] = capitalCountries[wrongId].capitalLabel.value;
}

questions[j] = new Question(questionText, answers, correctAnswer);
}

return questions;
}
}
}
32 changes: 32 additions & 0 deletions wikidata_service/WikiDataTest/Services/WikiDataService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Newtonsoft.Json;
using WikiDataTest.Controllers;
using WikiDataTest.Models;

namespace WikiDataTest.Services
{
public class WikiDataService
{
public WikiDataService() { }

public async Task<RootObject> GetQuestions(string sparqlQuery)
{
string endpointUrl = "https://query.wikidata.org/sparql?query=";

var fullUrl = endpointUrl + sparqlQuery;

using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", "Sergiollende/1.0");
client.DefaultRequestHeaders.Add("Accept", "application/sparql-results+json");

HttpResponseMessage response = await client.GetAsync(fullUrl);

string responseBody = await response.Content.ReadAsStringAsync();

RootObject jsonResult = JsonConvert.DeserializeObject<RootObject>(responseBody);

return jsonResult;
}
}
}
}