目录

  • 1、 程序的流程控制说明
  • 2、顺序控制的说明
  • 3、分支控制if-else
    • 3.1、分支控制if-else介绍
    • 3.2、单分支的使用
    • 3.3、双分支的使用
    • 3.4、单分支双分支练习题
    • 3.5、单分支和双分支课后题
    • 3.6 多分支
    • 3.7、分支控制if-else 注意事项
  • 4、嵌套分支
    • 4.1、基本介绍
    • 4.2、基本语法
    • 4.3、应用案例
  • 5、Switch分支结构
  • 6、for循环控制
    • 6.1、基本介绍
    • 6.2、范围数据循环方式1
    • 6.3、范围数据循环方式2
    • 6.4、循环守卫
    • 6.5、引入变量
    • 6.6、嵌套循环
    • 6.7、循环返回值
    • 6.8、使用{}代替()
    • 6.9、注意事项和细节说明
    • 6.10、for循环练习题
  • 7、While循环控制
    • 7.1、基本语法
    • 7.2、While循环应用实例
    • 7.3、注意事项和细节说明
    • 7.4、练习题
  • 8、do-While循环控制
    • 8.1、基本语法
    • 8.2、do-while循环应用实例
    • 8.3、注意事项和细节说明
    • 8.4、练习题
  • 9、多重循环控制
    • 9.1、介绍:
    • 9.2、应用实例
  • 10、While循环的中断
  • 11、练习题

1、 程序的流程控制说明

在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。
1、顺序控制
2、分支控制
3、循环控制

2、顺序控制的说明

程序从上到下逐行地执行,中间没有任何判断和跳转

Scala中定义变量时采用合法的前向引用。如:
def main(args : Array[String]) : Unit = {var num1 = 12var num2 = num1 + 2
}
错误形式:
def main(args : Array[String]) : Unit = {var num2 = num1 + 2var num1 = 12
}

3、分支控制if-else

3.1、分支控制if-else介绍

让程序有选择的的执行,分支控制有三种:

1、单分支
2、双分支
3、多分支

3.2、单分支的使用

基本语法
if (条件表达式) {
执行代码块
}
说明:当条件表达式为ture 时,就会执行 { } 的代码
案例说明:
编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出 “age > 18”

val age = 20
if (age > 18) {println("age > 18")
}

单分支对应的流程图:

3.3、双分支的使用

基本语法
if (条件表达式) {
执行代码块1
} else {
执行代码块2
}
说明:当条件表达式成立,即执行代码块1,否则执行代码块2.
案例说明:
编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出 “age >18”。否则 ,输出 "age <= 18 "

val age = StdIn.readInt()
if (age > 18) {println("age > 18")
}else{println("age <= 18")
}

双分支对应的流程图:

3.4、单分支双分支练习题

  1. 对下列代码,若有输出,指出输出结果。
var x = 4
var y = 1
if (x > 2) {if (y > 2) {println(x + y)}println("teacher")  // 输出内容 teacher
} elseprintln("x is " + x)

3.5、单分支和双分支课后题

1、编写程序,声明2个Int型变量并赋值。判断两数之和,如果大于等于50,打印“hello world!”

val a:Int = 11
val b:Int = 40
if ((a+b)>50) println("hello world!")

2、编写程序,声明2个Double型变量并赋值。判断第一个数大于10.0,且第2个数小于20.0,打印两数之和。

val a = 11.0
val b = 10.0
if (a > 10.0 && b < 20.0) {println(a + b)
} else {println("条件不满足")
}

3、【选作】定义两个变量Int,判断二者的和,是否既能被3又能被5整除,打印提示信息

val num1 = 10
val num2 = 2
val sum = num1 + num2
if (sum % 3 == 0 && sum % 5 == 0) {println("能被3又能被5整除")
} else {println("能被3又能被5整除,不成立~")
}

4、判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被4整除,但不能被100整除;(2)能被400整除

val year = 2020
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {println(s"${year} 是闰年...")
}else{println(s"${year} 不是闰年...")
}

3.6 多分支

基本语法
if (条件表达式1) {
执行代码块1
}
else if (条件表达式2) {
执行代码块2
}
……
else {
执行代码块n
}
多分支的流程图:

案例演示:
岳小鹏参加scala考试,他和父亲岳不群达成承诺:
如果:
成绩为100分时,奖励一辆BMW;
成绩为(80,99]时,奖励一台iphone7plus;
当成绩为[60,80]时,奖励一个 iPad;
其它时,什么奖励也没有。

说明: 成绩在控制台输入!

println("请输入成绩:")
val score = StdIn.readDouble()
if (score == 100) {println(" 成绩为100,奖励一台BMW")
} else if (score > 80 && score <= 99) { // 写法1 使用范围 , 写法2 就是严格的判断println("成绩为{80,99},奖励一台iPhone 11")
} else if (score >= 60 && score <= 80) {println("成绩为{60,80}时,奖励一个Ipad")
} else {println("什么奖励也没有")
}

案例演示2:
求ax2+bx+c=0方程的根。a,b,c分别为函数的参数,如果:b2-4ac>0,则有两个解;
b2-4ac=0,则有一个解;b2-4ac<0,则无解; [a=3 b=100 c=6]
提示1:x1=(-b+sqrt(b2-4ac))/2a
X2=(-b-sqrt(b2-4ac))/2a

提示2:sqrt(num) 在 scala 包中(默认引入的) 的math 的包对象有很多方法直接可用.

val a = 3
val b = 100
val c = 6
val m = b * b - 4 * a * c
var x1 = 0.0
var x2 = 0.0
if (m > 0) {x1 = (-b + sqrt(m)) / 2 * ax2 = (-b - sqrt(m)) / 2 * aprintln(s"方程有两个解,分别是x1=${x1.formatted("%.2f")},x2=${x2.formatted("%.2f")}")
} else if (m == 0) {x1 = (-b + sqrt(m)) / 2 * aprintln("方程有两个解,分别是x1=$x1")
} else {println("方程无解")
}

3.7、分支控制if-else 注意事项

1、如果大括号{}内的逻辑代码只有一行,大括号可以省略, 这点和java 的规定一样。
2、Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容.[案例演示] 既返回Unit ()
3、Scala中是没有三元运算符,因为可以这样简写

val result = if (flg) 1 else 0  // 因为 scala 的if-else 是有返回值的,因此,本身这个语言也不需要三元运算符了(如图),并且可以写在同一行,类似 三元运算

4、看下面案例,判断输出什么

object Hello01 {def main(args: Array[String]): Unit = {var sumVal = 9
val result =
if(sumVal > 20){"结果大于20"}
println(result) // Unit ()

4、嵌套分支

4.1、基本介绍

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。嵌套分支不要超过3层

4.2、基本语法

if(){if(){}else{}
}

4.3、应用案例

1、参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。输入成绩和性别,进行判断。

object Exercise04 {def main(args: Array[String]): Unit = {/*参加百米运动会,如果用时8秒进入决赛,否知提示淘汰,并且根据性别提示进入男子组或女子组,[可以让学员先练习一下5min],输入成绩和性别,进行判断*/println("请输入运动员的成绩:")val speed = StdIn.readDouble()if (speed <= 8){println("请输入你的性别:")val gender = StdIn.readChar()if (gender == '男'){println("进入男子组")}else{println("进入女子组")}}else{println("你被淘汰了....")}}
}

2、出票系统:根据淡旺季的月份和年龄,打印票价
4_10 旺季:
成人(18-60):60
儿童(<18):半价
老人(>60):1/3

淡季:
成人:40
其他:20

object Exercise05 {def main(args: Array[String]): Unit = {println("输入月份:")val month = StdIn.readInt()println("输入年龄:")val age = StdIn.readInt()val tikcet = 60if (month >= 4 && month <= 10) {if (age > 18 && age <= 60) {println("你的票价是:" + tikcet)} else if (age < 18) {println("你的票价是:" + tikcet / 2)} else {println("你的票价是:" + tikcet / 3)}} else {if (age > 18 && age <= 60) {println("你的票价为:" + 40)} else {println("你的票价为:" + 20)}}}
}

5、Switch分支结构

在scala中没有switch,而是使用模式匹配来处理。
模式匹配涉及到的知识点较为综合,因此我们放在后面讲解。
match-case

6、for循环控制

6.1、基本介绍

Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的特性被称为for 推导式(for comprehension)或for 表达式(for expression)

6.2、范围数据循环方式1

基本案例
for(i <- 1 to 3){
print(i + " ")
}
println()
说明
1、i 表示循环的变量, <- 规定好 to 规定
2、i 将会从 1-3 循环, 前后闭合

6.3、范围数据循环方式2

基本案例
for(i <- 1 until 3) {
print(i + " ")
}
println()
说明:
1、这种方式和前面的区别在于 i 是从1 到 3-1
2、**前闭合后开的范围,**和java的arr.length() 类似
for (int i = 0; i < arr.lenght; i++){}

6.4、循环守卫

基本案例
for(i <- 1 to 3 if i != 2) {
print(i + " ")
}
println()
基本案例说明
1、循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue
2、上面的代码等价
for (i <- 1 to 3) {
if (i != 2) {
println(i+"")
}
}

6.5、引入变量

基本案例
for(i <- 1 to 3; j = 4 - i) {
print(j + " ")
}
对基本案例说明
1、没有关键字,所以范围后一定要加;来隔断逻辑
2、上面的代码等价
for ( i <- 1 to 3)
{
val j = 4 –i
print(j+"")
}

6.6、嵌套循环

基本案例
for(i <- 1 to 3; j <- 1 to 3) {
println(" i =" + i + " j = " + j)
}
对基本案例说明
1、没有关键字,所以范围后一定要加;来隔断逻辑
2、上面的代码等价
for ( i <- 1 to 3) {
for ( j <- 1to 3){
println(i + " " + j + " ")
}
}

6.7、循环返回值

基本案例
val res = for(i <- 1 to 10) yield i
println(res)

1、将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字

6.8、使用{}代替()

基本案例
for(i <- 1 to 3; j = i * 2) {
println(" i= " + i + " j= " + j)
}
可以写成
for{
i <- 1 to 3
j = i * 2} {
println(" i= " + i + " j= " + j)
}
对基本案例说明
1、{}和()对于for表达式来说都可以
2、for 推导式有一个不成文的约定:当for 推导式仅包含单一表达式时使用圆括号,当其包含多个表达式时使用大括号
3、当使用{} 来换行写表达式时,分号就不用写了

6.9、注意事项和细节说明

1、scala 的for循环形式和java是较大差异,这点请同学们注意,但是基本的原理还是一样的。
2、scala 的for循环的步长如何控制! [for(i <- Range(1,3,2)]
3、思考题:如何使用循环守卫控制步长

for (i <- 1 to 10) {println("i=" + i)
}// 步长控制为2
println("····························")
// Range(1,10,2)对应的构建方法是
//   def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
for (i <- Range(1, 10, 2)) {println("i=" + i)
}// 控制步长的第二种方式->for循环守卫
println("····························")
for (i <- 1 to 10 if i % 2 == 1) {println("i=" + i)
}

6.10、for循环练习题

1、打印1~100之间所有是9的倍数的整数的个数及总和.
2、完成下面的表达式输出

/*
1、打印1~100 之间所有是9的倍数的整数的个数及总和*/
val start = 1
val end = 100
var count = 0
var sum = 0
for (i <- start to end){if (i%9==0){count += 1sum += i}
}
printf("count=%d,sum=%d\n",count,sum)/*2、输出加法的循环表达式*/
val num = 6
for (i<- 0 to num){printf("%d + %d = %d",i,(num-i),num)println()
}

7、While循环控制

7.1、基本语法

循环变量初始化
while (循环条件) {
循环体(语句)
循环变量迭代
}

7.2、While循环应用实例

1、输出10句"Hello,world"

var i = 0
while (i < 10) {println(i + "、" + "Hello,world")// 循环遍历迭代i += 1
}

7.3、注意事项和细节说明

1、循环条件是返回一个布尔值的表达式
2、while循环是先判断再执行语句
3、与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型的()
4、因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在while循环的外部,那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环

7.4、练习题

1、打印1—100之间所有能被3整除的数

var i = 1
while (i < 101) {if (i % 3 == 0) {println("i=" + i)}i += 1
}

2、打印40—200之间所有的偶数

var b = 40
while (b < 201) {if (b % 2 == 0) {println("b=" + b)}b += 1
}

8、do-While循环控制

8.1、基本语法

8.2、do-while循环应用实例

输出10 “hello,world”

var i = 1
do {println(i+"、"+"Hello,world")i += 1
} while (i < 11)

8.3、注意事项和细节说明

1、循环条件是返回一个布尔值的表达式
2、do…while循环是先执行,再判断
3、和while 一样,因为do…while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在do…while循环的外部,那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环

8.4、练习题

1、计算1—100的和

var i = 1var sum = 0do {sum += ii += 1} while (i < 101)printf("1-100的和=%d", sum)

2、统计1——200之间能被5整除但不能被3整除的个数

  var d = 1var count = 0do {if (d % 5 == 0 && d % 3 != 0) {count += 1}d += 1} while (d < 201)println("统计1-200之间能被5整除但不能被3整除的个数=" + count)

9、多重循环控制

9.1、介绍:

1、将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过3层】
2、实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。
3、设外层循环次数为m次,内层为n次, 则内层循环体实际上需要执行m*n=mn次。

9.2、应用实例

1、统计三个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。

  println("班级个数:")val classNum = 3val stuNum = 5var score = 0.0 // 分数var classScore = 0.0 // 班级的总分var totalScore = 0.0 // 所有班级的总分for (i <- 1 to classNum) {// 先将classScore ,清0classScore = 0.0for (j <- 1 to stuNum) {printf("请输入第%d的班级的第%d学生的成绩:\n", i, j)score = StdIn.readDouble()classScore += score}// 累计总分 totalScoretotalScore += classScoreprintf("第%d班级的平均分为%.2f\n", i, classScore / stuNum)}printf("所有班级的平均分为%.2f\n",totalScore/(stuNum*classNum))

2、统计三个班及格人数,每个班有5名同学。

def main(args: Array[String]): Unit = {println("班级个数:")val classNum = 3val stuNum = 5var score = 0.0 // 分数var classScore = 0.0 // 班级的总分var totalScore = 0.0 // 所有班级的总分var passNum = 0 // 统计及格人数for (i <- 1 to classNum) {// 先将classScore ,清0classScore = 0.0for (j <- 1 to stuNum) {printf("请输入第%d的班级的第%d学生的成绩:\n", i, j)score = StdIn.readDouble()if (score>=60){passNum+=1}classScore += score}// 累计总分 totalScoretotalScore += classScoreprintf("第%d班级的平均分为%.2f\n", i, classScore / stuNum)}printf("所有班级的平均分为%.2f\n", totalScore / (stuNum * classNum))printf("所有班级的及格人数为%d\n",passNum)

3、打印出九九乘法表

val num = 9
for (i <- 1 to num){ // 确定行数for (j<- 1 to i ){ //确定列数printf("%d * %d = %d\t",j,i,i*j)}println()
}

10、While循环的中断

Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数化编程,推荐使用函数式的风格解决break和contine的功能,而不是一个关键字。
break案例演示:

import util.control.Breaks._
// breakable()函数
// 说明
// 1、breakable是一个高阶函数:可以接受函数的函数就是高阶函数(后面详讲)
// 2、def breakable(op: => Unit) {//    try {//      op
//    } catch {//      case ex: BreakControl =>
//        if (ex ne breakException) throw ex
//    }
//  }
// (1) op: => Unit 表示接收的参数是一个没有输入,也没有返回值的函数
// (2) 既可以简单理解可以接受一段代码块
// 3 breakable 对break()抛出的异常做了处理,代码就可以继续执行
// 4 当我们传入的是代码块,scala程序会会将()改为{}
var n = 1
breakable{while (n <= 20) {n += 1println("n=" + n)if (n == 18) {// 中端while// 说明// 1、在Scala中使用函数式的break函数中端循环//  def break(): Nothing = { throw breakException }break()}}
}
println("ok~~~")
// 注意break函数,也可以使用在for或者do..while
breakable {for (i <- 1 to 100) {println("i="+i)if (i == 20) {break()}}
}
println("ok2········")

如何实现continue的效果
Scala内置控制结构特地也去掉了continue,是为了更好的适应函数化编程,可以使用if – else 或是 循环守卫实现continue的效果

continue案例演示:

// 说明
// 1. 1 to 10
// 2. 循环守卫 if (i != 2 && i != 3) 这个条件为真才执行循环体
//    即当i = 2 或 i = 3 时,就跳过
for (i <- 1 to 10 if (i != 2 && i != 3)) {println("i=" + i)
}// 也可以写成如下形式
println("···························")
for (i <- 1 to 10) {if (i != 2 && i != 3) {println("i=" + i)}
}

11、练习题

课后练习题:

1、100以内的数求和,求出当和 第一次大于20的当前数【for】

var sum = 0
breakable {for (i <- 1 to 100) {sum += iif (sum > 20) {println("和第一次大于20的当前数:" + s"第${i}次" + sum)break()}}
}
// 除了上面break机制来中端,我们也可以使用循环守卫实现中断
println("·····································")
var loop = true
var sum2 = 0
for (i <- 1 to 100 if loop == true) {sum2 += iif (sum2 > 20) {println("和第一次大于20的当前数:" + s"第${i}次" + sum2)loop = false}println("i=" + i)
}

2、实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,否则提示还有几次机会,请使用for 循环完成

var c = 3
val name = "张无忌"
val password = 888
var Stdname = ""
var Stdpassword = 0
var count = 3
breakable {for (i <- 1 to 3) {println("请输入用户名:")Stdname = StdIn.readLine()println("请输入密码:")Stdpassword = StdIn.readInt()if (Stdname == name && Stdpassword == password) {println("登录成功")break()} else {count -= 1println("登录失败")println(s"机会还有${count}次")}}
}
  1. 某人有100,000元,每经过一次路口,需要交费,规则如下:
    当现金>50000时,每次交5%
    当现金<=50000时,每次交1000
    编程计算该人可以经过多少次路口
var money: Double = 100000
var count = 0
while (money > 50000) {if (money > 50000) {money = money * 0.95count += 1}else{money = money - 1000count += 1}
}
println("该人可以经过多少次路口:"+count)

四、Scala从入门到精通一一循环控制相关推荐

  1. 六、Scala从入门到精通一一面对对象编程(初级)

    目录 6.面向对象编程 6.1.类与对象 6.1.1.Scala语言是面向对象的 6.1.2.快速入门-面向对象的方式解决养猫问题 6.1.3.类与对象的区别和联系 6.1.4.如何定义类 6.1.5 ...

  2. 八、Scala从入门到精通一一面向对象编程(高级特性)

    目录 8.1.静态属性和静态方法 8.1.1.静态属性-提出问题 8.1.2.基本介绍 8.1.3.伴生对象的快速入门 8.1.4.伴生对象的小结 8.1.5.最佳实践-使用伴生对象完成小孩玩游戏 8 ...

  3. Scala从入门到精通

    第一章 1. scala简介 scalable language,运行在jvm上,面向对象和面向函数式编程. 兼容java,可以访问庞大的java类库 2. scala与java对比 执行流程 3. ...

  4. C4D致富经典入门到精通(四)

    C4D中的Nurbs建模 C4D基础界面的介绍与常用快捷键:  C4D致富经典入门到精通(一) C4D父子关系的理解与创建参数几何体与可编辑对象: C4D致富经典入门到精通(二) C4D样条曲线创建  ...

  5. CUDA从入门到精通(四):加深对设备的认识

    CUDA从入门到精通(四):加深对设备的认识 2013-07-23 13:17 4211人阅读 评论(2) 收藏 举报  分类: GPU(29)  版权声明:本文为卜居原创文章,未经博主允许不得转载. ...

  6. GPU 编程入门到精通(四)之 GPU 程序优化

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 博主由于工作当中的需要,开始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GP ...

  7. EOS从入门到精通(四)

    大家好,非常感谢参加<EOS从入门到精通>系列课程,我是王巨,今天是EOS技术白皮书解读的第四讲.我们来解读EOS白皮书的最后几部分.今天的内容相对于上一节课会简单一些,主要讲EOS的治理 ...

  8. c语言从入门到精通第四版电子书_C语言从入门到精通(吐血分享)4.pdf

    C语言从入门到精通(吐血分享)4 成功! 结构体.链表.文件 数组.字符串 函数.指针 三种结构化程序设计 三种数据类型.六大表达式 一.简单的程序 #include 数学函数 命令行 main() ...

  9. 副本与ISR设计--Kafka从入门到精通(十四)

    上篇文章说了,broker的消息设计,采用紧凑的byteBuffer,存储设计主要包含attribute后三个表示压缩类型,还有crc效验,以及key和value,后面新增了时间戳. Broker消息 ...

最新文章

  1. atitit.php中的dwr 设计模式
  2. CentOS系统环境下安装MongoDB
  3. python hash
  4. 转行,转向哪里?电子工程师!!!
  5. sinh_带有Python示例的math.sinh()方法
  6. excel营销数据分析宝典 pdf_你见过最漂亮的 Excel 表格什么样?
  7. Linux基础学习十:Linux的权限管理
  8. 产生10个1-100的随机数,并放到一个数组中, 把数组中大于等于10的数字放到一个list集合中,并打印到控制台。
  9. c#与获得文件夹路径,站点目录
  10. 求数组中每个数字第一次出现的位置
  11. Asp.net mvc中Controller的返回值
  12. 7-2 求交错序列前N项和 (10 分)
  13. 酒与茶--网友-心香一束著
  14. PlantCV中文文档
  15. linux tuxedo查看服务进程数,tuxedo管理命令之tmboot与tmshutdown
  16. 生命的节日,散文一篇
  17. 中国移动启动2017年交直流列头柜集采:3个标段约8841台
  18. C++ 内存管理 —— 第一講:C++ 內存構件
  19. 将java对象存储到redis数据库(两种实现方式)
  20. xUtils3.x的网络请求封装和请求https之单向SSL验证

热门文章

  1. ubuntu如何设置默认程序打开方式
  2. FreeBSD使用CVSup升级Ports,让它涣然一新
  3. 使python脚本在运行时可以附带参数的方法
  4. 通过fork来剖析Linux内核的内存管理和进程管理(下)
  5. 400万像素摄像头,你还在用百兆交换机吗?
  6. 洛谷2530(codevs2098)化工厂装箱员
  7. python str和repr的区别_python的str()和repr()的区别
  8. 编程15年40岁程序员的我终于在压力下被迫转行了
  9. Python 办公自动化:全网最强最详细 PDF 文件操作手册!
  10. [Matlab] 论文画图技巧:预测曲线图