计算机基础

文章目录

计算机基础

​ 作者:xingzhe

​ 笔名:浮生渡己

一、计算工具与计算思维
1.1、计算工具的历史
1.2、计算思维的概述
  • 计算思维的特性:

    • 概念化,不是程序化
    • 基础的,不是机械的技能
    • 人的,不是计算机的思维
  • 能力目标:

    • 从现实问题中抽取必要的细节。
    • 以计算机能理解的方式描述问题。
    • 自动化地实施问题求解的过程。
  • 计算思维的表达体系

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 计算思维的本质

    • 抽象
    • 自动化
1.3、计算的自动化
1.3.1、从算盘开始

  • 完成计算的关键环节

    • 意识记录下参与运算的
    • 二是应用完成计算的规则
  • 起源于中国,迄今为止已有2600的历史,是中国古代的一项重要发明。

  • 算盘是一种手动工具。

1.3.2、帕斯卡加法器
  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
1.3.3、“可编程”的织布机和八音盒

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 巴贝奇“自动计算”的思想(程序控制和可编程的思想雏形)

    • 必须把计算步骤和原始数据预先地存在机器内。
    • 计算机能取出这些数据,在必要时能做一些简单的判断,决定自己下一步的计算顺序 。
  • 巴贝奇的分析机

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • “计算程序化”的思想

    • 为分析机“编织”计算的方式同杰卡德为织布机编织图案的方式完全一样。
1.3.4、“自动化”思想的内涵
  • 计算过程的关键要素:
    • 原始的数据。
    • 求解问题的计算步骤。
  • 计算自动化本质:计算工具能够按照预先设定的计算步骤,去处理相关的数据,从而得到预期的结果。
  • 算法:求解问题的计算步骤或方法。
  • 程序:用计算机可以理解的语言来描述算法。
  • 计算思维的能力目标:
    • 从实现问题中抽取必要的细节。
    • 以计算机能够理解的方式描述问题
    • 自动化的实施问题求解的过程
1.4、计算的抽象
1.4.1什么是抽象
  • 抽象:

    • 忽略一个主题中与当前问题(或目标)无关的那些放面,以便更充分地注意与当前问题(或目标)有关的方面。
    • 一种从个体把握一般、从现象把握本质的认知过程和思维方法。
  • 抽象过程的准心:

    • 问题本身
    • 要达成的目标
  • “抽象”认知的过程:

    • 清晰的描述问题。

    • 针对目标移除细节来突出主干。

    • 给出求解问题的方法和步骤。

      1.4.2、计算的抽象模型——图灵机
  • 图灵机的结构:

    • 一条两头可无限延伸的纸带

      • 纸带被划分为一个个的小方格
      • 方格中可包含有限非空符号集中的任意符号,也可以为空。
    • 一个读写头

      • 向左或向右到相邻方格。
      • 读或写。
    • 一个控制器

      • 状态转移规则

      • 状态转移规则的四个要素:

        • 当前状态
        • 读写头读到的当前符号
        • 读写头要完成的操作
        • 要进入的下一状态

    1.4.3、计算的本质
  • 从一个符号串f变换成另一个符号串g的过程

  • “通用性”的两成含义

    • 处理数据的多样性
    • 处理程序的多样性
  • 计算思维的核心

    • 从现实问题中抽取必要的细节
    • 以计算机能理解的方式描述问题
    • 自动化的实施问题求解的过程
1.5、小结
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、开启python之旅(I)
2.1、python
2.1.1环境的创建
  • Anaconda的安装和使用
    • 下载安装文件:Anaconda
    • 安装:安装路径不要包含空格或中文
    • 启动 Spyder:可以将Spyder图标固定到任务栏
  • EduCoder在线实践课程的使用:EduCoder
2.2、绘制炸弹轨迹(I)
2.2.1、“绘制炸弹轨迹”问题

某轰炸机在h=3km的高空以v0 =200m/s的速度水平匀速飞行,到达A点是将投下一枚无动力炸弹,建立如下坐标系,不考虑空气阻力,求绘制炸弹轨迹。(g=9.8m/s2)

  • 设经过时间t后炸弹坐标为(xt,yt)
    x t = v 0 t y t = h − 1 2 g t 2 x_t=v_0t\\ y_t=h-\frac{1}{2}gt^2 xt=v0tyt=h21gt2
2.2.2、计算第3.5秒时的炸弹纵坐标
  • print函数:打印括号中的内容

    print("hello world")
    #打印字符串(直接打印字符串内容)
    print("1+1")#结果为1+1
    #打印表达式(先计算值在进行打印)
    print(1+1)#结果为2
    #表示注释,解释代码功能的作用,不会被执行
    
  • 字符串:引号中的内容

  • 表达式中常用的运算符:加:+;减:-;乘:*;除:/;乘方:**

2.2.3、计算第3.5秒时的炸弹坐标
  • 赋值:将具体的某个值赋给自定义的变量

    pi=3.14 #程序执行过程是从右往左
    
    • 变量命名的具体规则
    • 可包含大(小)写字母、数字、下划线,但不能以数字开头
    • 区分大小写
    • 一般不使用python已用的名字
    print("你的名字是:",name)
    #打印"你的名字是:"和变量name的值(即从键盘上输入的姓名)
    
2.2.4、计算某时刻炸弹的坐标
  • input函数:从键盘读入一个字符串

    name = input("请输入你的姓名:")
    #打印提示文字"请输入你的姓名:";读入键盘上输入的字符串;将字符串赋值给变量name
    
  • type函数:查看类型

    type('18')	str
    type(18)	int
    type(3.14)	float
    
  • 数据类型的转换

    1.str函数:转换成字符串
    2.int函数:转换成整型
    3.float函数:转换成浮点型
    4.eval函数:对字符串表达式进行计算
    
2.2.5、绘制一个坐标点
  • python库的使用

    • 确定要使用的库

    • 在程序中导入库(可能需要安装)

      import math#导入math库
      import math as m #导入math库并取名为m
      from math import cos,pi 
      #导入math库中的cos,pi两个模块
      from math import * #导入math库中的所有对象
      
    • 使用库中的功能

      import matplotlib.pyplot as plt #导入库
      h,V0,g = 3000,200,9.8 #设置参数
      t = eval(input('t=')) #读取时刻t
      xt = V0*t #计算横坐标
      yt = h-1/2*g*t**2 #计算纵坐标
      plt.plot(xt,yt,'ro') #绘制坐标点(xt,yt)
      plt.grid('on') #显示网格线
      plt.axis([0,5000,0,h]) #设置坐标轴范围
      plt.show() #显示图像
      
2.2.6、办公软件的应用——搜索与文档“四步走”
  • “四步走”攻略之搜索

    • 工具
    • 技巧
      • 主题明确
      • 主题模糊
      • 辅助关键字
  • “四步走”攻略之整理、精炼

    • 大纲
    • 撰写文稿
  • “四步走”攻略之排版

    • 字体格式、段落格式、项目符号、特殊版式、段落边框
    • 插入图片、插入表格、插入图表、其它元素

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      	###### 2.2.6、摩尔定律与超级计算机
    
  • 电子计算机的分代:根据构成计算机的电子元器件

    • 第一代:电子管计算机(ENIAC)
    • 第二代:晶体管计算机(TRADIC、7090)
    • 第三代:集成电路(System360)
    • 第四代:大规模和超大规模集成电路
  • 摩尔定律

    • 在价格不变的时候,击集成电路上可容纳的晶体管数目约每隔18个月就会增加一倍
    • 微处理器的性能每隔18个月提高一倍而价格相对的就下降了一半
    • 每一个月能够买到的计算机性能每隔18个月翻一番
  • 千倍定律:高性能计算机的峰值性能每隔10年提升约1000倍(1P=1015,1E=1018)

  • 超级计算机:具有和高的计算速度,能完成个人计算机和服务器不能完成的大型任务的计算机

三、开启python之旅(II)
2.3、绘制炸弹轨迹(II)
2.3.1、if-else分支符和流程图
  • 缩进:若干(一般为4)个空格或/和制表符(Tab键)

  • 连续语句前添加一个相同的缩进可以形成一个语句块

  • 如条件表达式成立则执行语句块1,否则执行语句块2

    if 条件表达式:
        语句块1
    else:
        语句块2
    

    例:

    x=eval(input("x="))
    if x<0:
        a=-x
    else:
        a=x
    print('|x|=',a)
    
    开始
    输入x
    x<0?
    a=-x
    a=x
    打印
    结束
2.2.2、调试功能
  • 跟踪程序执行过程,也能更好的理解程序的执行过程,方便发现代码可能出现的问题
  • if条件表达式
    • 计算结果是一个布尔类型(bool)得值
      • 要么是true(真),表示条件成立
      • 要么是false(假),表示条件不成立
  • 条件表达式(比较)
    • 大于:>
    • 小于:<
    • 大于等于:>=
    • 小于等于:<=
    • 等于:==
    • 不等于:!=
  • 条件的复合
    • 与(而且):and
    • 或:or
    • 非(不是):not
2.3.3、在合理范围绘制一个坐标
import matplotlib.pyplot as plt #导入库
h,V0,g = 3000,200,9.8 #设置参数
tmax = (2*h/g)**0.5	
t = eval(input('t=')) #读取时刻t
if t<0 or t>tmax:
    print('输入错误')
else:
    xt = V0*t #计算横坐标
    yt = h-1/2*g*t**2 #计算纵坐标
    plt.plot(xt,yt,'ro') #绘制坐标点(xt,yt)
    plt.grid('on') #显示网格线
    plt.axis([0,5000,0,h]) #设置坐标轴范围
    plt.show() #显示图像
2.2.4、while循环
  • 重复执行语句块,直到条件表达式不成立

    while 条件表达式:
        语句块1
    
  • 需要注意的地方

    • 循环体的范围:需要重复执行的语句才被放入循环体
    • 变化量:注意检查某些变量在循环体中的变化是否与预期相符
    • 第一次执行:注意检查循环体第一次执行是否和预期相符
    • 最后一次执行:注意检查循环最后一次执行是否与预期相符
2.2.5、绘制n个坐标点
  • 两种结构

    • 分支:if-else
    • 循环:while
  • 任何算符都可以用顺序、分支、循环三种结构来描述

  • 两种工具:流程图、调试

    import matplotlib.pyplot as plt #导入库
    h,V0,g = 3000,200,9.8 #设置参数
    tmax = (2*h/g)**0.5	
    delta = tmax/(n-1)
    while t<=tmax:
        xt = V0*t #计算横坐标
        yt = h-1/2*g*t**2 #计算纵坐标
        plt.plot(xt,yt,'ro') #绘制坐标点(xt,yt)
        t=t+delta #可简写为t+=delta
    plt.grid('on') #显示网格线
    plt.axis([0,5000,0,h]) #设置坐标轴范围
    plt.show() #显示图像
    
2.4、绘制炸弹轨迹(III)
2.4.1、列表(list)
  • 包含若干元素

  • 元素是按序编号的(从0开始)

  • 利用编号可以对元素进行增删改查等操作

  • 创建列表

    L = [a,b,c,d]
    #用方括号括起来,元素之间用逗号隔开
    
    • range():生成类似等差数列整数序列

      range(a,b,c) #[a,b)左闭右开,c为公差
      range(a,b) #[a,b) 公差为1
      range(b) #[0,b) 公差为1
      
2.4.2、列表的查询与更新
  • 读取元素

    x = L[i] #读取的i号元素
    x = L[i:j] #读取第[i:j)号元素
    #i、j可为负数
    
  • 修改元素

    L[i] = x #修改第i号元素
    L[i:j] = x #修改第[i:j)号元素
    #i、j可为负数
    
  • 添加元素

    L.insert(i,x) #将x添加到L的第i出
    L.append(x) #将x添加到L的尾部
    
  • 删除元素

    L.pop(i) #删除L的第i号元素
    L.pop() #删除L最后一个元素
    
2.4.3、其他列表的操作
L.index(x) #返回L中首个x的编号
L.remove(x) #删除L中首个元素x
L.count(x) #返回L中x出现的次数
x in L #判断x是否是L中的元素
L.reverse() #升序排列
L.sort() #降序排列
L1 + L2 #将L1和L2拼接起来
L * n #将n个L拼接起来
len(L) #返回L的长度(元素的个数)
max(L)、min(L) #返回L中最大、最小的元素
sum(L) #返回L中所有元素之和
2.4.4、for循环
  • 语法

    • X为变量,L为列表(或一些其他的值)

    • 将L中的元素依次取出赋给X,没取一个元素,执行一次循环体

      for X in L :
          语句1
      
  • while循环和for循环

    • for循环一般用于循环次数可以提前确定的情况
    • while循环一般用于循环次数难以体检确定的情况
2.4.5、绘制一条轨迹
  • 列表:包含若干元素,元素按序标号

    L=[]、L = list(range()) #创建列表
    X = L[] #读取元素
    L[] = X #修改元素
    L.insert(i,X)、L.append(X) #添加元素
    L.pop(i)、L.pop() #删除元素
    
  • for循环

    for X in L、for X in range()
    
    import matplotlib.pyplot as plt #导入库
    h,V0,g = 3000,200,9.8 #设置参数
    tmax = (2*h/g)**0.5	
    delta = tmax/(n-1)
    xt,yt = [ ],[ ]
    #while循环
    #while t<=tmax:
    #   xt.append(V0*t) #计算横坐标
    #   yt.append(h-1/2*g*t**2)#计算纵坐标
    #   t=t+delta #可简写为t+=delta
    #forx
    #for i in range(n):
    #    t = delta*i
    #   xt.append(V0*t) #计算横坐标
    #   yt.append(h-1/2*g*t**2)#计算纵坐标
    plt.plot(xt,yt,'r-') #绘制坐标点(xt,yt)
    plt.grid('on') #显示网格线
    plt.axis([0,5000,0,h]) #设置坐标轴范围
    plt.show() #显示图像	
    
2.4.6、微机组装
  • 台式计算机的组成:显示器、主机、鼠标、键盘

  • 硬盘

  • 内存条

  • CPU(中央处理器)

  • 主板

  • 常用的维修方法

    • 维修思路
      • 定位故障、逐步缩小
      • 善用搜索引擎
    • 维修方法
      • 插板法:计算机部件接插在主板上或通过线缆进行连接,会出现松动、氧化等原因造成接触不良的可能
      • 变换法:计算机部件一般使用标准接口硬件,比如内存条、硬盘、光驱等,通过使用完好的部件更换可疑的部件,进行故障判断
      • 最小系统法:构建能够启动计算机的最小系统(主板、CPU、电源),然后逐步添加硬件部件,排查可能的故障部件
四、开启python之旅(III)
2.5绘制炸弹轨迹Ⅳ
2.5.1、利用for循环创建列表
  • 将序列中的每个元素X分别带入表达式,得到列表L

    L = [包含X的表达式 for X in 序列]#序列可为列表、range()……
    
  • 更简单的绘制一条轨迹(方法I)

    import matplotlib.pyplot as plt #导入库
    h,V0,g = 3000,200,9.8 #设置参数
    tmax = (2*h/g)**0.5	
    delta = tmax/(n-1)
    T = [i*delta for i in range(n)]
    xt = [v0*t for t in T]
    yt = [h-1/2*g*t**2 for t in T]
    plt.plot(xt,yt,'r-') #绘制坐标点(xt,yt)
    plt.grid('on') #显示网格线
    plt.axis([0,5000,0,h]) #设置坐标轴范围
    plt.show() #显示图像	
    
2.5.2、numpy数组
  • arange函数:用法、功能与range()函数类似,也可以生成等差数列,但不局限于整个数列

  • linspace函数:

    • linspace(i,j,n):将闭区间[i,j]尽量均分为n-1份,返回n个端点形成序列
  • 数组(Array)

    • arange()和linspace()返回的不是列表,而是numpy中的数组

    • numpy库中的数组能直接参与多种运算,而列表能参与的运算十分有限

      #A,B是numpy库中的数组,c是一个数
      A*B#对应元素相乘
      A*c#个元素分别乘以c
      A**c#求个元素的c次方
      A//c#求个元素整除c的商
      A%c#求个元素整除c的余数
      np.sqrt(A)#求个元素的平方根
      ...
      
2.5.3、更简单的绘制一条轨迹
import matplotlib.pyplot as plt #导入库
h,V0,g = 3000,200,9.8 #设置参数
tmax = (2*h/g)**0.5	
t = np.linspace(0,tmax)
xt = V0*t #计算横坐标
yt = h-1/2*g*t**2 #计算纵坐标
plt.grid('on') #显示网格线
plt.axis([0,5000,0,h]) #设置坐标轴范围
plt.show() #显示图像
2.6、绘制炸弹轨迹Ⅴ
2.6.1、定义函数
  • 函数:一种代码复用技术

    注:1、函数一般用来处理同类问题,而不是处理某一个特定问题;

    ​ 2、任以默认值参数右边不能再出现非默认值参数

    #函数被调用后才会被执行,被调用几次函数就执行几次
    def 函数名 (a,b):
        语句块1
    
  • 参数:在函数体内的使用方法与变量相同

  • 参数传递:调用函数时将具体值赋给参数

  • 返回值:return将调用的代码替换成返回值,执行到函数时函数体就停止

2.6.2、绘制多条轨迹
import numpy as np
import matplotlib.pyplot as plt #导入库
def calBombTrace(h,v0):
    g = 9.8
    tmax = (2*h/g)**0.5
    t = np.linspace(0,tmax)
    xt = v0*t
    yt = h-1/2*g*t**2
    return xt,yt
H = [3000,2000]
v0 = [200,260]
for h in H:
    for v0 in V0:
        xt,yt = calBombTrace(h,v0)
        plt.plot(xt,yt)
plt.grid('on') #显示网格线
plt.axis([0,5000,0,h]) #设置坐标轴范围
plt.show() #显示图像
2.6.4、思路的演示——四步走战略
  • “四不走”攻略之内容梳理

    • 理清逻辑思路——思维导图来帮忙
    • 确定应用场景——演示、演讲、阅读
  • “四步走”攻略之完成初稿

    • 熟悉“套路”——封面、目录、提示页、内容、封底
    • 搭建框架——套用版式
  • “四步走”攻略之整洁提升

    • 修饰文本、图文搭配、图标制作、SmartArt、动画设置
  • “四步走”攻略之精华设计

2.6.3、小结
五、信息表示与编码——0与1的故事
3.1、什么时信息
3.1.0、计算机需要表示数据
  • 计算机里需要表示各类数据:数字符号、推理符号、语言符号、声音图像

  • 信息论的创始人

  • 信息的定义:

    • 客观存在的表现形式

    • 事物复杂性和差异的反映

  • 信息的复杂性

    • 信息具体表现形式的多样性

    • 信息的分类标准不一

    • 信息的数学理论:信息是事物运动状态或存在方式的不确定性的描述

    • 信息的多少:事物不确定性的描述能够有效的表达和衡量信息的多少

    • 信息量计算公式(H:信息熵;单位:bit)

      • 信息和长度,重量这些物理属性一样,也可以测量规范
      • 信息定量公式的解析
        • p(xi)表示消息xi发生的概率
        • -log2p(xi)表示信息xi所包含的信息量
        • 事件的不确定程度可以用其出现的**概率
        • 消息出现的概率越小,包含的信息量越大,反之信息量越小
        • 每个消息的信息量乘上它发生的概率后再求总和,得到的是从一个信息源发出的各个消息所包含的平均信息量或H是所有信息的平均不确定性
      • 确定性为100%时的熵:
        • n=1,即1种可能性
        • p(xi)=1,即确定性100%
        • H=log2(1)=0,即信息量为零

      H = − ∑ i = 1 n p ( x i ) l o g 2 p ( x i ) I = − l o g 2 p ( x i ) 当 p ( x i ) > 0 时, I = ∞ 当 p ( x i ) < 0 时, I = 0 H = -\sum\limits_{i=1}^np(x_i)log_2p(x_i)\\ I=-log_2p(x_i)\\ 当p(x_i)>0时,I=\infin\\ 当p(x_i)<0时,I=0\\ H=i=1np(xi)log2p(xi)I=log2p(xi)p(xi)>0时,I=p(xi)<0时,I=0

    • 编码的概念

      • 一切信息源发出的信息或者信号的可以用0和1的组合来描述
      • 信息从一种形式转换为另一种形式的过程,成为编码
      • 具体需要用多少个0或1来编码取决于信息熵的大小
3.2、为什么只有0和1
  • 计算的本质:从一个0/1字符串到另一个0/1字符串的变换
3.2.1如何表示一个数
  • 进制:进位计算制的简称,一般用于刻画数量之间的数量关系,是人们在长期实践中发现和发明的
3.2.2、十进制与二进制的抉择
  • 十进制
    • 逢十进一
    • 十进制的基数
  • R进制
    • 逢R进一
  • 十进制与二进制
    • 任何一个数都可以用不同的进位制表示
    • 任何一个进制都可以通过按权展开的方式转换成十进制
  • 十进制与二进制的抉择
    • 二进制33位的表示最大可以表示10的10次方量级的数,采用二进制会比十进制的系统要经济的多
3.2.3、计算的通用性
  • 计算机为什么采用0/1编码来表示信息
    • 基于二进制的运算规则简单,简化设计
    • 与要实现的物理状态单一 ,系统可靠性和稳定性提高
    • 适合实现逻辑运算,通用性强
3.3、算术运算与逻辑运算
3.3.0、算术运算与逻辑运算
  • 任何运算过程都可以拆解为算术运算和逻辑运算

    CPU逻辑结果图
3.3.1、算术运算
  • 二进制运算规则

3.3.2、逻辑运算
  • 逻辑运算又称为布尔运算

  • 运算的结果为布尔值

  • 延伸出的一系列逻辑理论被称为布尔代数

  • 基于0/1的逻辑运算

    • 逻辑量的取值0或1

    • 与或非三种逻辑运算的真值表

    • 异或运算(XOR)

      • 逻辑规则:相同为假,不同为真
      • 等价表达式: a ⨁ b =   ( ¬ a ∧ b ) ∨ ( a ∧ ¬ b ) a\bigoplus b=\ (\lnot a \land b)\lor (a\land\lnot b) ab= (¬ab)(a¬b)
    • 逻辑运算丰富了程序结构

3.3.3、位运算
  • 数字电路

    • 数字电路是现代计算机的重要基石,它利用硬件在物理上实现了对0/1字符串的表示,处理和存储

    • 数字电路的基本原理,通过晶体管搭建不同功能的逻辑门来实现对0/1字符串中的每一位布尔运算

    • 一切计算的本质都是0与1之间的“与”,“或”,“非”

  • 位运算规则

    • 对于给定的两个等长的0/1字符串,从左到右安位对齐,注意对每一位进行布尔运算(“与”,“或”,““非””)
    • 对于单个定长的0/1字符串,根据应用的需求施加位运算(“非”,“左移位”,“右移位”)
3.4、进制转换
3.4.1、十进制与二进制之间的转换
  • R进制转换为十进制的通式

a R = ( a n − 1 . . . a 0 a − 1 a − 2 . . . a − m ) R = a n − 1 ∗ R n − 1 + . . . + a 1 ∗ R 1 + a 0 ∗ R 0 + a − 1 ∗ R − 1 + . . . + a − m ∗ R − m a_R=(a_{n-1}...a_0a_{-1}a_{-2}...a_{-m})_R\\=a_{n-1}*R^{n-1}+...+a_1*R^1+a_0*R^0+a_{-1}*R^{-1}+...+a_{-m}*R^{-m} aR=(an1...a0a1a2...am)R=an1Rn1+...+a1R1+a0R0+a1R1+...+amRm

  • 十进制转换为二进制的表示
    • 整数部分:除2取余法(余数法),即整数除以2之后留取余数作为结果 (自下而上)
    • 小数部分:乘2取整法(进位法),即小数乘以2之后留取整数部分作为结果(自上而下)
3.4.2、利用python实现“除二取余”
  • 算法的输入和输出

    • 0到多个输入
    • 1到多个输出
  • 算法包含一系列(用顺序、分支、循环结构进行组织)的步骤

    • 有限个步骤
    • 每个步骤都是可行
    • 每个步骤都是明确
  • 创建字符串

    • 用单引号、双引号、三引号(三个单引号’''或三个双引号"“”)

    • s=input()s=src(3.14)……

    • 可以理解为列表,所含元素为单个字符

    • 与列表类似的操作

      x=s[i]、x=s[i:j]#提取子串
      a=len(s)#求字符串长度
      a=s.index(x)#求子串首次出现的位置
      a=s.count(x)#求子串出现的次数
      s=s1+s2#字符串拼接
      s=s1*n#将s1拼接n次
      x in s#判断是否包含字串x
      for x in s#对x中的每个字符s
      ......
      
    • 专门的操作

      a = s.startseith(x)#判断s是否以x开头
      a = s.endswith(x)#判断s是否以x结尾
      a = s.upper()#将字母全部转换成大写
      a = lower()#将字母全部转换成小写
      a = s.swapcase()#大小写互换
      a = replace(s1,s2)#将s1替换为s2
      
  • 构建算法

  • 程序实现

    def DecTobin_int(d):
        if d = 0:
            return '0'
        sign = ''
        if d<0:
            d = -d
            sign = '-'
        b = ''
        while d != 0:
            b = str(d%2)+b
            d = d/2
        return sign + b
    d =  int(input('d='))
    print(DecTobin_int(d))
    
  • 递归函数:函数自己调用自己

  • 算法复杂度

    • 时间复杂度:随着为题规模N的增加,算法所需时间(一般用操作次数来衡量)的增加趋势
    • 空间复杂度
  • 递归实现

    • 递归:将复杂问题层层转化为与原来问题本质相同,但更容易解决的问题
  • 除二取余的递归定义(d∈Z+)

    def f(d):
        if d = 1:
            return '1'
        else:
            return f(d//2)+str(d%2)
    def DecToBin_int(d):
        if d==0:
            return '0'
        if d>0:
            return f(d)
        if d<0:
            return '-'+f(-d)
    d = int(input('d='))
    print(DecToBin_int)
    
3.4.3、八进制与十六进制
  • 转换方法

3.5、0/1表示的缺陷及计算机的局限性
  • 十进制小数转换成二进制 小数部分:乘2取整法(进位法)

    • 不一定能等值转换
    • 近似转换的精度取决与计算机内部用于数据表示和存储的位数
    • 可用的位数越多,精度就越高
  • 计算机的局限性

    • 数学思维的世界是连续的、无限的
    • 计算思维的世界是离散的、有限的
  • 位的概念(比特:bit;缩写:b)

    • 0/1信息编码中的一位
    • 信息量的最小度量单位
  • 字节的概念(字节:Byte;缩写:B)

    • 1个字节由8为组成
    • 1字节等于8比特(1B=8b)
  • 位模式:用于描述信息的0/1数字的位数

  • 误差的来源

    • 二进制无法精确表示部分十进制小鼠
    • 数学当中存在无限循环和无限不循环小数,因为位模式的局限而无法精确表示
3.6、数值信息编码-计算机码制
3.6.1、最自然却是最“复杂”的原码
  • 机器数

    • 机器数:将真值的正负符号数值化,用0表示正,用1表示负

    • 真值:带有“+”、“-”号的数据表示

  • 数值信息的编码——原码

    • 符号部分

      • 数的最高位“符号位”
      • 用代码0表示“+”,用代码1表示“-”
    • 数值部分与真值相同

    • 与位模式的关系:N为位模式下,数值部分不足N-1位,用0补足

    • 原码的有点:简单直观,容易理解

    • 原码的缺点

      • 浪费编码资源,增加计算开销

        外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      • 进行加减运算较为复杂:要对符号和数值的绝对值大小进行判断

3.6.2、“取反加一”——特殊的补码规则
  • 数值信息的编码——补码
    • 符号部分同原码
      • 最高位为符号位,0表示正数,1表示负数
    • 数值部分与它的符号位有关
      • 对于整数,补码的数值部分与原码相同
      • 对于负数,是将原码数值部分按位取反加1
3.6.3、0的回归——补码的表示范围
  • 符号部分同原码

  • 数值部分与它的符号位有关

    • 对于正数,补码的数值部分与原码相同

    • 对于负数,是将源码数值部分按位取反再加1

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.6.4、神奇的补码运算
  • 同余理论:两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于整数m同余,m称为模,记作a=b(mod m),读作a与b关于m同余

  • 推论

    • 在模为M的条件下,A减B,可以用A加上-B的补数来实现

    • 求-B的补数的公式:-B的补数 = -B + M

    • 补码的定义:[X] = (2n + X) mod 2n

    • 补码运算规则:两数和的补码等于两数补码的和

      [x1 + x2] = [x1] + [x2]

      [x1 - x2] = [x1] + [-x2]

    • 只需要一套实现加法运算的器件,从而简化了计算机内部硬件电路的结构

3.6.5、危险的溢出
  • 溢出的演示
    • 两个数参加运算,结果超出了计算机能表示的数值的范围,称之为溢出
  • 正溢出:加数和被加数的符号位为0,加完之后结果的符号位为1的情况,称之为正溢出
  • 负溢出:加数和被加数的符号位为0,加完之后结果的符号位为1的情况,称之为负溢出
  • 算法逻辑的设计,数据表示的范围和精度是导致错误的原因
3.6.6、小数点需要表示吗
  • 由于规则的约定小数点变成了交互双方的以个默认信息而无需表示

    • 信息论的解释:表示小数点的信息熵为零
  • 定点表示和浮点表示的优缺点

    • 定点表示法运算直观,但数表示范围小
    • 浮点表示法表示的数的范围和精度都提升,但浮点运算复杂
  • 定点数和浮点数

    • 根据小数点的位置是否固定,数据有定点数浮点数两种表达方式
    • 编码由原码或补码构成
  • 定点数:约定机器中所有数据的小数的小数点位置固定不变

    • 定点整数:小数点固定在数的最低点之后
    • 定点小数:小数点固定在符号位之后,最高数值之前
    • 小数点便为隐含信息不需要表示
    • 数符和数值部分的编码方式即可以用原码也可以用补码
    • 用定点数进行运算处理的计算机被称为定点机
  • 浮点数

    • 一个数N的科学计数法形式可写成:N = M*RE
      • 尾数M,通常是小数
      • 阶码E,通常是整数
    • 当尾数、阶码采用二进制,基数R= 2时,就是计算机中的浮点数据表示
  • 浮点表示格式

    • 浮点数据表示用一对定点数表示
    • 尾数:定点小数表示,决定了浮点数的表示精度
    • 阶码:定点整数表示,决定了浮点数的表示范围
  • 规格化浮点数

    • 为了不损失有效数字,常对位数进行规格化处理
      • 规格化对尾数M的要求:1/2<=|M|<1
      • 即保证尾数部分真值的最高位1,大小通过阶码调整
  • 定点机:CPU被设计为执行定点算数,通过分解运算序列,使用定点架构来实现浮点运算

  • 浮点运算单元(FPU)

    • 对浮点数执行加、减、乘、除、平方根和位移等操作
3.7、字符信息的编码
3.7.1、什么是ASCII码
  • 关于多媒体信息表示

    • 数值信息与非数值信息
    • 建立抽象与具象的连接
  • 美国信息交换标准码(American Standard Code for Information Interchange, ASCII)

    • 国际标准:ISO 646标准,适用与拉丁文字字母
    • 首发在1967年,最后一次更新在1986年
  • ASCII码的组成和存储

    • 138个字符,7位二进制表示

    • 在计算机内部用1个字节存放

      • 最高位均设为0
3.7.2、ACSCII码够用吗
  • ASCII码的扩展
    • 利用ASCII码中闲置的最高位编入新的符号
    • 可以表示最多256个符号
    • 0—127保持不变,128-255为扩展段
  • ASCII码不适于亚洲文字
    • 国标码GB2312
      • 用2个字节表示1个汉字
      • 最多可表示256*256=65536个字符
    • 计算机处理和显示不同的字符文字,必须适配不同的编码规则
3.7.3、庞大的汉字字符集
  • 国标码
    • 用2个字节表示1个汉字
    • 至少13位二进制编码
    • 考虑以后的扩充,设置14位
    • 14位需要2个字节保存,每个字节最高位设位0
  • 国标码与机内码的关系
    • ASCCII码和国标码并存出现二义性
    • 国标码每个字节的最高位置为1,机内码=国标码+8080H
  • 国标码的发展
    • **GB 2312-80:国标基本集6763个汉字,682个字符
    • GBK兼容GB2312,包含20902个汉字
    • GB18030-2000(或GBK2K)在GBK的基础上做了进一步扩充
3.7.4、万能的Unicode
  • Unicode又称统一码、万国码、单一码
    • 世界上所有语言的符号,组成通用字符集(Universal Character Set,UCS)
  • Unicode编码由4个字节组成
  • Unicode编码体系具有较复杂的“立体”结构
3.7.5、字符实训:凯撒加密
  • “凯撒加密”问题

    • 信息加密

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 凯撒加密:将每个明文字符按字母表顺序进行偏移

  • 加密一个小写字母

    firstASCII = ord('a')
    N = 26 #字符总数
    def enChar(x,key):
        xid = ord(x)-firstASCII
        yid = (xid+key) % N
        y = chr(firstASCII + yid)
        return y
    chars = 'abcdefghijklmnopqrstuvwxyz'
    for x in chars:
        print(x,'->',enChar(x,2))
    
  • 加密一段文本

    firstASCII = ord('a')
    N = 26 #字符总数
    def enChar(x,key):
        xid = ord(x)-firstASCII
        yid = (xid+key) % N
        y = chr(firstASCII+yid)
        return y
    def Caesar(text,key):
        result = ''
    	for x in text:
            if 'a'<=x<='z':
                x = enChar(x,key)
            result +=x
        return result
    #加密
    text = 'attack tonight'
    key = 2
    print(Caesar(text,key))
    
    #解密
    #text = 'attack tonight'
    #key = 2
    #print(Caesar(text,-key))
    
  • 加密其他字符

    firstASCII = 0
    N = 65535 #字符总数
    def enChar(x,key):
        xid = ord(x)-firstASCII
        yid = (xid+key) % N
        y = chr(firstASCII+yid)
        return y
    def Caesar(text,key):
        result = ''
    	for x in text:
            if 0<=ord(x)<N:
                x = enChar(x,key)
            result +=x
        return result
    #加密
    text = '今晚发动攻击,代号Python!'
    key = 1234
    print(Caesar(text,key))
    #解密
    #text = 'print(Caesar(text,key))'
    #key = 1234
    #print(Caesar(text,-key))
    
3.8、数字音频及其处理
3.8.1、声音的数字化
  • 声音:在介质中传播的机械波,是随时间连续变化的连续信号

  • 采样:每隔一个时间间隔取一个幅度值

  • 采样周期=1/采样频率

  • 量化:对振幅值进行限定近似的过程

  • 编码:将量化后的振幅值用二进制表示

  • 声音的数字化过程:模拟声音信号**(采样)、(量化)、(编码)**,最后转化成数字音频

3.8.2、数字音频的相关参数
  • 采样频率:单位时间内采样的次数,单位:赫兹(HZ)
  • 量化位数(也称采样精度):每个采样点的二进制位数,单位:位/字节
  • 声道数:包含声道的个数
  • 比特率:
    • 单位时间的比特数,单位:比特/秒(bps)
    • (采样频率量化位数声道数)
    • 比特率*持续时间(秒) = 数据量(比特)
3.8.3、查看儿歌的参数
#注意程序运行时需要与文件在同一文件夹下
from pydub import AudioSegment as AS
song = AS.from_file('文件名称'format = '文件格式')
print(len(song))		#时长,单位:毫秒
print(song.frame_rate)	#采样频率,单位:HZ
print(song.sample_width)#量化位数,单位:字节
print(song.channels)	#声道数
3.8.4、数据压缩
  • 原理:对原始数据进行重新编码,去除原始数据中的冗余数据

  • 行程编码:重复的数据用改值和重复的次数来代替

  • 压缩比:压缩前后的数据量之比

  • 无损压缩(或可逆压缩):被压缩的数据经过解压缩后,可以得到与原始数据完全相同的数据

  • 有所压缩(或不可逆压缩):被压缩后的数据经过解压缩后,不能得到与原始数据完全相同的数据

3.8.5、剪辑儿歌
  • 常见的音频文件格式:wav、MP3、Flac、rm、wma等

    #注意程序运行时需要与文件在同一文件夹下
    from pydub import AudioSegment as AS
    song = AS.from_file('record.mp3',format = 'mp3')
    song = son[4000:8500] + song[10000:14500]
    file = song.export('生成的文件名',format = '生成的文件格式')
    file.close()
    
3.8.6、为儿歌配乐
#注意程序运行时需要与文件在同一文件夹下
#根据简谱生成音乐
from pydub import AudioSegment as AS
duoRuiMi = [ ]#用列表存放发音
duoRuiMi.append(AS.silent(500)#第0号是0.5秒静音
for i in range(1,8):#哆瑞咪发梭拉西
    s = AS.from_file(str(i)+'.mp3',foramt = 'mp3')
    duoRuiMi.append(s)
notation = '01231231034503450' #简谱
music = AS.empty()#空音频
for i in notation:#将各音符转化为对应的发音
    music = music+duoRuiMi[ int(i) ]
file = music.export('music.mp3',format = 'mp3')
file.close()

#合并歌曲和配乐
for pydub import AudioSegment as AS
song = AS.from_file('song.mp3',format = 'mp3')
music = music[180 : 9180]
music +=8
song = song.split_to_mono()
music = music.split_to_mono()
twoTigers = AS.from_mono_audiosegment(music[0],song[0])
file = twoTigers.export('twoTigers.mp3',format = 'mp3')
file.close()                       
3.9、数字图像及其处理
3.9.1、绿幕抠像为题的描述
  • 将图片中的人从图片中抠取出来的过程
3.9.2、获取图像分辨率
  • 图片分辨率:横向像素数*纵向像素数

  • 元组:不能被修改的列表

  • 利用Python查看分辨率

    from PIL import Image
    img = Image.open(head.jpg)
    w,h = img.size
    print(w,'x',h)
    t = (1,4,9)#定义元组
    print(t[0],t[-1])#读取元素
    a,b,c = t#多重赋值
    print(a,b,c)
    
    3.9.3、获取一个像素的信息
    • 像素坐标(x,y):从左往右数的x个、从上往下数第y个**(x、y从0开始)**

      from PIL import Image
      img = Image.open('head.jpg')
      pix = img.getpixel((23,5))
      print(pix)
      
3.9.3、RGB颜色
  • RGB颜色模型;自然界任意颜色都可以由**红(red)、绿(green)、蓝(blue)**三种基本颜色按一定比例组合而成
3.9.4、RGBA颜色
  • A分量:透明度,取值为[0,255]

    • 0:完全透明
    • 255:完全不透明
    from PIL import Image
    boy = Image.open('boy.jpg')
    boy = boy.convert('RGBA')#修改格式为RGBA格式
    w,h = boy.size
    for x in range(0,w):#横坐标为x
        for y in range(0,h):#纵坐标为y
            r,g,b,a = boy.getpixel((x,y))#取出(x,y)处颜色
            a = 100#改为半透明
            boy.putpixel((x,y),(r,g,b,a))#修改(x,y)处颜色
    boy.save('boy.png')#png格式支持头透明度
    

3.9.5、实现绿幕抠像

#编写临时程序
#绿幕抠像
from PIL import Image
boy = Image.open('boy.jpg')
boy = boy.convert('RGBA')
w,h = boy.size
for x in range(0,w):
    for y in range(0,h):
        r,g,b,a = boy.getpixel((x,y))
        if g-r>30 and g-b>30:#若是偏绿色
            a = 0#改成完全透明
            boy.putpixel((x,y),(r,g,b,a))#设置像素颜色
            continue
boy.save('boy.png')

#添加场景
#from PIL import Image
#boy = Image,open('boy.png')
playground = Image.open('playground.jpg')
w,h = boy.size
boy = boy.resize((w//2,h//2))
playground.paste(boy,(620,140),mask = boy.split()[3])#将抠取下来的图片粘贴到'playground.jpg'中
playground.save('final.jpg')
3.10、小结
  • 信息与编码——思维导图

六、计算机系统的程序员视角
4.1、冯·诺依曼体系结构
4.1.1、 再谈计算
  • 理解计算:从一个符号串变换成另一个字符串
  • 计算过程:从初始符号或已知符号开始,一步一步地变换符号,经过有限步骤,最后得到一个满足预先规定的符号串的变换过程
  • 计算的实现:
    • 计算装置在某个“过程”的控制下根据输入产生输出
    • 一个通用的计算装置应该支持符号解译、过程记忆、可编程的功能
4.1.2、健忘的ENIAC与冯氏结构
  • 存储程序控制原理:把程序本身当作数据来对待,程序与其处理的数据用同样的方式储存

4.1.3、从抽象结构到具体实现
  • 冯氏结构的实现

  • 存储器与CPU的关系

    • 与CPU直接打交道的速度较快的内存储器
    • 外存是作为长期保存程序和数据的辅助存储器
  • 现代电子计算机的典型结构

  • 玩转表格—— “四步走”攻略

    • 制定计划
      • 新建表格、输入文字、调整格式
    • 搜集数据
    • 汇总数据
    • 分析数据
4.2、冯氏结构的软件模拟——TOY计算机
4.2.1、存储程序思想的实现
  • 冯诺依曼体系结构的核心思想是“存储程序”

  • 程序是指完成一项特定任务,用计算机语言描述的问题求解步骤的有序序列

  • 机器语言:程序和数据都用0/1形式表示,0/1编码称为机器语言

  • 指令:用机器语言描述的计算机执行的最小单位

  • 机器语言程序:由一组有序的指令组成的指令序列

  • 指令格式

  • 指令类型:

    • 操作指令
    • 数据移动指令
    • 控制指令
  • 指令系统:CPU所能执行的机器指令的集合,称为指令集或者指令系统

  • 任何程序都是由指令集和内的不同指令组合而成的指令序列

  • 汇编语言:用一些容易理解和记忆字母、单词来代替一个特定的指令中的0/1编码

  • 高级语言:独立于机器的硬件系统、面向过程或对象的语言,它较接近自然语言或数学语言

  • 高级语言编写的程序称之位源程序

  • 编译之后得到的0/1代码则称之为可执行程序

  • TOY指令集

  • 寄存器:CPU中用于存放数据和状态的临时存储单元

    • Rx、Ry:CPU中某个通用的寄存器编号(取值为整数)
  • 主存单元:主存被分为一个个的单元格,数据按字节顺序存放在这些单元格中

    • mem:主存中的某个单元(取值为整数)
4.2.3、CPU模拟于指令的执行
  • CPU组成结构

    • 算术逻辑运算单元(ALU):计算

      • 算术运算:加减乘除
      • 逻辑运算:与或非异或等、位运算
    • 寄存器组:用于临时保存数据(数据十分有限,属于稀缺资源);存储

      • 通用寄存器组:操作数、结果等;程序可以使用
      • 专用寄存器组:计算机当前状态;CPU专用,用户不可见
    • 控制单元(Control Unit):控制

      • 功能:分析指令、传送指令及操作数;产生时序逻辑:控制和威胁整个CPU工作
    • 控制单元(CU)的组成

      • 程序计数器(PC):保存下条指令的地址
      • 指令寄存器(IR):保存当前执行的指令
      • 指令译码器(ID):根据IR内容,决定进行何种操作
      • 操作控制器(OC):控制各种操作(取指令、取数、控制ALU)
    • CPU内部总线:互联

      • 数据和指令在CPU中的传送通道:数据总线(DB)、地址总线(AB)、控制总线(CB)
  • CPU的执行过程

    • 循环执行指令的过程:在CU的控制下,精确地、一步一步地完成

    • 一条指令执行的时间称为指令周期,每一步称为一个节拍

    • 时钟周期

      • CPU工作的最小时间单位

      • 一个节拍可能花费多个时钟周期

      • 时钟频率(主频):1/时钟周期

    mem = ['']*1000                     #主存
    reg = [0]*10                        #通用寄存器
    pReg = 0                            #程序计数器
    iReg = ''                           #指令寄存器
    
    def loadProgram(file):
        global pReg, mem                #全局变量声明
        fil = open(file, 'r')           #打开文件
        first = True                    #用于标识是否为第1条指令
        while True:                     #每循环一次加载一条指令
            line = fil.readline()       #读1行
            if line == '':              #若读取完毕,则结束循环
                break
            flds = line.split()         #将1行拆分为若干部分
            address = int(flds[0])      #第0部分为地址
            instruc = flds[1]           #将后面的部分重新拼接为指令
            for fld in flds[2:len(flds)]:
                instruc = instruc+' '+fld
            mem[address] = instruc      #将指令加载到主存单元
            
            if first==True:             #若是第1条指令
                pReg = address          #则将其地址存入程序寄存器
                first = False           #后面的指令不再是第1条指令'''
        fil.close()                     #关闭文件
        
    def cycle():
        global pReg, iReg, reg, mem
        
        #取指令
        iReg = mem[pReg]                #根据pReg的值,将指令从mem取到iReg
        pReg = pReg + 1                 #pReg加1,指向下一条指令
        
        #译码
        flds = iReg.split()
        opcode = flds[0]            #操作码
        if len(flds)>1: op1 = int(flds[1])  #操作数1
        if len(flds)>2: op2 = int(flds[2])  #操作数2
        
        #执行和写结果
        if opcode=='mov1':              #数据移动指令:寄存器←主存
            reg[op1] = mem[op2]
        elif opcode=='mov2':            #数据移动指令:主存←寄存器
            mem[op1] = reg[op2]
        elif opcode=='mov3':            #数据移动指令:寄存器←数字
            reg[op1] = op2
        elif opcode=='add':             #加法指令
            reg[op1] = reg[op1]+reg[op2]
        elif opcode=='sub':             #减法指令
            reg[op1] = reg[op1]-reg[op2]
        elif opcode=='mul':             #乘法指令
            reg[op1] = reg[op1]*reg[op2]
        elif opcode=='div':             #除法指令
            reg[op1] = reg[op1]/reg[op2]
        elif opcode=='jmp':             #无条件跳转指令
            pReg = op1
        elif opcode=='jz':              #条件跳转指令
            if reg[op1]==0: 
                pReg = op2
        elif opcode=='in':              #输入指令
            reg[op1] = int(input('input:'))
        elif opcode=='out':             #输出指令
            print('output:', reg[op1])
        elif opcode=='halt':            #停止指令
            return False
    
        return True
    
    def run(file):
        global pReg, iReg, reg, mem
        loadProgram(file)	#加载TOY程序
       
        while True:	#每循环一次,执行一条指令
            hasNextInstruc = cycle()	#执行一条TOY指令
            if hasNextInstruc==False:	#若执行的是halt指令
                break	#则跳出循环
    
    
    run('sum100.txt')	#运行sum100.txt中的TOY程序
    for i in range(11):
        print('主存单元', i, ':', mem[i]) #打印当前主存单元中保存的程序
    run('add.txt')	    #运行add.txt中的TOY程序
    for i in range(5):
        print('主存单元', i, ':', mem[i]) #打印当前主存单元中保存的程序
    
    
    
    
4.2.4、处理器的组成结构和制造过程
  • 处理器的组成结构

    • 处理器,即平时所说的芯片或CPU

    • 处理器主要完成的功能

      • 逻辑运算:Y~(A&B + C&D)
      • 算术运算:Sum = 100+200
    • “开关”器件,及它们之间的连线

      • 金属—氧化物·半导体场效应晶体管(MOSFET),晶体管
      • nMOS晶体管和pMOS晶体管

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 香农,1938年硕士论文《继电器于开关电路的符号分析》

      • 将电路系统的“开、关”与逻辑运算的“真、假对应”
      • 指出可以通过构建开关电路解决任何逻辑和数值运算
    • 实现逻辑运算的核心器件是开关

      • 基本逻辑运算:与、或、非
    • 算术运算的核心是“加法运算”

      • **1位二进制加法运算:{C,S} = A+B
      • 将多个1位二进制加法器连接得到一个多位二进制加法器

  • 处理器的制造过程
    • 采用类似于“印刷过程”的光刻机制
    • 包括多个步骤,每一步都对不同材料进行沉淀或腐蚀
4.3、操作系统漫谈
4.3.1、计算机硬件和软件
  • 软件系统:应用软件、系统软件
  • 硬件系统:CPU、鼠标、键盘、主机、显示屏
4.3.2、什么是操作系统
  • 操作系统(OS)是管理计算机硬件资源并向用户提供公共服务的软件
  • 操作系统(进程管理、存储管理、文件管理、设备管理)是资源得到充分有效的利用
  • 用户接口:人机接口、API接口
4.4、文件合并工具(I)
4.4.1、问合并问题
  • 文件合并前:原始文件;合并后:结果文件
  • 文件合并功能——文件管理
  • 打开关闭功能——进程管理
  • 图形化界面实现——用户接口
4.4.2、文件
  • 程序和数据以文件的形式存储在外存上

  • 文件包括文件内容文件属性

  • 文件名称:文件名称.扩展名

  • 文件的分类

    • 程序文件和数据文件

  • 目录(文件夹):便于管理文件

    • 实际上也是一种文件
      • 内容:所含文件的描述信息
      • 属性
    • 目录可以包含目录:父目录、子目录、根目录
  • 操作系统中的文件系统

    • 对外存上的文件实施管理
    • 并向用户提供调用接口
4.4.3文件路径
  • 用于标识文件(包括文件夹)的位置

    • 父文件夹路径+文件名称
    • 绝对路径:从根目录开始
    • 相对路径:从用户所在位置开始
  • Python中的特殊符:

    制表符:\t
    换行符:\n
    解决方法1:\\表示一个\
    解决方法2:/
    解决方法3:r 表示不使用特殊符
    
4.4.4、添加文件夹功能
import os
print(os.path.isfile(''))#判断是否为文件
print(os.path.isdir(''))#判断是否为目录
print(os.path.join(''))#形成路径
print(os.path.realpath(''))#绝对路径
print(os.listdir(''))#获取目录下所有名称

if not os.path.exists('temp'):#判断路径是否存在
    os.mkdir('tmp')#新建目录

os.rename('tmp','abc')#重命名    
  • 添加文件夹功能

    import os 
    #获取文件夹下所有txt文件的路径
    def getTxtPaths(dirpath):
        paths = [ ]
        filenames = os.listdir(dirpath)
        for filename in filenames:
            filepath = os.path.join(dirpath,filename)
            if os.path.isfile(filepath) and filename.endswith('.txt'):
                paths.append(filepath)
        return paths
    
    for path in getTxtPaths('学生反馈'):
        print(path)
    
4.4.5、读取一个txt文件
  • 写文件

    txt = open('test.txt','w')#以写模式打开文件
    txt.write('计算机\n')#写文件
    txt.write('计算思维\n')
    txt.write('Python\n')
    txt.close()#关闭文件
    
    #W:写模式(覆盖)
    #a:写模式(追加)
    
  • 读文件

    txt = open('test.txt','r')
    print(txt.read())#读所有内容返回值是字符串
    print(txt.readlines())#都所有内容返回值是列表
    print(txt.readline())读一行返回值是字符串
    txt.close()
    
  • 异常处理(当发生异常时程序终止运行):当try中发生异常时,转而执行except后的异常处理语句

  • 读取一个txt文件(异常时不终止)

    import os 
    def readOneTxt(filepath):
        try:
            file = open(filepath,'r')
            text = file.read()
            file.close()
            return text
        except:
            return ''
    print(readOneTxt('test.'))   	
    
4.4.6、文本合并功能
def mergeTxts(srcPaths,destPath):
    destFile = open(destPath,'w')
    for srcPath in srcPaths:
        text = readOneTxt(srcPath)
        if text!='':
            destFile.write(text)
            destFile.write('\n'*2+'-'*50+'\n'*2)
    destFile.close()
    return os.path.realpath(destPath)
srcPaths = getTxtPaths('红楼梦')
mergeTxts(srcPaths,'result.txt')
print(readOneTxt('result.txt'))
  • 操作系统的安装

  • 揭开操作系统的神秘“面纱”

    • 定位和作用

      • 管控计算机软硬件资源的程序

      • 计算机系统中的重要核心软件,是其他软件的基础

    • 直观的体验和技术内涵

  • 操作系统的“前世”和“今生”

    • 硬发展推动

      • 向下:追求更高地发挥硬件资源所提供的计算、存储、通信等能力
    • 应用需求牵引

      • 向上:更好地为用户和应用程序提供服务、提高易用性
4.5.文件合并工具(II)
4.5.1、进程
  • 现代操作系统的基本特征
    • 并发:多个程序在同一时间段中运行
    • 共享:资源可供多个并发程序共同使用
    • OS的CPU管理:如何将CPU合理地分配给各个程序,既提高CPU的使用效率,又能满足不同程序地要求
  • 进程
    • OS中最核心的概念
    • 可并发执行的程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位
    • 直观理解:程序的一次执行
  • 进程和程序的关系
    • 进程时动态的,程序时静态
      • 进程是程序的执行
      • 程序是指令的序列
    • 进程是暂时的,程序是永久
      • 进程有生命周期,会消亡
      • 程序可长期保存在外存上
    • 进程的组成包括程序、数据和程序控制快
    • 数量上的关系
      • 一个程序的多次运行对应到多个进程
      • 一个进程可以通过调用运行多个程序
4.5.2、进程的状态
  • 进程状态的转换

4.5.3、进程的管理
  • 进程控制块(PCB)

    • OS为了管理和控制进程的运行,为每个进程定义一个用于记录进程信息的表
    • 是进程存在的唯一标志,随着进程的创建二建立,随着进程的撤销而消失
    • 在进程生命周期中,OS利用PCB对进程进行调度和资源分配
  • PCB包含的信息

    • 进程标识信息:用于区别不同进程

    • 位置信息:程序和数据的存放位置

    • 状态信息:进程当前状态

    • 进程优先级:用于进程调度

    • 进程现场保护区

    • 队列指针:将同一状态进程链接成一个队列

      ……

4.5.4、进程调度策略
  • 先来先服务
  • 时间片轮转
  • 优先级法:抢占式、非抢占式
  • 多级反馈队列轮转
4.5.5利用Python查看进程信息

psutil库说明文档

  • 打印系统中所有进程的信息
import psutil
for p in psutil.process_iter():#查看w
    try:
        print(p.pid)
        print(p.name())
        print(p.status())
        print(p.username())
        print(p.cpu_percent())
        print('-'*10)
    except:
        print('-'*10)
print('*'*50)

for p in psutil.process_iter():
    if 'notepad' in p.name().lower():
        print(p.name(),end='\t')
        print(p.cmdline())
4.5.6、打开和关闭功能
from subprocess import Popen
import psutil
import os

def openOneTxt(path):
    if os.path.exists(path) and path.endswith('.txt'):
        Popen( ['notepad.exe', path] )

def openManyTxt(paths):
    for path in paths:
        openOneTxt(path)
        
def closeAllTxt():
    for p in psutil.process_iter():
        if p.name().lower()=='notepad.exe':
            p.terminate()


import time
paths=['红楼梦\\第001回.txt',
       '红楼梦\\第002回.txt',
       '红楼梦\\第003回.txt',
       '红楼梦\\第004回.txt']
openManyTxt(paths)
time.sleep(3)
closeAllTxt()
4.6、文件合并工具(III)
4.6.1、生成主窗口
import tkinter as tk
window =tk.TK()
window.title('文件合并工具')#标题窗口
window.geometry('440x600+300+200')
#窗口宽440,高600;窗口左上角离屏幕左侧距离300,离屏幕上方距离200
window.resizable(False,False)
window.mainloop()
4.6.2、添加控件
  • 控件:按钮、文本框、滚动式文本框、标签

    import tkinter as tk
    from tkinter import scrolledtext
    
    #主窗口
    window = tk.Tk()
    window.title('文件合并工具')
    window.geometry('440x600+300+200')
    window.resizable(False, False)
    
    #“添加文件”按钮
    button_addFile=tk.Button(window,text='添加文件',font=('楷体',12))
    button_addFile.place(x=20, y=20, width=120, height=40)
    
    #“添加文件夹”按钮
    button_addDir=tk.Button(window,text='添加文件夹',font=('楷体',12))
    button_addDir.place(x=160, y=20, width=120, height=40)
    
    #“开始合并”按钮
    button_merge=tk.Button(window,text='开始合并',font=('楷体',12), bg='orange')
    button_merge.place(x=300, y=20, width=120, height=40)
    
    #用于展示所选文件对应路径的文本框(可滚动)
    textbox_txtPath=scrolledtext.ScrolledText(window)
    textbox_txtPath.place(x=20,y=70,width=400,height=400)
    
    #“生成结果”标签
    label=tk.Label(window, text='生成结果:', font=('楷体',12))
    label.place(x=20,y=490,width=100,height=40)
    
    #用于展示生成结果路径的文本框
    textbox_resultPath=tk.Text(window)
    textbox_resultPath.place(x=120,y=490,width=300,height=40)
    textbox_resultPath.configure(state=tk.DISABLED)#不可修改
    
    #“打开结果”按钮
    button_openResult=tk.Button(window,text='打开结果',font=('楷体',12), bg='orange')
    button_openResult.place(x=20, y=540, width=120, height=40)
    
    #“打开所有”按钮
    button_openAll=tk.Button(window,text='打开原始文件',font=('楷体',12))
    button_openAll.place(x=160, y=540, width=120, height=40)
    
    #“关闭所有”按钮
    button_closeAll=tk.Button(window,text='关闭所有文件',font=('楷体',12))
    button_closeAll.place(x=300, y=540, width=120, height=40)
    
    #显示图形化界面
    window.mainloop()
    
4.6.3、消息响应
import tkinter as tk
from tkinter import scrolledtext
from tkinter import filedialog

def clickButton_addFile():
    filePaths = filedialog.askopenfilename(title = '选择文件',filetypes = [('txt','.txt')])
    for filePath in filePaths:
        				textbox_txtPath.insert(tk.END,filePath+'\n')
    textbox_txtPath.see(tk.END)

#主窗口
window = tk.Tk()
window.title('文件合并工具')
window.geometry('440x600+300+200')
window.resizable(False, False)

#“添加文件”按钮
button_addFile=tk.Button(window,text='添加文件',font=('楷体',12))
button_addFile.place(x=20, y=20, width=120, height=40)

#“添加文件夹”按钮
button_addDir=tk.Button(window,text='添加文件夹',font=('楷体',12))
button_addDir.place(x=160, y=20, width=120, height=40)

#“开始合并”按钮
button_merge=tk.Button(window,text='开始合并',font=('楷体',12), bg='orange')
button_merge.place(x=300, y=20, width=120, height=40)

#用于展示所选文件对应路径的文本框(可滚动)
textbox_txtPath=scrolledtext.ScrolledText(window)
textbox_txtPath.place(x=20,y=70,width=400,height=400)

#“生成结果”标签
label=tk.Label(window, text='生成结果:', font=('楷体',12))
label.place(x=20,y=490,width=100,height=40)

#用于展示生成结果路径的文本框
textbox_resultPath=tk.Text(window)
textbox_resultPath.place(x=120,y=490,width=300,height=40)
textbox_resultPath.configure(state=tk.DISABLED)#不可修改

#“打开结果”按钮
button_openResult=tk.Button(window,text='打开结果',font=('楷体',12), bg='orange')
button_openResult.place(x=20, y=540, width=120, height=40)

#“打开所有”按钮
button_openAll=tk.Button(window,text='打开原始文件',font=('楷体',12))
button_openAll.place(x=160, y=540, width=120, height=40)

#“关闭所有”按钮
button_closeAll=tk.Button(window,text='关闭所有文件',font=('楷体',12))
button_closeAll.place(x=300, y=540, width=120, height=40)

#显示图形化界面
window.mainloop()


4.6.4、再谈import语句
#位于同一文件夹下的不同Py文件之间相互调用其内部的函数,则可以利用import函数来进行调用。
#调用规则:调用的文件中的函数是将被调用的文件重新执行一边
#解决方法:if__name__=='__main__'

#a.py
myPi = 3.14
def myFunction(x):
    return x^2
#直接执行a.py则为True,a.py被导入时为False
if__name__=='__main__':
    print(myFunction(myPi))

#b.py
import a
print(a.myPi)
print(a.myFunction(3))
4.6.5、文件合并工具程序
#myFile.py
import os

'''
获取dirpath文件夹下所有txt文件的路径
'''
def getTxtPaths(dirpath):
    paths = [ ]
    filenames = os.listdir(dirpath)
    for filename in filenames :
        filepath = os.path.join(dirpath,filename)
        if os.path.isfile(filepath) and filename.endswith('.txt'):
            paths.append(filepath)
    return paths


'''
读取一个txt文件的内容,filepath是文件路径
'''
def readOneTxt(filepath):
    try:
        file = open(filepath, 'r')
        text = file.read()
        file.close()
        return text
    except:
        return ''


'''
将多个txt文件(原始文件)合并成一个txt文件(结果文件)
srcPaths是一个列表,存放了所有原始文件的路径
destPath是一个字符串,表示结果文件的路径
'''
def mergeTxts(srcPaths, destPath):
    destFile = open(destPath, 'w')
    for srcPath in srcPaths:
        text = readOneTxt(srcPath)
        if text != '':
            destFile.write(text)
            destFile.write('\n'*2+'-'*50+'\n'*2)
    destFile.close()
    return os.path.realpath(destPath)

if __name__ == '__main__':
    srcPaths = getTxtPaths('红楼梦')  #获取“红楼梦”文件夹下所有txt文件的路径
    mergeTxts(srcPaths, 'result.txt') #对文本文件进行合并
    print(readOneTxt('result.txt'))   #读取并打印结果文件
#myProcess.py
from subprocess import Popen
import psutil
import os

def openOneTxt(path):
    if os.path.exists(path) and path.endswith('.txt'):
        Popen( ['notepad.exe', path] )

def openManyTxt(paths):
    for path in paths:
        openOneTxt(path)
        
def closeAllTxt():
    for p in psutil.process_iter():
        if p.name().lower()=='notepad.exe':
            p.terminate()

if __name__ == '__main__':
    import time
    paths=['红楼梦\\第001回.txt',
           '红楼梦\\第002回.txt',
           '红楼梦\\第003回.txt',
           '红楼梦\\第004回.txt']
    openManyTxt(paths)
    time.sleep(3)
    closeAllTxt()
#注意与myFile、myprocess在同一文件夹下执行
#myTool.py
import tkinter as tk
from tkinter import scrolledtext
from tkinter import filedialog
import myFile
import myProcess

#“添加文件”按钮的消息响应函数
def clickButton_addFile():
    filePaths=filedialog.askopenfilenames(title='选择文件',filetypes=[('txt', '.txt')])
    for filePath in filePaths:
        textbox_txtPath.insert(tk.END,filePath+'\n')
    textbox_txtPath.see(tk.END)

#“添加文件夹”按钮的消息响应函数
def clickButton_addDir():
    dirpath=filedialog.askdirectory(title='选择文件夹')
    filePaths = myFile.getTxtPaths(dirpath)
    for filePath in filePaths:
        textbox_txtPath.insert(tk.END,filePath+'\n')
    textbox_txtPath.see(tk.END)
    
#“开始合并”按钮的消息响应函数
def clickButton_merge():
    tmp = textbox_txtPath.get(0.0, tk.END)
    filePaths = tmp.split('\n')
    destPath = myFile.mergeTxts(filePaths, 'result.txt')
    textbox_resultPath.configure(state=tk.NORMAL)
    textbox_resultPath.delete(0.0, tk.END)
    textbox_resultPath.insert(0.0, destPath)
    textbox_resultPath.configure(state=tk.DISABLED) 
    
#“打开结果”按钮的消息响应函数
def clickButton_openResult():
    destFile = textbox_resultPath.get(0.0, tk.END).strip()
    myProcess.openOneTxt(destFile)
    
#“打开原始文件”按钮的消息响应函数
def clickButton_openAll():
    tmp = textbox_txtPath.get(0.0, tk.END)
    filePaths = tmp.split('\n')
    myProcess.openManyTxt(filePaths)

#“关闭所有文件”按钮的消息响应函数
def clickButton_closeAll():
    myProcess.closeAllTxt()

#主窗口
window = tk.Tk()
window.title('文件合并工具')
window.geometry('440x600+300+200')
window.resizable(False, False)

#“添加文件”按钮
button_addFile=tk.Button(window,text='添加文件',font=('楷体',12), command=clickButton_addFile)
button_addFile.place(x=20, y=20, width=120, height=40)

#“添加文件夹”按钮
button_addDir=tk.Button(window,text='添加文件夹',font=('楷体',12), command=clickButton_addDir)
button_addDir.place(x=160, y=20, width=120, height=40)

#“开始合并”按钮
button_merge=tk.Button(window,text='开始合并',font=('楷体',12), bg='orange', command=clickButton_merge)
button_merge.place(x=300, y=20, width=120, height=40)

#用于展示所选文件对应路径的文本框(可滚动)
textbox_txtPath=scrolledtext.ScrolledText(window)
textbox_txtPath.place(x=20,y=70,width=400,height=400)

#“生成结果”标签
label=tk.Label(window, text='生成结果:', font=('楷体',12))
label.place(x=20,y=490,width=100,height=40)

#用于展示生成结果路径的文本框
textbox_resultPath=tk.Text(window)
textbox_resultPath.place(x=120,y=490,width=300,height=40)
textbox_resultPath.configure(state=tk.DISABLED)#不可修改

#“打开结果”按钮
button_openResult=tk.Button(window,text='打开结果',font=('楷体',12), bg='orange', command=clickButton_openResult)
button_openResult.place(x=20, y=540, width=120, height=40)

#“打开所有”按钮
button_openAll=tk.Button(window,text='打开原始文件',font=('楷体',12), command=clickButton_openAll)
button_openAll.place(x=160, y=540, width=120, height=40)

#“关闭所有”按钮
button_closeAll=tk.Button(window,text='关闭所有文件',font=('楷体',12), command=clickButton_closeAll)
button_closeAll.place(x=300, y=540, width=120, height=40)

#显示图形化界面
window.mainloop()


4.7、单元小结
七、网络知多少
5.1、互联网从何而来
  • 起源:美国组件了美国国防部高级研究计划局ARPA
  • 统一:TCP/IP协议
5.2、互联网如何工作
5.2.1、互联网的传输介质
  • 有线传输介质

    • 双绞线(传输距离较短(<100m))

      • 非屏蔽双绞线(Unshielded Twisted Pair,UTP)
      • 屏蔽双绞线(Shielded Twisted Pair,STP)
  • 同轴电缆

  • 光导纤维

5.2.2、互联网的关键设备
  • 网络适配器(网卡)

  • MAC地址(物理地址:16进制)

    • 设置在网络适配器(网卡)接口上,全球唯一
    • 长度:6字节(48位)
    • 前3个字节由IEEE的注册管理机构负责个不同的厂家分配的代码
    • 后3个字节由各厂家自行指派给生产的网络适配器接口
  • 交换机

    • 用于搭建局域网,即插即用
    • 实现多台计算机之间数据的并发交换
    • 根据交换机表中的表表项转发数据报文

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 路由器

    • 用于实现 多个网络之间的互联
    • 网络的调度中心和交通枢纽
5.3、互联网“吸粉”的奥秘
5.3.1、TCP/IP协议体系
  • OSI(Open System Interconnection Reference Model,开放系统互联参考模型)

  • TCP/IP(Transmision Control Protocol/Internet Protocol,传输控制协议/网际协议)

  • TCP/IP体系协议结构

  • 网络协议:未进行数据交换而建立的规则标准或约定

  • 组成要素:

    • 语法:数据与控制信息的结构或格式

    • 语义:数据与控制信息的含义

    • 同步:规定事件实现顺序的详细说明

5.3.2、IP地址
  • 全网唯一性,标识每个设备的位置和身份

  • IPv4地址

    • 32位二进制数表示
    • 点分十进制表示法(192.168.10.123)
  • IP地址的构成(网络号+主机号)

    • 主机号全为0代表本网络的网络地址号(主机号不能全为0或1)
    • 主机号全为1代表本网络段的广播地址(网络号不能全为0或1)
  • IP地址的分类

    • A类IP地址

      • 地址范围:0.0.0.0~127.255.255.255

      • 特殊用途:0.X.Y.Z、10.X.Y.Z、127.X.Y.Z

      • 可分配给27-3 = 125 个网络

      • 主机号不能全为0或1(包括B类和C类)

        每个A类网络可容纳224-2 = 16777214台主机

    • B类IP地址

      • 地址范围:128.0.0.0~191.255.255.255
      • 特殊用途:172.16.0.0~172.31.255.255
      • 可分配给214-16 = 16368个网络
      • 每个B类网络可容纳216-2 = 65534台主机
    • C类IP地址

      • 地址范围:192.0.0.0~223.255.255.255
      • 特殊用途:192.168.0.0~192.168.255.255
      • 可分配给221-256 = 2096896网络
      • 每个C类网络可容纳28-2 = 254台主机
  • 划分子网

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 把一个较大的网络划分成几个较小的子网
    • 主机号中分出若干位作为子网号
    • IP地址由两级变成三级
  • 子网掩码

5.3.3、域名系统
  • 域名

    • 用来代替难记忆、无意义的IP地址

    • 具有唯一性

    • 由一串用点分隔的名字组成

    • 采用层次结构,从左到右,域的范围变大

  • 域名系统

    • DNS(Domain Name System, 域名系统)
    • 将域名映射为IP地址
    • 由一组专门的服务器组成
5.3.4、网络组建
  • 小型局域网
    • 交换机
    • 网线和水晶头
      • 分类:CAT5(五类)、Cat5e(超五类)、Cat6(六类)、Cat6a(超六类)、Cat7(七类)
    • 路由器
5.4、“触摸”万维网——网络数据获取
5.4.1、数据获取——分数线目录页
  • URL——统一资源定位符

    • URL(Uniform Resource Locator,统一资源定位符)

    • <协议>://<主机名>:[端口号]/<被访问的网页在服务器上的路径>

      https://www.nudt.edu.cn/bkzs/xxgk/lqfs/index.html

  • HTTP协议(HyperText Transfer Protocol,超文本传输协议)

    • 基于TCP/IP的应用层协议
    • 规定了浏览器和服务器之间请求和响应的交互过程必须遵守的规则
    • B/S模式
      • browser:浏览器使用HTTP协议发送、接收web对象,并显示
      • server:Web服务器使用HTTP协议响应客户请求发送对象
    import urllib.request as req
    url = 'https://www.nudt.edu.cn/bkzs/'
    webpage = req.urlopen(url)
    webdata = webpage.read()
    webdata = webdata.decode('utf-8')
    print(webdata)
    
5.4.2、数据分析——提取历年分数线数据页
import urllib.request as req
url = 'https://www.nudt.edu.cn/bkzs/xxgk/lqfs/index.htm'
webpage = req.urlopen(url)
webdata = webpage.read().decode('utf-8')
for year in range(2016,2024):
    substr = str(year)+'年录取分数统计'
    index = webdata.find(substr)
    href = webdata[index-133:index-97]
    href = 'https://www.nudt.edu.cn/bkzs/xxgk/lqfs/'+href
    webpage = req.urlopen(href)
    content = webpage.read().decode('utf-8')
    #print(content)
    
    outfile = open(str(year)+'年录取分数网页.txt','w',encoding = 'utf-8')
    outfile.write(content+'\t')
    outfile.close()
5.4.3、数据分析——提取历年分数线的数据
  • 正则表达式

    • 用于表示一系列符号某一模式的字符串

    • 常用于字符串查找、替换、文本解析等

    • 点好(·):某一个字符,不包括换行符’\n’

      a.b:以a开头、以b结尾、长度为3的所有字符串

    • 星号(*):前一字符出现0到无限次

      a*b:以a开头、以b结尾所有字符串

    import re
    s = 'abd000\n0000acb'
    ab = re.findall(r'a.b*',s,re.S)#贪婪模式
    ab = re.findall(r'a.*?b',s,re.S)#非贪婪模式
    #findall找出所有匹配正则表达式的字串
    #r定义正则表达式
    #使点号匹配任意字符串,包括换行符
    #ab列表类型
    print(ab)
    
    import urllib.request as req
    import re
    url='https://www.nudt.edu.cn/bkzs/xxgk/lqfs/index.htm'
    webpage=req.urlopen(url)
    webdata=webpage.read().decode('utf-8')
    for year in range(2016, 2019):
        substr=str(year)+'年录取分数统计'
        index=webdata.find(substr)
        href=webdata[ index-133 : index-97 ]
        href='https://www.nudt.edu.cn/bkzs/xxgk/lqfs/'+href
        webpage=req.urlopen(href)
        content=webpage.read().decode('utf-8')
        tables=re.findall(r'<table.*?>(.*?)</table>',content, re.S)
        table=tables[0]
        rows = re.findall(r'<tr.*?>(.*?)</tr>', table, re.S)
        for row in rows:
            tds = re.findall(r'<td.*?>(.*?)</td>', row, re.S)
            for td in tds:
                print([ td ],'\n')
    
5.4.4、数据清洗——整理并保存数据
import urllib.request as req
import re
url='https://www.nudt.edu.cn/bkzs/xxgk/lqfs/index.htm'
webpage=req.urlopen(url)
webdata=webpage.read().decode('utf-8')
for year in range(2016, 2019):
    substr=str(year)+'年录取分数统计'
    index=webdata.find(substr)
    href=webdata[ index-133 : index-97 ]
    href='https://www.nudt.edu.cn/bkzs/xxgk/lqfs/'+href
    webpage=req.urlopen(href)
    content=webpage.read().decode('utf-8')
    tables=re.findall(r'<table.*?>(.*?)</table>',content, re.S)
    table=tables[0]
    rows = re.findall(r'<tr.*?>(.*?)</tr>', table, re.S)
    datalist = []
    for row in rows:
        tds = re.findall(r'<td.*?>(.*?)</td>', row, re.S)
        data_row = []
        for td in tds:
           	item = re.findall(r'<p.*?>(.*?)</p>',row,re.S)
           	if len(item)>0:
                data_row.append(item[0])
        datalist.append(data_row)
        outfile = open(str(year)+'年数据.txt','w',encoding = 'utf-8')
        for rows in datalist:
            for cell in rows:
                outfile.write(cell+'\t')
            outfile.write('\n')
        outfile.close()
5.5、小结
八、数据库探秘
6.1、MySQL的安装
  • 现代计算机主要用途之一:数据库管理
  • 数据库技术是数据库管理最有效的方法
    • 数据库技术已成为信息基础设施的核心技术之一
    • 数据库理论和技术是计算机领域的一个重要分支
    • 数据库系统的建设规模、信息的多少和使用频率已成为衡量一个国家信息化程度的重要标志
6.2、录取分数数据管理(II)
6.2.1、数据预处理
  • 删去标题行
  • 省份名用拼音表示
  • 空取值用NULL表示
6.2.2、问什么需要数据库
  • 利用文件系统同可以进行数据管理

  • 利用文件系统管理数据存在的问题

    • 程序员需要关注大量操作细节,负担很重

    • 数据可能因误操作、认为等原因存在错误

    • 数据格式发生变化,程序页需进行修改

      ……

  • 数据库系统(DBS)

    • 应用程序
    • 数据库管理系统(DBMS)
    • 数据库(DB):再不引起混淆的情况下,常把数据库系统简称为数据库
6.2.3、关系数据库
  • 关系:简单理解即二维表

    • 元组(或记录):表中一行
    • 属性:表中列
    • 主关键字(或主码)
      • 挑选出的一组属性,用来唯一标识每个元组
      • 元组的主关键字取值具有唯一性
  • 数据查询

    • 关系操作的最主要部分
    • 关系的查询表达能力很强
  • 数据更新

    • 插入、删除、修改
6.2.4、创建数据库
  • 查看数据库:show databases
    • 不区分大小写
    • 一般以分号结尾
    • 可以写成多行
  • 创建数据库:create database mydb
    • 数据库的名字
  • 删除数据库 drop database mydb
  • 选择数据库:uer mydb
    • 操作前要先选择一个数据库
6.2.5、创建基本列表
create table S(
	Sno		char(9),
    Sname	char(20),
    Ssex	char(2),
    Sage	int,
    primary key (Sno));
  • 可写成一行或多行,推荐后者
  • 注意标点,均为英文标点
  • 写在txt中,然后拷入cmd,以便修改
  • 查看数据库中所有表名:show tables;
  • 查看某表格的描述信息:desc S;
creat table grade(
	year	int,
    prov	char(100),
    ybx		int,
    jsMax	int,
    jsMin	int,
    jsAvg	int,
    hxMax	int,
    hxMin	int,
    hxAvg	int,
    primary key (year,prov)
);
6.3、录取分数数据管理(II)
6.3.1、数据更新
  • 插入数据(若属性名与表中数量、顺序相同,则可以省略)

    insert into S 
    values ('S1','Zhang','M',19);
    
  • 查看表中所有数据:select * from S;

  • 修改数据

    update S				改那个表
    set Sage = Sage + 1		怎么改
    where Ssex = 'M';		改哪些
    
  • 删除数据

    delete from S 			从那个表删
    where Sage>18;			删哪些
    
6.3.2、利用Python访问MySQL
import pymysql
#格式化打印游标中存放的结果
def display(cursor):
    #获取结果,结果的类型是嵌套元组,即元组中包含了很多小元组,小元组对应结果的一行
    records = cursor.detchall()
    print('\n-----',len(records),'lines -----')		#总行数
    for rec in records:		#对于每个小元组rec(对应表中一行)
        s = ''
        for value in rec :		#value相当于一行中的一个单元格
            s = s+str(value)+'\t'		#用制表符把这一行个单元格拼接成一个字符串
            print(s)

#连接数据库,相当于在命令行中执行mysql -uroot -p
conn = pymysql.connect(host = 'localhost', #MySQL所在主机(主机名、IP地址或域名),localhost为本机
                      user = 'root',	#账号
                      password = '11111',#密码,根据情况进行修改
                      charset = 'gbk')	#字符编码方式

#print(conn.get_host_info())	#显示MySQL所在主机信息(主机、端口等)

#获取游标
cs = conn.cursor()	#用于执行SQL语句并存放结果

#创建数据库
cs.execute('drop database if exists nudt')	#如存在nudt数据库则删除,execute函数用于执行括号内的SQL语句,若有结果则存于游标cs中
cs.execute('create databases nudt')	#创建nudt数据库
cs.execute('show databases')	#获取所有数据库名字
display(cs)		#格式化打印所有数据库名字

#创建表grade
conn.select_db('nudt')		#选择数据库nudt,相当于use nudt
cs.execute('create table grade(\
			year	int,\
			prov	char(100),\
			jsMax	int,\
			jsMin	int,\
			jsAvg	int,\
			hxMax	int,\
			hxMin	int,\
			hxAvg	int,\
			primary key (year,prov))')	#创建grade表
cs.execute('desc grade')	#获取表格的描述信息
display(cs)		#打印表格描述信息

#提交和关闭
conn.commit()	#提交结果
cs.close()		#关闭游标
conn.close()	#断开连接
6.3.3、字符串格式化
  • 占位符:整型(%d)、浮点型(%f)、字符串(%s)……
  • 格式设置
6.3.4、载入程序
  • SQL数据更新:insert、updata、delete

  • 利用Python访问MySQL:连接·用游标执行SQL语句·断开与关闭

    import pymysql
    
    #格式化打印游标中存放的结果
    def display(cursor):
        records=cursor.fetchall()   #获取结果,结果的类型是嵌套元组,即元组中包含了很多小元组,小元组对应结果中的一行
        print('\n-----', len(records), 'lines -----')   #总行数
        for rec in records:         #对于每个小元组rec(对应表中一行)
            s=''
            for value in rec:       #value相当于一行中的一个单元格
                s=s+str(value)+'\t' #用制表符把这一行各单元格拼接成一个字符串
            print(s)
    
    #连接数据库,相当于在命令行中执行mysql -uroot -p
    conn=pymysql.connect(host='localhost',  #MySQL所在主机(主机名、IP地址或域名),localhost为本机
                         user='root',       #账号
                         passwd='111111',   #密码,根据情况进行修改
                         charset='gbk')     #字符编码方式
    #print(conn.get_host_info())            #显示MySQL所在主机信息(主机、端口等)
    
    #获取游标
    cs = conn.cursor()  #用于执行SQL语句并存放结果
    
    #创建数据库
    cs.execute('drop database if exists nudt')  #若存在nudt数据库则删除,execute函数用于执行括号内的SQL语句,若有结果则存于游标cs中
    cs.execute('create database nudt')          #创建nudt数据库
    cs.execute('show databases')                #获取所有数据库名字
    #display(cs)                                 #格式化打印所有数据库名字
    
    #创建表grade
    conn.select_db('nudt')              #选择数据库nudt,相当于use nudt
    cs.execute('create table grade(\
                    year   int,\
                    prov   char(100),\
                    ybx    int,\
                    jsMax  int,\
                    jsMin  int,\
                    jsAvg  int,\
                    hxMax  int,\
                    hxMin  int,\
                    hxAvg  int,\
                    primary key (year, prov))')  #创建grade表(斜杠用于换行)
    cs.execute('desc grade')            #获取表格的描述信息
    #display(cs)                         #打印表格的描述信息
    
    #载入数据:将三个txt中的数据插入grade表
    for year in range(2014, 2017):              #对于2014~2016年中的某一年
        f=open(str(year)+'年数据.txt', 'r')     #打开这一年数据所在的txt文件
        while True:                             #依次处理文件中的每一行
            line=f.readline()                   #读取一行
            if line=='':                        #若这一行为空,表示文件读取完毕,跳出循环
                break                  
            v=line.split()                      #拆分这一行,得到对应的属性值
                                                #构建这一行对应的insert语句(斜杠用于换行)
            sql='insert into grade values\
                     (%s, "%s", %s, %s, %s, %s, %s, %s, %s)'\
                     % (year,v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
            cs.execute(sql)                     #执行插入语句,将这一行添加到grade表
        f.close()
    cs.execute('select * from grade')           #查询表中所有数据
    display(cs)
    
    #提交和关闭
    conn.commit()#提交结果
    cs.close()   #关闭游标
    conn.close() #断开连接
    
6.4、录取分数数据管理(III)
6.4.1、单表查询I
  • 查询所有学生的所有信息

    select *	所有属性
    from S;		从哪查
    
  • 查询所有学生的姓名和性别

    select Sname,Ssex		某些属性
    from S;		
    
  • 查询所有学生的姓名和性别,按性别升序排列

    select Sname,Ssex
    from S
    order by Ssex asc;	升序:asc,降序:desc
    
  • 查询所有学生的姓名和出生年份

    select Sname,2020-Sage
    from S;
    
  • 查询学生的平均年龄

    select avg(Sage)
    from S
    
  • 查询学生的总人数

    select count(Sno)
    from S;
    
  • 查询学生年龄,升序排列

    select Sage
    form S 
    order by Sage asc;
    
  • 查询学生年龄,升序排列,不重复

    select distinct Sage
    from S 
    order by Sage asc;
    
6.4.2、单表查询II
  • 查询女同学的姓名

    select Sname	挑选列(投影)
    from S
    where Ssex = 'F'挑选行(选择)
    
  • 查询18岁以上同学的姓名和年龄

    select Sname,Sage 
    from S 
    where Sage>18;
    
  • 查询18~20岁(包括)的同学的姓名和年龄

    select Sname,Sage
    from S 
    where Sage>=18 and Sage<=20;
    还可以使用or、not
    
6.4.3、多表查询
  • 连接的两种方式

    select Sname 
    from SC join S on S.Son = SC.Sno
    where Cno = 'C7';
    第二种
    select Sname 
    from SC ,S
    where S.Sno = SC.Sno and Cno = 'C7';
    
6.4.2、在Python中查询
import pymysql
import matplotlib pyplot as plt

#格式化打印
def display(cursor):
    records = cursor.fetchall()
    print('\n-----',len(records),'line -----')
    for rec in records:
        s = ''
        for value in rec:
            s = s+str(value)+'\t'
        print(s)
        
#图形化显示
def plot(cursor):
    records = cursor.fetchall()
    prov.frades = [],[]
    for rec in records:
        prov.append(rec[0])
        grades.append(int(rec[1]))
    plt.barh(range(len(grades)),grades,color = 'rgb',tick_lable = prov)	#barh是横向柱状图
    plt.show()
    
conn = pymysql.connect(host = 'localhost',
                      user = 'root',
                      password = '1111',
                      charset = 'gbk')	#连接数据库
conn.select_db('nudt')	#选择数据库
cs = conn.cursor()	#创建游标
sql = 'select prov , jsAvg from grade where year = 2016'
#sql = 'select prov,ybx from grade where year = 2015 order by ybx desc'
cs.esecute(sql)		#执行查询语句
#display(cs)		#打印结构
plot(cs)			#绘制结果
cs.close()			#关闭游标
conn.close()		#断开连接
6.5、单元小结

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
#读取一行
if line==‘’: #若这一行为空,表示文件读取完毕,跳出循环
break
v=line.split() #拆分这一行,得到对应的属性值
#构建这一行对应的insert语句(斜杠用于换行)
sql=‘insert into grade values
(%s, “%s”, %s, %s, %s, %s, %s, %s, %s)’
% (year,v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
cs.execute(sql) #执行插入语句,将这一行添加到grade表
f.close()
cs.execute(‘select * from grade’) #查询表中所有数据
display(cs)

#提交和关闭
conn.commit()#提交结果
cs.close() #关闭游标
conn.close() #断开连接


##### 6.4、录取分数数据管理(III)

###### 6.4.1、单表查询I

* 查询所有学生的所有信息

```mysql
select *	所有属性
from S;		从哪查
  • 查询所有学生的姓名和性别

    select Sname,Ssex		某些属性
    from S;		
    
  • 查询所有学生的姓名和性别,按性别升序排列

    select Sname,Ssex
    from S
    order by Ssex asc;	升序:asc,降序:desc
    
  • 查询所有学生的姓名和出生年份

    select Sname,2020-Sage
    from S;
    
  • 查询学生的平均年龄

    select avg(Sage)
    from S
    
  • 查询学生的总人数

    select count(Sno)
    from S;
    
  • 查询学生年龄,升序排列

    select Sage
    form S 
    order by Sage asc;
    
  • 查询学生年龄,升序排列,不重复

    select distinct Sage
    from S 
    order by Sage asc;
    
6.4.2、单表查询II
  • 查询女同学的姓名

    select Sname	挑选列(投影)
    from S
    where Ssex = 'F'挑选行(选择)
    
  • 查询18岁以上同学的姓名和年龄

    select Sname,Sage 
    from S 
    where Sage>18;
    
  • 查询18~20岁(包括)的同学的姓名和年龄

    select Sname,Sage
    from S 
    where Sage>=18 and Sage<=20;
    还可以使用or、not
    
6.4.3、多表查询
  • 连接的两种方式

    select Sname 
    from SC join S on S.Son = SC.Sno
    where Cno = 'C7';
    第二种
    select Sname 
    from SC ,S
    where S.Sno = SC.Sno and Cno = 'C7';
    
6.4.2、在Python中查询
import pymysql
import matplotlib pyplot as plt

#格式化打印
def display(cursor):
    records = cursor.fetchall()
    print('\n-----',len(records),'line -----')
    for rec in records:
        s = ''
        for value in rec:
            s = s+str(value)+'\t'
        print(s)
        
#图形化显示
def plot(cursor):
    records = cursor.fetchall()
    prov.frades = [],[]
    for rec in records:
        prov.append(rec[0])
        grades.append(int(rec[1]))
    plt.barh(range(len(grades)),grades,color = 'rgb',tick_lable = prov)	#barh是横向柱状图
    plt.show()
    
conn = pymysql.connect(host = 'localhost',
                      user = 'root',
                      password = '1111',
                      charset = 'gbk')	#连接数据库
conn.select_db('nudt')	#选择数据库
cs = conn.cursor()	#创建游标
sql = 'select prov , jsAvg from grade where year = 2016'
#sql = 'select prov,ybx from grade where year = 2015 order by ybx desc'
cs.esecute(sql)		#执行查询语句
#display(cs)		#打印结构
plot(cs)			#绘制结果
cs.close()			#关闭游标
conn.close()		#断开连接
6.5、单元小结

[外链图片转存中…(img-wBD1GB1f-1735281118896)]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值