problem c: 判断素数的函数_python100天 — Day 6 函数和模块的使用

c90fcf911c0392f0ea765283ad1c32e1.png

> 本文以GitHub上100天python从新手到大师为素材,规划为约100天的练习,每次的学习和总结均发在这里。有错误的地方还请朋友们指正。

函数的作用

如下面有一个问题,计算三个三角形的面积。 如果只运用之前所学的知识,我们需要复制粘贴三遍之前我们写的海伦公式代码:

a = float(input("输入第一条边的长度: "))
b = float(input("输入第二条边的长度: "))
c = float(input("输入第三条边的长度: "))

if a + b > c and a + c > b and b + c > a:
    perimeter = a + b + c
    p = perimeter / 2
    area = (p * (p - a) * (p - b) * (p - c))**0.5
    print("perimeter is %.2f narea is %.2f" %(perimeter,area))
else:
    print("该边长组不成立三角形")

而函数的出现可以使我们将这类功能封进函数里,每当我们想要调用此功能时,我们只需要调用该函数即可。例如:

def tri_area(a,b,c):
    if a + b > c and a + c > b and b + c > a:
        perimeter = a + b + c
        p = perimeter / 2
        area = (p * (p - a) * (p - b) * (p - c)) ** 0.5
        return area
    else:
        print('无法计算面积')

print(tri_area(2,4,5))
print(tri_area(3,4,5))
print(tri_area(2,4,7))

定义函数

参照上面的例子,我们使用关键词def来构建函数,后面的括号内可以放入传进函数内的参数,python的函数定义和数学中的函数定义类似,传入函数的参数可以理解为自变量,经过函数变换后我们可以使用return返回需要的结果,可以理解为函数中的因变量。

函数的参数

函数的参数有多种写法,除将变量名写进括号内外,我们也可以采用默认值,即预先规定好参数的值,例如我们写一个扔骰子并求和的函数,默认函数内有两个筛子:

from random import randint

def Throw_the_dice(n=2):
    total = 0
    for i in range(n):
        total += randint(1,6)
    return total

这样子是默认两个骰子扔出并求和,如果想要3个筛子求和,就直接输入Throw_the_dice(3)即可。

但在我们利用函数解决问题的过程中,可能我们并不知道函数具体要传入几个参数(例如求和问题中我们可能事先不知道是几个数求和)。我们可以使用可变参数。

下面利用求和函数来演示

def add(*args):
    total = 0
    for i in args:
        total += i
    return  total

*args 可以承载多个数据传入函数中,例如:

print(add(1,2,3))

用模块管理函数

有时候我们在和别人共同开发时,会遇到函数名冲突的情况,例如:

def foo():
    print("hello python")

def foo():
    print("hello world")

print(foo())

那么最后结果只会打印第二个函数的结果,因为第一个函数已经被覆盖住。如果想两个函数都被打印出来,我们可以采用模块管理函数。

还是用两个foo函数举例。

新建一个python文件命名为module2.py

#module2.py#
def foo():
    print("hello python")

再新建一个python文件名为module3.py

#module3.py#
def foo():
    print("hello world")

如果我们想分别使用这两个函数,可以引用模块:

from module2 import foo
foo()

from module3 import foo
foo()

#或者#

import module2 as md2
import module3 as md3
m2.foo()
m3.foo()

这样子两个函数都可以打印 但当这样子引用的时候:

from module2 import foo
from module3 import foo
foo()
foo()

则打印结果出来的都是第二个函数的结果,因为第一个函数也被覆盖了。

在模块中我们还会遇到别的代码,例如:

#module3.py#
print("干扰文字")

def foo():
    print(foo())

如果引用这个模块使用foo函数,那么module3内的其余执行代码也会一并执行,输出两行文字。

为了避免这种情况,我们可以这样写

def foo():
    print("Hello World")

if __name__ == "__mian__":
    print("干扰文字")

这样子只有在直接执行文件时才可以运行全部代码,而导入模块时他的名字时module3而不是main

练习部分

实现计算最大公约数和最小公倍数

代码如下:

def gcd_lcd(x,y):
    if x > y:
        x ,y = y, x #保证x比y小#
    gcd_num = 1
    for i in range(x,0,-1):
        if x%i == 0 and y%i == 0:
            gcd_num = i
            break
    lcd = x * y / gcd_num
    return gcd_num, lcd

官方代码如下:

def gcd(x, y):
    """求最大公约数"""
    (x, y) = (y, x) if x > y else (x, y)
    for factor in range(x, 0, -1):
        if x % factor == 0 and y % factor == 0:
            return factor


def lcm(x, y):
    """求最小公倍数"""
    return x * y // gcd(x, y)

判断一个数是不是回文数

Tips:回文数即从前往后和往后往前看时一样的

def palindromic(num):
    sum_total = 0
    here = num
    while True:
        sum_total = sum_total*10 + (num % 10)
        if num // 10 == 0:
            break
        else:
            num = num//10

    return  sum_total == here

官方代码如下:

def is_palindrome(num):
    """判断一个数是不是回文数"""
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10
    return total == num

判断一个数是不是素数

def is_prime(num):
    kaigen = int(num**0.5)+1
    test_num = 2
    not_prime = True
    while not_prime:
        if num % test_num == 0 and num > 1 :
            return False
            not_prime = False
        elif test_num < kaigen:
            test_num += 1
        else:
            return True
            break

官方代码如下:

def is_prime(num):
    """判断一个数是不是素数"""
    for factor in range(2, num):
        if num % factor == 0:
            return False
    return True if num != 1 else False

判断输入的正整数是不是回文素数

def alltrue(num):
    if is_prime(num) and palindromic(num):
        return True
    else:
        return False

官方如下:

if __name__ == '__main__':
    num = int(input('请输入正整数: '))
    if is_palindrome(num) and is_prime(num):
        print('%d是回文素数' % num)

在这里我们看到,如果我们将两个函数组合起来可以解决更复杂的问题,这就是我们构建函数的意义。

变量作用域

最后我们讨论变量作用域的问题。参考一下代码:

def foo():
    a = 100
    print(a)  # 200

if __name__ == "__main__":
    a = 200
    foo()

最终打印输出的a的值是多少呢?是100。因为在函数内a就寻找到100的取值,就不需要再去全局寻找变量值了。

变量作用域分为4种,分别为全局变量、嵌套变量、局部变量和内置变量。全局变量意思为跳脱函数外对于全局都有影响的变量,由于函数内部也可以嵌套函数,则第一层函数内、第二层函数外的变量即为嵌套变量,函数内的是局部变量,因为该变量只影响局部。内置变量即def、if、else等这些关键词。

下面用一段代码统一演示:

def foo():
    b = 'hello'

    # Python中可以在函数内部再定义函数
    def bar():
        c = True
        print(a)
        print(b)
        print(c)

    bar()
    # print(c)  # NameError: name 'c' is not defined


if __name__ == '__main__':
    a = 100
    # print(b)  # NameError: name 'b' is not defined
    foo()

再回到最开始的例子,那么如何改变a的值,使得打印的a也为200呢? 我们可以使用下面的方法:

def foo():
    global a
    a = 200
    print(a)  # 200


if __name__ == '__main__':
    foo()
    print(a)  # 200

通过global a来指示函数内a的值置于全局,即使全局没有该变量,在后面仍可以使用这个变量。

在我们正常编程当中,应当避免使用过多的全局变量,因为全局变量的生命周期长、影响过于广泛。

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页