整体需求完善
This commit is contained in:
@ -0,0 +1,57 @@
|
|||||||
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def quick_sort(arr):
|
||||||
|
"""
|
||||||
|
快速排序主函数,支持空数组处理
|
||||||
|
"""
|
||||||
|
if len(arr) <= 1:
|
||||||
|
return arr
|
||||||
|
|
||||||
|
def partition(low, high):
|
||||||
|
pivot_index = random.randint(low, high) # 随机选择基准
|
||||||
|
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]
|
||||||
|
pivot = arr[high]
|
||||||
|
i = low - 1
|
||||||
|
|
||||||
|
for j in range(low, high):
|
||||||
|
if arr[j] <= pivot:
|
||||||
|
i += 1
|
||||||
|
arr[i], arr[j] = arr[j], arr[i]
|
||||||
|
|
||||||
|
arr[i+1], arr[high] = arr[high], arr[i+1]
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
def recur_sort(low, high):
|
||||||
|
if low < high:
|
||||||
|
pi = partition(low, high)
|
||||||
|
recur_sort(low, pi - 1)
|
||||||
|
recur_sort(pi + 1, high)
|
||||||
|
|
||||||
|
recur_sort(0, len(arr) - 1)
|
||||||
|
return arr
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 从命令行参数读取数据
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
try:
|
||||||
|
# 处理多种输入格式:逗号分隔、空格分隔或混合分隔
|
||||||
|
input_str = " ".join(sys.argv[1:])
|
||||||
|
input_data = [float(x) if '.' in x else int(x)
|
||||||
|
for x in input_str.replace(',', ' ').split()]
|
||||||
|
|
||||||
|
print("原始输入:", sys.argv[1:])
|
||||||
|
print("解析数据:", input_data)
|
||||||
|
|
||||||
|
sorted_arr = quick_sort(input_data.copy())
|
||||||
|
print("排序结果:", sorted_arr)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
print("错误:输入数据包含非数字字符,请确保只输入数字")
|
||||||
|
print("用法: python script.py [数字1 数字2 ...]")
|
||||||
|
print("示例: python script.py 3 0 8 7 2 1 9 4")
|
||||||
|
else:
|
||||||
|
print("未提供输入数据,使用默认测试用例")
|
||||||
|
test_case = [3, 0, 8, 7, 2, 1, 9, 4]
|
||||||
|
print("测试数据:", test_case)
|
||||||
|
print("排序结果:", quick_sort(test_case.copy()))
|
@ -0,0 +1,57 @@
|
|||||||
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def quick_sort(arr):
|
||||||
|
"""
|
||||||
|
快速排序主函数,支持空数组处理
|
||||||
|
"""
|
||||||
|
if len(arr) <= 1:
|
||||||
|
return arr
|
||||||
|
|
||||||
|
def partition(low, high):
|
||||||
|
pivot_index = random.randint(low, high) # 随机选择基准
|
||||||
|
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]
|
||||||
|
pivot = arr[high]
|
||||||
|
i = low - 1
|
||||||
|
|
||||||
|
for j in range(low, high):
|
||||||
|
if arr[j] <= pivot:
|
||||||
|
i += 1
|
||||||
|
arr[i], arr[j] = arr[j], arr[i]
|
||||||
|
|
||||||
|
arr[i+1], arr[high] = arr[high], arr[i+1]
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
def recur_sort(low, high):
|
||||||
|
if low < high:
|
||||||
|
pi = partition(low, high)
|
||||||
|
recur_sort(low, pi - 1)
|
||||||
|
recur_sort(pi + 1, high)
|
||||||
|
|
||||||
|
recur_sort(0, len(arr) - 1)
|
||||||
|
return arr
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 从命令行参数读取数据
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
try:
|
||||||
|
# 处理多种输入格式:逗号分隔、空格分隔或混合分隔
|
||||||
|
input_str = " ".join(sys.argv[1:])
|
||||||
|
input_data = [float(x) if '.' in x else int(x)
|
||||||
|
for x in input_str.replace(',', ' ').split()]
|
||||||
|
|
||||||
|
print("原始输入:", sys.argv[1:])
|
||||||
|
print("解析数据:", input_data)
|
||||||
|
|
||||||
|
sorted_arr = quick_sort(input_data.copy())
|
||||||
|
print("排序结果:", sorted_arr)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
print("错误:输入数据包含非数字字符,请确保只输入数字")
|
||||||
|
print("用法: python script.py [数字1 数字2 ...]")
|
||||||
|
print("示例: python script.py 3 0 8 7 2 1 9 4")
|
||||||
|
else:
|
||||||
|
print("未提供输入数据,使用默认测试用例")
|
||||||
|
test_case = [3, 0, 8, 7, 2, 1, 9, 4]
|
||||||
|
print("测试数据:", test_case)
|
||||||
|
print("排序结果:", quick_sort(test_case.copy()))
|
@ -3,6 +3,7 @@ package com.bipt.intelligentapplicationorchestrationservice.service.Impl;
|
|||||||
import com.bipt.intelligentapplicationorchestrationservice.mapper.AlgorithmInfoMapper;
|
import com.bipt.intelligentapplicationorchestrationservice.mapper.AlgorithmInfoMapper;
|
||||||
import com.bipt.intelligentapplicationorchestrationservice.pojo.AlgorithmInfo;
|
import com.bipt.intelligentapplicationorchestrationservice.pojo.AlgorithmInfo;
|
||||||
import com.bipt.intelligentapplicationorchestrationservice.service.AlgorithmInfoService;
|
import com.bipt.intelligentapplicationorchestrationservice.service.AlgorithmInfoService;
|
||||||
|
import jakarta.servlet.ServletContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -11,10 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -31,8 +29,10 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AlgorithmInfoMapper algorithmInfoMapper;
|
private AlgorithmInfoMapper algorithmInfoMapper;
|
||||||
|
|
||||||
@Value("${algorithm.upload.dir:/tmp/algorithm-files/}") // 默认上传目录
|
// 从配置文件读取上传目录
|
||||||
|
@Value("${algorithm.upload.dir:algorithm_files}")
|
||||||
private String uploadDir;
|
private String uploadDir;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AlgorithmInfo getById(Long id) {
|
public AlgorithmInfo getById(Long id) {
|
||||||
return algorithmInfoMapper.selectById(id);
|
return algorithmInfoMapper.selectById(id);
|
||||||
@ -78,6 +78,11 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增算法
|
||||||
|
* @param algorithmInfo
|
||||||
|
* @param file
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void save(AlgorithmInfo algorithmInfo, MultipartFile file) {
|
public void save(AlgorithmInfo algorithmInfo, MultipartFile file) {
|
||||||
@ -99,32 +104,31 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
// 生成唯一文件名,避免冲突
|
// 生成唯一文件名,避免冲突
|
||||||
String fileName = UUID.randomUUID().toString() + "_" + originalFilename;
|
String fileName = UUID.randomUUID().toString() + "_" + originalFilename;
|
||||||
|
|
||||||
// 关键修改:使用实际存在的绝对路径(替换为你的实际路径,如 D:/algorithm_files)
|
// 构建相对路径(相对于项目根目录)
|
||||||
// 建议在配置文件中配置,而非硬编码
|
Path relativePath = Paths.get(uploadDir, fileName);
|
||||||
String uploadDir = "D:/algorithm_files"; // 例如:Windows 路径用 D:/xxx,Linux 用 /home/xxx
|
|
||||||
|
|
||||||
// 构建路径对象(使用 Path 而非 File,更适合跨平台)
|
// 获取当前应用的运行目录(兼容开发和部署环境)
|
||||||
Path saveDirPath = Paths.get(uploadDir);
|
Path basePath = Paths.get("").toAbsolutePath();
|
||||||
|
Path absolutePath = basePath.resolve(relativePath);
|
||||||
|
|
||||||
// 确保目录存在(createDirectories 会创建所有不存在的父目录,跨平台兼容)
|
// 确保目录存在
|
||||||
if (!Files.exists(saveDirPath)) {
|
Path parentDir = absolutePath.getParent();
|
||||||
Files.createDirectories(saveDirPath); // 关键:创建多级目录
|
if (!Files.exists(parentDir)) {
|
||||||
log.info("已创建存储目录: {}", saveDirPath.toAbsolutePath());
|
Files.createDirectories(parentDir);
|
||||||
|
log.info("已创建存储目录: {}", parentDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完整文件路径
|
|
||||||
Path saveFilePath = saveDirPath.resolve(fileName);
|
|
||||||
|
|
||||||
// 保存文件到指定路径
|
// 保存文件到指定路径
|
||||||
file.transferTo(saveFilePath); // 使用 Path 重载方法,更可靠
|
file.transferTo(absolutePath);
|
||||||
|
|
||||||
// 设置文件路径到实体类(存储绝对路径或可访问的相对路径)
|
// 存储相对路径到数据库
|
||||||
algorithmInfo.setAlgorithmFile(saveFilePath.toString());
|
algorithmInfo.setAlgorithmFile(relativePath.toString());
|
||||||
|
|
||||||
// 设置文件大小
|
// 设置文件大小
|
||||||
algorithmInfo.setFileSize(Files.size(saveFilePath));
|
algorithmInfo.setFileSize(Files.size(absolutePath));
|
||||||
|
|
||||||
log.info("文件保存成功: {}", saveFilePath.toAbsolutePath());
|
log.info("文件保存成功 - 相对路径: {}, 绝对路径: {}",
|
||||||
|
relativePath, absolutePath);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("文件保存失败", e);
|
log.error("文件保存失败", e);
|
||||||
throw new RuntimeException("文件保存失败: " + e.getMessage(), e);
|
throw new RuntimeException("文件保存失败: " + e.getMessage(), e);
|
||||||
@ -132,7 +136,7 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
} else {
|
} else {
|
||||||
// 文件为空的处理逻辑
|
// 文件为空的处理逻辑
|
||||||
algorithmInfo.setAlgorithmFile(null);
|
algorithmInfo.setAlgorithmFile(null);
|
||||||
algorithmInfo.setFileSize(0L); // 空文件大小设为0
|
algorithmInfo.setFileSize(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
algorithmInfo.setCreateTime(LocalDateTime.now());
|
algorithmInfo.setCreateTime(LocalDateTime.now());
|
||||||
@ -142,15 +146,33 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行Python算法脚本并返回结果
|
* 执行Python算法脚本并返回结果
|
||||||
* @param scriptPath Python脚本路径
|
* @param scriptPath Python脚本路径(数据库中存储的相对路径)
|
||||||
* @param args 命令行参数列表
|
* @param args 命令行参数列表
|
||||||
* @return 脚本执行结果
|
* @return 脚本执行结果
|
||||||
*/
|
*/
|
||||||
public String run(String scriptPath, List<String> args) throws IOException, InterruptedException {
|
public String run(String scriptPath, List<String> args) throws IOException, InterruptedException {
|
||||||
// 构建命令:python [脚本路径] [参数1] [参数2] ...
|
if (scriptPath == null || scriptPath.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("脚本路径不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前应用的运行目录(兼容开发和部署环境)
|
||||||
|
Path basePath = Paths.get("").toAbsolutePath();
|
||||||
|
Path absoluteScriptPath = basePath.resolve(scriptPath);
|
||||||
|
|
||||||
|
// 验证文件是否存在
|
||||||
|
if (!Files.exists(absoluteScriptPath)) {
|
||||||
|
throw new FileNotFoundException("脚本文件不存在: " + absoluteScriptPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证文件是否可执行(针对Python脚本)
|
||||||
|
if (!Files.isReadable(absoluteScriptPath)) {
|
||||||
|
throw new IOException("脚本文件不可读: " + absoluteScriptPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建命令:python [脚本绝对路径] [参数1] [参数2] ...
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("python"); // Python解释器路径,可配置在application.properties中
|
command.add("python"); // Python解释器路径,可配置在application.properties中
|
||||||
command.add(scriptPath); // 脚本路径
|
command.add(absoluteScriptPath.toString()); // 使用绝对路径执行脚本
|
||||||
command.addAll(args); // 添加所有参数
|
command.addAll(args); // 添加所有参数
|
||||||
|
|
||||||
// 打印完整命令(用于调试)
|
// 打印完整命令(用于调试)
|
||||||
@ -158,6 +180,10 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
|
|
||||||
// 创建进程并执行命令
|
// 创建进程并执行命令
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
|
|
||||||
|
// 设置工作目录为脚本所在目录
|
||||||
|
processBuilder.directory(absoluteScriptPath.getParent().toFile());
|
||||||
|
|
||||||
processBuilder.redirectErrorStream(true); // 将错误输出合并到标准输出
|
processBuilder.redirectErrorStream(true); // 将错误输出合并到标准输出
|
||||||
Process process = processBuilder.start();
|
Process process = processBuilder.start();
|
||||||
|
|
||||||
@ -176,7 +202,12 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
|||||||
|
|
||||||
// 检查脚本是否成功执行
|
// 检查脚本是否成功执行
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
throw new RuntimeException("脚本执行失败,退出码: " + exitCode);
|
// 捕获详细的错误信息
|
||||||
|
String errorMsg = "脚本执行失败,退出码: " + exitCode +
|
||||||
|
"\n命令: " + String.join(" ", command) +
|
||||||
|
"\n输出: " + output.toString();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new RuntimeException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.toString();
|
return output.toString();
|
||||||
|
@ -60,3 +60,6 @@ spring.profiles.active=dev
|
|||||||
#配置IP列表(后续根据需求修改ip数据,以下仅为测试用例)
|
#配置IP列表(后续根据需求修改ip数据,以下仅为测试用例)
|
||||||
available.ips=192.168.1.100,192.168.1.101,192.168.1.102
|
available.ips=192.168.1.100,192.168.1.101,192.168.1.102
|
||||||
|
|
||||||
|
# 算法文件上传目录(相对于项目根目录)
|
||||||
|
algorithm.upload.dir=algorithm_files
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user