Merge branch 'refs/heads/develop'

# Conflicts:
#	out/production/TestPaperGenerationSystem/AbstractProblemGenerator$1.class
#	out/production/TestPaperGenerationSystem/FileService.class
main
Teptao 7 months ago
commit 5b06fef741

@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="TestPaperGenerationSystem:jar">
<output-path>$PROJECT_DIR$/out/artifacts/TestPaperGenerationSystem_jar</output-path>
<root id="archive" name="TestPaperGenerationSystem.jar">
<element id="module-output" name="TestPaperGenerationSystem" />
</root>
</artifact>
</component>

@ -1,2 +1,4 @@
# TestPaperGenerationSystem
git测试
个人项目:中小学数学卷子自动生成程序
李文韬-202326010304-软件2303

Binary file not shown.

@ -0,0 +1,10 @@
张三1,123,小学
张三2,123,小学
张三3,123,小学
李四1,123,初中
李四2,123,初中
李四3,123,初中
王五1,123,高中
王五2,123,高中
王五3,123,高中
abc1,123,高中

@ -0,0 +1,19 @@
1. (45^2) * (5 - sin(45) - 7 * 94 = ?
2. cos(60) + 74 = ?
3. 47 - cos(45) - 63) = ?
4. 25 / 5 * cos(60) + 88) * (59^2) = ?
5. tan(30) + 8 = ?
6. 59 * cos(45) = ?
7. 91 * tan(0) + 100 / sqrt(9) = ?
8. 55 / tan(60) / 70 / sqrt(64) = ?
9. tan(0) + 69 = ?
10. sin(60) / sqrt(25) = ?

@ -0,0 +1,19 @@
1. 50 * 4 + 95 + 98 = ?
2. 47 + 36 = ?
3. 20 + 45 * 4 / 26 = ?
4. 34 + 72 = ?
5. (71 + 85) + 87 = ?
6. 58 - 14 = ?
7. 66 / (33 + 9) + 16 * 4 = ?
8. 95 / 1 / 5 + 59 + 69 = ?
9. 83 / 1 * 3 = ?
10. 98 / (1 + 96) = ?

@ -0,0 +1,39 @@
1. 9 - 6 - 3 - 0 = ?
2. 86 + 76 = ?
3. 82 + 43 / 1 + 89 = ?
4. 8 + 38 - 20 = ?
5. 69 * 9 / 3 = ?
6. 92 - 66 / 1 - 6 = ?
7. (39 + 38) + 28 - 12 = ?
8. 56 - (29 + 50) = ?
9. 9 * 10 = ?
10. 73 / 73 / 1 + 67 = ?
11. 40 * (4 - 151) = ?
12. 2 * 6 = ?
13. 7 / 7 / 1 - 1 = ?
14. 32 * 2 - 49 = ?
15. 48 - 34 + 83 = ?
16. 63 * 6 / 3 - 35 = ?
17. 49 * 6 = ?
18. 57 - 53 / 2 / 2 = ?
19. 51 * 9 * 10 = ?
20. 42 - 14 + 47 * 2 = ?

@ -0,0 +1,29 @@
1. 50 - 99 - 45 + sqrt(9) / 10 = ?
2. 65 / (5^2) + 70 * (30 - 6) = ?
3. 45 - 26 - sqrt(64) = ?
4. 29 - 68 / 42 / (3^2) = ?
5. (162^2) / 9 = ?
6. 90 * sqrt(36) / 54 / 9 = ?
7. sqrt(36) + 81 + 79 = ?
8. (9^2) * (37 - 89) = ?
9. 33 * sqrt(25) * 24 / 6 - 33 = ?
10. 85 + (86^2) = ?
11. 50 + sqrt(4) = ?
12. (26 + sqrt(25) - 126 / 9 = ?
13. sqrt(64) * 92 - 7 / 1 = ?
14. 52 + 35 + 55 * (24^2) / 6 = ?
15. 80 / sqrt(36) = ?

@ -0,0 +1,19 @@
1. 49 - (89^2) * 97 - 140 / sin(60) = ?
2. 42 - sqrt(64) / 1 - 18 * cos(90) = ?
3. 64 / sqrt(16) * cos(90) * 14 = ?
4. sqrt(9) * sin(90) = ?
5. 52 + 24 - sin(0) * (87^2) = ?
6. (22^2) - tan(45) + 68 = ?
7. tan(0) - (51^2) = ?
8. 8 / cos(90) = ?
9. 11 * sin(30) / (8^2) = ?
10. tan(45) / (4^2) + 57 - 47 = ?

@ -0,0 +1,19 @@
1. 7 - 7 - 0 * 1 = ?
2. 19 + 16 = ?
3. 20 + 37 = ?
4. 8 / 2 = ?
5. 65 + 76 * 7 - 363 - 466 = ?
6. 72 * (5 - 125) = ?
7. 83 * 2 = ?
8. 6 * 2 = ?
9. 56 - 33 = ?
10. 43 / 1 - 41 / 1 = ?

@ -0,0 +1,23 @@
1. 19 * sin(45) + sqrt(25) = ?
2. sin(0) / (10^2) + 91) - 24 = ?
3. (13^2) + (97 - tan(45) = ?
4. sin(45) - sqrt(25) = ?
5. 119 / cos(30) + 12 + (30^2) = ?
6. (12 - (98^2) / sin(90) / 1 * 36 = ?
7. 67 + 53 - 60 / sin(90) * 64 = ?
8. sqrt(81) - 60 + sin(45) + 98 = ?
9. tan(45) - 19) / sqrt(16) = ?
10. 26 + 7 * tan(45) = ?
11. (59 + (97^2) - tan(0) = ?
12. 55 * (49^2) + sin(45) + 35 = ?

@ -0,0 +1,19 @@
1. 9 * (10 + 75) + 32 = ?
2. 10 / 1 * 3 = ?
3. 8 / 1 + 17 / 5 - 3 = ?
4. 93 + 31 = ?
5. 37 - 29 - 1 = ?
6. 22 / 22 * 10 + 86 = ?
7. 68 * 3 + 43 = ?
8. 13 * 2 = ?
9. 43 - 39 + 12 + 41 - 16 = ?
10. 54 * 5 / 27 * 1 / 1 = ?

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Application

@ -23,6 +23,13 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE
};
/**
*
*
* @param count
* @param existingProblems
* @return Equation
*/
@Override
public final List<Equation> generate(int count, Set<String> existingProblems) {
List<Equation> newProblems = new ArrayList<>(count);
@ -45,6 +52,8 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
/**
*
*
* @return Equation
*/
protected abstract Equation createProblem();
@ -139,7 +148,9 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
operators.add(operator);
}
/**
* ()
*/
private void addParentheses(List<String> operands, List<Operator> operators) {
if (operators.size() > 1 && random.nextBoolean()) {
int pos = random.nextInt(operators.size());
@ -152,6 +163,12 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
}
}
/**
* ()
*
* @param number
* @return
*/
private List<Integer> findDivisors(int number) {
if (number == 0) {
return Collections.singletonList(1); // 避免除以0
@ -162,6 +179,13 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
.collect(Collectors.toList());
}
/**
* ()
*
* @param min
* @param max
* @return
*/
protected int getRandomNumber(int min, int max) {
if (min > max) {
return max; // 安全处理例如当currentResult变为1时

@ -12,17 +12,24 @@ import java.util.regex.Pattern;
*/
public class Application {
// 依赖注入:在构造函数中初始化所有需要的服务
// 用于从控制台读取用户输入
private final Scanner scanner;
// 负责用户认证服务,处理登录逻辑
private final AuthService authService;
// 管理用户会话信息,当前登录用户和题目难度级别
private final SessionManager sessionManager;
// 负责文件操作,读写历史题目和新生成的题目
private final IFileService fileService;
// 用于解析“切换为XX”命令的正则表达式
private static final Pattern SWITCH_COMMAND_PATTERN = Pattern.compile("^切换为(小学|初中|高中)$");
/**
*
*
*/
public Application() {
this.scanner = new Scanner(System.in, "UTF-8");
this.scanner = new Scanner(System.in);
// 创建数据访问层的实例
IUserRepository userRepository = new UserRepository();
@ -35,18 +42,26 @@ public class Application {
/**
*
*
*
*/
public void run() throws IOException {
public void run() {
System.out.println("欢迎使用中小学数学卷子自动生成程序!");
while (true) {
if (!sessionManager.isUserLoggedIn()) {
handleLoggedOutState();
} else {
handleLoggedInState();
try {
if (!sessionManager.isUserLoggedIn()) {
handleLoggedOutState();
} else {
handleLoggedInState();
}
} catch (Exception e) {
System.out.println("error");
break;
}
}
}
/**
*
*/
@ -54,28 +69,35 @@ public class Application {
System.out.print("请输入用户名和密码(以空格隔开,输入 'exit' 退出程序): ");
String input = scanner.nextLine();
// 检查用户是否希望退出
if ("exit".equalsIgnoreCase(input.trim())) {
System.out.println("感谢使用,程序已退出。");
System.exit(0);
}
// 按空格分割输入,获取用户名和密码
String[] credentials = input.split(" ");
if (credentials.length != 2) {
System.out.println("输入格式错误,请输入正确的用户名、密码。");
return;
}
// 调用认证服务进行登录验证
Optional<User> userOptional = authService.login(credentials[0], credentials[1]);
if (userOptional.isPresent()) {
// 如果登录成功,启动会话
sessionManager.startSession(userOptional.get());
System.out.println("登录成功!欢迎您," + credentials[0] + "。");
} else {
// 登录失败,提示用户
System.out.println("用户名或密码错误,请重试。");
}
}
/**
*
*
* 退
* @throws IOException IO
*/
private void handleLoggedInState() throws IOException {
String currentLevel = sessionManager.getCurrentLevel();
@ -84,23 +106,33 @@ public class Application {
currentLevel);
String input = scanner.nextLine().trim();
// 根据用户输入分发到不同的处理方法
if ("-1".equals(input)) {
handleLogout();
handleLogout(); // 处理退出登录
} else if (isSwitchCommand(input)) {
handleSwitchLevel(input);
handleSwitchLevel(input); // 处理切换级别
} else if (isNumeric(input)) {
handleGenerateProblems(input);
handleGenerateProblems(input); // 处理生成题目
} else {
System.out.println("无效的选项,请重新输入");
}
}
/**
* 退
* 退
*/
private void handleLogout() {
System.out.println("用户 " + sessionManager.getCurrentUser().getUsername() + " 已退出登录。");
sessionManager.endSession();
}
/**
*
* 使
* @param input "切换为小学"
*/
private void handleSwitchLevel(String input) {
Matcher matcher = SWITCH_COMMAND_PATTERN.matcher(input);
if (matcher.matches()) {
@ -112,21 +144,35 @@ public class Application {
}
}
/**
*
* 1. 10-30
* 2.
* 3.
* 4.
* 5.
* @param input
* @throws IOException
*/
private void handleGenerateProblems(String input) throws IOException {
int count = Integer.parseInt(input);
// 验证题目数量是否在指定范围内
if (count < 10 || count > 30) {
System.out.println("生成数量必须在10到30之间。");
return;
return; // 结束当前操作,返回到主循环
}
User currentUser = sessionManager.getCurrentUser();
System.out.println("正在加载历史题目,请稍候...");
// 从文件中加载该用户的所有历史题目,用于去重
Set<String> history = fileService.loadAllProblemHistory(currentUser);
System.out.println("历史题目加载完毕。共找到 " + history.size() + " 道历史题目。");
System.out.println("正在生成 " + count + " 道不重复的新题目...");
// 从会话中获取当前难度级别对应的题目生成器
IProblemGenerator generator = sessionManager.getCurrentGenerator();
// 生成指定数量且不与历史题目重复的新题目
List<Equation> newProblems = generator.generate(count, history);
// 命令行显示生成题目
@ -141,15 +187,30 @@ public class Application {
System.out.println("保存成功!新的题目已存储在用户目录 " + currentUser.getStoragePath() + " 下。");
}
/**
* XX
* @param input
* @return true false
*/
private boolean isSwitchCommand(String input) {
return SWITCH_COMMAND_PATTERN.matcher(input).matches();
}
/**
*
* @param str
* @return true false
*/
private boolean isNumeric(String str) {
return str != null && str.matches("\\d+");
}
public static void main(String[] args) throws IOException {
/**
* (main)
* Application
* @param args 使
*/
public static void main(String[] args) {
Application app = new Application();
app.run();
}

@ -21,7 +21,6 @@ public class AuthService implements IAuthService {
*/
public Optional<User> login(String username, String password) {
Optional<User> userOptional = userRepository.findByUsername(username);
// 检查用户是否存在,以及密码是否匹配
if (userOptional.isPresent() && userOptional.get().getPassword().equals(password)) {
return userOptional;

@ -22,6 +22,13 @@ public class FileService implements IFileService {
private static final DateTimeFormatter FILE_NAME_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
/**
*
*
* @param user
* @param problems {@link Equation}
* @throws IOException I/O
*/
@Override
public void saveProblems(User user, List<Equation> problems) throws IOException {
Path userDirectory = Paths.get(user.getStoragePath());
@ -47,6 +54,14 @@ public class FileService implements IFileService {
}
}
/**
*
* .txt
*
* @param user
* @return (Set)使 Set
* @throws IOException I/O
*/
@Override
public Set<String> loadAllProblemHistory(User user) throws IOException {
Set<String> historySet = new HashSet<>();
@ -57,7 +72,7 @@ public class FileService implements IFileService {
return historySet; // 如果目录不存在,直接返回空集合
}
File[] files = userDirectory.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
File[] files = userDirectory.listFiles((_, name) -> name.toLowerCase().endsWith(".txt"));
if (files == null) {
return historySet;
}

@ -8,9 +8,24 @@ import java.util.List;
*/
public class HighSchoolProblemGenerator extends MiddleSchoolProblemGenerator {
/**
*
* 0, 30, 45, 60, 90
*/
private static final int[] PREDEFINED_ANGLES = {0, 30, 45, 60, 90};
/**
*
* sincostan
*/
private static final String[] TRIG_FUNCTIONS = {"sin", "cos", "tan"};
/**
*
* `createProblem`
*
* @return Equation
*/
@Override
protected Equation createProblem() {
// 1. 调用父类(已修正的 MiddleSchoolProblemGenerator的方法

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Application

@ -1,9 +1,22 @@
// 修改后的 User.java
/**
*
* {@link AbstractUser}
* User使
*/
public class User extends AbstractUser {
// 用户登录后的默认出题级别(小学、初中、高中)
private final String defaultLevel;
// 为该用户存储历史题目目录路径
private final String storagePath;
/**
* User
*
* @param username
* @param password
* @param defaultLevel
*/
public User(String username, String password, String defaultLevel) {
// 调用父类的构造函数来初始化 username 和 password
super(username, password);
@ -12,10 +25,21 @@ public class User extends AbstractUser {
this.storagePath = "./data/" + this.username + "/";
}
/**
*
*
* @return "小学"
*/
public String getDefaultLevel() {
return defaultLevel;
}
/**
*
*
*
* @return
*/
public String getStoragePath() {
return storagePath;
}

@ -1,31 +1,57 @@
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*
*
*/
public class UserRepository implements IUserRepository {
private final Map<String, User> userDatabase = new ConcurrentHashMap<>();
public UserRepository() {
// 初始化预定义的9个用户账户
// 小学老师
userDatabase.put("张三1", new User("张三1", "123", "小学"));
userDatabase.put("张三2", new User("张三2", "123", "小学"));
userDatabase.put("张三3", new User("张三3", "123", "小学"));
// 初中老师
userDatabase.put("李四1", new User("李四1", "123", "初中"));
userDatabase.put("李四2", new User("李四2", "123", "初中"));
userDatabase.put("李四3", new User("李四3", "123", "初中"));
// 高中老师
userDatabase.put("王五1", new User("王五1", "123", "高中"));
userDatabase.put("王五2", new User("王五2", "123", "高中"));
userDatabase.put("王五3", new User("王五3", "123", "高中"));
// 从文件中加载用户数据
loadUsersFromFile();
}
/**
*
* "username,password,level"
*/
private void loadUsersFromFile() {
// 使用 try-with-resources 语句确保 BufferedReader 被正确关闭
try (BufferedReader reader = new BufferedReader(new FileReader("./account/account.txt"))) {
String line;
// 逐行读取文件
while ((line = reader.readLine()) != null) {
// 使用逗号分割每行的数据
String[] parts = line.split(",");
// 确保每行都有三部分:用户名、密码和用户级别
if (parts.length == 3) {
String username = parts[0].trim();
String password = parts[1].trim();
String level = parts[2].trim();
userDatabase.put(username, new User(username, password, level));
}
}
} catch (IOException e) {
// 如果文件未找到或发生其他IO错误打印错误信息
System.err.println("从文件加载用户数据时出错: " + "./account/account.txt");
}
}
/**
*
*
* @param username
* @return Optional
* Optional
*/
@Override
public Optional<User> findByUsername(String username) {
return Optional.ofNullable(userDatabase.get(username));

@ -0,0 +1,14 @@
@echo off
:: 1. 将控制台环境设置为 UTF-8确保中文输入输出正确
chcp 65001 > nul
:: 2. 告诉 Java 虚拟机(JVM) 使用 UTF-8 编码
set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
:: 3. 运行你的 JAR 包
echo loading...
java -jar TestPaperGenerationSystem.jar
:: 4. 清理环境变量并暂停,以便查看程序输出
set JAVA_TOOL_OPTIONS=
pause
Loading…
Cancel
Save