合工大Java大作业1:货物进销管理系统

news2024/11/28 16:34:37

问题描述

编写一个Inventory.java完成以下功能(没有学过Java文件处理之前,各位同学可以使用硬编码将数据放进两个Vector变量里。等学过Java文件处理之后,再补充数据文件读取部分):

    1.程序首先打开并读取Inventory.txt中记录的所有库存记录,然后读取Transactions.txt,处理这个文件中包含的事务,记录发货记录到Shipping.txt,并记录错误信息到Errors.txt中。最后更新库存到另外一个文件NewInventory.txt中。

    2.文件Inventory.txt和NewInventory.txt的每行包含一个存货记录,没条记录包含下面一些字段息,这些字段之间用一个tab分开(见后面的文件格式):

      

字段

格式和含义

Item number

字符串型,货物编号

Quantity

整型,货物数量

Supplier

字符串型,供应商编号

Description

字符串型,货物描述

    3.字段Items按照从小到大的顺序写入文件的。注意Item号不必连续,如Item号为752的后面可能是800。

    4.文件Transactions.txt包含几个不同的处理记录(每行一条记录)。每条记录前面以一个大写字母开头,表示这条记录是什么类型的事务。在不同的大写字母后面是不同的信息格式。所有的字段也是以tab键分开的(见Transactions.txt文件格式)。

5.以'O'开头的事务表示这是一个发货订单,即某一种货物应该发给特定的客户。Item number和Quantity的格式如上面表格定义。Custom编号和上面的Supplier编号一致。处理一条定单记录(以'O'开头的事务)意味着从减少库存记录中相应货物的数量(减少的数量=发货单中的数量),记录发货信息到Shipping.txt中。注意:Inventory.txt中的quantity不应该小于0,如果对于某一种货物,库存的数量小于发货单的数量的话,系统应该停止处理发货单,并记录出错信息到Errors.txt。如果对于某一种货物有多个发货单,而且库存总量小于这些发货单的总和的话,系统应该按照发货单中的数量从小到大的有限原则满足客户。也就是说,对于某一种货物如果一个数量Quantity少的发货单没有处理之前,数量Quantity多的发货单永远不会被处理。(这种处理原则不受发货单记录在Transactions.txt的先后顺序影响)

6.以'R'开头的事务表示这是一个到货单记录,在'R'后面是Item number和它的数量Quanlity。处理一条到货单意味着增加库存中相应货物的数量(增加的数量=到货单中的数量)。注意:如果在Transactions.txt文件中,到货单出现在发货单之后,到货单中的货物数量可以用来填补发货单中的数量(可以理解成在Transactions.txt中,优先处理到货单)。

7.以'A'开头的事务表示向库存中增加一种新的货物(即这种货物以前库存中没有),在'A'后面是Item number,供应商supplier以及货物的描述description。处理一个新增货物记录意味着向库存中增加一个数量Quantity为0的新的Item。你可以假设在一个Transactions.txt中,新增货物记录总是出现在第一个到货单之前。

8.以'D'开头的事务表示从库存中删除一种货物,在'D'后面是Item号。删除操作总是在所有的事物处理之后才被处理,以保证对于可能出现的同一种货物的发货单的操作能在删除之前被正确处理。如果要删除的某种货物的库存量Quantity不为0的话,系统应该向Errors.txt记录出错信息。

9.文件Shipping.txt中的每一行代表给某一客户的发货信息。Shipping.txt中的每一行分别是客户编号、Item号、货物数量,它们之间用tab键分隔。如果发货单中有两条客户编号和Item编号一样的记录,在Shipping.txt中应该将这两条发货信息合并(即将它们的数量相加)。

10.Errors.txt文件包含未发送的发货记录和库存量大于0的删除记录。Errors.txt每一行包含Custom编号、Item编号以及发货单上的数量Quantity。对于删除操作,Custom编号为0,数量Quntity为库存中的Quantity.

11.实验测试数据:

Inventory.txt

Transactions.txt

如果有问题,加QQ群623914970,可以来问

希望同学们学习其中的思路,而不是直接复制粘贴代码。

 设计思路

1.设计货物类Goods,包含Item_number、Quantity、Supplier、Description等属性和相应的get和set方法

2.设计库存类Inventory。该类包含一个protected ArrayList<Goods> inventory存放各种货物的信息。构造函数从文件Inventory.txt读取库存,存放于inventory中。类中还包含一个updateInventory的方法,来更新交易后的库存

3.设计交易类Transaction。该类派生自Inventory,包含4个私有属性

Vector<String[]> Output Vector<String[]> Receive   

Vector<String[]> Delete private Vector<String[]> Add

分别存放从文件中读取的4种交易的信息。

由构造函数从Transaction中读取交易信息,按照首字母存放到各自容器中。

函数 add、receive、output、delete分别用于处理各自容器中的交易信息。

函数handleTransaction用于实现交易功能。该函数按题目中交易顺序调用add、receive、output、delete 4个函数,并最后调用父类函数updateInventory来更新交易后的数据。

具体代码

注意,如果要参考(copy),代码下面的代码一定要看明白,注释中写了很多的提示信息

goods(货物)类

货物类中保存货物的各项信息

package inventory;

//货物的各种属性
public class Goods {
	private String Item_number;
	private int Quantity;
	private String Supplier;
	private String Description;

	public String getItem_number() {
		return Item_number;
	}

	public void setItem_number(String item_number) {
		Item_number = item_number;
	}

	public int getQuantity() {
		return Quantity;
	}

	public void setQuantity(int quantity) {
		Quantity = quantity;
	}

	public String getSupplier() {
		return Supplier;
	}

	public void setSupplier(String supplier) {
		Supplier = supplier;
	}

	public String getDescription() {
		return Description;
	}

	public void setDescription(String description) {
		Description = description;
	}

}

Inventory类

该类主要用于从文件中读取货物信息,保存到库存中

package inventory;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;



//库存信息
public class Inventory {

	protected ArrayList<Goods> inventory = new ArrayList<>();//子类也要用到,故为protected
	// 程序在单线程环境下运行,ArrayList是更好的选择,比Vector快。
	// 如果程序在多线程环境下运行,并且需要确保数据的线程安全性,那么Vector可能是更好的选择。

	public Inventory() {
		String line = null;// 暂存从文件中读取的每一段字符
		try {
			// 读取库存记录存入inventory中
			BufferedReader bfreader = new BufferedReader(new FileReader("Inventory.txt"));
			while ((line = bfreader.readLine()) != null) {
				// 使用正则表达式将一个长字符串分解为各个字符
				String[] str = line.split("[^a-zA-Z0-9,]+");
				Goods g1 = new Goods();
				g1.setItem_number(str[0]);// 第一项为货物编号
				g1.setQuantity(Integer.parseInt(str[1]));// 第二项为货物数量
				g1.setSupplier(str[2]);// 第三项为供应商
				g1.setDescription(str[3]);// 第四项为描述
				inventory.add(g1);// 添加到inventory中
			}
			bfreader.close();// 清空读取器中的缓冲区,用于下次读取

		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("Inventory.txt doesn't exist!");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}


	// 更新库存内容
	public void updataInventory() throws IOException {
		FileWriter writer = new FileWriter("NewInventory.txt");
		for (int i = 0; i < inventory.size(); i++) {
			//writer.write(String.format("%10s %10s %10s %20s\n", "Field1", "Field2", "Field3", "Field4"));
			//这样控制文字间隔
			writer.write(String.format("%10s %10s %10s %20s",
					inventory.get(i).getItem_number()+"\t",
					inventory.get(i).getQuantity()+"\t",
					inventory.get(i).getSupplier()+"\t",
					inventory.get(i).getDescription())+"\n");
					
		}
		writer.close();
	}


	// 显示出ArrayList中的内容
	public void showInventory() {
		for(Goods s:inventory) {
			System.out.println(s.getItem_number()+"\t"+s.getQuantity()+"\t"+s.getSupplier()+"\t"+s.getDescription());
		}
	}




}

Transaction类

处理题目要求的各种交易,主要的代码

package transactions;

import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Vector;

import inventory.Goods;
import inventory.Inventory;

public class Transaction extends Inventory {
	// O(发货订单) 123123(货物编号) 1000(交易货物数量) 9(客户编号)
	// R (到货单) 123123 1 (到货数量)
	// D (删除某种货物) 1234(删除的货物编号)
	// A(添加一种货物) 5(添加的新的货物编号) 4(新增货物数量) Thingy(新货物描述)
	// 第一个符号表示交易类型,其余是各种具体交易信息
	// 货物编号 客户编号、物品数量、货物描述 在父类(库存)中有

	// 存放多个字符串数组,每个字符串数组中存着各类交易信息
	private Vector<String[]> Output = new Vector<>();
	private Vector<String[]> Receive = new Vector<>();
	private Vector<String[]> Delete = new Vector<>();
	private Vector<String[]> Add = new Vector<>();

	// 构造函数用于从文件中读取各种交易信息
	public Transaction() throws IOException {
		String line = null;// 用于读取每一行
		FileReader reader = null;
		try {
			reader = new FileReader("Transactions.txt");
		} catch (FileNotFoundException e1) {
			System.out.println("Transactions Exists Error!");
			e1.printStackTrace();
		}

		BufferedReader bfreader = new BufferedReader(reader);

		while ((line = bfreader.readLine()) != null) {
			String[] parts = line.split("[^a-zA-Z0-9]+");
			switch (parts[0].charAt(0)) {
			case 'O':
				Output.add(parts);
				break;
			case 'R':
				Receive.add(parts);
				break;
			case 'D':
				Delete.add(parts);
				break;
			case 'A':
				Add.add(parts);
				break;
			}
		}
		reader.close();
		bfreader.close();// 清空读取器中的缓冲区,用于下次读取
		sort_output();// 对output进行排序
	}

	// 按照数量对output排序,使要输出的数量少的排在前面
	public void sort_output() {
		Output.sort(Comparator.comparing(output -> Integer.parseInt(output[2])));
	}

	// 处理交易信息
	public void handleTransaction() throws IOException {
		this.add();// 新增货物记录总是出现在第一个到货单之前。
		this.receive();// 在Transactions.txt中,优先处理到货单
		this.output();
		this.delete();// 删除操作总是在所有的事物处理之后才被处理
		super.updataInventory();// 更新库存
	}
	// 以'O'开头的事务表示这是一个发货订单,即某一种货物应该发给特定的客户。
	// Item number和Quantity的格式如上面表格定义。Custom编号和上面的Supplier编号一致。
	// 处理一条定单记录(以'O'开头的事务)意味着从减少库存记录中相应货物的数量(减少的数量=发货单中的数量),
	// 记录发货信息到Shipping.txt中。
	// 注意:Inventory.txt中的quantity不应该小于0,
	// 如果对于某一种货物,库存的数量小于发货单的数量的话,系统应该停止处理发货单,并记录出错信息到Errors.txt。
	// 如果对于某一种货物有多个发货单,而且库存总量小于这些发货单的总和的话,
	// 系统应该按照发货单中的数量从小到大的有限原则满足客户。
	// 也就是说,对于某一种货物如果一个数量Quantity少的发货单没有处理之前,数量Quantity多的发货单永远不会被处理。
	// (这种处理原则不受发货单记录在Transactions.txt的先后顺序影响)

	// O(发货订单) 123123(货物编号) 1000(交易货物数量) 9(客户编号)
	public void output() throws IOException {
		BufferedWriter errorwriter = new BufferedWriter(new FileWriter("Errors.txt"));
		BufferedWriter shopwriter = new BufferedWriter(new FileWriter("Shopping.txt"));

		int index = -1;// 存储库存中对应的要输出的货物的编号

		for (int i = 0; i < Output.size(); i++) {
			for (int j = 0; j < inventory.size(); j++) {
				if (Output.get(i)[1].equals(inventory.get(j).getItem_number())) {// 使输出的货物的编号与库存中的编号对应
					index = j;
				}
			}
			if (index == -1) {// 没有对应编号的元素
				errorwriter.write("库存中不存在编号为:" + Integer.parseInt(Output.get(i)[1]) + "不存在\n");
			} else {
				int nowQuantity = inventory.get(index).getQuantity() - Integer.parseInt(Output.get(i)[2]);// 计算实际数量
				if (nowQuantity < 0) {
					// ErrorWriter.write("编号为 " + Output.get(i)[1] + " 的商品库存不足" + Output.get(i)[2] +
					// "件,未发货至编号为 "
					// + Output.get(i)[3] + " 的客户!\n");
					errorwriter.write(Output.get(i)[3] + "\t" + Output.get(i)[1] + "\t" + Output.get(i)[2]);
				} else {
					inventory.get(index).setQuantity(nowQuantity);

					// 收货编号,货号,数量
					shopwriter.write(Output.get(i)[3] + "\t" + Output.get(i)[1] + "\t" + Output.get(i)[2] + "\n");
//					shopwriter.write(
//							"编号为 " + Integer.parseInt(Output.get(i)[1]) + " 的商品 " + Integer.parseInt(Output.get(i)[2])
//									+ " 件已发货至编号为 " + Integer.parseInt(Output.get(i)[3]) + " 的客户\n");
				}
			}
		}
		shopwriter.close();
		errorwriter.close();
		cmbItem_number();//将这相同的两条发货信息合并

	}

	void cmbItem_number() throws IOException {

		BufferedReader reader = new BufferedReader(new FileReader("Shopping.txt"));
		ArrayList<String[]> shop = new ArrayList<>();
		// 收货编号,货号,数量
		String line;
		while ((line = reader.readLine()) != null) {
			String[] arr = line.split("\t");
			shop.add(arr);
		}
		reader.close();
		// int indexs[]=new int[shop.size()];
		for (int i = 0; i < shop.size(); i++) {
		    for (int j = i + 1; j < shop.size(); j++) {
		        if (shop.get(i)[1].equals(shop.get(j)[1])) {
		            shop.get(i)[2] = String.valueOf(Integer.parseInt(shop.get(i)[2])+Integer.parseInt(shop.get(j)[2]));
		            shop.remove(j);
		            j--;
		        }
		    }
		}

		BufferedWriter writer = new BufferedWriter(new FileWriter("Shopping.txt"));
		for (String arr[] : shop) {
			writer.write(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\n");
		}

		writer.close();

	}

	// R (到货单) 123123 1 (到货数量)
	// 以'R'开头的事务表示这是一个到货单记录,
	// 在'R'后面是Item number和它的数量Quanlity。
	// 处理一条到货单意味着增加库存中相应货物的数量(增加的数量=到货单中的数量)。
	// 注意:如果在Transactions.txt文件中,到货单出现在发货单之后,到货单中的货物数量可以用来填补发货单中的数量
	// (可以理解成在Transactions.txt中,优先处理到货单)。
	public void receive() throws IOException {
		for (int i = 0; i < Receive.size(); i++) {
			int index = -1;// 存储库存中对应的要输出的货物的编号
			for (int j = 0; j < inventory.size(); j++) {
				if (Receive.get(i)[1].equals(inventory.get(j).getItem_number())) {// 使输出的货物的编号与库存中的编号对应
					index = j;
				}
			}
			if (index == -1) {
				FileWriter writer = new FileWriter("Errors.txt", true);
				writer.write("编号为" + Receive.get(i)[1] + "的货物不存在,请先添加这种货物");
				writer.close();
			} else {
				inventory.get(index)
						.setQuantity(inventory.get(index).getQuantity() + Integer.parseInt(Receive.get(i)[2]));

			}
		}
	}

	// 以'A'开头的事务表示向库存中增加一种新的货物(即这种货物以前库存中没有)
	// 在'A'后面是Item number,供应商supplier以及货物的描述description。
	// 处理一个新增货物记录意味着向库存中增加一个数量Quantity为0的新的Item。
	// 你可以假设在一个Transactions.txt中,新增货物记录总是出现在第一个到货单之前。
	public void add() {
		if (Add.isEmpty())
			return;// 没有要添加的直接返回
		for (int i = 0; i < Add.size(); i++) {
			int index = 0;
			for (int j = 0; j < inventory.size(); j++) {
				// 寻找合适的位置加入
				if (Integer.parseInt(inventory.get(j).getItem_number()) > Integer.parseInt(Add.get(i)[1])) {
					index = j;
					break;
				}
			}
			Goods g = new Goods();
			g.setItem_number(Add.get(i)[1]);
			g.setQuantity(0);
			g.setSupplier(Add.get(i)[2]);
			g.setDescription(Add.get(i)[3]);
			inventory.add(index, g);
		}
	}

	// D (删除某种货物) 1234(删除的货物编号)
	// 以'D'开头的事务表示从库存中删除一种货物,在'D'后面是Item号。
	// 删除操作总是在所有的事物处理之后才被处理,以保证对于可能出现的同一种货物的发货单的操作能在删除之前被正确处理。
	// 如果要删除的某种货物的库存量Quantity不为0的话,系统应该向Errors.txt记录出错信息。
	public void delete() throws IOException {
		FileWriter errorWriter = new FileWriter("Errors.txt", true);// 不清除原有的
		for (int i = 0; i < Delete.size(); i++) {
			int index = -1;
			for (int j = 0; j < inventory.size(); j++) {// 查找要删除的编号的下标
				if (Delete.get(i)[1].equals(inventory.get(j).getItem_number())) {
					index = j;
				}
			}
			if (index == -1) {
				errorWriter.write("要删除的编号为 " + Delete.get(i)[1] + " 的货物不存在!\n");
				continue;
			} else if (inventory.get(index).getQuantity() == 0) {
				inventory.remove(index);
			} else {
				errorWriter.write("要删除的编号为" + Delete.get(index)[1] + "的货物库存不为0!\n");
			}

		}
		errorWriter.close();
	}


}

主类

这个不必借鉴,根据自己的需要写

package inventory;

import java.io.IOException;

import transactions.Transaction;

public class Main {

	public static void main(String[] args) throws IOException {
       Transaction T=new Transaction();
       System.out.println("交易前的库存为:");
       T.showInventory();
       T.handleTransaction();
       System.out.println("交易后的库存为:");
       T.showInventory();
	}

}

测试数据及结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC源码分析:SpringMVC九大组件分析(三)

一、概述 SpringMVC九大组件如下图&#xff0c;我将一个个进行介绍。各个组件使用的入口DispatcherServlet.doDispatch是各个组件使用的入口&#xff0c;我们大部分代码都是从这里开始进入的。 二、MultipartResolver 下面是MultipartResolver组件具体的使用流程&#xff0c;…

【UE打包apk过程遇到的报错】

教程遇到的问题UE5 打包android提示 sdk未设置解决方案 UE5打包apk 报错 ERROR: cmd.exe failed with args :app:assembleDebug解决方案 我在打包的时候&#xff0c;日志中的报错信息如下&#xff08;每个人的报错信息可能不一样&#xff0c;根据报错日志找对应的解决方案&…

扼流圈天线是如何解决RTK的误差源

扼流圈天线是一种用于GPS定位的天线&#xff0c;它将电流流过一圈线圈来产生电磁场&#xff0c;这个电磁场可以用来接收卫星信号。扼流圈天线的优势在于它可以有效地减少多径干扰和多路传播所造成的误差&#xff0c;从而提高定位精度。 对于RTK定位来说&#xff0c;扼流圈天线可…

__LINE__打印出来的值与source insight不一致

一个project里面有几百个文件&#xff0c;有些&#xff0c;__LINE__ 和pc上看到的值总是不一致 在这个函数前重新定义一下line

h5调用微信支付报错,商家存在未配置的参数,请联系商家解决

报错&#xff1a; 商家存在未配置的参数&#xff0c;请联系商家解决 原因&#xff1a; 发起微信支付的域名和项目域名不一致 确认原因&#xff1a; 发起微信支付的域名是需要在微信支付平台&#xff08;微信商户&#xff09;进行h5域名的添加配置 项目的域名是 发送请求的…

VS code使用及插件(python、vue)

VS code使用及插件&#xff08;python、vue&#xff09; 说明一、下载及安装二、vs code 常规设置三、 pyhton插件四、 vue相关插件 说明 本教程主要内宅vs code使用及vue、python插件vs code 常规设置pyhton插件vue相关插件 一、下载及安装 二、vs code 常规设置 注&#…

vscode配置nodejs

文章目录 前言Nodejs在vscode中的配置1、扩展插件Code RunnerJavaScript(ES6) code snippetLive Server 2、创建配置文件3、调整配置文件内容 前言 npm ERR! enoent This is related to npm not being able to find a file. ‘vue-cli-service’ 不是内部或外部命令&#xff…

内网安全:域内信息收集

目录 环境搭建 域基础知识 工作组和域 现实背景 常规信息收集 方式一&#xff1a;操作系统命令执行 常用总结 方式二&#xff1a;使用CS插件 关键信息收集 密码抓取测试 自动化信息收集工具 ADFind BloodHound域分析使用(渗透流程信息) 从今天开始&#xff0c;将…

第七章 文件和数据格式化

文章目录 第七章 文件和数据格式化7.1 文件的使用7.1.1 文件的类型7.1.2 文件的打开和关闭7.1.3 文件的读写 7.2 数据组织的维度7.2.1 一维数据7.2.2 二维数据7.2.3 高维数据 7.3 一维数据的处理7.3.1 一维数据的表示7.3.2 一维数据的存储7.3.3 一维数据的处理 7.4 二维数据的处…

VS2019 WPF制作OTA上位机(四)串口收发数据

首先说一下&#xff0c;这个上位机是模拟服务器对嵌入式设备发起通信进行OTA升级。如下图所示 上位机发送过程&#xff1a;服务器将数据发送到云端&#xff0c;云端是通信模块的&#xff0c;比如移动/电信的云平台&#xff0c;云端将数据传给通信模块&#xff0c;比如NB模块&a…

【PCIE701】基于PCIE总线架构的高性能数据预处理平台

板卡概述 PCIE701是北京青翼科技的一款基于PCI Express总线架构的高性能数据预处理FMC载板&#xff0c;板卡具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;1个X8 PCIe主机接口&#xff0c;板卡采用Xilinx的高性能Kintex-7系列FPGA作为实时处理器&#xff0c;实现…

知识付费小程序搭建 为有价值的知识买单

以前我们学习写作遇到难题的时候&#xff0c;总喜欢上网搜一下参考资料&#xff0c;但是不知具体从何时起&#xff0c;很多平台内容查看都要钱了。这说明知识付费已经深入到我们的生活中了。再加上疫情爆发这几年&#xff0c;很多教育培训机构都抓住风口&#xff0c;开发了线上…

知乎运营分析平台 — 舰桥平台如何通过 Apache Doris 实现查询速度 10+ 倍提升?

导读&#xff1a;知乎为实现精细化运营&#xff0c;提高运营效率&#xff0c;依赖 Apache Doris 构建了内部统一的运营分析平台——舰桥平台&#xff0c;主要应用于事实接入层、事实建模层和事实运算层等架构核心层的建设&#xff0c;并持续对导入、查询等方面进行性能调优&…

5. 缓存

5. 缓存 5.1.缓存-缓存介绍 MyBatis官方文档 MyBatis 包含一个非常强大的查询缓存特性&#xff0c;它可以非常方便地配置和定制。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存&#xff0c;一级缓存和二级缓存。 默认情况下&#xff0c;只有一级缓存&…

FSV40罗德与施瓦茨频谱分析仪

R&S FSV40 是一款多功能信号和频谱分析仪&#xff0c;适用于从事射频系统开发、生产、安装和服务工作的用户。 R&S FSV40 是适用于所有通用测量任务的理想仪器——在工作台上、在生产中和在现场。它为最新的蜂窝和无线标准提供数字调制分析&#xff0c;分析带宽高达 16…

科技驱动进化:群硕为企业定制“数字人”,追赶元宇宙时代步伐

你还记得这张图吗&#xff1f; 千万年前&#xff0c;一颗巨型陨石降落地球&#xff0c;爬行动物的黄金时代结束&#xff0c;哺乳动物加速进化&#xff0c;智人成为几十亿人类共同的祖先。 千万年后的今天&#xff0c;在掌握了数字技术以后&#xff0c;人类创造出了一种世界上…

Python学习39:维吉尼亚密码——加密

描述‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 凯撒密码的加密强度是很低的&…

项目管理中的有效沟通指南:掌握技巧提高沟通效率

良好的团队沟通是项目成功的关键&#xff0c;在项目管理过程中&#xff0c;高效的团队沟通可以享受一系列增强团队合作的好处。那么如何进行有效的团队沟通呢&#xff1f; 1.选择正确的沟通方式 在项目管理中&#xff0c;要注意双向沟通&#xff0c;正确运用文字沟通。双向沟通…

【OpenCV DNN】Flask 视频监控目标检测教程 05

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 05 3.5 浏览器播放视频服务器上的视频文件cvFlask05 项目文件树cvFlask05 项目程序文件cvFlask05 项目网页模版cvFlask05 项目运行 3.6 浏览器播放视频文件控制按钮cvFla…

Camtasia Studio2023中文版下载安装图文教程

Camtasia Studio是TechSmith旗下的一套专业屏幕录像软件&#xff0c;同时包含Camtasia 录像器、Camtasia Studio&#xff08;编辑器&#xff09;、Camtasia 菜单制作器、Camtasia 剧场、Camtasia 播放器和Screencast的内置功能。在这里我亲测安装了Camtasia2023版本&#xff0c…