Skip to content

Commit

Permalink
Merge pull request #114 from Arquisoft/question_generator
Browse files Browse the repository at this point in the history
Question automator created, more templates added to the "geography" category and storage of the generated questions.
  • Loading branch information
UO287747 authored Mar 24, 2024
2 parents a22846d + 075a2ab commit 61c3bc1
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 90 deletions.
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ services:
- "8003:8003"
networks:
- mynetwork
environment:
QUESTIONS_SERVICE_URL: http://questionservice:8004

questionservice:
container_name: questionservice-${teamname:-defaultASW}
Expand Down
189 changes: 125 additions & 64 deletions question_generator/geography/cities/citiesQuestions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const queryExecutor=require("../../queryExecutor")
const queryExecutor=require("../../queryExecutor");
const QuestionsUtils = require("../../questions-utils");
class CitiesQuestions{
#citiesQuestions=null;
static getInstance(){
Expand All @@ -10,54 +11,128 @@ class CitiesQuestions{
constructor(){
this.cities={};
}
async loadData(){
let newResults={};
const query=`
SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level
WITH{
SELECT ?city ?cityLabel
WHERE{
?city wdt:P31 wd:Q515
}
LIMIT 1000
} AS %i
WHERE {
INCLUDE %i
OPTIONAL{
?city wdt:P1082 ?population.
?city wdt:P17 ?country.
?city wdt:P2044 ?elevation_above_sea_level
async loadCities(){
let result={};
const citiesQueries=[
//Instancia de CITY
`SELECT ?city ?cityLabel ?population ?countryLabel
WITH{
SELECT ?city ?cityLabel
WHERE{
?city wdt:P31 wd:Q515
}
FILTER EXISTS{
LIMIT 1000
} AS %i
WHERE {
INCLUDE %i
OPTIONAL{
?city wdt:P1082 ?population.
?city wdt:P17 ?country.
?city wdt:P2044 ?elevation_above_sea_level
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
ORDER BY DESC(?population)
LIMIT 100
`
let cities = await queryExecutor.execute(query);
cities.forEach(city => {
const cityId = city.city.value;
const cityName = city.cityLabel.value;
const population = city.population.value;
const country = city.countryLabel.value;
const elevationAboveSeaLevel = city.elevation_above_sea_level.value;
ORDER BY DESC(?population)
LIMIT 100`,
//Ciudades de España
`SELECT ?city ?cityLabel ?population ?countryLabel
WITH{
SELECT ?city ?cityLabel
WHERE{
?city wdt:P31 wd:Q2074737
}
LIMIT 1000
} AS %i
WHERE {
INCLUDE %i
OPTIONAL{
?city wdt:P1082 ?population.
?city wdt:P17 ?country.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
ORDER BY DESC(?population)
LIMIT 20`,
//Metropolis
`SELECT ?city ?cityLabel ?population ?countryLabel
WITH{
SELECT ?city ?cityLabel
WHERE{
?city wdt:P31 wd:Q200250
}
LIMIT 1000
} AS %i
WHERE {
INCLUDE %i
OPTIONAL{
?city wdt:P1082 ?population.
?city wdt:P17 ?country.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
ORDER BY DESC(?population)
LIMIT 5`

if (!newResults[cityId]) {
newResults[cityId] = {
cityId: cityId,
cityName: cityName,
population: population,
country: country,
elevation_above_sea_level: []
};
];
for(let i = 0; i <citiesQueries.length; i++) {
let query = citiesQueries[i];
let cities = await queryExecutor.execute(query);
cities.forEach(city=>{
const cityId = city.city.value.match(/Q\d+/)[0];
const cityName = city.cityLabel.value;
const population = city.population.value;
const country = city.countryLabel.value;
if (!result[cityId]) {
result[cityId] = {
cityId: cityId,
name: cityName,
population: population,
country: country
}
}
});
}
return result;

}
async loadData(){
let newResults = await this.loadCities();
const propertiesToLoad=[
{
name:'elevation_above_sea_level',
id: 'P2044'
},
{
name:'highest_point',
id: 'P610'
},
{
name: 'area',
id: 'P2046'
},
{
name: 'continent',
id: 'P30'
},
{
name: 'head_of_government',
id: 'P6'
},
{
name: 'located_in_time_zone',
id: 'P421'
}

newResults[cityId].elevation_above_sea_level.push(parseFloat(elevationAboveSeaLevel));
});
]
for(let i = 0; i <Object.keys(newResults).length; i++) {
let cityId = Object.keys(newResults)[i];
let r= await queryExecutor.executeQueryForEntityAndProperty(cityId, propertiesToLoad);
if(r.length>0){
for(let j=0;j<propertiesToLoad.length;j++){
if(r[0][propertiesToLoad[j].name]!==undefined){
newResults[cityId][propertiesToLoad[j].name] = r[0][propertiesToLoad[j].name].value;
}
}
}
}
this.cities=newResults;

}
Expand All @@ -74,7 +149,7 @@ class CitiesQuestions{
const results=await this.getRandomCities(numberOfCities);
const formattedResults = await results.map(result => {
return {
item: result.cityName,
item: result.name,
value:parseFloat(result.population),
};
}).sort((a, b) => b.value - a.value);
Expand All @@ -92,26 +167,12 @@ class CitiesQuestions{
}
return finalResults
}
async getCityForCountry(){
let numberOfCities=4;
let result =(await this.getRandomCities(1))[0];
let country=result.country;

let correct = result.cityName;
let incorrects = []
let i=1;
while(i<numberOfCities){
let city=(await this.getRandomCities(1))[0];
if(city.country!=country){
incorrects.push(city.cityName);
i++;
}
}
return {
country:country,
correct:correct,
incorrects:incorrects
async doQuestion(property,nValues){
if(Object.keys(this.cities).length==0){
await this.loadData();
}
return QuestionsUtils.getValuesFromDataAndProperty(this.cities, property, nValues);
}
async getHigherCity(){
let numberOfCities=4;
Expand All @@ -124,10 +185,10 @@ class CitiesQuestions{
}
for(let i=0;i<numberOfCities;i++){
if(i==0){
finalResults.correct=formattedResults[i].cityName
finalResults.correct=formattedResults[i].name
}
else{
finalResults.incorrects.push(formattedResults[i].cityName)
finalResults.incorrects.push(formattedResults[i].name)
}
}
return finalResults;
Expand Down
43 changes: 39 additions & 4 deletions question_generator/geography/cities/citiesTemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,60 @@ const templates=[
},
async ()=>
{
const results= await citiesQuery.getCityForCountry();
const results= await citiesQuery.doQuestion('country',4);
return{
"question":"Which city is in?",
"question_param":results.country,
"question_param":results.question_param,
"correct":results.correct,
"incorrects":results.incorrects
}
},
async ()=>
{
const results= await citiesQuery.getHigherCity();
const results= await citiesQuery.doQuestion('elevation_above_sea_level',4);
return{
"question":"Which city is higher above sea level?",
"correct":results.correct,
"incorrects":results.incorrects
}
},
async () => {
const results = await citiesQuery.doQuestion('area', 4);
return {
"question": "Which city has an area of?",
"question_param": results.question_param,
"correct": results.correct,
"incorrects": results.incorrects
}
},
async () => {
const results = await citiesQuery.doQuestion('continent', 4);
return {
"question": "Which city is in?",
"question_param": results.question_param,
"correct": results.correct,
"incorrects": results.incorrects
}
},
async () => {
const results = await citiesQuery.doQuestion('head_of_government', 4);
return {
"question": "Which city is governed by?",
"question_param": results.question_param,
"correct": results.correct,
"incorrects": results.incorrects
}
},
async () => {
const results = await citiesQuery.doQuestion('located_in_time_zone', 4);
return {
"question": "Which city is in the time zone?",
"question_param": results.question_param,
"correct": results.correct,
"incorrects": results.incorrects
}
}


]
module.exports.getRandomQuestion = () => templates[Math.floor(Math.random()*templates.length)]();
module.exports.loadData = () =>loadData();
9 changes: 8 additions & 1 deletion question_generator/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
"Which city is higher above sea level?": "Which city is higher above sea level?",
"Which city has more population?": "Which city has more population?",
"Which city is in?": "Which city is in %s?",
"Which city has an area of?": "Which city has an area od %s km2?",
"Which city is governed by?": "Which city is governed by %s?",
"Which city is in the time zone?": "Which city is in the time zone %s?",

"Which planet is bigger?": "Which planet is bigger?",

"Who has more Grand Slams?": "Who has more Grand Slams?",
"Who has more followers?": "Who has more followers?",
"Who has more looses?": "Who has more looses?"
"Who has more looses?": "Who has more looses?",
"Who has more wins?": "Who has more wins?",
"Which tennis player is from?" : "Which tennis player is from %s?"
}
22 changes: 12 additions & 10 deletions question_generator/locales/es.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{

"Which city is higher above sea level?": "¿Qué ciudad tiene más altitud sobre el nivel del mar?",
"Which city is higher above sea level?": "¿Qué ciudad está a mayor altitud?",
"Which city has more population?": "¿Qué ciudad tiene más población?",
"Which city is in?": "¿Qué ciudad está en %s?",



"Which planet is bigger?": "¿Qué planeta tiene un tamaño mayor?",


"Which city is in?": "¿Qué ciudad se encuentra %s?",
"Which city has an area of?": "¿Qué ciudad tiene un área de %s km2?",
"Which city is governed by?": "¿Qué ciudad es gobernada por %s?",
"Which city is in the time zone?": "¿Qué ciudad está en la zona horaria %s?",

"Which planet is bigger?": "¿Qué planeta es más grande?",

"Who has more Grand Slams?": "¿Quién tiene más Grand Slams?"
"Who has more Grand Slams?": "¿Quién tiene más Grand Slams?",
"Who has more followers?": "¿Quién tiene más seguidores?",
"Who has more looses?": "¿Quién tiene más derrotas?",
"Who has more wins?": "¿Quién tiene más victorias?",
"Which tennis player is from?" : "¿Qué jugador es de %s?"

}
21 changes: 21 additions & 0 deletions question_generator/queryExecutor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class QueryExecutor{
},
...config,
});
if (!response || !response.data) {
console.error('La consulta a Wikidata no devolvió ningún resultado');
return;
}

return response.data.results.bindings;

Expand All @@ -28,5 +32,22 @@ class QueryExecutor{
console.error('Error al realizar la consulta a Wikidata:', error.message);
}
}
static async executeQueryForEntityAndProperty(entity, properties){
if(!Array.isArray(properties) || properties.length==0){
return [];
}
const query=
`SELECT ${properties.map(property=>`?${property.name}Label`).join(' ')} WHERE {${properties.map(property=>`OPTIONAL {wd:${entity} wdt:${property.id} ?${property.name}.}`).join(' ')} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}LIMIT 1`
let results=await this.execute(query);
const editedResults = results.map(result => {
const editedResult = {};
for (const key in result) {
const newKey = key.replace(/Label$/, '');
editedResult[newKey] = result[key];
}
return editedResult;
});
return editedResults;
}
}
module.exports=QueryExecutor
Loading

0 comments on commit 61c3bc1

Please sign in to comment.