Datawhale 聪明办法学Python | HUSH随笔

147 阅读17分钟

Datawhale 聪明办法学Python | HUSH随笔

hydro.ac/d/datawhale…

记录参加Datawhale 训练营的一些心得体会和学习笔记

[起源]  之前参加过Datawhale高校行活动的杭电站,就对这个机构比较感兴趣,当时体验了AI生成图片,蛮有意思的。我是统计学专业,研究方向是金融统计与风险管理,也一直想学习一些人工智能方面的知识,就一直关注Datawhale。暑期留校因为右手手腕受伤报名了AI夏令营,但是没有最终完成项目,开学右手腕康复了,就准备先复习巩固一下python知识,为后续AI学习打基础。其实在做科研中已经会使用一些模型和算法了,但都是调参,没有深刻理解,期待后续加强学习,拓宽职业选择道路。

[感想]  视频课程很详细,保姆式教学,每一步都给出了操作展示,有问题还可以群里答疑,群内很活跃氛围很好,助教答疑很热情很认真,比自学效率高很多,遇到问题解决问题,以解决问题做项目来学习,比照课本听网课要快很多,也更直接。

Chapter2 数据类型与操作

2.1 注释

单行注释:用#; 多行注释:使用3个单引号或3个双引号包裹起来(头和尾都是3个),单引号与双引号在 Python 中井无太大区别。

2.2 数据类型

2.2.1 常用数据类型

整数Integer(int)、 浮点数Float、 布尔值Boolean(bool)、 类型Type 备注:数字数据类型不只有int和float,还有复数,以及其他用户自定义的数字类型,所以不只是这几个类型的集合。 print(type(x))可以输出对象的类型; print(isinstance(x, numbers.Number))可以判断对象的类型是否是数字数据类型。

2.2.2 其他数据类型

字符串 string(str)、 列表 List、 元组 Tuple、 集合 Set、 字典 Dictfonary(dict,或者你可以叫它“映射”,map)、 复数Complex Number(complex)、 函数Function、 模块 Module。

2.3 运算

2.3.1 常数

True表示布尔真;False表示布尔假;None表示空值。

math库中的一些数学常量:

import math      
print(math.pi)     #圆周率π
print(math.e)      #自然常数e
print(math.tau)    #两倍圆周率τ
print(math.inf)    #浮点正无穷大
print(-math.inf)   #浮点负无穷大
2.3.2 常用运算符
算术运算符:

加+、减-、乘*、除以/、整除//、幂**、取余%(math.fmod())、矩阵乘法@、-(一元算符)、+(一元算符)、向上取整(math.ceil())、(向下取整math.floor()

备注:字符串之间可以进行加法、整数与字符串可以进行乘法,整数与字符串无法进行加法。

比较运算符:

小于<、小于等于<=、大于等于>=、大于>、等于==、不等于!=

赋值运算符:

简单赋值=、加法赋值+=、减法赋值-=、法赋值*=、除法赋值/=、整除赋值//=、幂赋值**=、取余赋值%=

逻辑运算符:

与and、或or、非not

逻辑运算参照表

7bc95320a85f1eacf2d3520722f523a.png

逻辑运算符——短路求值
def yes():
    return True
def no():
    return False
def crash():
    return 1/0 #崩溃
#and运算
print(no() and crash())   #成功运行,输出False
print(crash() and no())   #崩溃
print(yes() and crash())  #崩溃,因为前一行命令已经崩溃,这行不会运行,python是逐行运行
#or运算
print(yes() or crash())   #成功运行,输出True
print(crash() or yes())   #崩溃
print(no() or crash())  #崩溃,因为前一行命令已经崩溃,这行不会运行,python是逐行运行

总结:x and y,如果x为

2.3.3 运算优先级

优先顺序:“乘方”优先于“乘除”优先于“加减”,即乘方 > 乘除 > 加减。

结合律:加减乘除:从左往右计算;乘方:从右往左计算。

print(4**3**2)  #262144,不是4096
print(3**2)     #9
print(4**9)     #262144
print(4**3)     #64
print(64**2)    #4096

备注:注意浮点数误差(来源于十进制与二进制转换的误差,误差极小但存在)。

Chap2 课后习题

第一题 Is Number

解题思路 (1)isinstance函数:用该函数于检查输入的对象是否是指定的类型或类型之一;

(2)表示数字数据类型:numbers.Number 是一个抽象基类(ABC),位于 numbers 模块中。这个基类定义了数字类型的一般属性和方法,可以用来检查一个对象是否是数字类型(包括整数、浮点数、复数等)。

第二题 Egg Cartons

解题思路  (1)是否为空:如果鸡蛋个数是0,则不需要箱子,输出0;

(2)能整除12:箱子刚好装满,直接输出商;

(3)不能整除12:无论是大于12的倍数还是小于12的倍数,都是一样的情况。箱子没有装满,还有空余 位置,输出商+1。

第三题 Number of Pool Balls

解题思路 “杨辉三角”类型,采用等差数列求和公式。

第四题 Number of Pool Ball Rows

解题思路 输入输出调换,于是反解等差数列求和公式,演化为求一元二次方程的解,应用求根公式。因为输出为整数,故最后采用向上取整函数math.ceil()。

第五题 Get Kth Digit

解题思路 本质上是取一个多位数n的个位数、十位数、百位数、千位数等,于是采用“取余”来取那个数字,在这之前采用“整除”将想取的那位数的右边部分切断,可以发现需要整除的那个数刚好是10的k次方。

解题思路总结 本节课后习题我的解题思路基本都是数学思维,由于解题有所用知识约束,我都是先在草稿纸上演算,找规律,然后运用本节知识设计代码,可能会有一些笨重或者粗暴,相信在今后学习更多知识后,可以采用一些更简单方便的代码。

Chapter3 变量与函数

3.1 变量

3.1.1 变量赋值

等号 = 用来给变量赋值。

counter = 100    # 整型int 
miles = 1000.0   # 浮点型float 
name = "John"    # 字符串string

备注:赋值过程中,新值会覆盖旧值,且新值的数据类型与旧值不必相同。

3.1.2 多个变量赋值

例1:a = b = c = 1

例2:a, b, c = 1, 2, "john"

3.1.3 变量命名

变量命名规则:

(1)必须以字母或下划线()开头;

(2)命名可由字母、数字和下划线组成;

(3)大小写敏感;

(4)尽量避免使用保留字命名。

3.2 函数

3.2.1 函数的概念

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。

Python提供了许多内建函数,比如print()、max()、min()等。但你也可以自己创建函数,这叫做用户自定义函数。

3.2.2 定义新函数

函数由两个部分组成:header和body。header:用于定义函数接口(函数名称与参数);body:包含函数所需要执行的操作。参数可以有一个,也可以有多个,也可以一个也没有。

def functionname( parameters ):   #header部分,注意有冒号“:”
   function_suite                 #body部分
   return [expression]            #不带表达式的return相当于返回 None
3.2.3 调用函数

定义一个函数:给定了函数一个名称,指定了函数里包含的参数,和代码块结构。通过函数的名字functionname( parameters )可以调用函数。

3.2.4 内置函数
bool(1)         #转换为布尔类型
float(2)        #转换为浮点数
int(1.2)        #转换为整型,舍弃小数点
asb(-5)         #绝对值
max(2,3)        #取最大值
min(2,3)        #取最小值
pow(2,4)        #次方运算,等价于2**4
round(2.354,2)  #取最近的一个整数,不完全是四舍五入,二进制精度丢失
3.2.5 变量作用域

变量作用域:(1)每个变量都有属于自己的作用范围;(2)超出作用范围后,变量不可见。 例1:

def f(x)
    print('x',x)
    y = 5 #局部变量
    print('y',y)
    return x + y

函数内的变量具有局部作用域,它只存在于函数内部,与其他函数中的同名变量无关。在函数外部定义变量时,变量具有全局作用域,在任何地方都可以使用。尽量避免使用全局变量,但在比较少的一些场合可能会需要用到它。

3.2.6 返回语句

返回语句return

(1)返回一个值或者一个表达式的值;

(2)一旦返回,函数立即结束;

(3)没有返回语句的时候,函数会返回 None。

3.2.7 函数组合

函数组合(复合函数):对于嵌套的函数而言,应该最先运行最内层的函数。

备注:编写函数是用来解决问题的。我们还可以编写函数来存储那些经常被用到的一系列操作,这种函数就叫做 Helper Function。

3.3 语句与表达式

3.3.1 表达式

对于表达式: (1)它本身是值; (2)它的计算结果是值; (3)它能打印。

4
1+1
'Datewhale'
3 > 2
3.3.2 语句

对于语句: (1)它不是值; (2)它不能打印; (3)但它能执行一些操作。

#例1
def f(x)
    return x**2
#例2
x = 5 + 4
#例3
if x > 5:
    y = x + 3

Chap3 课后习题

第一题 Square Root

解题思路 直接求平方根y=math.sqrt(x)

第二题 Square

解题思路 直接求平方y=x**2

第三题 Odd numberr

解题思路 偶数就是对2取余为0,即能够整除2;奇数就是对2取余不等于0,即不能整除2。

第四题 Range

解题思路 (1)运用最大值函数max()和最小值函数min()求两个数字的上界和下界; (2)将上界和下界转换为字符串然后在中间加上空格输出即可。

第五题 Circles Intersect

解题思路  (1)求两个圆心之间的距离d = math.sqrt( (x1-x2)**2+(y1-y1)**2 )

(2)分析两个圆之间的位置关系:

1)相切:外切 d = r1+r2 或 内切 d = |r1-r2|;

2)相离:外离 d > r1+r2 或 内离 d < |r1-r2|;

3)相交:|r1-r2| < d < r1+r2。

Chapter4 条件

4.1

Chap4 课后习题

第一题 Output Letter Grade by Score

解题思路 

第二题 getInRange

解题思路 

第三题 Is Point Inside Square

解题思路 

第四题 Check Leap Year

解题思路 

第五题 Days in Month

解题思路 

Chapter5 循环

5.1 For 循环

5.1.1 基本形式

基于提供的范围,重复执行特定次数的操作。 例1:

import ast
m, n = ast.literal_eval(input())
def sumfromMtoN(m,n):
    total = 0
    for x in range(m,n+1): #range(x,y)是左闭右开区间,即包含x,不包含y
        total += x
    return total
print(sumfromMtoN(m,n))
5.1.2 range() 函数

range() 是一个内置函数,用于生成一个固定的整数序列,这个序列从起始值开始(默认为0),每次增加一个步长值(默认为1),直到达到一个结束值(但不包括结束值本身)。range() 函数在循环中特别有用,可以用来指定循环的次数。range() 函数返回的是一个 range 对象,它是一个可迭代对象,不是列表,但是可以很容易地转换成列表。

range() 函数的使用方式

(1) range(stop):只有一个参数,表示从0开始到 stop 结束(不包含 stop)。例:range(5) 生成的序列是 0, 1, 2, 3, 4。

(2) range(start, stop):有两个参数,表示从 start 开始到 stop 结束(不包含 stop)。例:range(1, 5) 生成的序列是 1, 2, 3, 4。

(3) range(start, stop, step):有三个参数,表示从 start 开始到 stop 结束(不包含 stop),每次增加 step。例:range(1, 10, 2) 生成的序列是 1, 3, 5, 7, 9。

5.1.3 For嵌套循环

例1:

import ast
xMax, yMax = ast.literal_eval(input())
def printcoordinates(xMax, yMax):
    for x in range(1,xMax+1):
        for y in range(1,yMax+1):
            print(f"({x},{y})",end="")
        print() # 换行,开始下一行的打印
printcoordinates(xMax, yMax)

例2:

import ast
n = ast.literal_eval(input())
def printMysterystarshape(n):
    for row in range(n):
        print(row, end=" ")
        for col in range(row):
            print("*",end=" ")
        print() # 换行,开始下一行的打印
printMysterystarshape(n)

5.2 While循环

在给定的判断条件为 true 时执行循环体,否则退出循环体。

5.2.1 基本形式

例1:

import ast  #找出一个数最左边的那一位的数值
n = ast.literal_eval(input())
def leftmostDigit(n):
    n= abs(n)
    while n >= 10:
        n = n // 10
    return n
print(leftmostDigit(n))

例2:

import ast
n = ast.literal_eval(input())
def isMultiple0f4or7(x):
    return( ((x % 4) == 0) or ((x % 7) == 0))
def nthMultiple0f4or7(n):
    found = 0
    guess = 0
    while found < n:
        if isMultiple0f4or7(guess):
            found += 1
            if found == n:
                return guess
        guess += 1
print(nthMultiple0f4or7(n))

备注:在知道循环范围的情况下不推荐使用 while循环。

5.2.2 continuebreak 语句
for n in range(200):
    if n % 3 == 0:
        continue    # 跳过这次循环
    elif n == 8:
        break   # 跳出当前整个循环
    else:
        pass    # 啥也不做,占位符,不会被运行
    print(n, end=" ")
5.2.3 假·死循环

与环境交互后,在特定条件下终止的循环

Chap5 课后习题

第一题 N*M Matrix

解题思路 循环打印生成矩阵:

(1)保证同行打印间有空格print(1, end=' ')

(2)同一行打印结束跳转打印下一行;

(3)本题为打印1,还可以打印*、@、$等。

第二题 ReverseNumber

解题思路 循环取低位数字并赋新位生成反转数字:

(1)用取余digit = n % 10获取最低位的数字,即从右往左数取出第一位数字;

(2)赋予新位,循环乘 10 即可;

(3)n = n // 10 去掉已经处理过的最低位,开启新的循环计算。

第三题 hasConsecutiveDigits

解题思路 循环将相邻两个数字进行比较,相同则结束,不同则继续比较:

(1)取出相邻俩个数字

digits_1 = n % 10  # 取出n的第一位,从右往左数
n = n // 10  # 去掉最后一位
digits_2 = n % 10  # 取出n的第二位,从右往左数

(2)比较相邻俩个数字

if digits_1 == digits_2:
    return True

(3)若相同则结束,不同则继续比较。

第四题 nthPalindromicPrime

解题思路 

(1)利用试除法判断 x 是否是素数;

def is_primenumber(x):
    if x < 2:
        return False
    for i in range(2, int(x**0.5) + 1):
        if x % i == 0:
            return False
    return True

(2)利用第二题创建的函数反转 x;

(3)判断 x 是否是回文数;

(4)取第 n 个回文素数。

def nthPalindromicPrime(n):
    count = 0  # 初始化计数器
    num = 2    # 从第一个素数开始
    while True:
        if is_primenumber(num) and is_palindrome(num):
            if count == n:
                return num
            count += 1
        num += 1
print(nthPalindromicPrime(n))
第五题 carrylessAdd

解题思路 循环取出俩个数字的最低位数字进行不进位加法

(1)取出俩个数字的最低位数字

digit_x1 = x1 % 10
digit_x2 = x2 % 10

(2)将俩个数字的最低位数字进行不进位加法

digit_sum = (digit_x1 + digit_x2) % 10

(3)去掉已经处理过的最低位,开启新的循环计算

x1 //= 10
x2 //= 10

Chapter6 字符串

6.1 引号

字符串是 Python 中最常用的数据类型。我们可以使用引号 ( ' 或 " ) 来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。使用两种不同的引号可以帮助我们区分字符串,避免报错,例如print('聪明办法学 Python 第二版的课程简称是"P2S"')

6.2 转义字符

前面有反斜杠 \ 的字符,叫做转义序列。比如 \n 代表换行,尽管它看起来像两个字符,但是Python依然把它视为一个特殊的字符。

\\             #反斜杠符号
\(在行尾时)     #续行符
\n             #换行
\t             #横向制表符(按Tab键)
\"             #双引号
\'             #单引号

6.3 REPR() VS PRINT()

Chap6 课后习题

**第一题 **

解题思路 

**第二题 **

解题思路 

**第三题 **

解题思路 

**第四题 **

解题思路 

**第五题 **

解题思路 

Talk1 优雅代码编写指北

1.1 代码布局

1.1.1 缩进

(1)如果有开始定界符(比如小括号、中括号、花括号等),其余行的缩进需与开始定界符对齐。

(2)需要额外的4个空格(长度等于一个Tab键),以区分开传入参数,和其他内容。

(3)空格一般用于添加以上这种缩进,Tab键一般用于保持行与行之间的一致性。

(4)多行if语句衔接,需要一个额外的缩进,以区分其他内容

# Aligned with opening delimiter.
foo = long function name(var one,var two,
                        var_three,var four)

# Add 4 spaces (an extra level of indentation)to distinguish arguments from the rest.
def long_function_name(
        var_one,var_two,var three,
        var four):
    print(var one)

# Add some extra indentation on the conditional continuation line.
if(this is one thing
        and that is another thing):
    do something()
1.1.2 换行

(1)将所有行限制为最多 79 个字符。

(2)一般语句接受“隐式”延续,但是with语句等不支持,需要使用反斜杠\来衔接。

(3)另一个这样的例子是assert语句。

(4)多行if语句的缩进详见上一小节。

(5)通常不鼓励使用复合语句(同一行上的多个语句)

with open('/path/to/some/file/you/want/to/read')as file_1,\
        open('/path/to/some/file/being/written','w')as file_2:
    file 2.write(file 1.read())

1.2 导入规范

1.2.1 import 本地模块/包

(1)当我们需要导入本地自己封装好的一些模块时,需要通过import来导入。

(2)如果我们需要在m1.py文件中导入同目录下的m2.py文件,直接导入即可

1.2.2 import Python库的模块/包

(1)Python基础库自带丰富的模块和包,无需自己逐一实现,只需要一键import即可享用。

(2)使用 from x import y,其中x是包前缀,y是没有前缀的模块名称。

1.3 关于空格

(1)紧接在圆括号、方括号或大括号内,不需要多余空格。

(2)在逗号、分号或冒号之前,尾随逗号之后均不需要多余空格。

(3)在切片中,两个冒号必须应用相同的间距。

(4)紧接在开始函数调用的参数列表的左括号之前,不需要多余空格。

(5)赋值(或其他)运算符周围需要多个空格以使其与另一个运算符对齐。

1.4 代码注释规范

(1)注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码。

(2)注释是编写程序时,写程序的人给一个语句、程序段、函数等的解释或提示,能提高程序代码的可读性。

(3)在有处理逻辑的代码中,源程序有效注释量必须在20%以上。

1.4.1 单行注释

单行注释:用#。

# 课堂练习
import math
c = ast.literal_eval(input())
print(math.floor(c))
1.4.2 多行注释

多行注释:使用3个单引号或3个双引号包裹起来(头和尾都是3个),单引号与双引号在 Python 中井无太大区别。

'''
# 第一题Is Number
import decimal as numpy
x = eval(input())
print(isinstance(x, (int,float,complex,numpy.Decimal)))
'''

1.5 变量与函数命名规则与规范

1.5.1 命名规则

(1)变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头,但不能以数字打头,例如,可将变量命名为message_1,但不能将其命名为1_message

(2)变量名不能包含空格,但可使用下划线来分隔其中的单词。例如,变量名greeting_message 可行,但变量名greeting message会引发错误。

1.5.2 命名规范

(1)不要将Python关键字和函数名用作变量名,即不要使用Python保留用于特殊用途的单词,如print。

(2)变量名与函数名应既简短又具有描述性。例如name比n好,student_name比s_n好。

Talk2 如何Debug

#Datawhale #聪明办法学Python  #笔记会一直更新直到学习结束