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 generation #47

Merged
merged 23 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
177e4a9
Created the question generator project
UO289845 Mar 1, 2024
dca5a1b
Created and set up the generator, with some basic examples
UO289845 Mar 2, 2024
3520d5f
Make it so there are three examples per question type
UO289845 Mar 2, 2024
c7ea8d8
Added two extra cases: size and language
UO289845 Mar 2, 2024
a6fcc52
Changed the main a bit so it¡s more concise
UO289845 Mar 2, 2024
3552a4d
Refactored code to an abstract class and also some to a common one.
UO289845 Mar 2, 2024
59bfcd1
Getting the wrong answers for population questions.
ErdemYabaci Mar 2, 2024
8dc32ff
Updated with the changes and fixed small import problem
UO289845 Mar 2, 2024
293ad7c
Improved package distribution
UO289845 Mar 2, 2024
7c0a4c3
Added a way to store already searched entites
UO289845 Mar 2, 2024
7f72711
The properties taht are also entities now are also stored to avoid se…
UO289845 Mar 2, 2024
b467de0
Modified the classes so that they pass the template and property id t…
UO289845 Mar 3, 2024
4c99d7d
Removed the sample data now that there's one question with incorrect …
UO289845 Mar 3, 2024
232e343
Added examples of wrong answers to all questions
UO289845 Mar 4, 2024
a0f4044
Updated the condition of the wrong answers
UO289845 Mar 4, 2024
1474946
Added internaztionalization support for english and spanish
UO289845 Mar 5, 2024
7bbfee8
Turned the specific generators into singletons
UO289845 Mar 5, 2024
aec3218
Fixed an issue with the path to the messages
UO289845 Mar 5, 2024
29b573e
Allowed for changing dinamically the language
UO289845 Mar 5, 2024
8420182
Removed the singleton functionality
UO289845 Mar 5, 2024
e26e32d
Improved the localization algorithm to avoid code repetition
UO289845 Mar 5, 2024
04d3a2d
Made the localization method more robust
UO289845 Mar 6, 2024
df147ea
Removed commented code
UO289845 Mar 6, 2024
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
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"configurations": [
{
"type": "java",
"name": "Main",
"request": "launch",
"mainClass": "com.wiq.wiq.services.questionGenerator.Main",
"projectName": "wiq"
},
{
"type": "java",
"name": "Spring Boot-WiqApplication<wiq>",
Expand Down
42 changes: 42 additions & 0 deletions backend/wiq/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<slf4jVersion>1.7.10</slf4jVersion>
<wikidataToolkitVersion>0.11.0</wikidataToolkitVersion>
</properties>
<dependencies>
<dependency>
Expand All @@ -32,6 +34,38 @@
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>

<dependency>
<groupId>org.wikidata.wdtk</groupId>
<artifactId>wdtk-datamodel</artifactId>
<version>${wikidataToolkitVersion}</version>
</dependency>
<dependency>
<groupId>org.wikidata.wdtk</groupId>
<artifactId>wdtk-dumpfiles</artifactId>
<version>${wikidataToolkitVersion}</version>
</dependency>
<dependency>
<groupId>org.wikidata.wdtk</groupId>
<artifactId>wdtk-rdf</artifactId>
<version>${wikidataToolkitVersion}</version>
</dependency>
<dependency>
<groupId>org.wikidata.wdtk</groupId>
<artifactId>wdtk-wikibaseapi</artifactId>
<version>${wikidataToolkitVersion}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4jVersion}</version>
</dependency>

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20230618</version>
</dependency>
</dependencies>

<build>
Expand All @@ -40,6 +74,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.wiq.wiq.services.questionGenerator;

import com.wiq.wiq.services.questionGenerator.question.QuestionType;

public class Main {

private static QuestionType[] types = {QuestionType.POPULATION, QuestionType.CAPITAL, QuestionType.SIZE,
QuestionType.LANGUAGE};

public static void main(String[] args) {
QuestionGenerator qg = new QuestionGenerator("en");
for(QuestionType t : types) {
run(qg, t);
System.out.println();
}

}

private static void run(QuestionGenerator qg, QuestionType type) {
for(int i=0; i<3; i++) {
System.out.println(qg.generateQuestion(type));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.wiq.wiq.services.questionGenerator;

import com.wiq.wiq.services.questionGenerator.generator.AbstractGenerator;
import com.wiq.wiq.services.questionGenerator.generator.specificGenerators.CapitalGenerator;
import com.wiq.wiq.services.questionGenerator.generator.specificGenerators.LanguageGenerator;
import com.wiq.wiq.services.questionGenerator.generator.specificGenerators.PopulationGenerator;
import com.wiq.wiq.services.questionGenerator.generator.specificGenerators.SizeGenerator;
import com.wiq.wiq.services.questionGenerator.question.QuestionType;



public class QuestionGenerator {

private AbstractGenerator generator;
private String id;
private String languageCode;

private static String[] POP_ENTITIES = {"Q14317", "Q12273", "Q14649"};
private static String[] CAP_ENTITIES = {"Q3934", "Q29", "Q43"};
private static String[] SIZE_ENTITIES = {"Q29", "Q12273", "Q3934"};
private static String[] LANG_ENTITIES = {"Q29", "Q43", "Q3934"};

public QuestionGenerator(String languageCode){
this.languageCode = languageCode;
}

public String generateQuestion(QuestionType type) {
generatorFactory(type);
generator.setLocalization(languageCode);
String answer = generator.generate(id).getJSON().toString();
return answer;
}

private void generatorFactory(QuestionType type) {
switch (type) {
case POPULATION: {
id = POP_ENTITIES[0];
generator = new PopulationGenerator();
moveUp(POP_ENTITIES);
POP_ENTITIES[POP_ENTITIES.length-1] = id;
break;
}
case CAPITAL: {
id = CAP_ENTITIES[0];
generator = new CapitalGenerator();
moveUp(CAP_ENTITIES);
CAP_ENTITIES[CAP_ENTITIES.length-1] = id;
break;

}
case SIZE: {
id = SIZE_ENTITIES[0];
generator = new SizeGenerator();
moveUp(SIZE_ENTITIES);
SIZE_ENTITIES[SIZE_ENTITIES.length-1] = id;
break;
}
case LANGUAGE: {
id = LANG_ENTITIES[0];
generator = new LanguageGenerator();
moveUp(LANG_ENTITIES);
LANG_ENTITIES[LANG_ENTITIES.length-1] = id;
break;
}
}
}

private void moveUp(String[] list) {
for(int i=0; i<list.length-1; i++) {
list[i] = list[i+1];
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.wiq.wiq.services.questionGenerator.generator;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.wikidata.wdtk.datamodel.implementation.ItemDocumentImpl;
import org.wikidata.wdtk.datamodel.interfaces.MonolingualTextValue;
import org.wikidata.wdtk.datamodel.interfaces.Statement;
import org.wikidata.wdtk.wikibaseapi.WikibaseDataFetcher;
import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorException;

import com.wiq.wiq.services.questionGenerator.question.Question;

public abstract class AbstractGenerator {

protected static final WikibaseDataFetcher wbdf = WikibaseDataFetcher.getWikidataDataFetcher();
private String language = "en";

private Locale localization = Locale.getDefault();
private ResourceBundle messages;

private static Map<String, ItemDocumentImpl> alreadyProcessedEntities = new HashMap<>();

private String propertyId = "";

private static final String MESSAGES_PATH = "com/wiq/wiq/services/questionGenerator/"+
"generator/rsc/messages";

public AbstractGenerator(String propertyId) {
this.propertyId = propertyId;
}

/**
*
* @param id
* @return question generated or null if wikidata gives an error
*/
public Question generate(String id) {
//get the wikidata entity using the id
ItemDocumentImpl idi = alreadyProcessedEntities.get(id);

if(idi==null) {
try {
idi = (ItemDocumentImpl) wbdf.getEntityDocument(id);
alreadyProcessedEntities.put(id, idi);
} catch (MediaWikiApiErrorException | IOException e) {
/*
* * @throws MediaWikiApiErrorException
* if the API returns an error
* @throws IOException
* if we encounter network issues or HTTP 500 errors from Wikibase
*/
return null;
}
}


String name = getName(idi.getLabels());

//get the question
String question = getQuestion(name);

//get the right answer
String rightAnswer = getRightAnswer(idi.getJsonClaims());

//get the wrong answers
List<String> answers = getWrongAnswers(rightAnswer);

answers.add(0, rightAnswer);
//create and return the question

return new Question(question, answers);
}

protected String getName(Map<String, MonolingualTextValue> names) {
MonolingualTextValue mtv = names.get(language);
return mtv.getText();
}

protected abstract String getQuestion(String name);
protected abstract String getRightAnswer(Map<String, List<Statement>> claims);
protected abstract List<String> getWrongAnswers(String rightAnswer);

public String getPropertyId() {
return propertyId;
}

public static Map<String, ItemDocumentImpl> getAlreadyProcessedEntities() {
return new HashMap<>(alreadyProcessedEntities);
}

public static void addItem(String entity, ItemDocumentImpl item) {
alreadyProcessedEntities.put(entity, item);
}

public ResourceBundle getMessages() {
return messages;
}

public void setLocalization(String languageCode) {
if(languageCode==null)
languageCode = "en";
else
languageCode = languageCode.toLowerCase();
switch (languageCode) {
case "en":{
localize(languageCode);
break;
}
case "es":{
localize(languageCode);
break;
}
default:{
localize("en");
break;
}
}
}

private void localize(String languageCode) {
this.language = languageCode;
this.localization = new Locale(languageCode);
this.messages = ResourceBundle.getBundle(MESSAGES_PATH, localization);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.wiq.wiq.services.questionGenerator.generator;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.wikidata.wdtk.datamodel.implementation.ItemDocumentImpl;
import org.wikidata.wdtk.datamodel.interfaces.Statement;
import org.wikidata.wdtk.datamodel.interfaces.Value;
import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorException;

public abstract class RightAnswerIsEntity extends AbstractGenerator {

public RightAnswerIsEntity(String propertyId) {
super(propertyId);
}

@Override
protected String getRightAnswer(Map<String, List<Statement>> claims) {
Value v = claims.get(super.getPropertyId()).get(0).getValue();
String entity = getRightAnswerEntity(v.toString());
String answer = "";
try {
ItemDocumentImpl idi = getAlreadyProcessedEntities().get(entity);
if(idi==null) {
idi = (ItemDocumentImpl) wbdf.getEntityDocument(entity);
answer = getName(idi.getLabels());
addItem(entity, idi);
}
else
answer = getName(idi.getLabels());
} catch (MediaWikiApiErrorException | IOException e) {
return null;
}
return answer;
}

private String getRightAnswerEntity(String url) {
String[] split1 = url.split(" ");
String[] split2 = split1[0].split("/");
return split2[split2.length-1];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
question.population = What's the population of %s?
question.language = What's the official language of %s?
question.capital = What's the capital of %s?
question.size = What's the size of %s?
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
question.population = What's the population of %s?
question.language = What's the official language of %s?
question.capital = What's the capital of %s?
question.size = What's the size of %s?
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
question.population = �Cu�l es la poblaci�n de %s?
question.language = �Cu�l es el idioma oficial de %s?
question.capital = �Cu�l es la capital de %s?
question.size = �Cu�l es el �rea (km cuadrados) de %s?
Loading