<jupyter_start><jupyter_text>第三讲 函数、对象与类、文件读写  第一部分 函数  1. 函数的定义及调用  1.1 为什么要用函数？    - 提高代码的复用性——抽象出来、封装为函数        - 将复杂的大问题分解成一系列小问题，分而治之——模块化设计的思想        - 利于代码的维护和管理<jupyter_code># 顺序式

# 5的阶乘
n = 5
res = 1
for i in range(1, 6): #1,2,3,4,5
    res *= i
print(res)

# 20的阶乘
n = 20
res = 1
for i in range(1, n+1):
    res *= i
print(res)
# 抽象成函数
def factoria(n):
    res = 1
    for i in range(1, n+1):
        res *= i
    return res


print(factoria(5))
print(factoria(20))

factoria(3) +factoria(5)<jupyter_output>120
2432902008176640000<jupyter_text>1.2 函数的定义和调用白箱子：输入——处理——输出三要素：参数、函数体、返回值- 定义```def 函数名(参数):    函数体    return 返回值```<jupyter_code># 求正方形的面积
def area_of_square(length_of_side):
    return pow(length_of_side, 2)

area_of_square(16)
a = 5
area_of_square(a)<jupyter_output><empty_output><jupyter_text>- 调用```函数名(参数)```<jupyter_code>area = area_of_square(5)
print(area)<jupyter_output><empty_output><jupyter_text>1.3 参数传递- 形参与实参    - 形参：形式参数，函数定义时的参数，实际上就是变量名        - 实参：实际参数，函数调用时的参数，实际上就是变量值    - 位置参数    - 严格按照位置顺序，用实参对形参进行赋值（关联）        - 一般用在参数比较少的时候        - 实参与形参个数必须一一对应，一个不能多，一个不能少<jupyter_code>def function(x, y, z):
    print(x, y, z)
    
    
function(1, 2, 3)     # x = 1; y = 2; z = 3
function(3, 2, 1)
function(1, 2)
function(1, 2, 3, 4)<jupyter_output><empty_output><jupyter_text>- 关键字参数    - 打破位置限制，直呼其名的进行值的传递        - 必须遵守实参与形参数量上一一对应        - 多用在参数比较多的场合<jupyter_code>def foo(name, gender, age=18):
    print(name, gender, age)
    
foo(name='Aye', gender='female')<jupyter_output>Aye female 18<jupyter_text>- 位置参数可以与关键字参数混合使用- 但是，位置参数必须放在关键字参数前面<jupyter_code>function(1, z=2, y=3)<jupyter_output>1 3 2<jupyter_text>- 不能为同一个形参重复传值<jupyter_code>def function(x, y, z):
    print(x, y, z)
    
    
function(1, z=2, x=3)<jupyter_output><empty_output><jupyter_text>1.4 默认参数- 在定义阶段就给形参赋值——该形参的常用值- 机器学习库中类的方法里非常常见- 调用函数时，可以不对该形参传值<jupyter_code>def register(name, age, gender='male'):
    print(name, age, gender)
    
    
register('刘子瑜', 34)<jupyter_output>刘子瑜 34 male<jupyter_text>- 也可以按正常的形参进行传值<jupyter_code>register('林仙儿', 23, 'female')<jupyter_output>林仙儿 23 female<jupyter_text>- 位置形参必须在默认形参的前面<jupyter_code>def register(gender='male', name, age):
    print(name, age, gender)
    
    
register('刘子瑜', 34)<jupyter_output><empty_output><jupyter_text>- 默认参数应该设置为不可变类型（数字、字符串、元组）<jupyter_code>def function(ls=[]):
    print(id(ls))
    ls.append(1)
    print(id(ls))
    print(ls)
    
    
function()
function()
function()
def function(ls='Python'):
    print(id(ls))
    ls += '3.8'
    print(id(ls))
    pring(ls)
    

function()
function()
function()<jupyter_output><empty_output><jupyter_text>- 让参数变成可选的<jupyter_code>def name(first_name, last_name, middle_name=None):
    if middle_name:
        return first_name+middle_name+last_name
    else:
        return first_name+last_name

    
print(name('刘'，'瑜'))
print((name('刘', '瑜', '子')))<jupyter_output><empty_output><jupyter_text>1.5 可变长参数  *args- 顾名思义，可变参数就是传入的参数个数是可变的，可以是1个、2个到任意个，还可以是0个。 \*args(也可以是别的参数名，在前面加\*即可）- 可变长参数必须放在参数列表的最后<jupyter_code>def square_sum(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum


print(square_sum(1, 2, 3))
print(square_sum(5, 6, 7, 8))<jupyter_output>14
174<jupyter_text>- 实参打散<jupyter_code>#如果已经有一个list或者tuple，要调用一个可变参数怎么办？
num = [1, 2, 3]
square_sum(*num)
#square_sum(*num)  #*num表示把num这个list的所有元素打散，作为可变参数传进去。这种写法常见且有用。
square_sum(1, 2, 3, *[1, 2, 3])  #打散的是列表、字符串、元组或集合<jupyter_output><empty_output><jupyter_text>1.6 关键字参数  **kwargs可变参数允许你传入0个或任意个参数，这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数，这些关键字参数在函数内部自动组装为一个dict。<jupyter_code>def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
    
    
person('Michael', 30)
person('Bob', 35, city='Beijing')
person('Adam', 45, gender='M', job='Engineer')<jupyter_output>name: Michael age: 30 other: {}
name: Bob age: 35 other: {'city': 'Beijing'}
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}<jupyter_text>关键字参数可以扩展函数的功能。比如，在person函数里，我们保证能接收到name和age这两个参数，但是，如果调用者愿意提供更多的参数，我们也能收到。试想你正在做一个用户注册的功能，除了用户名和年龄是必填项外，其他都是可选项，利用关键字参数来定义这个函数就能满足注册的需求。- 字典实参打散和可变参数类似，也可以先组装出一个dict，然后，把该dict打散传进去。<jupyter_code>extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)  #**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数，kw将获得一个dict，注意kw获得的dict是extra的一份拷贝，对kw的改动不会影响到函数外的extra。<jupyter_output>name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}<jupyter_text>1.6 函数体与变量作用域- 函数体就是一段只在函数被调用时，才会执行的代码，代码构成与其他代码相同。- 局部变量——仅在函数体内定义和发挥作用<jupyter_code>def multiply(x, y):
    z = x * y
    return z


multiply(2, 9)
print(y)        #函数执行完毕，局部变量z就被释放掉了<jupyter_output><empty_output><jupyter_text>- 全局变量——外部定义的都是全局变量- 全局变量可以在函数体内被直接使用<jupyter_code>n = 3
ls = [0]


def multiply(x, y):
    z = n * x * y
    ls.append(z)
    return z

print(multiply(5, 5))
print(multiply(2, 9))
ls
print(x, y, z)<jupyter_output>75
54<jupyter_text>- 通过global在函数体内定义全局变量<jupyter_code>def multiply(x, y):
    global z
    z = x * y
    return z


multiply(2, 9)
print(z)<jupyter_output>18<jupyter_text>1.7 返回值- 单个返回值<jupyter_code>def foo(x):
    return x**2

foo(5)<jupyter_output><empty_output><jupyter_text>- 多个返回值——以元组的形式<jupyter_code>def foo(x):
    return x**0, x**1, x**2, x**3  #逗号分开，打包返回


print(foo(3))

a, b, c, d = foo(3)     #解包赋值
print(a)
print(b)
print(c)
print(d)<jupyter_output>(1, 3, 9, 27)
1
3
9
27<jupyter_text>- 可以有多个return语句，但一旦其中一个执行，代表了函数运行的结束<jupyter_code>def is_weekend(day):
    if day in ['Saturday', 'Sunday']:
        return 'Is weekend'
    else:
        return 'Not weekend'
    print('巴啦啦能量，变身！')           #这句根本没机会执行
    
    
print(is_weekend('Sunday'))
print(is_weekend('Monday'))
print(is_weekend(1))<jupyter_output>Is weekend
Not weekend
Not weekend<jupyter_text>- 没有return语句，返回值为None<jupyter_code>def foo():
    #打印几句诗
    print('问余何意栖碧山，日照香炉生紫烟。')
    print('我寄愁心与明月，将船买酒白云边。')
    

res = foo()
print(res)<jupyter_output>问余何意栖碧山，日照香炉生紫烟。
我寄愁心与明月，将船买酒白云边。
None<jupyter_text>1.8 几点建议- 函数及其参数的命名参照变量的命名    - 字母小写及下划线组合    - 有实际意义- 应包含简要阐述函数功能的注释，紧跟函数定义后- 函数定义前后空两行- 默认参数赋值等号两侧不需加空格  2. 函数式编程实例 **【问题描述】**- 小丹和小伟都喜欢打羽毛球，小丹略胜一筹，基本上，打100个球，小丹赢53次，小伟赢47次。- 但每次大型比赛（1局定胜负，先赢到21分获胜），小丹的胜率远大于小伟。小伟很不服气。- 亲爱的小伙伴，你能通过模拟试验，来揭示其中的奥妙吗？**【问题抽象】**- 在小丹vs小伟的比赛中，小丹每球获胜概率53%，小伟每球获胜概率47%；- 每局比赛，先赢21球（21分）者获胜；- 假设进行n=1000场独立的比赛，小丹会获胜多少场？（n较大的时候，实验结果约等与真是结果。 **【问题分解】**<jupyter_code>def main():
    #主要逻辑
    prob_A, prob_B, number_of_games = get_inputs()
    win_A, win_B = sim_n_games(prob_A, prob_B, number_of_games)
    print_summary(win_A, win_B, number_of_games)
a = float(input())
type(a)<jupyter_output>0.53<jupyter_text>**【输入原始数据】**<jupyter_code>def get_inputs():
    #输入原始数据
    prob_A = eval(input('请输入运动员A的每球获胜概率（0-1）：'))
    prob_B = round(1-prob_A, 2)
    number_of_games = eval(input('请输入模拟的场次（正整数）：'))
    print('模拟比赛总次数：', number_of_games)
    print('A选手每球获胜概率：', prob_A)
    print('B选手每球获胜概率：', prob_B)
    return prob_A, prob_B, number_of_games<jupyter_output><empty_output><jupyter_text>**【单元测试】**<jupyter_code>prob_A, prob_B, number_of_games = get_inputs()<jupyter_output>请输入运动员A的每球获胜概率（0-1）：0.4
请输入模拟的场次（正整数）：500
模拟比赛总次数： 500
A选手每球获胜概率： 0.4
B选手每球获胜概率： 0.6<jupyter_text>**【多场比赛模拟】**<jupyter_code>def sim_n_games(prob_A, prob_B, number_of_games):
    #模拟多场比赛的结果
    win_A, win_B = 0, 0                    #初始化A、B的获胜场次
    for i in range(number_of_games):      #迭代number_of_games次
        score_A, score_B = sim_one_game(prob_A, prob_B)  #获得模拟依次比赛的比分
        if score_A > score_B:
            win_A += 1
        else:
            win_B += 1
    return win_A, win_B
import random
def sim_one_game(prob_A, prob_B):
    #模拟一场比赛的结果
    score_A, score_B = 0, 0    
    while not game_over(score_A, score_B):
        if random.random() < prob_A:           #random.random()产生[0,1)之间的随机小数，均匀分布
            score_A += 1
        else:
            score_B += 1
    return score_A, score_B
def game_over(score_A, score_B):
    #单场模拟结束条件，一方先达到21分则结束
    return score_A == 21 or score_B == 21<jupyter_output><empty_output><jupyter_text>**【单元测试】** 用assert——断言进行- assert expression- 表达式结果为False的时候触发异常<jupyter_code>assert game_over(21, 9) == True
assert game_over(15, 21) == True
assert game_over(11, 7) == False
print(sim_one_game(0.51, 0.49))
print(sim_one_game(0.55, 0.45))
print(sim_one_game(0.6, 0.4))
print(sim_n_games(0.53, 0.47, 1000))<jupyter_output>(645, 355)<jupyter_text>**【结果汇总输出】**<jupyter_code>def print_summary(win_A, win_B, number_of_games):
    # 结果汇总输出
    print('共模拟了{}场比赛'.format(number_of_games))
    print('选手A获胜{0}场，占比{1:.1%}'.format(win_A, win_A/number_of_games))
    print('选手B获胜{0}场，占比{1:.1%}'.format(win_B, win_B/number_of_games))
print_summary(729, 271, 1000)<jupyter_output>共模拟了1000场比赛
选手A获胜729场，占比72.9%
选手B获胜271场，占比27.1%<jupyter_text>**【完整程序】**<jupyter_code>import random


def get_inputs():
    #输入原始数据
    prob_A = eval(input('请输入运动员A的每球获胜概率（0-1）：'))
    prob_B = round(1-prob_A, 2)
    number_of_games = eval(input('请输入模拟的场次（正整数）：'))
    print('模拟比赛总次数：', number_of_games)
    print('A选手每球获胜概率：', prob_A)
    print('B选手每球获胜概率：', prob_B)
    return prob_A, prob_B, number_of_games


def game_over(score_A, score_B):
    #单场模拟结束条件，一方先达到21分则结束
    return score_A == 21 or score_B == 21


def sim_one_game(prob_A, prob_B):
    #模拟一场比赛的结果
    score_A, score_B = 0, 0    
    while not game_over(score_A, score_B):
        if random.random() < prob_A:           #random.random()产生[0,1)之间的随机小数，均匀分布
            score_A += 1
        else:
            score_B += 1
    return score_A, score_B


def sim_n_games(prob_A, prob_B, number_of_games):
    #模拟多场比赛的结果
    win_A, win_B = 0, 0                    #初始化A、B的获胜场次
    for i in range(number_of_games):      #迭代number_of_games次
        score_A, score_B = sim_one_game(prob_A, prob_B)  #获得模拟依次比赛的比分
        if score_A > score_B:
            win_A += 1
        else:
            win_B += 1
    return win_A, win_B


def print_summary(win_A, win_B, number_of_games):
    # 结果汇总输出
    print('共模拟了{}场比赛'.format(number_of_games))
    print('选手A获胜{0}场，占比{1:.1%}'.format(win_A, win_A/number_of_games))
    print('选手B获胜{0}场，占比{1:.1%}'.format(win_B, win_B/number_of_games))
    
    
def main():
    #主要逻辑
    prob_A, prob_B, number_of_games = get_inputs()
    win_A, win_B = sim_n_games(prob_A, prob_B, number_of_games)
    print_summary(win_A, win_B, number_of_games)
    
    
main()<jupyter_output>请输入运动员A的每球获胜概率（0-1）：0.55
请输入模拟的场次（正整数）：10000
模拟比赛总次数： 10000
A选手每球获胜概率： 0.55
B选手每球获胜概率： 0.45
共模拟了10000场比赛
选手A获胜7425场，占比74.2%
选手B获胜2575场，占比25.8%<jupyter_text>3. 匿名函数 - 基本形式```lambda 变量: 函数体```- 常用用法在参数列表中最适合食用匿名函数，尤其是与key = 搭配 排序 sort() sorted()<jupyter_code>def square_sum(*numbers):
    sum = 0
    for i in numbers:
        sum += i**2
    return sum

square_sum(5)
ls = [(93, 88), (79, 100), (86, 71), (85, 85), (76, 94)]
ls.sort()
ls
ls.sort(key = lambda x: x[1])
ls
ls =[(3, 8), (9, 16), (2, 7), (5, 5), (6, 4)]
temp = sorted(ls, key = lambda x: x[1])
print(ls)
print(temp)<jupyter_output>[(3, 8), (9, 16), (2, 7), (5, 5), (6, 4)]
[(6, 4), (5, 5), (2, 7), (3, 8), (9, 16)]<jupyter_text>max()  min()<jupyter_code>n = max(ls, key = lambda x: x[1])
n
n = min(ls, key = lambda x: x[1])
n<jupyter_output><empty_output><jupyter_text>4. 面向过程和面向对象 **面向过程**——以过程为中心的编程思想，以“什么正在发生”为主要目标进行编程。  **冰冷的、程序化的****面向对象**——将现实世界的事物抽象成对象，更关注“谁在受影响”，更加贴近现实。  **有血有肉，拟人（物）化的**- 以公共汽车为例**面向过程**：汽车启动是一个事件，汽车到站是另一个事件。编程过程中我们关心某一个事件，而不是汽车本身。我们分别对启动和到站编写程序。**面向对象**：构造“汽车”这个对象。对象包含动力、服役时间、生产厂家等一系列**“属性”**。也包含加油、启动、加速、刹车、拐弯、鸣喇叭、到站、维修等一系列的**“方法”**。通过对象的行为表达相应的事件。  第二部分 对象和类 **WHY：面向对象更符合人类对客观世界的抽象和理解**- **一切皆对象**    一件衣服，一台电脑，一碗面，一只小狗……    - **一切对象，都有自己的内在属性**    衣服的款式，电脑的配置，面的味道，狗狗的品种……- **一切行为，都是对象的行为**    衣服破了，电脑重启，面端走了，狗狗蹲下……    **HOW：类是对象的本体** Class instance不同年龄、毛色、大小的狗，每一只都是一个对象它们有一个共同的特征：都是狗我们可以把一类对象的公共特征抽象出来，创建通用的类<jupyter_code># 创建类
class Dog():
    '''模拟狗'''
    
    def __init__(self, name, color=None, size='middle', weight=None): #initial, initialize, 前后各加两个下划线 _ _ 
        '''初始化属性'''
        self.name = name
        self.color = color
        self.size = size
        self.weight = weight
        
        
    def jump(self):
        '''模拟狗跳跃'''
        print(self.name + 'is jumping.')
#用类创建实例
my_dog = Dog('A Huang')
your_dog = Dog('Xiao Bai')
#调用属性
print(my_dog.name, my_dog.color)
print(your_dog.name)
#调用方法
my_dog.jump()
your_dog.jump()<jupyter_output>A Huangis jumping.
Xiao Baiis jumping.<jupyter_text>1. 类的定义**三要素：类名、属性、方法** 1.1 类的命名- 要有实际意义- 驼峰体，组成的单词首字母大写    - 函数：square_sum        - 类：DogFoodDog、CreditCard、ElectricCar<jupyter_code># class 类名
'''类前空两行'''


class Car():
    '''对该类的简单介绍'''
    pass


'''类后空两行'''<jupyter_output><empty_output><jupyter_text>1.2 类的属性<jupyter_code># def __init__(self, 要传递的参数)   初始化类的属性
class Car():
    '''模拟汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化汽车属性'''                 #相当于类内部的变量
        self.brand = brand                   #汽车的品牌
        self.model = model                   #汽车的型号
        self.year = year                     #汽车出场年份
        self.mileage = 0                     #新车总里程初始化为0
my_car = Car('Tesla', 'Model 3', 2020)
print(my_car.mileage)<jupyter_output>0<jupyter_text>1.3 类的方法<jupyter_code># 相当于类内部定义的函数
class Car():
    '''模拟汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化汽车属性'''                 #相当于类内部的变量
        self.brand = brand                   #汽车的品牌
        self.model = model                   #汽车的型号
        self.year = year                     #汽车出场年份
        self.mileage = 0                     #新车总里程初始化为0
        
        
    def get_main_information(self):
        '''获取汽车主要信息'''
        print('品牌：{}   型号：{}    出场年份：{}'.format(self.brand, self.model, self.year))
        
    def get_mileage(self):
        '''获得总里程数'''
        return '行车总里程：{}公里'.format(self.mileage)<jupyter_output><empty_output><jupyter_text>2. 创建实例 2.1 实例的创建将实例赋值给对象，实例化过程中，传入相应的参数```v = 类名(必要的初始化参数)```<jupyter_code>my_new_car = Car('Audi', 'A8', 2018)<jupyter_output><empty_output><jupyter_text>2.2 访问属性```实例名.属性名```<jupyter_code>print(my_new_car.brand)
print(my_new_car.model)
print(my_new_car.year)<jupyter_output><empty_output><jupyter_text>2.3 调用方法```实例名.方法名(必要的参数)```<jupyter_code>my_new_car = Car('Audi', 'A8', 2020)
my_new_car.get_main_information()
s = my_new_car.get_mileage()
print(s)<jupyter_output>品牌：Audi   型号：A8    出场年份：2020
行车总里程：0公里<jupyter_text>2.4 修改属性- 直接修改<jupyter_code>my_old_car = Car('Hyundai', 'Sonata', 2014)<jupyter_output><empty_output><jupyter_text>先访问，后修改<jupyter_code>print(my_old_car.mileage)
my_old_car.mileage = 50000
print(my_old_car.mileage)
print(my_old_car.get_mileage())<jupyter_output>行车总里程：50000公里<jupyter_text>- 通过方法修改属性<jupyter_code>class Car():
    '''模拟汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化汽车属性'''                 #相当于类内部的变量
        self.brand = brand                   #汽车的品牌
        self.model = model                   #汽车的型号
        self.year = year                     #汽车出场年份
        self.mileage = 0                     #新车总里程初始化为0
        
        
    def get_main_information(self):
        '''获取汽车主要信息'''
        print('品牌：{}   型号：{}    出场年份：{}'.format(self.brand, self.model, self.year))
        
    def get_mileage(self):
        '''获得总里程数'''
        return '行车总里程：{}公里'.format(self.mileage)
    
    def set_mileage(self, distance):
        '''设置总里程数'''
        self.mileage = distance
my_old_car = Car('Hyundai', 'Sonata', 2014)
print(my_old_car.mileage)
my_old_car.set_mileage(15000)
print(my_old_car.get_mileage())<jupyter_output>0
行车总里程：15000公里<jupyter_text>- 继续拓展    1. 禁止设置负里程        2. 将每次的里程数增加<jupyter_code>class Car():
    '''模拟汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化汽车属性'''                 #相当于类内部的变量
        self.brand = brand                   #汽车的品牌
        self.model = model                   #汽车的型号
        self.year = year                     #汽车出场年份
        self.mileage = 0                     #新车总里程初始化为0
        
        
    def get_main_information(self):
        '''获取汽车主要信息'''
        print('品牌：{}   型号：{}    出场年份：{}'.format(self.brand, self.model, self.year))
        
    def get_mileage(self):
        '''获得总里程数'''
        return '行车总里程：{}公里'.format(self.mileage)
    
    def set_mileage(self, distance):
        '''设置总里程数'''
        if distance >= 0:
            self.mileage = distance
        else:
            print('里程数不能为负！')
            
    def increase_mileage(self, distance):
        '''总里程数累计'''
        if distance > 0:
            self.mileage += distance
        else:
            print('新增里程数不能为负！')
my_old_car = Car('Hyundai', 'Sonata', 2014)
my_old_car.get_mileage()
my_old_car.set_mileage(-5000)
my_old_car.get_mileage()
my_old_car.increase_mileage(500)
my_old_car.get_mileage()
my_new_car = Car('Audi', 'A8', 2020)
my_old_car = Car('Hyundai', 'Sonata', 2014)
my_cars = [my_new_car, my_old_car]<jupyter_output><empty_output><jupyter_text>- 类中包含的信息可以是极大的，可以创建无穷多的实例- 高度的拟人（物）化，符合人类对客观世界的抽象和理解  3. 类的继承 **引子** > 生物——动物界——脊索动物门——哺乳动物纲——灵长目——人科——人属——智人种分类的过程，也是公共特征逐渐增加的过程**【问题】**假设二元系统：人属 = {A人种， B人种， C人种, ...}为每一个人种构造一个类**方案一**：各自独立，分别构造各自人种的类**方案二**：1. 将各人种公共特征提取出来，建立人属的类；2. 各人种继承上一级（人属）的公共特征，然后添加自身特殊特征，构建各自人种的类。通常我们选择方案二，因为可以避免很多重复劳动。**所谓继承，就是低层抽象继承高层抽象的过程** 3.1 简单的继承**父类**<jupyter_code>class Car():
    '''模拟汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化汽车属性'''                 #相当于类内部的变量
        self.brand = brand                   #汽车的品牌
        self.model = model                   #汽车的型号
        self.year = year                     #汽车出场年份
        self.mileage = 0                     #新车总里程初始化为0
        
        
    def get_main_information(self):
        '''获取汽车主要信息'''
        print('品牌：{}   型号：{}    出场年份：{}'.format(self.brand, self.model, self.year))
        
    def get_mileage(self):
        '''获得总里程数'''
        return '行车总里程：{}公里'.format(self.mileage)
    
    def set_mileage(self, distance):
        '''设置总里程数'''
        if distance >= 0:
            self.mileage = distance
        else:
            print('里程数不能为负！')
            
    def increase_mileage(self, distance):
        '''总里程数累计'''
        if distance > 0:
            self.mileage += distance
        else:
            print('新增里程数不能为负！')<jupyter_output><empty_output><jupyter_text>**子类**```class 子类名(父类名):```<jupyter_code>#新建一个电动汽车的类


class ElectricCar(Car):
    '''模拟电动汽车'''
    
    def __init__(self, brand, model, year):
        '''初始化电动汽车属性'''
        super().__init__(brand, model, year)  #声明继承父类的属性<jupyter_output><empty_output><jupyter_text>- 自动继承父类的所有方法<jupyter_code>my_electric_car = ElectricCar('BYD', '宋pro', 2020)
my_electric_car.get_main_information()<jupyter_output>品牌：BYD   型号：宋pro    出场年份：2020<jupyter_text>3.2 给子类添加方法<jupyter_code>class ElectricCar(Car):
    '''模拟电动汽车'''
    
    def __init__(self, brand, model, year, battery_size):
        '''初始化电动汽车属性'''
        super().__init__(brand, model, year)  #声明继承父类的属性
        self.battery_size = battery_size      #电池容量
        self.battery_remaining = battery_size #剩余电量
        self.battery2distance_ratio = 6      #电量距离换算系数 6公里/kwh
        self.reminder_range = self.battery_remaining*self.battery2distance_ratio
        
    def get_battery_remaining(self):
        '''查看当前剩余电量'''
        print('当前剩余电量为：{} kwh'.format(self.battery_remaining))
        
    def set_battery_remaining(self, battery_remaining):
        '''设置电池剩余电量，重新计算电量可支撑行驶里程'''
        if battery_remaining >= 0 and battery_remaining < self.battery_size:
            self.battery_remaining = battery_remaining
            self.reminder_range = self.battery_remaining*self.battery2distance_ratio
        else:
            print('电量未设置在合理范围！')
            
    def get_reminder_range(self):
        '''查看剩余可行驶里程'''
        print('当前点亮还可以继续行驶 {} 公里'.format(self.reminder_range))
my_electric_car = ElectricCar('BYD', '宋pro', 2020, 70)
my_electric_car.get_battery_remaining()
my_electric_car.get_reminder_range()
my_electric_car.set_battery_remaining(50)
my_electric_car.get_battery_remaining()
my_electric_car.get_reminder_range()<jupyter_output>当前剩余电量为：50 kwh
当前点亮还可以继续行驶 300 公里<jupyter_text>3.3 重写父类的方法——多态<jupyter_code>class ElectricCar(Car):
    '''模拟电动汽车'''
    
    def __init__(self, brand, model, year, battery_size):
        '''初始化电动汽车属性'''
        super().__init__(brand, model, year)  #声明继承父类的属性
        self.battery_size = battery_size      #电池容量
        self.battery_remaining = battery_size #剩余电量
        self.battery2distance_ratio = 6       #电量距离换算系数 6公里/kwh
        self.reminder_range = self.battery_remaining*self.battery2distance_ratio
                                              #剩余可行驶里程
    
    def get_main_information(self):           #重写父类方法
        '''获取汽车主要信息'''
        print('品牌：{}  型号：{}  出场年份：{}  续航里程：{}公里'.format(self.brand, self.model, self.year, self.reminder_range))
           
    def get_battery_remaining(self):
        '''查看当前剩余电量'''
        print('当前剩余电量为：{} kwh'.format(self.battery.remaining))
        
    def set_battery_remaining(self, battery_remaining):
        '''设置电池剩余电量，重新计算电量可支撑行驶里程'''
        if battery_remaining >= 0 and battery_remaining < self.battery_size:
            self.battery_remaining = battery_remaining
            self.reminder_range = self.battery_remaining*self.battery2distance_ratio
        else:
            print('电量未设置在合理范围！')
            
    def get_reminder_range(self):
        '''查看剩余可行驶里程'''
        print('当前点亮还可以继续行驶 {} 公里'.format(self.reminder_range))
my_electric_car = ElectricCar('BYD', '宋pro', 2020, 70)
my_electric_car.get_main_information()
my_old_car.get_main_information()<jupyter_output>品牌：BYD  型号：宋pro  出场年份：2020  续航里程：420公里
品牌：Hyundai   型号：Sonata    出场年份：2014<jupyter_text>3.4 用在类中的实例例如把电池抽象成一个对象逻辑更加清晰<jupyter_code>class Battery():
    '''模拟电动汽车的电池'''
    
    def __init__(self, battery_size = 70):
        self.battery_size = battery_size
        self.battery_remaining = battery_size
        self.battery2distance_ratio = 6
        self.reminder_range = self.battery_remaining*self.battery2distance_ratio
    
    def get_battery_remaining(self):
        '''查看当前剩余电量'''
        print('当前剩余电量为：{} kwh'.format(self.battery_remaining))

    def set_battery_remaining(self, battery_remaining):
        '''设置电池剩余电量，重新计算电量可支撑行驶里程'''
        if battery_remaining >= 0 and battery_remaining < self.battery_size:
            self.battery_remaining = battery_remaining
            self.reminder_range = self.battery_remaining*self.battery2distance_ratio
        else:
            print('电量未设置在合理范围！')
            
    def get_reminder_range(self):
        '''查看剩余可行驶里程'''
        print('当前电量还可以继续行驶 {} 公里'.format(self.reminder_range))
class ElectricCar(Car):
    '''模拟电动汽车'''
    
    def __init__(self, brand, model, year, battery_size):
        '''初始化电动汽车属性'''
        super().__init__(brand, model, year)  #声明继承父类的属性
        self.battery_size = Battery(battery_size)
        
    def get_main_information(self):           #重写父类方法
        '''获取汽车主要信息'''
        print('品牌：{}  型号：{}  出场年份：{}  续航里程：{}公里'.
              format(self.brand, self.model, self.year, self.battery_size.reminder_range))
my_electric_car = ElectricCar('BYD', '宋pro', 2020, 70)
my_electric_car.get_main_information()
my_electric_car.battery_size.get_reminder_range()
my_electric_car.battery_size.set_battery_remaining(50)
my_electric_car.battery_size.get_battery_remaining()
my_electric_car.battery_size.get_reminder_range()<jupyter_output>当前点亮还可以继续行驶 300 公里<jupyter_text>第三部分 文件读写   1. 文件的打开- 文件打开的通用格式<jupyter_code>with open('文件路径', '打开模式', '打开模式', encoding = '操作文件的字符编码') as f:
    pass  #对文件进行相应的读写操作

#使用with块的好处，执行完毕后，自动对文件执行close操作。

f = open('文件路径', '打开模式', encoding = '操作文件的字符编码')
f.read()
###
f.close()<jupyter_output><empty_output><jupyter_text>【例】一个简单的文件读写<jupyter_code>with open(r"F:\Projects\Data-Analysis-with-Python\test.txt", 'r', encoding = 'utf-8') as f:
        text = f.read()
        print(text)<jupyter_output>This is a test file.<jupyter_text>1.1 文件路径- 完整路径，如上例所示- 程序与文件在同一文件夹，可简化成文件名<jupyter_code>with open('test.txt', 'r', encoding = 'utf-8') as f:
    text = f.read()
    print(text)<jupyter_output>b'This is a test file.'<jupyter_text>1.2 打开模式|访问模式|说明|:--------|:--r	|以只读方式打开文件。文件的指针将会放在文件的开头，文件不存在则报错。这是默认模式，如果打开模式缺省，则为该模式。w	|打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。x   |创建写模式，如文件不存在，则创建；如存在，则报错。a	|打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。b	|以二进制格式打开一个文件，不能单独使用，需要配合“wb”、“rb”、“ab”等，该模式不需要指定encoding。t  |文本文件模式，默认值。+  |与“r”、“w”、“x”、“a”配合使用，在基础功能上增加读写功能。r+	|打开一个文件用于读写。文件指针将会放在文件的开头。w+	|打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。a+	|打开一个文件用于读写。如果该文件已存在，文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在，创建新文件用于读写。rb+	|以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。wb+	|以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。ab+	|以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写。  1.3 字符编码- 万国码 utf-8包含全世界所有国家需要用到的字符- 中文简码 gbk专门解决中文编码问题- unicode- windows系统默认为所在区域的编码- 为清楚起见，除了处理二进制文件，**不要缺省encoding**。  2. 文件的读取 2.1 读取整个内容  f.read()<jupyter_code>with open('imagine_lyrics.txt', encoding = 'utf-8') as f:
    text = f.read()
    print(text)<jupyter_output>﻿Imagine there's no heaven
It's easy if you try
No hell below us
Above us only sky

Imagine all the people
Living for today (ah ah ah)

Imagine there's no countries
It isn't hard to do
Nothing to kill or die for
And no religion, too

Imagine all the people
Living life in peace 

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will be as one

Imagine no possessions
I wonder if you can
No need for greed or hunger
A brotherhood of man

Imagine all the people
Sharing all the world

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will live as one<jupyter_text>- 解码模式不匹配<jupyter_code>with open('imagine_lyrics.txt', encoding = 'gbk') as f:
    text = f.read()
    print(text)
with open('imagine_lyrics.txt') as f:
    text = f.read()
    print(text)<jupyter_output>锘縄magine there's no heaven
It's easy if you try
No hell below us
Above us only sky

Imagine all the people
Living for today (ah ah ah)

Imagine there's no countries
It isn't hard to do
Nothing to kill or die for
And no religion, too

Imagine all the people
Living life in peace 

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will be as one

Imagine no possessions
I wonder if you can
No need for greed or hunger
A brotherhood of man

Imagine all the people
Sharing all the world

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will live as one<jupyter_text>2.2 逐行读取 f.readline()<jupyter_code>with open('imagine_lyrics.txt', encoding = 'utf-8') as f:
    text = f.readline()
    print(text)
    text = f.readline()
    print(text)
with open('imagine_lyrics.txt', encoding = 'utf-8') as f:
    while True:
        text = f.readline()
        if not text:
            break
        else:
            print(text, end='')   #保留原文的换行，使print()的默认换行不起作用<jupyter_output>﻿Imagine there's no heaven
It's easy if you try
No hell below us
Above us only sky

Imagine all the people
Living for today (ah ah ah)

Imagine there's no countries
It isn't hard to do
Nothing to kill or die for
And no religion, too

Imagine all the people
Living life in peace 

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will be as one

Imagine no possessions
I wonder if you can
No need for greed or hunger
A brotherhood of man

Imagine all the people
Sharing all the world

You may say that I'm a dreamer
But I'm not the only one
I hope someday you'll join us
And the world will live as one<jupyter_text>2.3 读入所有行，以每行为元素形成一个列表 f.readlines()<jupyter_code>with open('imagine_lyrics.txt', encoding = 'utf-8') as f:
    text = f.readlines()
    print(text)<jupyter_output>["\ufeffImagine there's no heaven\n", "It's easy if you try\n", 'No hell below us\n', 'Above us only sky\n', '\n', 'Imagine all the people\n', 'Living for today (ah ah ah)\n', '\n', "Imagine there's no countries\n", "It isn't hard to do\n", 'Nothing to kill or die for\n', 'And no religion, too\n', '\n', 'Imagine all the people\n', 'Living life in peace \n', '\n', "You may say that I'm a dreamer\n", "But I'm not the only one\n", "I hope someday you'll join us\n", 'And the world will be as one\n', '\n', 'Imagine no possessions\n', 'I wonder if you can\n', 'No need for greed or hunger\n', 'A brotherhood of man\n', '\n', 'Imagine all the people\n', 'Sharing all the world\n', '\n', "You may say that I'm a dreamer\n", "But I'm not the only one\n", "I hope someday you'll join us\n", 'And the world will live as one']<jupyter_text>2.4 文本文件读取小结文件比较大时，read()和readlines()占用内存过大，不建议使用但readline用起来又不太方便<jupyter_code>with open('imagine_lyrics.txt', encoding = 'utf-8') as f:
    for text in f:     #f本身就是一个可迭代对象，每次迭代读取一行内容
        print(text)<jupyter_output>﻿Imagine there's no heaven

It's easy if you try

No hell below us

Above us only sky



Imagine all the people

Living for today (ah ah ah)



Imagine there's no countries

It isn't hard to do

Nothing to kill or die for

And no religion, too



Imagine all the people

Living life in peace 



You may say that I'm a dreamer

But I'm not the only one

I hope someday you'll join us

And the world will be as one



Imagine no possessions

I wonder if you can

No need for greed or hunger

A brotherhood of man



Imagine all the people

Sharing all the world



You may say that I'm a dreamer

But I'm not the only one

I hope someday you'll join us

And the world will live as one<jupyter_text>2.5 二进制文件图片是一种典型的二进制文件<jupyter_code>with open('test.jpg', 'rb') as f:
    for line in f:
        print(line, end='')
    print(len(f.readlines()))<jupyter_output>b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb\x00C\x00\x08\x05\x06\x07\x06\x05\x08\x07\x06\x07\t\x08\x08\t\x0c\x13\x0c\x0c\x0b\x0b\x0c\x18\x11\x12\x0e\x13\x1c\x18\x1d\x1d\x1b\x18\x1b\x1a\x1f#,%\x1f!*!\x1a\x1b&4'*./121\x1e%6:60:,010\xff\xdb\x00C\x01\x08\t\t\x0c\n"b'\x0c\x17\x0c\x0c\x170 \x1b 00000000000000000000000000000000000000000000000000\xff\xc0\x00\x11\x08\x02\xbc\x03\xbc\x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1c\x00\x01\x00\x02\x03\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x06\x01\x03\x04\x07\x02\x08\xff\xc4\x00O\x10\x00\x02\x01\x03\x01\x05\x04\x06\x06\x06\x08\x05\x03\x03\x04\x03\x00\x01\x02\x03\x04\x11\x05\x12!1AQ\x06\x13aq"\x81\x91\xa1\xb1\xc1\x07\x142BR\xd1#3br\xe1\xf0\x15\x164CS\x82\x92\xf1$5Tcs\xa2\xb2\xc2\x08%D\x17\x83\x93\xd2EUd\xff\xc4\x00\x1c\x01\x01\x00\x01\x05\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x02\x03\x05\x06\x07\x08\xff\xc4\x006\x11\x00\x02\x02\x01\x03\x03\x02\x05\x01\x08\x01\x05\x01\x01\x00\[...]<jupyter_text>3. 文件的写入  3.1 向文件写入一个字符串或字节流（二进制） f.write()<jupyter_code>with open('hey_jude_lyrics.txt', 'w', encoding = 'utf-8') as f:
    f.write('Hey Jude， don\'t make it bad.\n')   #文件不存在则创建一个
    f.write('Take a sad song and make it better.\n')
    f.write('Remember to let her into your heart.\n')
    f.write('Then you can start to make it better.\n')
with open('hey_jude_lyrics.txt', 'w', encoding = 'utf-8') as f:
    f.write('Hey Jude, don\'t be afraid.\n')   #文件存在则覆盖
    f.write('You were made to go out and get her.\n')
    f.write('The minute you let her under your skin.\n')
    f.write('Then you begin to make it better.\n')<jupyter_output><empty_output><jupyter_text>3.2 追加模式 'a'<jupyter_code>with open('hey_jude_lyrics.txt', 'a', encoding = 'utf-8') as f:
    f.write('Hey Jude, don\'t be afraid.\n')   #文件存在则追加
    f.write('You were made to go out and get her.\n')
    f.write('The minute you let her under your skin.\n')
    f.write('Then you begin to make it better.\n')<jupyter_output><empty_output><jupyter_text>3.3 将一个元素为字符串的列表整体写入文件 f.writelines()<jupyter_code>ls = ['And anytime you feel the pain, hey Jude, refrain.', 
      'Don\'t carry the world upon your shoulders.', 
      'For well you know that it\'s a fool who plays it cool.',
      'By making his world a little colder.', 
      'Hey Jude, don\'t let me down.', 
      'You have found her now go and get her.', 
      'Remember to let her into your heart.', 
      'Then you can start to make it better.', 
      'So let it out and let it in, hey Jude, begin',
      'You\'re waiting for someone to perform with.', 
      'And don\'t you know that it\'s just you, hey Jude, you\'ll do', 
      'The movement you need is on your shoulder.', 
      'Hey Jude, don\'t make it bad.', 
      'Take a sad song and make it better.', 
      'Remember to let her under your skin.', 
      'Then you\'ll begin to make it.', 
      'Better better better better better better, oh.', 
      'Da da da da da da, da da da, hey Jude...']
with open('hey_jude_lyrics.txt', 'a', encoding = 'utf-8') as f:
    f.writelines(ls)<jupyter_output><empty_output><jupyter_text>4. 既读又写 4.1  'r+'- 如果文件名不存在，则报错- 指针在开始- 要把指针移到末尾才可以开始写，否则会覆盖前面内容<jupyter_code>with open('hey_jude_lyrics.txt', 'r+', encoding = 'utf-8') as f:
#    for line in f:
#        pass
    f.seek(0, 2)
    text = ['by\n', '<NAME>\n']
    f.writelines(text)<jupyter_output><empty_output><jupyter_text>python中可以使用seek()移动文件指针到指定位置，然后读/写。通常配合 r+ 、w+、a+ 模式，在此三种模式下，seek指针移动只能从头开始移动，即seek(x,0) 。模式|默认|写方式|与seek()配合---写|与seek()配合---读-:-|-:-|-:-|-:-|-:-|r+|文件指针在文件头部，即seek(0)|覆盖|f = open('test.txt','r+',encoding='utf-8')\nf.seek(3,0)\nf.write('aaa') 移动文件指针到指定位置，再写|f = open('test.txt','r+',encoding='utf-8')\nf.seek(3,0)\nf.read() 移动文件指针到指定位置，读取后面的内容w+|文件指针在文件头部，即seek(0)|清除|f = open('test.txt','w+',encoding='utf-8')\nf.seek(3,0)\nf.write('aaa') 清除文件内容，移动文件指针到指定位置，再写|f = open('test.txt','w+',encoding='utf-8')\nf.write('aaa') \nf.seek(3,0)\nf.read()清除文件内容写入，移动文件指针到指定位置，读取后面内容a+|文件指针在文件尾部，即seek(0,2)|追加|f = open('test.txt','a+',encoding='utf-8')\nf.seek(3,0)\nf.write('aaa') 直接在文件末尾写入，seek移动指针不起作用|同 r+（1）seek(offset[,whence])：（2）offset--偏移量，可以是负值，代表从后向前移动；（3）whence--偏移相对位置，分别有：os.SEEK_SET（相对文件起始位置，也可用“0”表示）；os.SEEK_CUR（相对文件当前位置，也可用“1”表示）；os.SEEK_END（相对文件结尾位置，也可用“2”表示）。  seek（x，0）：表示指针从开头位置移动到x位置 seek（x，1）：表示指针从当前位置向后移动x个位置 seek（-x，2）：表示指针从文件结尾向前移动x个位置例：file.seek(-1,2)，文件指针从文件末尾向前移动一个字符，配合read相关方法/函数可读取该字符。  4.2 'w+'- 如果文件不存在，则创建- 如果文件存在，会立刻清空原内容！！！<jupyter_code>with open('hey_jude_lyrics.txt', 'w+', encoding = 'utf-8') as f:
    pass
with open('hey_jude_lyrics.txt', 'r+', encoding = 'utf-8') as f:
    text = ['<NAME>', 'by\n', '<NAME>\n']    #打开后立即清空内容
    f.writelines(text)                                 #写入新内容
    f.seek(0, 0)      #指针移动到开始
    print(f.read())   #读取内容并打印<jupyter_output>H<NAME>by
<NAME><jupyter_text>4.3 'a+'- 如果文件不存在，则创建- 指针在末尾，添加新内容，不会清空原内容<jupyter_code>with open('hey_jude_lyrics.txt', 'a+', encoding = 'utf-8') as f:
    f.seek(0, 0)      #指针移动到开始
    print(f.read())   #读取内容并打印
with open('hey_jude_lyrics.txt', 'a+', encoding = 'utf-8') as f:
    text = ['<NAME>， don\'t make it bad.\n', 
            'Take a sad song and make it better.\n', 
            'Remember to let her into your heart.\n', 
            'Then you can start to make it better.\n']
    f.writelines(text)  #此时指针在末尾，追加新内容
    f.seek(0, 0)      #指针移动到开始
    print(f.read())   #读取内容并打印<jupyter_output><empty_output><jupyter_text>4.4 在文件头部插入内容<jupyter_code>with open(path, "r+") as f:
    old = f.read()
    f.seek(0， 0)
    text = 'This is the lyrics of Hey Jude.'
    f.write(text)
    f.write(old)
    print(f.read())<jupyter_output><empty_output><jupyter_text>5. 数据的存储与读取**通用的数据格式，可以在不同语言中加载和存储****本节简单了解两种数据存储结构csv和json** 5.1 csv格式由逗号或制表符将数据分开的字符序列，可以由excel打开- 读取<jupyter_code>with open('score.csv', 'r', encoding = 'gbk') as f:
    ls = []
    for line in f:                              #逐行读取
        ls.append(line.strip('\n').split('\t'))  #去掉每行的换行符，用','进行分割
print(ls)<jupyter_output>[['姓名', '成绩'], ['小红', '86'], ['小刚', '91'], ['小明', '88']]<jupyter_text>- 写入<jupyter_code>ls = [['学号', '姓名', '数学成绩', '语文成绩']， 
      [1, '小明', 84, 86], 
      [2, '小刚', 91, 82], 
      [3, '小红', 89, 90]]
with open('score.csv', 'w', encoding = 'gbk') as f:
    for row in ls:                     #逐行写入
        f.write('\t'.join(row)+'\n')   #用\t组合成字符串形式，末尾加换行符<jupyter_output><empty_output><jupyter_text>也可以借助csv模块完成上述操作 5.2 json 格式常被用来存储字典类型- 写入——dump()<jupyter_code>import json

scores = {'Peter':{'Math':96, 'Science':98},
         'Paul':{"Math":92, 'Science':99},
         'Marry':{'Math':98, 'Science':97}}
with open('Score.json', 'w', encoding = 'utf-8') as f:
    # indent表示字符串换行+缩进 ensure_ascii=False 显示中文
    json.dump(scores, f, indent=4, ensure_ascii=False)<jupyter_output><empty_output><jupyter_text>- 读取——load()<jupyter_code>with open('Score.json', 'r', encoding = 'utf-8') as f:
    scores = json.load(f)
    for k, v in score.items():
        print(k, v)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1479908526625286, 'fraction_numerical': 0.03266906239790918, 'mean_word_length': 3.697314578005115, 'pattern_counts': {'":': 1, '<': 250, '<?xml version=': 0, '>': 255, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '69', 'dir': 'jupyter-structured-clean-dedup', 'id': '341777', 'license': 'Apache-2.0', 'n_tokens_mistral': 19096, 'n_tokens_neox': 19422, 'n_words': 2774, 'path': 'Lesson_Three/.ipynb_checkpoints/Python_Lesson_Three-checkpoint.ipynb', 'repo_name': 'CAU-LiuZiyu/Data-Analysis-with-Python', 'size': '36761'}