Python学习笔记

参考视频:黑马程序员python教程,8天python从入门到精通,学python看这套就够了_哔哩哔哩_bilibili

目录

前言

第一、二章 基础知识

第三章 判断

第四章 循环

第五章 函数

第六章 容器

第七章 函数补充

第八章 文件

第九章 异常、模块、包

第十章 综合案例(可视化)

第二阶段 第一部分面向对象

第二阶段 第二部分 SQL


前言

本文主要记录学习python过程中记录的笔记,包含部分代码


第一、二章 基础知识

# 单行注释

"""1.字面量--在代码中被写下来的固定的值,称之为字面量
数字--int float complex(复数) bool  复数:4+3j,以j结尾表示复数
字符串--string  用引号包围起来
列表--List 有序的可变序列
元组--Tuple 有序的不可变序列
集合--Set 无序不重复集合
字典--Dictionary 无序Key-Value集合
"""
# print(666)
# print(13.14)
# print("黑马程序员")

"""
2.变量--在程序运行时,能存储计算结果或能表示值的抽象概念
 -变量定义格式  变量名称=变量的值
 -每一个变量都有自己的名称,称之为:变量名,也就是变量本身
 -每一个变量都有自己存储的值,称之为:变量值
"""
# money = 50
# print("当前钱包余额:",money)
#
# money -= 10
# print("购买了冰激凌,花费:", 10, "元")
#
# money -= 5
# print("购买了可乐,花费:", 5, "元")
# print("最终,钱包剩余:",money)

"""
3.数据类型
-type()语句
-变量无类型 存储的数据有类型 type(变量)查看的是变量存储的数据的类型

"""
# print(type(666))
# print(type(11.11))
# print(type("123"))
# name = "123"
# print(type(name))

"""4.数据类型转换
 -从文件中读取的数字,默认是字符串,我们需要转换成字符类型
 -后续学习的input()语句,默认结果是字符串,若需要数字也需要转换
 -将数字转换成字符串用以写出到外部系统
 - int(x) 将x转换为一个整数  字符串里面只有数字的时候才可以转成int 否则会报错
 -float(x) 将x转换为一个浮点数  浮点数转整数会丢失精度
 -str(x) 将对象x转换为字符串
"""
# number_str = str(11)
# print(type(number_str),number_str)

# error:
# num3 = int("黑马程序员")
# print(type(num3),num3)

"""
5.标识符--在用户编程的时候所使用的一系列名字,用于给变量、类、方法等命名
 -python中标识符命名规则有内容限定、大小写敏感、不可使用关键字
 -内容限定→标识符命名中只允许出现:英文、中文、数字、下划线这四类元素  不推荐使用中文、数字不可以开头
 -大小写敏感 Andy和andy是两个变量 完全区分
 -不可使用关键字→false true as if else等等 关键字同样大小写敏感
 -命名规范 见名知意、下划线命名(多个单词组合用下划线分隔)、英文字母全小写
"""

"""
6.运算符
 算术运算符--加减乘除、取整除(返回商的整数部分)、取余(返回除法的余数)、指数(10**20为10的20次方)
 赋值和复合赋值运算符-- =、+=、-=、*=、/=、%=、**=、//=
"""
# print("1+1=", 1+1)
# print("2-1=", 2-1)
# print("3*3=", 3*3)
# print("4/2=", 4/2)
# print("9//2=", 9//2)
# print("9%2=", 9 % 2)
# print("2**4=", 2**4)
# num = 20
# num+=1
# print("num+1=",num)
# num-=1
# print("num-1=",num)
# num*=2
# print("num*2=",num)
# num/=2
# print("num/2=",num)
# num**=2
# print("num**2=",num)
# num//=2
# print("num//2=",num)
# num%=2
# print("num%2=",num)

"""
7.字符串扩展
-字符串的三种定义方法
  --单引号定义法、双引号定义法、三引号定义法(使用变量接受就是字符串,不接受就是多行注释)
  --字符串引号嵌套 单引号定义法可以内含双引号、双引号定义法可以内含单引号、可以使用转义字符\来将引号解除效用,变成普通字符串
-字符串拼接
  --两个字符串字面量/字符量和变量/变量和变量之间都可以通过+进行拼接  字符串无法和非字符串类型进行拼接
-字符串格式化
  --通过 "%占位符" % 变量 语法实现字符串和变量的快速拼接 变量可以为数字类型
  --%s 的%表示我要占位 s表示将变量变成字符串放入占位的地方 
  --如果有多个变量占位,变量要用括号括起来并按照占位的顺序填入 
  --%d 将内容转换成整数,放入占位位置
  --%f 将内容转换成浮点型,放入占位位置
-格式化的精度控制
  --使用辅助符号"m.n"来控制数据的宽度和精度  
  --m控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效   %5d表示将整数的宽度控制在5位,如数字11会变成[空格][空格][空格]11
  --.n 控制小数点精度,要求是数字,会进行小数的四舍五入  %5.2f表示将宽度控制为5,小数点精度设置为2,如11.345设置%7.2f,结果为[空格][空格]11.35
-字符串格式化方式2
  --通过语法 f"内容{变量}"的格式快速格式化 快速格式化不做精度控制,原样输出  f就是format的意思
-对表达式进行格式化
  --表达式:一条具有明确执行结果的代码语句
  --在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码
  --f"{表达式}"  "%s/%d/%f" % (表达式、表达式、表达式)
"""
# 课后习题
# name = "xxx公司"
# stock_price = 19.99
# # 股票代码
# stock_code = 111111
# # 股票每日增长系数 浮点数类型
# stock_price_daily_growth_factor = 1.2
# # 增长天数
# growth_days = 7
# # 计算经过growth_days天的增长后,股价达到了多少钱  使用字符串格式化进行输出,如果是浮点数,要求小数点精度2位数
# print(f"公司:{name},股票代码:{stock_code},当前股价:{stock_price}")
# print("每日增长系数是:%.1f,经过%d天的增长后,股价达到了:%.2f" % (stock_price_daily_growth_factor,growth_days,(stock_price*(stock_price_daily_growth_factor**growth_days))))


# print("1*1的结果是:%d" % (1*1))
# print(f"1*1的结果是:{1*1}")
# print("字符串在python中的类型是:%s" % type('字符串'))

# name = "kiki"
# year = 2003
# high = 161.5
# print(f"我是{name},我出生于{year},我的身高是{high}")

# name1 = 'kiki'
# name2 = "kiki"
# name3 = """kiki...."""
# print(name1)
# print(name2)
# print(name3)

# name1 = '"kiki"'
# name2 = "'kiki'"
# name3 = "\"kiki\""
# print(name1)
# print(name2)
# print(name3)

#字符串拼接
# str1 = "好好学习"
# str2 = "天天向上"
# num1=1111
# print("好好学习"+"天天向上")
# print("好好学习"+str1)
# print(str1+str2)
# print("好好学习"+num1)  error

# num1 = 111
# num2 = 222
# name = "天天向上"
# message = "好好学习 %s" % name
# message2 = "好好学习 %s: %s 和 %s" % (name,num1,num2)
# print(message)
# print(message2)

# print("%.2f" % 11.3456)
# print("%7d" % 11)


"""
8.数据输入
-获取键盘输入 input()
--input()语句可以在要求使用者输入内容前输出提示内容,而不用单独写print语句 提示信息写在input括号里就行
--输入的数据不管是什么类型 input()默认当做字符串处理 有需要则进行数据类型转换即可
"""
# print("What's your name?")
# name = input()
# print("My name is %s" % name)

# name = input("What's your name?")
# print("My name is %s"% name)

#练习
user_name = input("请输入您的名称")
user_type = input("请输入您的用户类型")
print(f"您好:{user_name},您是尊贵的:{user_type}用户,欢迎您的光临")

第三章 判断

"""
1.布尔类型和比较运算符
-布尔类型 bool表达现实生活中的逻辑,即真和假  True表示真1  False表示假0
-定义布尔类型数据  变量名称=布尔类型字面量  布尔类型的数据不仅可以通过定义得到,也可以通过比较运算符进行内容比较得到
-比较运算符 ==、!=、>、<、>=、<=  可用于字符串之间的比较、数字之间的比较
"""
# bool1 = True
# bool2 = False
# print(f"bool1的内容是:{bool1},类型是:{type(bool1)}")

"""
2.if语句的基本格式
- if 要判断的条件: 
      条件成立时,要做的事情
-判断条件的结果一定要是布尔类型、不要忘记判断条件后的冒号、归属于if语句的代码块前方要填充4个空格缩进
"""
# age = 30
# if age >= 18:
#     print("你已经成年了")
#     print("是个大人了")
# print("时间好快")

# 练习
# 通过input语句,获取键盘输入,为变量age赋值(注意转换成数字类型)  通过if判断是否是成年人,满足条件则输出提示信息
# print("欢迎来到黑马儿童游乐场,儿童免费,成人收费")
# age = input("请输入您的年龄:")
# age = int(age)
# if age >= 18:
#     print("您已成年,游玩需要补票10元")
# print("祝您游玩愉快")

"""
3.if else语句
-if 条件:
    满足条件时要做的事情1
    满足条件时要做的事情2
    满足条件时要做的事情3
    。。。。。。
 else:
    不满足条件时要做的事情1
    不满足条件时要做的事情2
    不满足条件时要做的事情3
    。。。。。。
-else后不需要判断条件 和if代码块一样,else的代码块同样需要4个空格作为缩进
"""
# print("欢迎来到黑马儿童游乐场,儿童免费,成人收费")
# age = int(input("请输入您的年龄:"))
# if age >= 18:
#     print("您已成年,游玩需要补票10元")
# else:
#     print("您未成年,可以免费游玩。")
# print("祝您游玩愉快")

# 练习
# 通过input语句获取键盘输入的身高 判断身高是否超过120cm,并通过print给出提示信息
# print("欢迎来到黑马动物园")
# high = int(input("请输入你的身高(cm):"))
# if high >= 120:
#     print("您的身高超出120cm,游玩需要购票10元。")
# else:
#     print("您的身高未超出120cm,可以免费游玩。")
# print("祝您游玩愉快!")

"""
4.if elif else语句  判断是互斥的且有顺序的 空格缩进不可省略 input输入语句可以直接写入判断条件中
-if 条件1:
    条件1满足应做的事
 elif 条件2:
    条件2满足应做的事情
 elif 条件3:
    条件3满足应做的事情
 else:
    所有条件都不满足应做的事情
"""
# print("欢迎来到黑马动物园。")
# # height = int(input("请输入你的身高(cm):"))
# vip_level = int(input("请输入你的vip级别(1~5):"))
# if int(input("请输入你的身高(cm):")) < 120:
#     print("您的身高未超出120cm,可以免费游玩。")
# elif vip_level > 3:
#     print("您的vip级别大于3,可以免费游玩。")
# else:
#     print("不好意思,所有条件都不满足,需要购票10元。")
# print("祝您游玩愉快!")

# 练习
# 定义一个变量,数字类型,内容随意 基于input语句输入猜想的数字,通过if和多次elif组合,判断猜想的数字是否和心理数字一致
# num = 10
# if int(input("请输入第一次猜想的数字:")) == num:
#     print("恭喜第一次就猜对啦!")
# elif int(input("不对,再猜一次:")) == num:
#     print("猜对啦!")
# elif int(input("猜错了,再猜一次:")) == num:
#     print("恭喜,最后一次机会,你猜对了")
# else:
#     print("Sorry 猜错了")

"""
5.判断语句的嵌套 自由组合if elif else 完成特定需求的要求
-嵌套的关键点在于:空格缩进
-通过空格缩进,来决定语句之间的:层次关系
"""

"""
6.实战案例
需求:定义一个数字(1~10,随机产生),通过3次判断来猜出数字
要求:
(1)数字随机产生,范围1-10
(2)有3次机会猜测数字,通过3层嵌套判断实现
(3)每次猜不中,会提示大了或小了
"""
# 定义变量num,变量内存储随机数字
import random
num = random.randint(1,10)
guess_num = int(input("输入你猜测的数字:"))
if guess_num == num:
    print("恭喜你!第一次就猜中了!")
else:
    if guess_num > num:
        print("数字猜大了哦")
    else:
        print("数字猜小了哦")
    guess_num = int(input("再次输入你猜测的数字:"))
    if guess_num == num:
        print("恭喜你!第二次就猜中了!")
    else:
        if guess_num > num:
            print("数字猜大了哦")
        else:
            print("数字猜小了哦")

        guess_num = int(input("最后一次输入你猜测的数字:"))
        if guess_num == num:
            print("恭喜你!第三次就猜中了!")
        else:
            print("三次机会用完了,没有猜中")

第四章 循环

"""
1.while循环的基础语法  只要条件满足 会无线循环执行
-while 条件:
    条件满足时,做的事情
-while的条件需得到布尔类型,True表示继续循环,False表示结束循环,需要设置循环终止的条件,需要设置空格缩进
"""
# i = 0
# while i < 100:
#     print("我爱学习")
#     i+=1

# 练习
# 需求:通过while循环,计算从1累加到100的和
# 提示:终止条件不要忘记,设置为确保while循环100次,确保累加的数字,从1开始,到100结束
# i = 1
# sum = 0
# while i<=100:
#     sum +=i
#     i+=1
# print(sum)

"""
2.while循环的基础案例
-猜数字案例 设置一个范围1-100的随机整数变量 通过while循环,配合input语句,判断输入的数字是否等于随机数
-无限次机会,直到猜中为止  每一次猜不中 都会提示大了或小了  猜完数字后,提示猜了几次
"""
# import random
# num = random.randint(1,100)
# count = 1
# guess_num = int(input("请输入你猜的数字"))
# while guess_num != num:
#     if guess_num < num:
#         print("猜小了")
#     else:
#         print("猜大了")
#     guess_num = int(input("再次输入你猜的数字"))
#     count += 1
# print(f"恭喜你猜中啦!你总共猜了{count}次")

"""
3.while循环的嵌套应用
-同判断语句的浅谈一样,循环语句的嵌套,要注意空格缩进  基于空格缩进来决定层次关系
-注意条件的控制,避免无限循环
"""

"""
4.while循环的嵌套案例
-默认print输出会自动换行 想要输出不换行,只需要在print语句中加上 end='' 即可
-制表符 \t 效果等同于在键盘上按下tab键 可以将多行字符串进行对齐
-练习案例 打印九九乘法表
"""
# i = 1
# while i <= 9:
#     j = 1
#     while j <= i:
#         print(f"{j}*{i}={j*i}\t",end='')
#         j += 1
#     i += 1
#     print()

"""
5.for循环的基础语法
-for 临时变量 in 待处理数据集
    循环满足条件时执行的代码
-无法定义循环条件 只能从被处理的数据集中,依次取出内容进行处理  循环内的语句需要有空格缩进
-range 语句
   for循环中的待处理数据集严格来说应该称之为序列类型 序列类型指其内容可以一个个依次取出的一种类型 包括字符串、列表、元组等
   range语句→获得一个简单的数字序列   range(num)获取一个从0开始到num结束的数字序列(不含num)
   range(num1,num2)获得一个从num1开始到num2结束的数字序列(不包含num2)
   range(num1,num2,step)获得一个从num1开始,到num2结束的数字序列(不含num2)数字之间的步长,以step为准
-for循环的变量作用域  在编程规范上,作用域只限定在for循环内部  如果在for循环外部访问临时变量实际上是可以访问到的 在编程规范上是不允许不建议的

"""
# name = "kiki"
# # 将name的内容,挨个取出赋于x临时变量 就可以在循环体内对x进行处理
# for x in name:
#     print(x)

# 练习--数一数有几个a 定义字符串变量name,内容为"itheima is a brand of itcast" 通过for循环,遍历此字符串,统计有多少个英文字母"a"
# name = "itheima is a brand of itcast"
# count = 0
# for x in name :
#     if x == 'a':
#         count += 1
# print(f"{name}中共含有:{count}个字母a")
# for x in range(10):
#     print(f"{x}\t", end='')
# print()
# for x in range(0, 10):
#     print(f"{x}\t", end='')
# print()
# for x in range(0, 10, 2):
#     print(f"{x}\t", end='')
# 练习--偶数 定义一个数字变量num 内容随意 使用range语句获取从1到num的序列,使用for循环遍历,在遍历过程中统计有多少偶数出现
# num = 100
# count = 0
# for x in range(1,num):
#     if x % 2 == 0:
#         count += 1
# print(f"1到{num}(不含{num}本身)范围内,有{count}个偶数。")

"""
6.for循环的嵌套应用--注意缩进 嵌套for循环同样通过缩进确定层次关系 for循环和while循环可以相互嵌套使用
"""
# 练习-打印九九乘法表
# for i in range(1, 10):
#     # j = 1
#     # while j <= i:
#     #     print(f"{j}*{i}={j*i}\t",end='')
#     #     j += 1
#     for j in range(1,i+1):
#         print(f"{j}*{i}={j * i}\t", end='')
#     print()

"""
7.循环中断:break和continue
-continue 中断本次循环,直接进入下一次循环 嵌套下:它只可以使它所在的循环临时退出 for循环和while循环均可  
-break 直接结束循环 在嵌套循环中break一样只能控制它所在的循环结束
"""

"""
8.综合案例
-某公司,账户余额有1万元,给20名员工发工资
-员工编号1到20,从编号1开始,依次领取工资,每人可领1000元
-领工资时,财务判断员工的绩效分(1-10)(随机生成),如果低于5,不发工资,换下一位
-如果工资发完了,结束发工资
"""
import random
money = 10000
for i in range(1, 21):
    if money == 0:
        print("工资发完了,下个月领取吧")
        break
    num = random.randint(1, 10)
    if num < 5:
        print(f"员工{i},绩效分{num},低于5,不发工资,下一位")
        continue
    else:
        money -= 1000
        print(f"向员工{i}发放工资1000元,账户余额还剩余{money}元")

第五章 函数

"""
函数--是组织好的,可重复使用的,用来实现特定功能的代码段
为什么要学习、使用函数--为了得到一个针对特定需求、可供重复利用的代码段 提高程序的复用性,减少重复性代码,提高开发效率

"""
# def my_len(data):
#     count = 0
#     for i in data:
#         count += 1
#     print(f"字符串{data}的长度是{count}")
# str1 = "kiki"
# my_len(str1)

"""
1.函数的定义--函数必须先定义后使用
def 函数名(传入参数):
    函数体
    return 返回值
函数的调用  函数名(参数)
"""
# 练习--定义一个函数,函数名任意,要求调用函数后可以输出如下欢迎语
# def say():
#     print("欢迎来到黑马程序员!")
#     print("请出示您的健康码以及72小时核酸证明!")
# say()

"""
2.函数的参数
-函数传入参数的作用是在函数运行的时候,接受外部传入的数据
-函数定义中提供的参数x,y称之为:形式参数,表示函数声明将要使用2个参数 参数之间用逗号进行分隔
-函数调用中,提供的5和6,称之为:实际参数,表示函数执行时真正使用的参数值 传入的时候,按照顺序传入数据,使用逗号分隔
-传入参数的数量是不受限制的 可以不使用参数 也可以仅适用任意N个参数
"""
# def add(num1,num2):
#     result = num1 + num2
#     print(f"{num1}+{num2}={result}")
# add(2,3)

# 练习--定义一个函数,名称任意,并接受一个参数传入(数字类型,表示体温) 在函数内进行体温判断(正常范围:小于等于37.5度),并输出如下内容
# def justify(data):
#     print(f"欢迎来到黑马程序员!请出示您的健康码以及72小时核酸证明,并配合测量体温!")
#     if data <= 37.5:
#         print(f"体温测量中,您的体温是:{data}度,体温正常请进!")
#     else:
#         print(f"体温测量中,您的体温是:{data}度,需要隔离!")
#
# justify(37.3)
# justify(39.3)

"""
3.函数的返回值--return关键字,向调用者返回数据  函数体在遇到return后就结束了,return后的代码不会执行
-def 函数(参数...): 
     函数体
     return 返回值
 变量=函数(参数)
-无返回值的函数,实际上就是返回了None这个字面量 None空的,无实际意义的意思
-None用在if判断中,None等同于False 一般用于在函数中主动返回None,配合if判断做相关处理
-None用于声明无内容的变量上,定义变量,但暂时不需要变量有具体值,可以用None来代替 name=None
"""

"""
4.函数说明文档
-给函数添加说明文档,辅助理解函数的作用
"""
# def func(x,y):
#     """
#     函数说明 eg:add函数可以接收两个参数,进行两数相加的功能
#     :param x: 形参x的说明
#     :param y: 形参y的说明
#     :return: 返回值的说明
#     """
#     函数体
#     return 返回值

"""
5.函数的嵌套调用--一个函数里面又调用了另一个函数
-执行流程 函数A中执行到调用函数B的雨具 会将函数B全部执行完成后,继续执行函数A的剩余内容
"""

"""
6.变量的作用域--变量作用域指的是变量的作用范围(变量在哪里可以用,在哪里不可以用) 主要分为两类:局部变量和全局变量
-局部变量 定义在函数体内部的变量,即只在函数体内部生效  作用:在函数体内部,临时保存数据,当函数调用完成以后则销毁局部变量
-全局变量 在函数体内外都能生效的变量  在函数内修改全局变量失败(因为在函数内部写的变量又变成了全局变量
-可以使用global关键字在函数内部声明变量为全局变量
"""

"""
7.综合案例--黑马ATM
-主菜单、查询余额
-存取款
"""
# 用户余额
money = 0
name = input("请输入您的名字:")
def menu():
    """
    menu函数用于输出主菜单
    :return: 
    """
    print("-----------------主菜单----------------")
    print(f"{name},您好,欢迎来到黑马银行ATM。请选择操作:")
    print("查询余额\t[输入1]")
    print("存款\t[输入2]")
    print("取款\t[输入3]")
    print("退出\t[输入4]")

def search():
    """
    search函数用于查询用户余额
    :return:
    """
    print("-----------------查询余额----------------")
    global money
    print(f"{name},您好,您的余额剩余:{money}元")
    print()

def send(num):
    print("-----------------存款----------------")
    global money
    money += num
    print(f"{name},您好,您存款{num}元成功")
    print(f"{name},您好,您的余额剩余{money}元")
    print()

# 取款
def draw(num):
    print("-----------------取款----------------")
    global money
    global name
    money -= num
    print(f"{name},您好,您取款{num}元成功")
    print(f"{name},您好,您的余额剩余{money}元")
    print()

while 1:
    menu()
    select = int(input("请输入您的选择:"))
    if select == 1:
      search()
      continue
    elif select == 2:
        send_num = int(input("请输入您要存款的数额:"))
        send(send_num)
        continue
    elif select == 3:
        draw_num = int(input("请输入您要取款的数额:"))
        draw(draw_num)
        continue
    elif select == 4:
        breakd

第六章 容器

"""
1.数据容器入门
-一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素  每个元素,可以是任意类型的数据,如字符串、数字、布尔等
-数据容器根据特点的不同,如:是否支持重复元素,是否可以修改,是否有序等分为五类
   分别是:列表(list),元组(tuple),字符串(str),集合(set),字典(dict)
"""

"""
2.数据容器:List(列表)
-列表的定义 
  基本语法  字面量 [元素1,元素2,元素3,...]   定义变量  变量名称=[元素1,元素2,元素3...]  定义空列表 变量名称=[] 变量名称=list()
  列表内的每一个数据,称之为元素  以[]作为标识,列表内每一个元素之间用,逗号隔开
  列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套
-列表的下表索引 通过下标索引取数据,一定不要超出范围,会报错
  列表中的每一个元素都有其位置下标索引,从前向后的方向,从0开始,依次递增 
  反向索引-从后向前,索引从-1开始,依次递减
  语法: 列表[下表索引]
  嵌套列表也支持下标索引
-列表的常用操作
 列表除了可以定义、使用下标索引获取值 还有一系列功能:插入元素、删除元素、清空列表、修改元素、统计元素个数等等功能(方法)
 在python中,如果将函数定义为class(类)的成员,那么函数会称之为:方法
 方法和函数功能一样,有传入参数,有返回值,只是方法的使用格式不同
 -查找某元素的下标 查找指定元素在列表的下标,如果找不到,报错ValueError 语法:列表.index(元素)
 -修改特定位置(索引)的元素值 语法:列表[下标]=值 重新赋值
 -插入元素 语法:列表.insert(下标,元素),在指定的下标位置,插入指定的元素
 -追加元素 语法:列表.append(元素),将指定元素追加到列表的尾部
 -追加元素方法2 语法:列表.extend(其他数据容器),将其他数据容器的内容取出,依次追加到列表尾部
 -删除元素 语法1:del 列表[下标]  语法2:列表.pop(下标)
 -删除某元素在列表中的第一个匹配项 语法:列表.remove(元素)
 -清空列表内容 语法:列表.clear()
 -统计某元素在列表内的数量 语法:列表.count(元素)
 -统计列表内有多少元素 语法:len(列表)
-列表的特点 可以容纳多个元素 可以容纳不同类型的元素 数据是有序存储的(有下标序号) 允许重复数据存在 可以修改(增加或删除元素)
"""
# name=["kiki", "yiyi", "qiqi", "bibi"]
# index=name.index("qiqi")
# print(index)
#
# # 练习:有一个列表,内容是[21,25,21,23,22,20],记录的是一批学生的年龄
# # 1.定义这个列表,并用变量接收它
# my_list = [21,25,21,23,22,20]
#
# # 2.追加一个数字31,到列表的尾部
# my_list.append(31)
# print(my_list)
# # 3.追加一个新列表[29,33,30],到列表的尾部
# my_list.extend([29,33,30])
# print(my_list)
# # 4.取出第一个元素(应是:21)
# print(my_list.pop(0))
# my_list[0]
# # 5.取出最后一个元素(应是:30)
# count=len(my_list)
# my_list[-1]
# print(my_list.pop(count-1))
# # 6. 查找元素31,在列表中的下标位置
# index = my_list.index(31)
# print(index)

"""
3.list(列表)的遍历 利用while和for循环  for循环不能自定义循环条件 for适用于遍历数据容器的场景
"""

"""
4.数据容器:tuple(元组)
-元组同列表一样,可以封装多个、不同类型的元素在内,但最大的不同点在于元组一旦定义完成就不可修改
-元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型 
 定义元组字面量 (元素,元素,元素.....)
 定义元组变量 变量名称 = (元素,元素,....,元素)
 定义空元组 变量名称 = () 变量名称=tuple()
 元组只有一个数据的情况下在这个数据后面要加逗号 不然不是元组类型
 元组也支持嵌套 
-相关操作 index() 查找某个数据,如果数据存在返回对应的下标,否则报错
         count() 统计某个数据在当前元组出现的次数
         len() 统计元组内的元素个数 
-不可以修改元组的内容,否则会直接报错
"""

"""
5.数据容器:str(字符串) 字符串是字符的容器,一个字符串可以存放任意数量的字符
-同元组一样,字符串是一个:无法修改的数据容器
-字符串的替换 语法:字符串.replace(字符串1,字符串2) 功能:将字符串内的全部字符串1替换为字符串2  不是修改字符串本身,而是得到了一个新字符串
-字符串的分割 语法:字符串.split(分割字符串) 功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中  字符串本身不变,而是得到了一个列表对象
-字符串的规整操作(去前后空格) 语法:字符串.strip()
-字符串的规整操作(去前后指定字符串) 语法:字符串.strip(字符串)
-统计字符串内某字符串出现的次数 字符串.count(字符串)
-统计字符串的字符个数 len(字符串)
-字符串的遍历 同列表、元组一样,字符串也支持while循环和for循环进行遍历
-字符串只可以存储字符串 长度任意(取决于内存大小) 支持下标索引 允许重复字符串存在 不可以修改(增加或删除元素等) 支持for循环 

"""
# 练习--统计字符串内有多少个"it"字符  将字符串内的空格,全部替换为字符"|" 按照"|"进行字符串分割,得到列表
# str = "itheima itcast boxuegu"
# count = str.count("it")
# print(f"字符串{str}中有:{count}个it字符")
#
# str1 = str.replace(" ","|")
# print(f"字符串{str},被替换空格后,结果:{str1}")
#
# my_list = str1.split("|")
# print(f"字符串{str},按照|分隔后得到:{my_list}")


"""
6.数据容器的切片
-序列 内容连续、有序,可使用下标索引的一类数据容器  列表元组、字符串均可以视为序列
-序列支持切片,即:列表、元组、字符串均支持进行切片操作  切片:从一个序列中,取出一个子序列
  语法:序列[起始下标:结束下标:步长] 标售从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列
  起始下标表示从何处开始,可以留空,留空视为从头开始
  结束下标(不含)表示何处结束,可以留空,留空视为截取到结尾
  步长表示,依次取元素的问题  步长1表示一个个取元素 步长2表示每次跳过1个元素取 步长N表示每次跳过N-1个元素取 步长为负数表示反向取
 此操作不会影响序列本身,而是会得到一个新的序列
"""
# 练习
# str = "万过薪月,员序程马黑来,nohtyp学"
# result = str[9:4:-1]
# print(result)

"""
7.数据容器:set(集合)--不支持元素重复 内容无序
-基本语法 定义集合字面量{元素,元素,元素....} 定义集合变量 变量名称={元素,元素,元素....} 定义空集合 变量名称=set()
-和列表、元组、字符串等定义基本相同
-集合是无序的,集合不支持下标索引访问,但允许修改
-添加新元素 语法:集合.add(元素) 将指定元素添加到集合内 结果:集合本身被修改,添加了新元素
-移除元素 语法:集合.remove(元素),将指定元素从集合内移除 结果:集合本身被修改,移除了元素
-从集合中随机取出元素 语法:集合.pop() 结果:会得到一个元素的结果。同时集合本身被修改,元素被移除
-清空集合 集合.clear()
-取两个集合的差集 语法:集合1.difference(集合2),功能:取出集合1和集合2的差集(集合1有而集合2没有的)结果:得到一个新集合,集合1和集合2不变
-消除2个集合的差集 语法:集合1.difference_update(集合2) 功能:对比集合1和集合2,在集合1内删除和集合2相同的元素 结果:集合1被修改,集合2不变
-2个集合的合并 语法:集合1.union(集合2) 功能:将集合1和集合2组合成新集合 结果:得到新集合,集合1和2不变
-统计集合元素数量len()
-集合的遍历 不支持下标索引,不能用while循环 只能用for循环进行遍历
-集合的特点 可以容纳多个数据 可以容纳不同类型的数据(混装) 数据是无序存储的(不支持下标索引) 不允许重复数据存在 可以修改 支持for循环

"""
# 练习 信息去重
# my_list = ['黑马程序员', '传智播客', '黑马程序员', '传智播客', 'itheima', 'itcast', 'itheima', 'itcast', 'best']
# my_set = set()
# for x in my_list:
#     my_set.add(x)
# print(f"有列表:{my_list}")
# print(f"存入集合后结果:{my_set}")

"""
8.数据容器:dict(字典、映射)
-python中的字典  key:value 可以按[key]找出对应的[value]
-字典的定义 同样使用{},不过存储的元素是一个个的:键值对
  定义字典字面量  {key:value,key:value,...}  定义字典变量 my_dict={key:value,key:value...} 定义空字典 my_dict={} my_dict=dict()
-字典数据的获取  不可以使用下标索引,但字典可以通过key值来取得对应的value 语法:字典[key]
-字典的嵌套 字典的key和value可以是任何数据类型(key不可以为字典)
-key不允许重复 重复添加等于覆盖原有数据
-新增元素 语法:字典[key]=value 结果:字典被修改,新增了元素
-更新元素 语法:字典[key]=value 结果:字典被修改,元素被更新
-删除元素 语法:字典.pop(Key) 结果:获得指定key的value,同时字典被修改,指定key的数据被删除
-清空字典 语法:字典.clear() 结果:字典被修改,元素被清空
-获取全部key 语法:字典.keys() 
-遍历字典 for循环获取全部的key来完成遍历  对字典直接进行for循环,每一次循环直接得到key
-统计字典内元素数量 len()
"""
# 练习
# my_dict = {
#     "王力宏":{
#         "部门":"科技部",
#         "工资":3000,
#         "级别":1
#     },
#     "周杰伦":{
#         "部门":"市场部",
#         "工资":5000,
#         "级别":2
#     },
#     "林俊杰":{
#         "部门":"市场部",
#         "工资":7000,
#         "级别":3
#     },
#     "张学友":{
#         "部门":"科技部",
#         "工资":4000,
#         "级别":1
#     },
#     "刘德华":{
#         "部门":"市场部",
#         "工资":6000,
#         "级别":2
#     },
# }
# print("全体员工当前信息如下:")
# print(my_dict)
# for key in my_dict:
#     if my_dict[key]["级别"] == 1:
#         my_dict[key]["级别"] += 1
#         my_dict[key]["工资"] += 1000
# print("全体员工级别为1的员工完成升职加薪后:")
# print(my_dict)

"""
数据容器的总结对比
-是否支持下标索引   支持:列表、元组、字符串-序列类型  不支持:集合、字典-非序列类型
-是否支持重复元素   支持:列表、元组、字符串-序列类型  不支持:集合、字典-非序列类型
-是否可以修改   支持:列表、集合、字典  不支持:元组、字符串
各类容器的使用场景
  -列表:一批数据,可修改、可重复的存储场景
  -元组:一批数据,不可修改、可重复的存储场景
  -字符串:一串字符串的存储场景
  -集合:一批数据,去重存储场景
  -字典:一批数据,可用key检索value的存储场景
"""

"""
9.数据容器的通用操作
-在遍历上,5类数据容器都支持for遍历循环 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)
-len(容器) 统计容器的元素个数  max(容器) 统计容器的最大元素 min(容器) 统计容器的最小元素
-容器的通用转换功能  list(容器)  str(容器) tuple(容器) set(容器)
-容器通用排序功能 sorted(容器,[reverse=True]) 将给定容器排序 加上[reverse=True]进行逆序排序
"""

第七章 函数补充

"""
1.函数多返回值
-一个函数要有多个返回值, 则采用return x,y的格式返回 即按照返回值的顺序,写对应顺序的多个变量接受即可 变量之间用逗号隔开 支持不同类型的数据return
"""

"""
2.函数多种传参方式
-位置参数  调用函数时根据函数定义的参数位置来传递参数  传递的参数和定义的参数的顺序和个数必须一致
-关键字参数 函数调用时通过“键=值”的形式传递参数 作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
   eg def user_info(name,age,gender)  传参 user_info(name="小明" age=20 gender="男") 也可以不按照固定顺序
   可以和位置参数混用,位置参数必须在前且匹配参数顺序
   注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
-缺省参数 也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
  eg def user_info(name,age,gender='男') user_info('TOM',20) user_info('kiki',18,'女')
  注意:函数调用时,如果为缺省参数传值则修改默认参数值,否则使用这个默认值  设置默认值时该默认值必须在最后
-不定长参数 也叫可变参数,用于确定调用的时候会传递多少个参数(不传参也可以)的场景
  作用:当调用函数时不确定参数个数时,可以使用不定长参数
  不定长参数的类型:位置传递、关键字传递
  -位置传递  def userinfo(*args)  传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组,args是元组类型
  -关键字传递 def userinfo(**kwargs) 参数是“键=值”形式的形式的情况下,所有的“键=值”都会被kwargs接受,同时会根据“键=值”组成字典
"""

"""
3.匿名函数
-函数本身是作为参数传入另一个函数中进行使用的。 将函数传入的作用在于:传入计算逻辑,而非传入数据
-函数定义中 def关键字可以定义带有名称的函数
          lambda关键字,可以定义匿名函数(无名称)
 有名称的函数,可以基于名称重复使用 无名称的匿名函数只可临时使用一次
-匿名函数定义语法: lambda 传入参数:函数体(一行代码)
 lambda是关键字,表示定义匿名函数  传入参数表示匿名函数的形式参数  函数体就是函数的执行逻辑,只能写一行
 eg lambda x,y:x+y
"""

第八章 文件

"""
1.文件的编码
-编码就是一种规则集合,记录了内容和二进制间进行相互转换的逻辑
 编码有许多种,最常用的是UTF-8编码
"""

"""
2.文件的读取
-open() 打开函数 可以打开一个已经存在的文件或者创建一个新文件 
  语法:open(name,mode,encoding)  name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)
  mode:设置打开文件的模式(访问模式):只读、写入、追加等 encoding:编码格式(推荐使用UTF-8)
  eg f=open('python.txt','r',encoding="UTF-8") encoding的顺序不是第三位,所以不能使用位置参数,用关键字参数直接指定
-三种访问模式 r:只读的方式打开文件  w:打开一个文件只用于写入,如果文件已存在则打开文件,从头开始编辑,原有内容会被删除。若文件不存在则创建新文件
           a:打开一个文件用于追加,如果文件已存在,新的内容将会被写入到已有内容之后,若文件不存在,创建新文件进行写入
-读操作相关方法
 文件对象.read(num) num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中的所有的数据
 文件对象.readlines() 可以按照行的方式将整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
 文件对象.readline() 一次读取一行内容
 for循环读取文件行 for line in open("python.txt","r")
-close() 关闭文件对象
-with open("python.txt","r")as f:
 通过在with open的语句块中对文件进行操作 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
"""
# 练习 单词计数
# with open("word.txt","r",encoding="UTF-8") as f:
# content = f.read()
# print(f"出现次数{content.count("itheima")}")
# count = 0
# with open("word.txt","r",encoding="UTF-8") as f:
#     for line in f:
#         line = line.strip()
#         words = line.split(" ")
#         for word in words:
#             if word == "itheima":
#                 count += 1
# print(f"出现次数{count}")

"""
3.文件的写入 打开文件时,用w模式
-f.write('hello world) f.flush()
 直接调用write内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区,当调用flush的时候,内容会真正写入文件 是为了避免频繁的操作硬盘,导致效率下降

"""

"""
4.文件的追加
-打开文件时,通过a模式打开即可,文件写入用f.write(),内容刷新f.flush() 可以用\n来写出换行符
"""

"""
5.文件操作综合案例-完成文件备份
有一份账单文件,记录了消费收入的具体记录,将内容复制为bill.txt文件
需要①读取文件 ②将文件写出到bill.txt.bak文件作为备份 ③同时,将文件内容标记为测试的数据行丢弃
实现思路 ①open和r模式打开一个文件对象,并读取文件  
       ②open和w模式打开另一个文件对象,用于文件写出
       ③for循环内容,判断是否是测试,不是测试就write写出,是测试就continue跳过
       ④将两个文件对象均close
"""
fr = open("bill.txt","r",encoding="UTF-8")
fw = open("bill.txt.bak","w",encoding="UTF-8")
for line in fr:
    line = line.strip()
    if line.split(",")[4]=="测试":
        continue
    fw.write(line)
    fw.write("\n")
fr.close()
fw.close()

第九章 异常、模块、包

"""
1.了解异常--异常就是程序运行的过程中出现了错误
"""

"""
2.异常的捕获方法
-捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段
-基本语法  try: 可能发生错误的代码  except:如果出现异常执行的代码
-捕获指定异常 try: print(name) except NameError as e: print('name变量名称未定义错误')
  如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常  一般try下方只放一行尝试执行的代码
-捕获多个异常 当捕获多个异常时,可以把要捕获的异常类型的名字,放到excpet后,并使用元组的方式进行书写
  eg try: print(1/0)  except(NameError,ZeroDivisionError):print('ZeroDivision错误...')
-捕获所有异常 try:   except Exception as e:
-异常else  else表示的是如果没有异常要执行的代码   try: 语句  except Exception as e:语句     else: 语句
-异常的finally  finally表示的时无论是否异常都要执行的代码,例如关闭文件 try: 语句  except Exception as e:语句 else: 语句 finally:语句
"""

"""
3.异常的传递性
-异常是具有传递性的,当函数func01中发生异常时,并没有捕获处理这个异常的时候,异常会传递到函数func02
  当func02也没有捕获处理这个异常的时候main函数会捕获这个异常,这就是异常的传递性
  当所有函数都没有捕获异常的时候,程序就会报错
"""

"""
4.python模块
-模块导入
  Python模块是一个python文件,以.py结尾,模块能定义函数,类和变量,模块里也能包含可执行的代码
  模块的作用:python中有很多各种不同的模块,每一个模块都可以帮助我们快速实现一些功能,比如实现和时间相关的功能就可以使用time模块
           我们可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能。
  通俗理解:模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用(导入模块去使用)
  模块的导入方式  模块在使用前需要先导入 导入的语法如下: [from 模块名] import [模块|类|变量|函数|*] [as 别名]
  常见的组合形式如: ①import 模块名  ②from 模块名 import 类、变量、方法等 ③from 模块名 import * ④import 模块名 as 别名 ⑤from 模块名 import 功能名 as 别名
  import 模块名  基本语法:import 模块名1,模块名2   模块名.功能名()
  from 模块名 import 功能名  功能名() eg:from time import sleep  sleep()
  模块的导入一般写在代码文件的开头位置
-自定义模块 新建一个python文件,并在里面定义函数  自定义模块名必须要符合标识符命名规则
  当导入多个模块的时候,且模块内有同名功能,当调用这个同名功能的时候,调用到的时后面导入的模块的功能
-测试模块  开发人员会自行在py文件中添加一些测试信息,会导致其他导入该模块的文件运行时也会自动执行测试函数
   解决方法  加上  if __name__=='__main__':test()  则只有在当前文件中调用该函数时,其他导入的文件内不会调用测试函数
   if __name__=='__main__' 意思是只有当程序是直接执行的才会进入if内部,如果是被导入的则if无法进入
-如果一个模块文件有'__all__'变量,当使用from xxx import *导入时,只能导入这个列表中的元素
  eg __all__=['test_A'] 只能调用test_A函数  即*=__all__
"""

"""
5.python包
-从物理上看包就是一个文件夹,在该文件夹下包含了一个__init__.py文件,该文件夹可用于包含多个模块文件,从逻辑上看,包的本质依然是模块
-包的作用,当我们的模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含
-创建包 ①新建包my_package ②新建包内模块 my_module1和my_module2 ③模块内代码写所需函数等
      新建包后包内会自动创建'__init__.py文件,这个文件控制着包的导入行为
-导入包  方法①:import 包名.模块名  包名.模块名.目标  方法②:必须在__init__.py文件中添加'__all__=[]',控制允许导入的模块列表 from 包名 import* 模块名.目标
"""

"""
6.安装第三方python包
-科学计算常用numpy包  数据分析常用pandas包 大数据计算常用pyspark、apache-flink包 图形可视化常用matplotlib、pyecharts包 人工智能常用tensorflow包
 pip install 包名称  pip install -i 网站 包名称 
 
"""

"""
综合案例 自定义工具包
"""

第十章 综合案例(可视化)

"""
python基础综合案例  数据可视化-折线图可视化
效果一:2020年印美日新冠累计确诊人数
效果二:全国疫情地图可视化
效果三:动态GDP增长图

实现数据可视化效果图,可以借助pyecharts模块来完成

"""
import json

"""
JSON是一个带有特定格式的字符串 是一种非常良好的中转数据格式
Python数据和Json数据的相互转化  导入json模块import json
-通过json.dumps(data)把python数据转化为了json数据
-通过json.loads(data)方法把json数据转化为python数据
"""

# import json
# data = [{"name":"张三","age":11},{"name":"李四","age":11},{"name":"王五","age":11}]
# json_str = json.dumps(data,ensure_ascii=False)
# print(json_str)
#
# d = {"name":"张三","age":11}
# json_str2 = json.dumps(d,ensure_ascii=False)
# print(json_str2)
#
# s = '[{"name":"张三","age":11},{"name":"李四","age":11},{"name":"王五","age":11}]'
# s1 = json.loads(s)
# print(s1)

"""
pycharts入门
-全局配置选项可以通过set_global_opts方法来进行配置  
  titleOpts:标题配置项 legendOpts:图例配置项 ToolboxOpts:工具箱配置项 VisualMapOpts:视觉映射配置项 ToolTipOpts:提示框配置项 
  DataZoomOpts:区域缩放配置项
                                       
"""
# 导包,导入line功能构建折线图对象
# from pyecharts.charts import Line
# from pyecharts.options import TitleOpts, LegendOpts, ToolboxOpts
#
# # 得到折线图对象
# line = Line()
# # 添加x轴数据
# line.add_xaxis(["中国", "美国", "英国"])
# # 添加y轴数据
# line.add_yaxis("GDP", [30, 20, 10])
# # 设置全局配置
# line.set_global_opts(
#     title_opts=TitleOpts(title="GDP展示", pos_left="center",pos_bottom="1%"),
#     legend_opts=LegendOpts(is_show=True),
#     toolbox_opts=ToolboxOpts(is_show=True),
# )
# # 生成图表
# line.render()

"""
数据准备
"""
# import json
# from pyecharts.charts import Line
# from pyecharts.options import TitleOpts, LegendOpts, ToolboxOpts,LabelOpts
# # 处理数据
# f_us = open("C:/美国.txt","r",encoding="UTF-8")
# us_data = f_us.read()
#
# f_jp = open("C:/日本.txt","r",encoding="UTF-8")
# jp_data = f_jp.read()
#
# f_in = open("C:/Desktop/印度.txt","r",encoding="UTF-8")
# in_data = f_in.read()
#
# # 去除不合JSON规范的结尾
# us_data = us_data.replace("jsonp_1629344292311_69436(","")
# jp_data = jp_data.replace("jsonp_1629350871167_29498(","")
# in_data = in_data.replace("jsonp_1629350745930_63180(","")
# # 去掉不合JSON规范的结尾
# us_data = us_data[:-2]
# jp_data = jp_data[:-2]
# in_data = in_data[:-2]
# # JSON转Python字典
# us_dict = json.loads(us_data)
# jp_dict = json.loads(jp_data)
# in_dict = json.loads(in_data)
# # 获取trend key
# us_trend_data = us_dict['data'][0]['trend']
# jp_trend_data = jp_dict['data'][0]['trend']
# in_trend_data = in_dict['data'][0]['trend']
# # 获取日期数据,用于x轴,取2020年(到314下标结束)
# us_x_data = us_trend_data['updateDate'][:314]
# jp_x_data = jp_trend_data['updateDate'][:314]
# in_x_data = in_trend_data['updateDate'][:314]
# # 获取确认数据,用于y轴,取2020年(到314下标结束)
# us_y_data = us_trend_data['list'][0]['data'][:314]
# jp_y_data = jp_trend_data['list'][0]['data'][:314]
# in_y_data = in_trend_data['list'][0]['data'][:314]
# #生成图表
# line = Line()
# # 添加x轴数据 共用
# line.add_xaxis(us_x_data)
# # 添加y轴数据
# line.add_yaxis("美国确诊人数", us_y_data, label_opts=LabelOpts(is_show=False))
# line.add_yaxis("日本确诊人数", jp_y_data, label_opts=LabelOpts(is_show=False))
# line.add_yaxis("印度确诊人数", in_y_data, label_opts=LabelOpts(is_show=False))
# # 设置全局选项
# line.set_global_opts(
#     title_opts=TitleOpts(title="2020年美日印三国确诊人数对比折线图",pos_left="center",pos_bottom="1%")
#
# )
#
# # 生成图表
# line.render()
# f_us.close()
# f_jp.close()
# f_in.close()

"""
基础地图演示
"""
# import json
# from pyecharts.charts import Map
# from pyecharts.options import VisualMapOpts
#
# f = open("C:/疫情.txt","r",encoding="UTF-8")
# data = f.read()
# f.close()
# data_dict = json.loads(data)
# province_data_list = data_dict["areaTree"][0]["children"]
#
# map1 = Map()
# data = [
#     ("北京市", 99),
#     ("上海市", 199),
#     ("湖南省", 299),
#     ("台湾省", 199),
#     ("安徽省", 299),
#     ("广州市", 399),
#     ("湖北省", 599),
# ]
# map1.add("地图", data, "china")
# map1.set_global_opts(
#     visualmap_opts=VisualMapOpts(
#         is_show=True,
#         is_piecewise=True,
#         pieces=[
#             {"min":1,"max":9,"label":"1-9人","color":"#CCFFFF"},
#             {"min":10,"max":99,"label":"10-99人","color":"#FFFF99"},
#             {"min":100,"max":499,"label":"99-499人","color":"#FF9966"},
#             {"min":500,"max":999,"label":"499-999人","color":"#FF6666"},
#             {"min":1000,"max":9999,"label":"1000-9999人","color":"#CC3333"},
#             {"min":10000,"label":"10000以上","color":"#990033"},
#         ]
#
#     )
# )
# map1.render()

# import json
# from pyecharts.charts import Map
# from pyecharts.options import VisualMapOpts,TitleOpts
#
# f = open("C:/疫情.txt","r",encoding="UTF-8")
# data = f.read()
# f.close()
# data_dict = json.loads(data)
# province_data_list = data_dict["areaTree"][0]["children"]
# data_list = []
# for province_data in province_data_list:
#     province_name = province_data["name"] + "省"
#     province_confirm = province_data["total"]["confirm"]
#     data_list.append((province_name, province_confirm))
#
# map = Map()
# map.add("各省份确诊人数", data_list, "china")
# map.set_global_opts(
#     title_opts=TitleOpts(title="全国疫情地图"),
#     visualmap_opts=VisualMapOpts(
#         is_show=True,
#         is_piecewise=True,     # 是否分段
#         pieces=[
#             {"min":1,"max":9,"label":"1-9人","color":"#CCFFFF"},
#             {"min":10,"max":99,"label":"10-99人","color":"#FFFF99"},
#             {"min":100,"max":499,"label":"99-499人","color":"#FF9966"},
#             {"min":500,"max":999,"label":"499-999人","color":"#FF6666"},
#             {"min":1000,"max":9999,"label":"1000-9999人","color":"#CC3333"},
#             {"min":10000,"label":"10000以上","color":"#990033"},
#         ]
#
#     )
# )
# map.render("全国疫情地图.html")

"""
通过Bar构建基础柱状图
"""
# from pyecharts.charts import Bar
# from pyecharts.options import *
#
# bar=Bar()
#
# bar.add_xaxis(["中国", "美国", "英国"])
# bar.add_yaxis("GDP",[30, 20, 10],label_opts=LabelOpts(position="right"))   # 数值标签在右侧显示
#
# # 反转xy轴
# bar.reversal_axis()
# bar.render("基础柱状图.html")

# # 创建时间线 TimeLine()--时间线
# from pyecharts.charts import Bar, Timeline
# from pyecharts.options import *
# # 时间线设置主题
# from pyecharts.globals import ThemeType
#
# bar1 = Bar()
# bar1.add_xaxis(["中国", "美国", "英国"])
# bar1.add_yaxis("GDP",[30,20,10],label_opts=LabelOpts(position="right"))
# bar1.reversal_axis()
#
# bar2 = Bar()
# bar2.add_xaxis(["中国", "美国", "英国"])
# bar2.add_yaxis("GDP",[50,30,20],label_opts=LabelOpts(position="right"))
# bar2.reversal_axis()
#
# timeline = Timeline({"theme":ThemeType.LIGHT})
# timeline.add(bar1,"2021年GDP")
# timeline.add(bar2,"2022年GDP")
#
# # 设置自动播放
# timeline.add_schema(
#     play_interval=1000,
#     is_timeline_show=True,
#     is_auto_play=True,
#     is_loop_play=True
# )
#
# timeline.render("基础柱状图-时间线.html")

"""列表的sort方法
列表.sort(key=选择排序依据的函数,reverse=True|False)
key要求传入一个函数,表示将列表的每一个元素都传入函数中,返回排序的依据
"""
# my_list = [["a",33],["b",55],["c",11]]
# def choose_sort_key(element):
#     return element[1]
# my_list.sort(key=choose_sort_key, reverse=True)         # 按数字进行排序
# print(my_list)
#
# my_list.sort(key=lambda element:element[1], reverse=True)

"""
效果图要求:
1.GDP数据处理为亿级
2.有时间轴,按照年份为时间轴的点
3.x轴和y轴反转,同时每一年的数据只要前8名国家
4.有标题,标题的年份会动态更改
5.设置了主题为LIGHT
"""

from pyecharts.charts import Bar, Timeline
from pyecharts.options import *
from pyecharts.globals import ThemeType
# 处理数据
f = open("C:/1960-2019全球GDP数据.csv","r",encoding="GB2312")
data_lines = f.readlines()
f.close()
# 删除第一条
data_lines.pop(0)
# 将数据转换为字典存储,格式为:{年份:[[国家,gdp],[国家,gdp],...],年份:[[国家,gdp][国家,gdp],...]
data_dict = {}
for line in data_lines:
    year = int(line.split(",")[0])
    country = line.split(",")[1]
    gdp = float(line.split(",")[2])
    # 如何判定字典里面有没有key
    try:
        data_dict[year].append([country, gdp])
    except KeyError:
        data_dict[year] = []
        data_dict[year].append([country, gdp])
# 创建时间线对象
timeline = Timeline({"theme": ThemeType.LIGHT})

# 排序年份
sorted_year_list = sorted(data_dict.keys())
for year in sorted_year_list:
    data_dict[year].sort(key=lambda element:element[1], reverse=True)
    # 取出本年份前八名国家 绘制柱状图
    year_data = data_dict[year][0:8]
    x_data = []
    y_data = []
    for country_gdp in year_data:
        x_data.append(country_gdp[0])
        y_data.append(country_gdp[1]/100000000)
    # 构建柱状图对象
    bar = Bar()
    x_data.reverse()
    y_data.reverse()
    bar.add_xaxis(x_data)
    bar.add_yaxis("GDP(亿)", y_data, label_opts=LabelOpts(position="right"))
    # 反转
    bar.reversal_axis()
    bar.set_global_opts(
        title_opts=TitleOpts(title=f"{year}年全球前8GDP数据")
    )
    timeline.add(bar, str(year))

# 设置自动播放
timeline.add_schema(
    play_interval=1000,
    is_timeline_show=True,
    is_auto_play=True,
    is_loop_play=True
)
timeline.render("1960-2019全球GDP前8国家.html")

第二阶段 第一部分面向对象

"""
1.初识对象
-使用对象组织数据 在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的
  --在程序中设计表格,我们称之为:设计类(class)  class Student: name=None
  --在程序中打印生产表格,我们称之为:创建对象   stu_1=Student()  stu_2=Student()
  --在程序中填写表格,我们称之为:对象属性赋值   stu_1.name="周杰伦"
可以使用类去封装属性,并基于类创建出一个个的对象来使用
"""
import json
import random

"""
2.成员方法
-类的使用语法  
   class 类名称: 
       类的属性   【即,定义在类中的变量(成员变量)】
       类的行为   【即定义在类中的函数(成员方法)】
-创建类对象的语法:  对象=类名称()
-在类中定义成员方法和定义函数基本一致,但仍有细微区别
   def 方法名(self,形参1,形参2....):
       方法体
  在方法定义的参数列表中,有一个self关键字
  self关键字是成员方法定义的时候,必须填写的,它用来表示类对象自身的意思,当我们使用类对象调用方法的是self会自动被python传入
  在方法内部,想要访问类的成员变量,必须使用self
-注意事项:self关键字,尽管在参数列表中,但是传参的时候可以忽略它。 在传入参数时self是透明的
"""
# class Student:
#     name = None
#     age = None
#     def say_hi(self):
#         print(f"Hi大家好,我是{self.name}")
# stu=Student()
# stu.name="kiki"
# stu.say_hi()

"""
3.类和对象
-现实世界的事物也有属性和行为,类也有属性和行为,使用程序中的类,可以完美的描述现实世界的事物
-类只是一种程序内的“设计图纸”,需要基于图纸生产实体(对象),才能正常工作  这种套路称之为面向对象
-面向对象编程就是使用对象进行编程 设计一个类,基于类去创建对象,并使用对象去完成具体工作
"""

"""
4.构造方法
-创建对象后一个个为对象的每个属性赋值过于繁琐
-使用构造方法__init__()通过传参的形式对属性赋值
  Python类中可以使用__init__()方法,称之为构造方法。
  可以实现:①在创建类对象(构造类)的时候,会自动执行  ②在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用
  
"""
# 练习 学生信息录入
# class Student:
#     name = None
#     age = None
#     address = None
#
#     def __init__(self,name,age,address):
#         self.name = name
#         self.age = age
#         self.address = address
#
# for i in range(1,11):
#     print(f"当前录入第{i}位学生信息,共需录入10位学生信息")
#     stu = Student(input("请输入学生姓名:"), input("请输入学生年龄:"), input("请输入学生地址:"))
#     print(f"学生{i}信息录入完成,信息为:【学生姓名:{stu.name},学生年龄:{stu.age},学生地址:{stu.address}】")

"""
5.其他内置方法  又称之为魔术方法
-__init__构造方法
-__str__字符串方法   当类对象需要被转换为字符串之时,会输出内存地址,通过__str__方法使得其打印出字符串而不是内存地址
-__lt__小于,大于符号比较  两个对象不能直接比较,在类中实现__lt__方法可以同时完成:小于符号和大于符号两种比较
-__le__小于等于,大于等于符号比较
-__eq__==符号比较  不识闲__eq__方法,对象之间可以比较,但是是比较内存地址,也即是不同对象==比较一定是False结果
"""
# class Student:
#     name = None
#     age = None
#     address = None
#
#     def __init__(self,name,age,address):
#         self.name = name
#         self.age = age
#         self.address = address
#
#     def __str__(self):
#         return f"Student类对象,name={self.name},age={self.age},address={self.address}"
#
#     def __lt__(self, other):
#         return self.age < other.age
#
#     def __le__(self, other):
#         return self.age <= other.age
#
#     def __eq__(self, other):
#         return self.age == other.age
"""
6.封装
-类中提供了私有成员的形式来支持  
   私有成员变量  变量名以__开头
   私有成员方法  方法名以__开头
-私有方法无法直接被类对象使用  私有变量无法复制,也无法获取值
-私有成员无法被类对象使用,但是可以被其他的成员使用
-私有成员的实际意义:在类中提供仅供内部使用的属性和方法,而不对外开放(类对象无法使用)
"""
# 练习 设计带有私有成员的手机
# class Phone:
#     __is_5g_enable = False
#     # __current_voltage = 0.5
#
#     def __check_5g(self):
#         if self.__is_5g_enable:
#             print("5g开启")
#         else:
#             print("5g关闭,使用4g网络")
#
#     def call_by_5g(self):
#         self.__check_5g()
#         print("正在通话中...")
#
# phone = Phone()
# phone.call_by_5g()

"""
7.继承  将从父类那里集成(复制)来成员变量和成员方法(不含私有)
-单继承  class 类名(父类名): 类内容体
-多继承  class 类名(父类1,父类2,...,父类N): 类内容体
   多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级 即先继承的保留,后继承的被覆盖
-pass关键字的作用  普通的占位语句,保证函数/方法/类定义的完整性,表示无内容,空的意思
-复写  子类集成父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写 即在子类中重新定义同名的属性或方法即可
-调用父类同名成员
   一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员  如果需要使用被复写的父类的成员,需要特殊的调用方式
   方法1:调用父类成员: 使用成员变量:父类名.成员变量  使用成员方法:父类名.成员方法(self)
   方法2:使用super()调用父类成员 使用成员变量:super.成员变量  使用成员方法:super().成员方法()
 注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
"""
# class Phone:
#     IMEI = None
#
# class Phone2022(Phone):
#     face_id = True

"""
8.类型注解  pycharm无法通过代码确定应传入什么类型,所以需要使用类型注释
-调用方法进行传参时ctrl+p弹出提示
-类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显示的说明)
  主要功能:帮助第三方IDE工具对代码进行类型判断,协助做代码提示  帮助开发者自身对变量进行类型注释
  支持: 变量的类型注释  函数(方法)形参列表和返回值的类型注释
-为变量设置类型注解基础语法: 变量:类型  基础容器也相同
  元组类型设置类型详细注释,需要将每一个元素都标记出来
  字典类型设置类型详细注释,需要两个类型,第一个是key,第二个是value
 除了使用 变量:类型这种语法做注解外,也可以在注释中进行类型注解
 显示的变量定义一般无需注解,无法看出变量类型之时会添加变量的类型注解
-类型注解仅仅是提示性的,而不会真正的对类型做验证和判断
-函数(方法)的类型注解-形参注解和返回值注解
  def 函数方法名(形参名:类型,形参名:类型....)->返回值类型:
    pass
-使用union[类型,...,类型]可以定义联合类型注解 Union联合类型注解,在变量注解、函数(方法)形参和返回值注释中,均可使用
"""
# from typing import Union
# my_list: list[Union[str,int]] = [1,2,"itheima","itcast"]   # 存放的元素要么是字符串,要么是int
# my_dict:dict[str,Union[str,int]] = {"name":"周杰伦","age":31}   # value的类型要么是字符串要么是int
# def func(data:Union[int,str])->Union[int,str]:
#     pass
#
# var_1: int =10
# var_2: float = 3.1415926
# my_list:list =[1,2,3]
# my_tuple:tuple = (1,2,3)
# my_tuple:tuple[str,int,bool] = ("Itheima",666,True)
# my_dict: dict[str,int] = {"itheima":666}
# var_1 = random.randint(1,10)  # type:int
# var_2 = json.loads('{"name":"zhangsan"}')  # type: dict[str,str]
# class Student:
#     pass
# stu:Student = Student()

"""
9.多态--多种状态,即完成某个行为时,使用不同的对象会得到不同的状态
-同样的行为(函数),传入不同的对象,得到不同的状态
-以父类做定义声明,以子类做实际工作,用以获得同一行为,不同状态
-抽象类(接口)  父类Animal的speak方法是空实现,这种设计的含义是父类用来确定有哪些方法,具体的方法实现,由子类自行决定
               这种写法,就叫做抽象类(也可以称之为接口)  抽象类:含有抽象方法的类称之为抽象类  
               抽象方法:方法体是空实现(pass)称之为抽象方法
    抽象类好比定义了一个标准,包含了一些抽象的方法,要求子类必须实现
"""
# class Animal:
#     def speak(self):
#         pass
#
# class Dog(Animal):
#     def speak(self):
#         print("汪汪汪")
#
# class Cat(Animal):
#     def speak(self):
#         print("喵喵喵")
#
# def make_noise(animal: Animal):
#     animal.speak()
#
# dog = Dog()
# cat = Cat()
#
# make_noise(dog)
# make_noise(cat)

"""
10.综合案例  数据分析案例 
-使用面向对象思想完成数据读取和处理
-基于面向对象思想重新认知第三方库的使用 

某公司有两份数据文件,现需要对其进行分析处理,计算每日的销售额并以柱状图表的形式进行展示
1月份的数据是普通文本,使用逗号分隔数据记录,从前到后分别是(日期,订单id,销售额,销售省份)
2月份的数据是JSON数据,同样包含(日期,订单id,销售额,销售省份
需求分析: 读取数据->封装数据对象->计算数据对象->pyecharts绘图
1.设计FileReader类
2.设计数据封装类
3.对对象进行逻辑计算
4.以面向对象思想重新认知pyecharts

实现步骤:
1.设计一个类,可以完成数据的封装
2.设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能
3.读取文件,生产数据对象
4.进行数据需求的逻辑计算(计算每一天的销售额)
5.通过pyecharts进行图形绘制
"""

from data_define import Record
from file_define import FileReader,TextFileReader,JsonFileReader
from pyecharts.charts import Bar
from pyecharts.options import *
from pyecharts.globals import ThemeType

text_file_reader = TextFileReader("C:/Desktop/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("C:/Desktop/2011年2月销售数据JSON.txt")

jan_data: list[Record] = text_file_reader.read_data()
feb_data: list[Record] = json_file_reader.read_data()
# 将2个月的数据合并为1个list来存储
all_data: list[Record] = jan_data + feb_data

# 进行数据计算 计算同一天的销售额
# {"2011-01-01":1234,"2011-01-02":300,....} 有的话累加,没有创建
data_dict = {}
for record in all_data:
    if record.date in data_dict.keys():
        # 累加
        data_dict[record.date] += record.money
    else:
        data_dict[record.date] = record.money

# 可视化图标开发
bar = Bar(init_opts=InitOpts(theme=ThemeType.LIGHT))
bar.add_xaxis(list(data_dict.keys()))  # 添加x轴数据
bar.add_yaxis("销售额",list(data_dict.values()),label_opts=LabelOpts(is_show=False))
bar.set_global_opts(
    title_opts=TitleOpts(title="每日销售额")
)
bar.render("每日销售额柱状图.html")

第二阶段 第二部分 SQL

# 单行注释
# -- 单行注释
# /*多行注释*/
"""
DDL-库管理
查看数据库 show databases;
使用数据库 use 数据库名称;
创建数据库 create database 数据库名称 [charset UTF8];
删除数据库 drop database 数据库名称
查看当前使用的数据库 select database();
DDL-表管理
查看有哪些表  show tables;
删除表 drop table 表名称;  drop table if exists;
创建表 create Table 表名称(列名称 列类型, 列名称 列类型....)   列类型有int、float、varchar(长度)、date、timestamp

DML-数据操控  插入删除更新
数据插入insert  insert into 表[(列1,列2,...,列N)] values(值1,值2,...,值N),[(值1,值2,...,值N).....]
数据删除delete  delete from 表名称 [where 条件判断]     条件判断:列 操作符 值
数据更新update  update 表名 set 列=值 [where 条件判断]
字符串出现在SQL语句中必须用单引号包围起来

DQL-基础查询、分组聚合、排序分页
数据查询  select 字段列表|* from 表 [where 条件判断]
分组聚合  select 字段|聚合函数 from 表 [where 条件判断] group by 列
        聚合函数有 -sum(列) 求和 -avg(列) 求平均值 -min(列) 求最小值 -max(列) 求最大值 -count(列|*) 求数量
        group by 中出现了哪个列,哪个列才能出现在select的非聚合中
结果排序  select 列|聚合函数|* from 表 where ... group by ... order by ...[asc|desc] 指定某个列进行排序
结果分页限制 使用limit关键字,对查询结果进行数量显示或分页显示   n,m表示从第n+1条开始取m条
           select 列|聚合函数|* from 表 where ... group by... order by...[asc|desc] limit n[,m]
"""
import json

# # 创建到MYSQL的数据库链接
# from pymysql import Connection
# # 获取到MYSQL的数据库链接对象
# conn = Connection(
#     host='localhost', # 主机名
#     port=3306,
#     user='root',
#     password='hqq123456',
#     autocommit=True   # 设置自动提交
# )
# # 获取游标对象
# cursor = conn.cursor()
# conn.select_db("test")   # 先选择数据库
# # 使用游标对象,执行sql语句
# # cursor.execute("create table test_pymysql(id int, info varchar(255));")  创建表格
# # cursor.execute("select * from consumer")   # 查询
# cursor.execute("insert into test_pymysql values(1,'kiki'),(2,'ooo')")  # 执行完并不会插入 需要提交才可以
# conn.commit()
#
# # 获取查询结果
# # results: tuple = cursor.fetchall()  # 将元素封装到元组中
# # for r in results:
# #     print(r)
#
# # 打印Mysql数据库软件信息
# # print(conn.get_server_info())
#
# # 关闭到数据库的链接
# conn.close()


# 综合案例 将数据集使用python语言,读取数据,写入mysql
# 获取数据集 同上一章
# from data_define import Record
# from file_define import FileReader,TextFileReader,JsonFileReader
# from pymysql import Connection
#
# text_file_reader = TextFileReader("C:/Desktop/2011年1月销售数据.txt")
# json_file_reader = JsonFileReader("C:/Desktop/2011年2月销售数据JSON.txt")
#
# jan_data: list[Record] = text_file_reader.read_data()
# feb_data: list[Record] = json_file_reader.read_data()
# # 将2个月的数据合并为1个list来存储
# all_data: list[Record] = jan_data + feb_data
#
# # 获取到MYSQL的数据库链接对象
# conn = Connection(
#     host='localhost',   # 主机名
#     port=3306,
#     user='root',
#     password='hqq123456',
#     autocommit=True   # 设置自动提交
# )
# # 获取游标对象
# cursor = conn.cursor()
# conn.select_db("py_sql")   # 先选择数据库
#
# # 组织SQL语句
# for record in all_data:
#     sql = (f"insert into orders(order_date,order_id,money,province) "
#            f"values('{record.date}','{record.order_id}',{record.money},'{record.province}')")
#     # 执行语句
#     cursor.execute(sql)
#
# # 关闭
# conn.close()

# 课后练习 从数据库读取数据,转换成字典
# 获取数据集 同上一章
from data_define import Record
from pymysql import Connection
import json

# 获取到MYSQL的数据库链接对象
conn = Connection(
    host='localhost',   # 主机名
    port=3306,
    user='root',
    password='hqq123456',
    autocommit=True   # 设置自动提交
)
# 获取游标对象
cursor = conn.cursor()
conn.select_db("py_sql")   # 先选择数据库
# 查询
cursor.execute("select * from orders")
f = open("C:/Desktop/py_sql.txt","w",encoding="UTF-8")
# 获取数据
results: tuple = cursor.fetchall()
for r in results:
    data_dict = {}
    data_dict["date"] = r[0]
    data_dict["order_id"] = r[1]
    data_dict["money"] = r[2]
    data_dict["province"] = r[3]
    data_str = json.dumps(data_dict, ensure_ascii=False)
    f.write(f"{data_str}\n")

f.close()

# 关闭
conn.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茄味琪琪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值