Python 计算思维训练——数组和曲线绘制练习(一)

第1关:使用函数值填充列表

任务描述
本关任务:使用函数值填充列表。

相关知识
为了完成本关任务,你需要掌握:

Python 的列表推导式;
Python 的 math 第三方库。
Python 的列表推导式
在一般的编程语言中,如果我们想对一个数组每个位置的元素赋上一个其对应下标的值,或许可以通过循环来完成,就像下面这样。

for i in range(10):
a[i] = i #对长度为 10 的 a 数组进行赋值
print(a)
输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这对于大部分编程语言来说可能是一个比较简洁、标准的写法,但是对于 Python 来说,我们可以通过列表推导式来完成这部分的内容!

列表推导式的形式:

[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件]

举个例子,对于上一份代码,用 Python 可以这样写:

a = [i for i in range(10)]
print(a)
输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

当然上述只是列表推导式的一个简单的例子,但却是使用复杂表达式的基础,用好列表推导式,能让我们的代码更加 Pythonic 。

Python 的 math 第三方库
Python 另一个特点就是它具有各种各样强大的第三方库,对于编程人员来说,数学是一个必不可少的工具。因此,Python 也具有自带的数学库 —— math 。

接下来介绍些 math 库中常用的数学方法:

#使用之前不要忘记导入 math 库了
import math
#求根号 2
print(math.sqrt(2))
#计算半径为 2 的圆的面积
print(math.pi * 2 * 2)
#计算 e^3
print(math.exp(3))
#计算 sin(30°),因为精度问题可能会有误差
#Python 的 math 模块中的 sin 函数计算单位为角度
#1角度=π/180弧度,30角度=π/60弧度,
print(math.sin(math.pi / 6))
输出:

1.4142135623730951
12.566370614359172
20.085536923187668
0.49999999999999994

编程要求
给定区间 [s, e] ,求取该区间中 41 个等间隔的坐标值,填充到列表变量xlist中,作为标准正态分布的概率密度函数h(x)的输入,然后将函数h(x)的输出结果填充到列表变量ylist中并返回。概率密度函数h(x)公式如下:

在这里插入图片描述

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:s = -1,e = 1

预期输出:

[0.241971, 0.254059, 0.266085, 0.277985, 0.289692, 0.301137, 0.312254, 0.322972, 0.333225, 0.342944, 0.352065, 0.360527, 0.36827, 0.37524, 0.381388, 0.386668, 0.391043, 0.394479, 0.396953, 0.398444, 0.398942, 0.398444, 0.396953, 0.394479, 0.391043, 0.386668, 0.381388, 0.37524, 0.36827, 0.360527, 0.352065, 0.342944, 0.333225, 0.322972, 0.312254, 0.301137, 0.289692, 0.277985, 0.266085, 0.254059, 0.241971]

提示:

上述实例计算的是区间 [-1, 1] 之间的 41 个坐标值(误差在 0.000001 内认为正确):

[-1.0, -0.95, -0.9, -0.85, -0.8, -0.75, -0.7, -0.6499999999999999, -0.6, -0.55, -0.5, -0.44999999999999996, -0.3999999999999999, -0.35, -0.29999999999999993, -0.25, -0.19999999999999996, -0.1499999999999999, 0.09999999999999998, -0.04999999999999993, 0.0, 0.050000000000000044, 0.10000000000000009, 0.15000000000000013, 0.20000000000000018, 0.25, 0.30000000000000004, 0.3500000000000001, 0.40000000000000013, 0.4500000000000002, 0.5, 0.55, 0.6000000000000001, 0.6500000000000001, 0.7000000000000002, 0.75, 0.8, 0.8500000000000001, 0.9000000000000001, 0.9500000000000002, 1.0]

开始你的任务吧,祝你成功!

class Solution:
    def solve(self, s, e):
        """
        :type s, e: int, int
        :rtype: list
        """
        #请在此按照“编程要求”填写代码
        #********** Begin *********#
        import math
        dx = (e-s)/40
        xlist = [s+i*dx for i in range(0,41)]
        def f(x):
            return 1/math.sqrt(2*math.pi)*math.exp(-0.5*x**2)
        ylist = [f(x) for x in xlist]
        return ylist


        ##********** End **********#

第2关:填充数组(循环版本)

任务描述
本关任务:编写一个能计算指定函数输出的程序。

相关知识
为了完成本关任务,你需要掌握 numpy 第三方库的基本用法。

numpy 第三方库的用法
在之前我们已经了解了 math 库一些常用的函数,但在 Python 的科学计算中,我们更倾向于用功能强大的 numpy ,因为它相对于 math ,支持向量操作,而我们在科学计算中,往往需要成批成对地对数据进行相同的运算,比如矩阵和向量方面的运算。而使用普通的 math 库,我们需要去实现矩阵的基本运算,甚至需要设计特殊的数据结构来存储,而在 numpy 中,这些都是已经实现了的,而且还进行了一定的优化,这就意味着我们能够在更短的时间内完成我们的计算任务。

接下来对前一节的运算用 numpy 的一些方法进行重写:

#使用之前不要忘记导入 numpy 库了
import numpy as np
#求 2 和 3 的平方根
print(np.sqrt([2, 3]))
#计算半径为 2 和 3 的圆的面积
print(np.pi * (np.array([2, 3]) ** 2) )
#计算e1、e3
print(np.exp([1, 3]))
#计算sin(30°)、sin(90°),因为精度问题可能会有误差
print(np.sin(np.pi / np.array([6, 2])))
示例输出:

[1.41421356 1.73205081]
[12.56637061 28.27433388]
[ 2.71828183 20.08553692]
[0.5 1. ]

另外,我们还必须了解向量运算中的一些常用向量——零向量和 1 向量,通过列表推导式我们可以这样的方式得到
[0 for i in range(10)]或者[1 for i in range(10)],但在 numpy 中,已经封装好专门的函数接口了,上述两个向量分别可以对应np.zeros(10)和np.ones(10)。

编程要求
给定区间 [s, e] ,要求取该区间中 41 个等间隔的坐标值,填充到numpy.array类型的变量xlist中,作为标准正态分布的概率密度函数h(x)的输入,然后将函数h(x)的输出结果填充到numpy.array类型的变量ylist中并返回。概率密度函数h(x)公式如下:

在这里插入图片描述

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:s = -1,e = 1

预期输出:

[0.24197072451914337, 0.254059056469189, 0.2660852498987548, 0.2779848861309965, 0.28969155276148273, 0.30113743215480443, 0.31225393336676127, 0.3229723596679143, 0.33322460289179967, 0.3429438550193839, 0.3520653267642995, 0.36052696246164795, 0.3682701403033234, 0.3752403469169379, 0.38138781546052414, 0.38666811680284924, 0.39104269397545594, 0.39447933090788895, 0.3969525474770118, 0.39844391409476404, 0.3989422804014327, 0.39844391409476404, 0.3969525474770118, 0.3944793309078889, 0.3910426939754559, 0.38666811680284924, 0.3813878154605241, 0.3752403469169379, 0.36827014030332333, 0.36052696246164795, 0.3520653267642995, 0.3429438550193839, 0.33322460289179967, 0.32297235966791427, 0.3122539333667612, 0.30113743215480443, 0.28969155276148273, 0.2779848861309964, 0.26608524989875476, 0.25405905646918897, 0.24197072451914337]

提示:

上述实例计算的是区间 [-1, 1] 之间的 41 个坐标值:

[-1.0, -0.95, -0.9, -0.85, -0.8, -0.75, -0.7, -0.6499999999999999, -0.6, -0.55, -0.5, -0.44999999999999996, -0.3999999999999999, -0.35, -0.29999999999999993, -0.25, -0.19999999999999996, -0.1499999999999999, -0.09999999999999998, -0.04999999999999993, 0.0, 0.050000000000000044, 0.10000000000000009, 0.15000000000000013, 0.20000000000000018, 0.25, 0.30000000000000004, 0.3500000000000001, 0.40000000000000013, 0.4500000000000002, 0.5, 0.55, 0.6000000000000001, 0.6500000000000001, 0.7000000000000002, 0.75, 0.8, 0.8500000000000001, 0.9000000000000001, 0.9500000000000002, 1.0]

开始你的任务吧,祝你成功!

class Solution:
        def solve(self, s, e):
                """
                :type s, e: int, int
                :rtype: numpy.ndarray
                """
                #请在此按照“编程要求”填写代码
                #********** Begin *********#
                import numpy as np

                xlist = np.zeros(41)
                ylist = np.zeros(41)
                for i in range(41):
                        xlist[i]=s+i*(e - s)/40
                        ylist[i]=1/np.sqrt(2*np.pi)*np.exp(-0.5*xlist[i]**2)
                return ylist
                ##********** End **********#

第3关:填充数组(向量化版本)

任务描述
本关任务:编写一个能计算指定函数输出的程序。

相关知识
为了完成本关任务,你需要掌握:

1.numpy第三方库的向量运算功能。

numpy第三方库的向量运算功能
在之前我们已经了解了numpy库的一些基本用法,但是还是用了一个循环,而我们最初使用numpy的目的,是想利用它强大的向量运算功能。

numpy的常用数据对象有np.array和np.mat,他们之间的运算都自动使用numpy内置的向量运算,我们现在需要做的就是如何生成特定范围内指定数量的值,方便使用numpy的向量运算。这里可以用到np.linspace函数实现自动生成特定范围内指定数值的功能,下面介绍些它的基本用法。

#使用之前不要忘记导入numpy库了
import numpy as np
#生成在区间[1, 10]中,10个等间隔的值
print(np.linspace(1, 10, 10))
示例输出:

[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]

从上述实例,大致可以看出各个参数所代表的的含义,前两个参数分别代表左边界和右边界,自然而然,这两个参数是必须参数,第三个参数就是所需要的值的数量,这个参数是可省略参数,默认值为50。

除了np.linspace,这里还有一个常用来划分指定区间内数值的函数np.arange,类似于np.linspace,np.arange的前两个参数也是起点和终点,不过这里描述的是左闭右开区间[s, e),也就是不包含终点值。另外,不像np.linspace指定了划分的数量,np.arange是指定划分的步长,也就是每间隔一定距离取数。

示例如下:

#取区间[1, 10]等间隔的10个数
print(np.linspace(1, 10, 10))
#每隔差值1取区间[1, 11)中的一个数
print(np.arange(1, 11, 1))
示例输出:

[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[ 1 2 3 4 5 6 7 8 9 10]

编程要求
给定区间[s, e],要求取该区间中41个等间隔的坐标值,填充到numpy.array类型的变量xlist中,作为标准正态分布的概率密度函数h(x)的输入,然后将函数h(x)的输出结果填充到numpy.array类型的变量ylist中并返回。

在这里插入图片描述

要求变量xlist的值用np.linspace来生成,最后返回xlist和ylist。

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:s = -1,e = 1

预期输出:

(array([-1. , -0.95, -0.9 , -0.85, -0.8 , -0.75, -0.7 , -0.65, -0.6 , -0.55, -0.5 , -0.45, -0.4 , -0.35, -0.3 , -0.25, -0.2 , -0.15, -0.1 , -0.05, 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 , 0.45, 0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95, 1. ]), array([ 0.24197072, 0.25405906, 0.26608525, 0.27798489, 0.28969155, 0.30113743, 0.31225393, 0.32297236, 0.3332246 , 0.34294386, 0.35206533, 0.36052696, 0.36827014, 0.37524035, 0.38138782, 0.38666812, 0.39104269, 0.39447933, 0.39695255, 0.39844391, 0.39894228, 0.39844391, 0.39695255, 0.39447933, 0.39104269, 0.38666812, 0.38138782, 0.37524035, 0.36827014, 0.36052696, 0.35206533, 0.34294386, 0.3332246 , 0.32297236, 0.31225393, 0.30113743, 0.28969155, 0.27798489, 0.26608525, 0.25405906, 0.24197072]))

提示:

上述实例计算的是区间[-1, 1]之间的41个坐标值:

[-1.0, -0.95, -0.9, -0.85, -0.8, -0.75, -0.7, -0.6499999999999999, -0.6, -0.55, -0.5, -0.44999999999999996, -0.3999999999999999, -0.35, -0.29999999999999993, -0.25, -0.19999999999999996, -0.1499999999999999, -0.09999999999999998, -0.04999999999999993, 0.0, 0.050000000000000044, 0.10000000000000009, 0.15000000000000013, 0.20000000000000018, 0.25, 0.30000000000000004, 0.3500000000000001, 0.40000000000000013, 0.4500000000000002, 0.5, 0.55, 0.6000000000000001, 0.6500000000000001, 0.7000000000000002, 0.75, 0.8, 0.8500000000000001, 0.9000000000000001, 0.9500000000000002, 1.0]

开始你的任务吧,祝你成功!

class Solution:
    def solve(self, s, e):
        """
        :type s, e: int, int
        :rtype xlist, ylist: numpy.array, numpy.array
        """
        #请在此按照“编程要求”填写代码
        #********** Begin *********#
        import numpy as np
        xlist = np.linspace(s, e, 41)
        ylist = 1/np.sqrt(2*np.pi)*np.exp(-0.5*xlist**2)
        return xlist, ylist
        ##********** End **********#

第4关:绘制函数

任务描述
本关任务:编写一个能根据二维点集绘制出其对应的图像的程序。

相关知识
为了完成本关任务,你需要掌握matplotlib.pyplot的基本使用。

matplotlib.pyplot的基本使用
One picture is worth more than ten thousand words. ————Anonymous

大部分人可能对数字不太敏感,这就意味着我们很难从数字中直接地发现一些数学规律,但是如果我们能将这些数据用图形表示,往往都具有事半功倍的奇效,而Python的matplotlib就是一个强大的数学图像绘制库。

折线图
matplotlib.pyplot.plot函数能够把我们输入的二维点集按存储顺序在图形上连接起来,对应参数为点的坐标,第一个参数是点集的横坐标值,第二个参数是点集的纵坐标值。如,我们要绘制一个过点(1, 3)和(2, 4)的直线,可以这样做:

#使用之前不要忘记导入所需要的包
import matplotlib.pyplot as plt
#将点(1, 3)和(2, 4)连接起来
plt.plot([1, 2], [3, 4])
#将图形显示
plt.show()
输出:

在这里插入图片描述

尽管我们已经学会了折线图的基本绘制方法,但是生活中的数据往往是无法用直线描绘出来,更多的是曲线,那曲线我们又可以怎么画呢?事实上,大多计算机程序所描绘的曲线,其实都是由一个具有很多点集的折线图所构成的,就是因为用来描绘这个折线图的点太多了,以至于从我们人眼看上去是曲线。熟悉积分的同学一定知道,积分的计算实际上也是把被积函数的图形分成无数个小矩形,然后将所有的矩形的面积累加起来,取极限,最后作为积分值。比如,我们来描绘图像y = x^2:
#取区间[-5, 5]内等间隔的100个点
x = np.linspace(-5, 5, 100)
#计算横坐标在函数y=x^2上对应的函数值
y = x**2
#绘制y=x^2的图形
plt.plot(x, y)
plt.show()
输出:

在这里插入图片描述

编程要求
根据输入的区间[s,e],在其中取41个等间隔的值作为横坐标,并求出在下列函数h(x)中的输出,并将该输出作为纵坐标,最后将所得到的点集按对应顺序一一描绘在图像中。

在这里插入图片描述

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:s = -4,e = 4

预期输出:

在这里插入图片描述

开始你的任务吧,祝你成功!

class Solution:
    def solve(self, s, e):
        """
        :type s, e: int, int
        :rtype: None
        """
        #请在此按照“编程要求”添加代码
        #********** Begin *********#
        from matplotlib import pyplot as plt
        import math
        dx = (e - s) / 40
        xlist = [s+i*dx for i in range(0,41)]
        def f(x):
            return 1/math.sqrt(2*math.pi)*math.exp(-0.5*x**2)
        ylist = [f(x) for x in xlist]
        plt.plot(xlist, ylist)
        plt.show()
        ##********** End **********#
        plt.savefig("step4/stu_img/student.png")

第5关:函数作用于向量

任务描述
本关任务:编写一个能将函数作用于向量的小程序。

相关知识
Python 中的 Numpy 库能够定义一个向量,但是如何判断是否为向量呢?下面我们将介绍哪些数组能表示向量以及构建向量的方式:

什么数组不能表示向量:秩为1的数组不能表示为向量
构建向量的方式:
reshape()函数:通过reshape()函数可以依据数组创建指定维度的向量或者矩阵。
zeros(),ones(),randn()等函数构建指定形状的数组、向量、矩阵,例如:
np.zeros([4,2])
输出:
[[0. 0.]
[0. 0.]
[0. 0.]
[0. 0.]]
编程要求
给定向量v和函数:

在这里插入图片描述

在solve_1函数中,将f作用于v中每一个元素,将结果存在列表变量y中并返回。
在solve_2函数中,运用向量计算规则按照numpy表达式v
3
+v∗exp(v)+1计算f(v)的值,将结果存在numpy.array类型的变量y_1中并返回。

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:v = (2, 3, -1)

预期输出:

solve_1 的输出:
[23.7781121978613, 88.256610769563, -0.36787944117144233]
solve_2 的输出:
[23.7781122 88.25661077 -0.36787944]

class Solution:
    def solve_1(self, v):
        """
        :type v: list
        :rtype: list
        """
        #请在此按照“编程要求”添加代码
        #********** Begin *********#
        import math
        def f(x):
            return x**3+x*math.exp(x)+1
        y = [f(a) for a in v]
        return y
        ##********** End **********#
    def solve_2(self, v):
        """
        :type v: list
        :rtype: numpy.array
        """
        #请在此按照“编程要求”添加代码
        #********** Begin *********#
        import numpy as np
        xlist = np.array(v)
        ylist = xlist**3+xlist*np.exp(xlist)+1
        return ylist
        ##********** End **********#

第6关:手工模拟执行向量表达式

任务描述
本关任务:分别使用math库手工模拟和numpy向量运算完成向量表达式的执行。

相关知识
(略)

编程要求
在向量表达式y = cos(sin(x)) + exp(1/t)中,x和t为长度相同的两个数组。

假设x有两个元素0和2,t有两个元素1和1.5,手工(或用计算器)计算y数组。然后,编写模拟手工计算过程的程序(即用循环加math库模拟手工计算)以及直接使用numpy向量运算的程序。

在solve_1函数中,将向量表达式作用于x和t中每一个对应的元素,将结果存在列表变量y中并返回。
在solve_2函数中,运用向量计算规则计算向量表达式的值,将结果存在numpy.array类型的变量y_1中并返回。

根据提示,在右侧编辑器补充代码,完成编程要求。

测试说明
平台会对你编写的代码进行测试:

测试输入:x = (0, 2),t = (1, 1.5)

预期输出:

solve_1 的输出:
[3.718281828459045, 2.562034323171158]
solve_2 的输出:
[3.71828183 2.56203432]
误差:
[0. 0.]

提示:

误差小于1e-6忽略不计。

开始你的任务吧,祝你成功!

class Solution:
    def solve_1(self, x, t):
        """
        :type x, t: list, list
        :rtype: list
        """
        #请在此按照“编程要求:使用math库实现”添加代码
        #********** Begin *********#
        import math
        y = []
        for xi, ti in zip(x, t):
            y.append(math.cos(math.sin(xi)) + math.exp(1/ti))
        return y
        ##********** End **********#
    def solve_2(self, x, t):
        """
        :type x, t: list, list
        :rtype: numpy.array
        """
        #请在此按照“编程要求:使用numpy库实现”添加代码
        #********** Begin *********#
        import numpy as np
        y_1 = np.cos(np.sin(x))+np.exp(1/np.array(t))
        return y_1
        ##********** End **********#

欢迎大家加我微信学习讨论
在这里插入图片描述

  • 20
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程子的小段

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

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

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

打赏作者

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

抵扣说明:

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

余额充值