Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
18e0254
Add blank base classes and interfaces
DudkoAndrei Nov 24, 2022
83b01fe
Fix some javadocs
DudkoAndrei Nov 24, 2022
0affb72
Make TaskGenerator Task's nested interface
DudkoAndrei Nov 24, 2022
9a57b7d
Implement Quiz methods
DudkoAndrei Nov 25, 2022
afca867
Add MathTask interface and AbstractMathTask class
DudkoAndrei Nov 27, 2022
0c5145f
Add TextTask class
DudkoAndrei Nov 27, 2022
32cd8fb
Add PoolTaskGenerator class
DudkoAndrei Nov 27, 2022
bbd8241
Add GroupTaskGenerator class
DudkoAndrei Nov 27, 2022
da6e27b
Add isDoubleEqual and truncate methods to AbstractMathTask
DudkoAndrei Nov 28, 2022
3beb748
Add compute method to MathTask.Operation
DudkoAndrei Nov 28, 2022
3f7f5a0
Add ExpressionTask class
DudkoAndrei Nov 28, 2022
ac5bc55
Remove code duplicates from AbstractMathTask.Generator class
DudkoAndrei Nov 29, 2022
cf8324a
Add EquationTask class
DudkoAndrei Nov 29, 2022
8f45f52
Add getRandomDouble method to AbstractMathTask.Generator class
DudkoAndrei Nov 29, 2022
904ebb4
Add exceptions
DudkoAndrei Nov 29, 2022
913ebbe
Make TextTask class public
DudkoAndrei Nov 29, 2022
504603f
Refactor switches in MathTask class
DudkoAndrei Nov 29, 2022
f751caa
Fix GroupTaskGenerator.generate and make constructors public
DudkoAndrei Nov 29, 2022
a3967d2
Fix some cases with integer division
DudkoAndrei Nov 29, 2022
a3d5646
Fix minor problems
DudkoAndrei Nov 29, 2022
f69fa09
Add quizzes
DudkoAndrei Nov 29, 2022
822abe3
Refactor AbstractMathTask.Generator.getRandomDouble method
DudkoAndrei Dec 7, 2022
f142e48
Fix PoolTaskGenerator constructor
DudkoAndrei Dec 7, 2022
2224cf5
Refactor GroupTaskGenerator.generate method
DudkoAndrei Dec 7, 2022
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
73 changes: 73 additions & 0 deletions lab-01/src/by/dudkoandrei/quizer/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package by.dudkoandrei.quizer;

import by.dudkoandrei.quizer.constants.EquationTaskGeneratorConstants;
import by.dudkoandrei.quizer.constants.ExpressionTaskGeneratorConstants;
import by.dudkoandrei.quizer.constants.TextGeneratorConstats;
import by.dudkoandrei.quizer.task_generators.GroupTaskGenerator;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

/**
* @return тесты в {@link Map}, где ключ - название теста {@link String} значение - сам тест
* {@link Quiz}
*/
static Map<String, Quiz> getQuizMap() {
Map<String, Quiz> quizMap = new HashMap<>();

quizMap.put("Text Quiz", new Quiz(TextGeneratorConstats.generator, 3));
quizMap.put("Integer equations", new Quiz(EquationTaskGeneratorConstants.integerGenerator, 10));
quizMap.put("Equations", new Quiz(EquationTaskGeneratorConstants.generator, 10));
quizMap.put("Integer expressions",
new Quiz(ExpressionTaskGeneratorConstants.integerGenerator, 10));
quizMap.put("Expressions", new Quiz(ExpressionTaskGeneratorConstants.generator, 10));
quizMap.put("All tasks", new Quiz(
new GroupTaskGenerator(TextGeneratorConstats.generator,
EquationTaskGeneratorConstants.integerGenerator,
EquationTaskGeneratorConstants.generator,
ExpressionTaskGeneratorConstants.integerGenerator,
ExpressionTaskGeneratorConstants.generator), 20));

return quizMap;
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

var quizMap = getQuizMap();

System.out.println("Available quizzes:");

for (var name : quizMap.keySet()) {
System.out.println(name);
}

System.out.println("Select quiz:");

String name = scanner.nextLine();
while (!quizMap.containsKey(name)) {
System.out.println("No such quiz. Try again");
name = scanner.nextLine();
}

Quiz quiz = quizMap.get(name);

System.out.println("Quiz: \"" + name + "\" started");
while (!quiz.isFinished()) {
System.out.println(quiz.nextTask().getText());

String answer = scanner.nextLine();
Result result = quiz.provideAnswer(answer);

System.out.println(result + "\n");
}

System.out.println("Quiz ended");
System.out.println("Your score: " + quiz.getMark() * 10);
System.out.println("Correct answers: " + quiz.getCorrectAnswerNumber());
System.out.println("Wrong answers: " + quiz.getWrongAnswerNumber());
System.out.println("Incorrect input: " + quiz.getIncorrectInputNumber());
}
}
119 changes: 119 additions & 0 deletions lab-01/src/by/dudkoandrei/quizer/Quiz.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package by.dudkoandrei.quizer;

import by.dudkoandrei.quizer.exceptions.QuizFinishedException;
import by.dudkoandrei.quizer.exceptions.QuizNotFinishedException;
import by.dudkoandrei.quizer.tasks.Task;

/**
* Class, который описывает один тест.
*/
class Quiz {

private final Task.Generator taskGenerator;

private Task currentTask = null;
private final int taskCount;
private boolean answeredOnCurrentTask = false;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется, что лучше хранить последний результат.

private int correctAnswerNumber = 0;
private int wrongAnswerNumber = 0;
private int incorrectInputNumber = 0;

/**
* @param generator генератор заданий
* @param taskCount количество заданий в тесте
*/
Quiz(Task.Generator generator, int taskCount) {
if (taskCount <= 0) {
throw new IllegalArgumentException("Task count should be positive");
}
if (generator == null) {
throw new IllegalArgumentException("Generator is null");
}
this.taskGenerator = generator;
this.taskCount = taskCount;
}

/**
* @return задание, повторный вызов вернет слелующее
* @see Task
*/
Task nextTask() {
if (isFinished()) {
throw new QuizFinishedException();
}

if (answeredOnCurrentTask || currentTask == null) {
currentTask = taskGenerator.generate();
answeredOnCurrentTask = false;
}

return currentTask;
}

/**
* Предоставить ответ ученика. Если результат {@link Result#INCORRECT_INPUT}, то счетчик
* неправильных ответов не увеличивается, а {@link #nextTask()} в следующий раз вернет тот же
* самый объект {@link Task}.
*/
Result provideAnswer(String answer) {
if (isFinished()) {
throw new QuizFinishedException();
}

Result result = currentTask.validate(answer);

switch (result) {
case OK -> {
correctAnswerNumber++;
answeredOnCurrentTask = true;
}
case WRONG -> {
wrongAnswerNumber++;
answeredOnCurrentTask = true;
}
case INCORRECT_INPUT -> incorrectInputNumber++;
}

return result;
}

/**
* @return завершен ли тест
*/
boolean isFinished() {
return correctAnswerNumber + wrongAnswerNumber == taskCount;
}

/**
* @return количество правильных ответов
*/
int getCorrectAnswerNumber() {
return correctAnswerNumber;
}

/**
* @return количество неправильных ответов
*/
int getWrongAnswerNumber() {
return wrongAnswerNumber;
}

/**
* @return количество раз, когда был предоставлен неправильный ввод
*/
int getIncorrectInputNumber() {
return incorrectInputNumber;
}

/**
* @return оценка, которая является отношением количества правильных ответов к количеству всех
* вопросов. Оценка выставляется только в конце!
*/
double getMark() {
if (!isFinished()) {
throw new QuizNotFinishedException();
}

return ((double) correctAnswerNumber) / taskCount;
}
}
10 changes: 10 additions & 0 deletions lab-01/src/by/dudkoandrei/quizer/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package by.dudkoandrei.quizer;

/**
* Enum, который описывает результат ответа на задание.
*/
public enum Result {
OK, // Получен правильный ответ
WRONG, // Получен неправильный ответ
INCORRECT_INPUT // Некорректный ввод. Например, текст, когда ожидалось число
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package by.dudkoandrei.quizer.constants;

import by.dudkoandrei.quizer.tasks.Task.Generator;
import by.dudkoandrei.quizer.tasks.math_tasks.EquationTask;
import by.dudkoandrei.quizer.tasks.math_tasks.MathTask.Operation;
import java.util.EnumSet;

public class EquationTaskGeneratorConstants {

public static final Generator generator = new EquationTask.Generator(
0,
25,
4,
EnumSet.allOf(Operation.class));
public static final Generator integerGenerator = new EquationTask.Generator(
0,
25,
EnumSet.allOf(Operation.class));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package by.dudkoandrei.quizer.constants;

import by.dudkoandrei.quizer.tasks.Task.Generator;
import by.dudkoandrei.quizer.tasks.math_tasks.ExpressionTask;
import by.dudkoandrei.quizer.tasks.math_tasks.MathTask.Operation;
import java.util.EnumSet;

public class ExpressionTaskGeneratorConstants {

public static final Generator generator = new ExpressionTask.Generator(
0,
25,
4,
EnumSet.allOf(Operation.class));
public static final Generator integerGenerator = new ExpressionTask.Generator(
0,
25,
EnumSet.allOf(Operation.class));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package by.dudkoandrei.quizer.constants;

import by.dudkoandrei.quizer.task_generators.PoolTaskGenerator;
import by.dudkoandrei.quizer.tasks.Task.Generator;
import by.dudkoandrei.quizer.tasks.TextTask;

public class TextGeneratorConstats {

public static final Generator generator = new PoolTaskGenerator(
false,
new TextTask("Fill in the blank: \"_____. I'm your father.\"\n"
+ "a) Luke\n"
+ "b) Boy\n"
+ "c) Skywalker\n"
+ "d) No", "d"),
new TextTask("Mace Windu light-saber color?\n"
+ "a) Red\n"
+ "b) Purple\n"
+ "c) Green\n"
+ "d) Blue", "b"),
new TextTask("What species of alien is Yoda?\n"
+ "a) Ortolan\n"
+ "b) Human\n"
+ "c) Unknown\n"
+ "d) Gungan", "c"));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package by.dudkoandrei.quizer.exceptions;

public class GeneratorsFailedException extends RuntimeException {

public GeneratorsFailedException() {
super("All generators threw exceptions");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package by.dudkoandrei.quizer.exceptions;

public class NoMoreTasksException extends RuntimeException {

public NoMoreTasksException() {
super("No more tasks");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package by.dudkoandrei.quizer.exceptions;

public class QuizFinishedException extends RuntimeException {

public QuizFinishedException() {
super("Quiz is finished");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package by.dudkoandrei.quizer.exceptions;

public class QuizNotFinishedException extends RuntimeException {

public QuizNotFinishedException() {
super("Quiz is not finished");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package by.dudkoandrei.quizer.task_generators;

import by.dudkoandrei.quizer.exceptions.GeneratorsFailedException;
import by.dudkoandrei.quizer.tasks.Task;
import by.dudkoandrei.quizer.tasks.Task.Generator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
* Task.Generator, который позволяет объединить несколько других Task.Generator.
*/
public class GroupTaskGenerator implements Task.Generator {

private final List<Generator> generators;
private int lastGeneratorIndex = 0;

/**
* Конструктор с переменным числом аргументов.
*
* @param generators генераторы, которые в конструктор передаются через запятую
*/
public GroupTaskGenerator(Task.Generator... generators) {
this(Arrays.asList(generators));
}

/**
* Конструктор, который принимает коллекцию генераторов.
*
* @param generators генераторы, которые передаются в конструктор в Collection (например,
* {@link ArrayList})
*/
public GroupTaskGenerator(Collection<Generator> generators) {
if (generators == null) {
throw new IllegalArgumentException("generators is null");
}
if (generators.isEmpty()) {
throw new IllegalArgumentException("generators is empty");
}
if (generators.contains(null)) {
throw new IllegalArgumentException("generators contains null");
}

this.generators = new ArrayList<>(generators);

Collections.shuffle(this.generators);
}

/**
* @return результат метода generate() случайного генератора из списка. Если этот генератор
* выбросил исключение в методе generate(), выбирается другой. Если все генераторы выбрасывают
* исключение, то и тут выбрасывается исключение.
*/
public Task generate() {
for (int offset = 1; offset <= generators.size(); ++offset) {
try {
int index = getGeneratorIndex(offset);
Task t = generators.get(index).generate();
lastGeneratorIndex = index;
return t;
} catch (Exception ignored) {
}
}

throw new GeneratorsFailedException();
}

private int getGeneratorIndex(int offset) {
return (lastGeneratorIndex + offset) % generators.size();
}
}
Loading