diff --git a/.vscode/launch.json b/.vscode/launch.json index 2f30dd50..ce33cad0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,19 @@ { "configurations": [ + { + "type": "java", + "name": "MainMock", + "request": "launch", + "mainClass": "main.java.MainMock", + "projectName": "questionGenerator" + }, + { + "type": "java", + "name": "MainRandomizer", + "request": "launch", + "mainClass": "main.java.MainRandomizer", + "projectName": "questionGenerator" + }, { "type": "java", "name": "Main", diff --git a/questionGenerator/src/main/java/Main.java b/questionGenerator/src/main/java/Main.java index 41a0d999..44500083 100644 --- a/questionGenerator/src/main/java/Main.java +++ b/questionGenerator/src/main/java/Main.java @@ -1,6 +1,5 @@ package main.java; -import java.util.ArrayList; import java.util.List; import main.java.questionGenerator.QuestionGenerator; @@ -10,43 +9,28 @@ public class Main { - private static QuestionType[] types = {QuestionType.POPULATION, QuestionType.CAPITAL, QuestionType.SIZE, - QuestionType.LANGUAGE}; - - public static void main(String[] args) { - System.out.println("Ahora en Espa�ol"); - QuestionGenerator qg = new QuestionGenerator("es"); - for(QuestionType t : types) { - run(qg, t); - System.out.println(); - } - System.out.println("Now English"); - qg = new QuestionGenerator("en"); - for(QuestionType t : types) { - run(qg, t); - System.out.println(); - } - System.out.println("Now in english but with bad language code"); - qg = new QuestionGenerator("ep"); - for(QuestionType t : types) { - run(qg, t); - System.out.println(); - } - + public static void main(String[] args) { + QuestionGenerator qg = new QuestionGenerator("en"); + + run(qg, QuestionType.CAPITAL, 3); + System.out.println(); + + run(qg, QuestionType.LANGUAGE, 3); + System.out.println(); + + run(qg, QuestionType.POPULATION, 3); + System.out.println(); + + run(qg, QuestionType.SIZE, 3); } - private static void run(QuestionGenerator qg, QuestionType type) { - List questionJSONList = new ArrayList<>(); - - //Populate JSON list here - for(int i=0; i<3; i++) { - Question question = qg.generateQuestion(type); - question.setNumber(i); - questionJSONList.add(question.getJSON().toString()); - System.out.println(question.getJSON().toString()); - } - - QuestionRepository.getInstance().insert(questionJSONList); + private static void run(QuestionGenerator qg, QuestionType type, int numberOfQuestions){ + List questions = qg.generateQuestions(type, numberOfQuestions); + for(int i=0; i q.getJSON().toString()).toList()); } - } diff --git a/questionGenerator/src/main/java/MainMock.java b/questionGenerator/src/main/java/MainMock.java new file mode 100644 index 00000000..208458da --- /dev/null +++ b/questionGenerator/src/main/java/MainMock.java @@ -0,0 +1,52 @@ +package main.java; + +import java.util.ArrayList; +import java.util.List; + +import main.java.questionGenerator.QuestionGeneratorMock; +import main.java.questionGenerator.question.Question; +import main.java.questionGenerator.question.QuestionType; +import main.java.questionGenerator.repository.QuestionRepository; + +public class MainMock { + + private static QuestionType[] types = {QuestionType.POPULATION, QuestionType.CAPITAL, QuestionType.SIZE, + QuestionType.LANGUAGE}; + + public static void main(String[] args) { + System.out.println("Ahora en Espa�ol"); + QuestionGeneratorMock qg = new QuestionGeneratorMock("es"); + for(QuestionType t : types) { + run(qg, t); + System.out.println(); + } + System.out.println("Now English"); + qg = new QuestionGeneratorMock("en"); + for(QuestionType t : types) { + run(qg, t); + System.out.println(); + } + System.out.println("Now in english but with bad language code"); + qg = new QuestionGeneratorMock("ep"); + for(QuestionType t : types) { + run(qg, t); + System.out.println(); + } + + } + + private static void run(QuestionGeneratorMock qg, QuestionType type) { + List questionJSONList = new ArrayList<>(); + + //Populate JSON list here + for(int i=0; i<3; i++) { + Question question = qg.generateQuestion(type); + question.setNumber(i); + questionJSONList.add(question.getJSON().toString()); + System.out.println(question.getJSON().toString()); + } + + QuestionRepository.getInstance().insert(questionJSONList); + } + +} diff --git a/questionGenerator/src/main/java/questionGenerator/QuestionGenerator.java b/questionGenerator/src/main/java/questionGenerator/QuestionGenerator.java index d386f698..92879cbe 100644 --- a/questionGenerator/src/main/java/questionGenerator/QuestionGenerator.java +++ b/questionGenerator/src/main/java/questionGenerator/QuestionGenerator.java @@ -1,5 +1,11 @@ package main.java.questionGenerator; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import main.java.questionGenerator.entityGenerator.EntityGenerator; import main.java.questionGenerator.generator.AbstractGenerator; import main.java.questionGenerator.generator.specificGenerators.CapitalGenerator; import main.java.questionGenerator.generator.specificGenerators.LanguageGenerator; @@ -8,67 +14,62 @@ import main.java.questionGenerator.question.Question; import main.java.questionGenerator.question.QuestionType; - - public class QuestionGenerator { - - private AbstractGenerator generator; - private String id; + + private AbstractGenerator generator; 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 Question generateQuestion(QuestionType type) { - generatorFactory(type); + public List generateQuestions(QuestionType type, int amount){ + setGenerator(type); generator.setLocalization(languageCode); - return generator.generate(id); - } + List questions = new ArrayList<>(); + List entites = new ArrayList<>(); + try { + entites = EntityGenerator.getEntities(type, 100); + } catch (IOException e) { + e.printStackTrace(); + } + Random rnd = new Random(); + List chosen = new ArrayList<>(); + int size = entites.size(); + int number = 0; + while(number generateQuestions(QuestionType type, int amount){ + setGenerator(type); + generator.setLocalization(languageCode); + List questions = new ArrayList<>(); + List entites = new ArrayList<>(); + try { + entites = EntityGenerator.getEntities(type, 100); + } catch (IOException e) { + e.printStackTrace(); + } + Random rnd = new Random(); + List chosen = new ArrayList<>(); + int size = entites.size(); + int number = 0; + while(number getEntities(QuestionType type, int size) throws IOException{ + propertyFactory(type); + URL url = new URL(PRE_URL+PROPERTY_URL+property+POST_URL+LIMIT+size); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer content = new StringBuffer(); + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + + con.disconnect(); + + String json = content.toString(); + List result = extractEntities(json); + + return result; + } + + private static void propertyFactory(QuestionType type) { + switch (type) { + case CAPITAL: + property = "36"; + break; + case LANGUAGE: + property = "37"; + break; + case POPULATION: + property = "1082"; + break; + case SIZE: + property = "2046"; + break; + } + } + + private static List extractEntities(String json){ + List result = new ArrayList<>(); + String[] entities = json.split("\"title\":"); + for(int i=1; i names) { return mtv.getText(); } - protected abstract String getQuestion(String name); + + protected String getQuestion(String name) { + String q = getMessages().getString(message); + return String.format(q, name); + } + protected abstract String getRightAnswer(Map> claims); protected abstract List getWrongAnswers(String rightAnswer); + public String getPropertyId() { return propertyId; } diff --git a/questionGenerator/src/main/java/questionGenerator/generator/RightAnswerIsEntity.java b/questionGenerator/src/main/java/questionGenerator/generator/AnswersAreEntities.java similarity index 58% rename from questionGenerator/src/main/java/questionGenerator/generator/RightAnswerIsEntity.java rename to questionGenerator/src/main/java/questionGenerator/generator/AnswersAreEntities.java index a65130b9..171b22cc 100644 --- a/questionGenerator/src/main/java/questionGenerator/generator/RightAnswerIsEntity.java +++ b/questionGenerator/src/main/java/questionGenerator/generator/AnswersAreEntities.java @@ -7,28 +7,49 @@ import java.util.Random; import org.wikidata.wdtk.datamodel.implementation.ItemDocumentImpl; +import org.wikidata.wdtk.datamodel.interfaces.Snak; +import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; import org.wikidata.wdtk.datamodel.interfaces.Statement; import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorException; +import main.java.questionGenerator.entityGenerator.EntityGenerator; import main.java.questionGenerator.question.QuestionType; -public abstract class RightAnswerIsEntity extends AbstractGenerator { +public abstract class AnswersAreEntities extends AbstractGenerator { - public RightAnswerIsEntity(String propertyId, QuestionType type) { - super(propertyId, type); + private final String PROPERTY_TO_CHECK; + private final QuestionType type; + + public AnswersAreEntities(String propertyId, QuestionType type, String propertyToCheck, String message) { + super(propertyId, type, message); + this.PROPERTY_TO_CHECK = propertyToCheck; + this.type = type; } - /** - * This method acts as a wrapper because in some cases this is enough, but not in all of them, - * so the rest are in charge of overriding it and modifying what they need - */ @Override protected String getRightAnswer(Map> claims) { - return processRightAnswer(claims.get(super.getPropertyId()).get(0)); + for(Statement st : claims.get(super.getPropertyId())) { + boolean valid = true; + for(SnakGroup sg : st.getQualifiers()) { + for(Snak s : sg.getSnaks()) { + String value = getIdFromLink(s.getPropertyId().toString()); + if(value.equals(PROPERTY_TO_CHECK)) { + valid = false; + break; + } + } + if(!valid) + break; + } + if(valid) { + return processRightAnswer(st); + } + } + return null; } protected String processRightAnswer(Statement st) { - String entity = getRightAnswerEntity(st.getValue().toString()); + String entity = getIdFromLink(st.getValue().toString()); String answer = ""; try { ItemDocumentImpl idi = getAlreadyProcessedEntity(entity); @@ -65,23 +86,27 @@ protected String getAnswer(String id){ return getRightAnswer(idi.getJsonClaims()); } - protected String getRightAnswerEntity(String url) { + protected String getIdFromLink(String url) { String[] split1 = url.split(" "); String[] split2 = split1[0].split("/"); return split2[split2.length-1]; } - + @Override protected List getWrongAnswers(String rightAnswer) { + List entites = new ArrayList<>(); + try { + entites = EntityGenerator.getEntities(type, 100); + } catch (IOException e) { + e.printStackTrace(); + } Random rnd = new Random(); - String[] entities = {"Q142", "Q183", "Q16", "Q142", "Q30", "Q408", "Q668", "Q17", "Q38", "Q159", - "Q79", "Q155", "Q884", "Q414", "Q41", "Q258", "Q96", "Q843", "Q148", "Q20"}; List result = new ArrayList<>(); List used = new ArrayList<>(); for(int i = 0; i < 3; i++){ - int rndnum = rnd.nextInt(entities.length); - String wrong = getAnswer(entities[rndnum]); - if(wrong.equals(rightAnswer) || used.contains(rndnum)) + int rndnum = rnd.nextInt(entites.size()); + String wrong = getAnswer(entites.get(rndnum)); + if(wrong == null || wrong.equals(rightAnswer) || used.contains(rndnum)) i--; else{ result.add(wrong); diff --git a/questionGenerator/src/main/java/questionGenerator/generator/AnswersAreNotEntites.java b/questionGenerator/src/main/java/questionGenerator/generator/AnswersAreNotEntites.java new file mode 100644 index 00000000..9d5f0017 --- /dev/null +++ b/questionGenerator/src/main/java/questionGenerator/generator/AnswersAreNotEntites.java @@ -0,0 +1,75 @@ +package main.java.questionGenerator.generator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import main.java.questionGenerator.question.QuestionType; + +public abstract class AnswersAreNotEntites extends AbstractGenerator{ + + //Open to changes if needed. + public AnswersAreNotEntites(String propertyId, QuestionType type, String message) { + super(propertyId, type, message); + } + + @Override + protected List getWrongAnswers(String rightAnswer) { + int inumber = 0; + float fnumber = 0; + // Check if it is a float + try { + inumber = Integer.parseInt(rightAnswer); + } catch(NumberFormatException e1) { + try { + fnumber = Float.parseFloat(rightAnswer); + } catch (NumberFormatException e2) { + //throw some exception or return null. + } + } + + List wrongAnswers = new ArrayList<>(); + Random rnd = new Random(); + + // Gives values depending on parameter with percentage + // Example: If parameter is 50 value range is number*.5 and number*1.5 + int parameter = 50; + + + if(inumber != 0){ + //for integer values + for(int i = 0; i < 3; i++){ + long wrong = (inumber * (100 + rnd.nextInt(parameter * 2 + 1) - parameter) / 100); + // An extra check for the wrong answer to be same sign. + if((inumber > 0 && wrong < 0) || (inumber < 0 && wrong > 0)) + { + i--; + continue; + } + // Checking if it creates the same answer as any other. + if(wrong == inumber || wrongAnswers.contains(String.valueOf(wrong))) + i--; + else + wrongAnswers.add(String.valueOf(wrong)); + } + } + else{ + //for float values + for(int i = 0; i < 3; i++){ + float wrong = (fnumber * (100 + rnd.nextInt(parameter * 2 + 1) - parameter) / 100); + // An extra check for the wrong answer to be same sign. + if((fnumber > 0 && wrong < 0) || (fnumber < 0 && wrong > 0)) + { + i--; + continue; + } + // Checking if it creates the same answer as any other + if(wrong == fnumber || wrongAnswers.contains(String.valueOf(wrong))) + i--; + else + wrongAnswers.add(String.valueOf(wrong)); + } + } + return wrongAnswers; + } +} diff --git a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/CapitalGenerator.java b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/CapitalGenerator.java index 59f72953..64444133 100644 --- a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/CapitalGenerator.java +++ b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/CapitalGenerator.java @@ -1,49 +1,16 @@ package main.java.questionGenerator.generator.specificGenerators; -import java.util.List; -import java.util.Map; - -import org.wikidata.wdtk.datamodel.interfaces.Snak; -import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; -import org.wikidata.wdtk.datamodel.interfaces.Statement; - -import main.java.questionGenerator.generator.RightAnswerIsEntity; +import main.java.questionGenerator.generator.AnswersAreEntities; import main.java.questionGenerator.question.QuestionType; -public class CapitalGenerator extends RightAnswerIsEntity { +public class CapitalGenerator extends AnswersAreEntities { private final static String PROPERTY = "P36"; + private final static String PROPERTY_TO_CHECK = "P582"; + private final static String MESSAGE = "question.capital"; public CapitalGenerator(){ - super(PROPERTY, QuestionType.CAPITAL); - } - - @Override - protected String getQuestion(String name) { - String q = getMessages().getString("question.capital"); - return String.format(q, name); - } - - @Override - protected String getRightAnswer(Map> claims) { - for(Statement st : claims.get(super.getPropertyId())) { - boolean valid = true; - for(SnakGroup sg : st.getQualifiers()) { - for(Snak s : sg.getSnaks()) { - String value = getRightAnswerEntity(s.getPropertyId().toString()); - if(value.equals("P582")) { - valid = false; - break; - } - } - if(!valid) - break; - } - if(valid) { - return processRightAnswer(st); - } - } - return null; + super(PROPERTY, QuestionType.CAPITAL, PROPERTY_TO_CHECK, MESSAGE); } } diff --git a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/LanguageGenerator.java b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/LanguageGenerator.java index 07bb70b0..5e2b7781 100644 --- a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/LanguageGenerator.java +++ b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/LanguageGenerator.java @@ -1,20 +1,16 @@ package main.java.questionGenerator.generator.specificGenerators; -import main.java.questionGenerator.generator.RightAnswerIsEntity; +import main.java.questionGenerator.generator.AnswersAreEntities; import main.java.questionGenerator.question.QuestionType; -public class LanguageGenerator extends RightAnswerIsEntity { +public class LanguageGenerator extends AnswersAreEntities { private final static String PROPERTY = "P37"; + private final static String PROPERTY_TO_CHECK = "P518"; + private final static String MESSAGE = "question.language"; public LanguageGenerator(){ - super(PROPERTY, QuestionType.LANGUAGE); - } - - @Override - protected String getQuestion(String name) { - String q = getMessages().getString("question.language"); - return String.format(q, name); + super(PROPERTY, QuestionType.LANGUAGE, PROPERTY_TO_CHECK, MESSAGE); } } diff --git a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/PopulationGenerator.java b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/PopulationGenerator.java index 9ba5273b..b1feb771 100644 --- a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/PopulationGenerator.java +++ b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/PopulationGenerator.java @@ -1,62 +1,27 @@ package main.java.questionGenerator.generator.specificGenerators; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Random; import org.wikidata.wdtk.datamodel.interfaces.Statement; import org.wikidata.wdtk.datamodel.interfaces.Value; -import main.java.questionGenerator.generator.AbstractGenerator; +import main.java.questionGenerator.generator.AnswersAreNotEntites; import main.java.questionGenerator.question.QuestionType; -public class PopulationGenerator extends AbstractGenerator { +public class PopulationGenerator extends AnswersAreNotEntites { private final static String PROPERTY = "P1082"; + private final static String MESSAGE = "question.population"; public PopulationGenerator(){ - super(PROPERTY, QuestionType.POPULATION); - } - - @Override - protected String getQuestion(String name) { - String q = getMessages().getString("question.population"); - return String.format(q, name); + super(PROPERTY, QuestionType.POPULATION, MESSAGE); } @Override protected String getRightAnswer(Map> claims) { - Value v = claims.get(PROPERTY).get(0).getValue(); + List statements = claims.get(PROPERTY); + Value v = statements.get(statements.size()-1).getValue(); return v.toString(); } - - @Override - protected List getWrongAnswers(String rightAnswer) { - int number = 0; - // Check if it is a integer - try { - number = Integer.parseInt(rightAnswer); - } catch(NumberFormatException e) { - //throw exception or maybe return null - } - - List wrongAnswers = new ArrayList(); - - Random rnd = new Random(); - - // Gives values depending on parameter with percentage - // Example: If parameter is 50 value range is number*.5 and number*1.5 - int parameter = 50; - for(int i = 0; i < 3; i++){ - int wrong = Math.round(number * (100 - parameter + rnd.nextInt(parameter * 2 + 1)) / 100); - // Checking if it creates the same answer - if(wrong == number) - i--; - else - wrongAnswers.add(String.valueOf(wrong)); - } - return wrongAnswers; - } - } diff --git a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/SizeGenerator.java b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/SizeGenerator.java index a6066984..2259c13e 100644 --- a/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/SizeGenerator.java +++ b/questionGenerator/src/main/java/questionGenerator/generator/specificGenerators/SizeGenerator.java @@ -1,28 +1,21 @@ package main.java.questionGenerator.generator.specificGenerators; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Random; import org.wikidata.wdtk.datamodel.interfaces.Statement; import org.wikidata.wdtk.datamodel.interfaces.Value; -import main.java.questionGenerator.generator.AbstractGenerator; +import main.java.questionGenerator.generator.AnswersAreNotEntites; import main.java.questionGenerator.question.QuestionType; -public class SizeGenerator extends AbstractGenerator { +public class SizeGenerator extends AnswersAreNotEntites { private final static String PROPERTY = "P2046"; + private final static String MESSAGE = "question.size"; - public SizeGenerator(){ - super(PROPERTY, QuestionType.SIZE); - } - - @Override - protected String getQuestion(String name) { - String q = getMessages().getString("question.size"); - return String.format(q, name); + public SizeGenerator() { + super(PROPERTY, QuestionType.SIZE, MESSAGE); } @Override @@ -31,33 +24,6 @@ protected String getRightAnswer(Map> claims) { return getRightAnswerEntity(v.toString()); } - @Override - protected List getWrongAnswers(String rightAnswer) { - float number = 0; - // Check if it is a float - try { - number = Float.parseFloat(rightAnswer); - } catch(NumberFormatException e) { - //throw exception or maybe return null - } - - List result = new ArrayList<>(); - Random rnd = new Random(); - - // Gives values depending on parameter with percentage - // Example: If parameter is 50 value range is number*.5 and number*1.5 - int parameter = 50; - for(int i = 0; i < 3; i++){ - float wrong = (number * (100 - parameter + rnd.nextInt(parameter * 2 + 1)) / 100); - // Checking if it creates the same answer - if(wrong == number) - i--; - else - result.add(String.valueOf(wrong)); - } - return result; - } - private String getRightAnswerEntity(String url) { String[] split1 = url.split(" "); String[] split2 = split1[0].split("/"); diff --git a/questionGenerator/src/test/java/questionGenerator/QuestionGeneratorTests.java b/questionGenerator/src/test/java/questionGenerator/QuestionGeneratorTests.java index 0ea0c41a..67a6aa97 100644 --- a/questionGenerator/src/test/java/questionGenerator/QuestionGeneratorTests.java +++ b/questionGenerator/src/test/java/questionGenerator/QuestionGeneratorTests.java @@ -39,7 +39,7 @@ void testGenerateQuestionsEnglish() { for(QuestionType t : types) { for(int i=0; i<3; i++) { - question = qgEN.generateQuestion(t).getJSON().toString(); + question = qgEN.generateQuestions(t, 1).get(0).getJSON().toString(); JSONObject json = null; //Check correct format @@ -98,7 +98,7 @@ void testGenerateQuestionsSpanish() { for(QuestionType t : types) { for(int i=0; i<3; i++) { - question = qgES.generateQuestion(t).getJSON().toString(); + question = qgES.generateQuestions(t, 1).get(0).getJSON().toString(); JSONObject json = null; //Check correct format