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

Question automator created, more templates added to the "geography" category and storage of the generated questions. #114

Merged
merged 11 commits into from
Mar 24, 2024
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