1695_week2_算法与函数(MIT使用Python编程学习手记)

news2024/11/23 21:33:48

全部学习汇总: GreyZhang/python_basic: My learning notes about python. (github.com)

首先说明一下,这部分信息的整理只是我个人的理解。由于自己的知识功底以及英语水准,很可能会有大量的疏漏。再此,我只想把自己学习时候的一点收获整理分享一下。如果能够给别人一点点帮助,荣幸之至。如果有错误,也请予以斧正。如果感觉我有描述不清的,当然也可以跟我邮件交流。由于直接复制代码排版上会有很多问题,稳文中代码全都截取VIM编辑器的界面展示。如果需要代码可以给我发邮件索取,以下是我的联系方式:

Email : greyzhang@126.com

这部分学习需要有一定的Python学习基础了,需要掌握的概念大致有以下几个:

Python的语法、Python的数据类型(整形、浮点、元组、列表、字典等)。有一个数据类型需要单独拿出来强调一下,那就是布尔量。接下来的很多判断或者程序分支的概念会建立在最一个布尔量的判断基础上。

在之前的学习手记中已经总结了一部分Python的语句操作,我们可以通过在Python shell中年输入一系列的语句来实现某个功能。看起来,我们是让计算机运行了我们的软件功能,但是功能肯定是远远不够。

迭代

在程序设计中,一个很重要的算法概念便是迭代。通过迭代,我们可以反复重用同一段代码来解决我们的问题。通过程序语言对我们需要处理的信息进行描述,然后再迭代的程序段中反复执行我们写好的一段程序,在执行的过程中通过对布尔量的查看判断来确认我们是否找到一个合适的结果。这是对“猜想——验证”的计算机思考方法的一种实践尝试。

接下来通过一个简单的小例子来说明一下:通过Python实现求解一个正整数点额平方。

代码如下:

这里我们用到了while循环,while循环最简单的结构如下:

While <判断条件>:

循环体

以上程序的执行结果:

>>> ================================ RESTART ================================

>>>

3*3 = 9

如果改变x的数值,可以得到你想要的不同结果。比如改成12345,执行结果如下:

>>> ================================ RESTART ================================

>>>

12345*12345 = 152399025

虽说此处还谈不上代码的优化,使用Python可以有更好的实现方法。但是可以看出的式程序执行速度还是很快的,一瞬间就可以得出你想要的结果。

猜想——验证

“猜想——验证”是计算机思维的一种常用的方法,我们假定一系列的可能性然后一次次验证,最终判断是否有我们想要的结果。

通过一个简单的例子来说明一下:寻找一个整数是否存在整数立方根。

我们可以从0开始,直到这个数本身为止一次次查看猜测数值的三次方是否等于给出的整数。如果找到那就寻找到了这个数的整数立方根,如果找不到,那这个数肯定是没有整数立方根。

设计代码如下:

执行结果如下:

>>> ================================ RESTART ================================

>>>

input a number:123

can't find %d's cube root

>>> ================================ RESTART ================================

>>>

input a number:27

cube root of 27 is: 3

通过以上的例子可以看出“猜想——验证”方法的大致步骤:

1,给出初始的猜想

2,在循环的结构中不断验证,如果满足条件则终止,因为找到了我们要的答案。如果不满足验证条件,那么在循环结构中改变猜想再次验证。

常用迭代的特点:

通过以上几个例子大致可以总结出常用迭代程序的特点:

1,有一个状态变量

a,在循环体外进行初始化

b,在循环体中改变状态量

c,判断验证的依据来自于状态量的变化

2,状态量递减:

A,初始化的数值为整数

B,执行的时候整数非负

C,<=0的时候结束

D,在循环中递减

以上特点并不是所有迭代程序的特征,但是是常用迭代程序一般都有的特点。如果满足以上特点的迭代程序,我们可以通过看状态量的数值来弄清楚我们程序的执行度。由于规律递减的存在,我们很清楚就能够知道到底还有多少没有执行完。

For循环:

While循环通常可以用来对一系列信息进行验证,如同我们前面看到的数字。在Python中,对这种情况的处理还有另外一种特殊的方式叫做for循环。

For循环的结构入下:

For <判断条件> :

循环体

在for循环中,循环的状态量首先被绑定为序列中的第一个元素,然后执行循环体程序。循环体执行结束后,状态量绑定为第二个元素,执行循环体程序,一直这样执行下去。如果遇到break,循环会直接终止。

如果想使用一系列连续的数字序列,可能会用到Python的内置函数range(n)。这个函数可以用来产生0到n-1的连续数字序列。函数是重载的,针对不同的需要也可以有更加方便的使用方式。

下面使用for循环实现上面的cube root功能:

执行结果如下:

>>> ================================ RESTART ================================

>>>

input a number:27

cube root of 27 is 3

>>> ================================ RESTART ================================

>>>

input a number:-27

cube root of -27 is -3

>>> ================================ RESTART ================================

>>>

input a number:123

123 is not a perfect cube

以上代码不仅完成了与之前while循环相同的功能,而且同时支持负数的判断。

浮点数的处理;

首先看一下十进制的表示:

302 = 3*10**2 + 0*10**1 + 2*10**0

为什么我们的祖先首先采用的是十进制的计数方式呢?那是因为我们有十根手指头,但是计算机没这个。计算机知道的就只有开或者关两种状态,只知道0或者1。

这样,用二进制表示一个十进制的例子如下:

10011 = 1*2**4 + 0*2**3 + 0*2**2 + 1*2**1 + 1*2**0

(用十进制表示是19 = 16 + 2 + 1)

在计算机的内部,数字是以二进制的形式才存储的。考虑一下10011除以2后的表达方式,实际上可以表示为:1*2**3 + 0*2**2 + 0*2**1 + 1*2**0。如果在计算机中进行除以2的操作,实际上是把二进制的数值向右移动了一位。

把这思考的一切用Python处理展示出来,可以设计如下的代码:

执行效果如下:

>>> ================================ RESTART ================================

>>>

input a number:19

10011

>>> ================================ RESTART ================================

>>>

input a number:-19

-10011

如果考虑到分数会是怎么样呢?

3/8 = 0.375 = 3*10**(--1) + 7*10**(-2)+5*10**(-3)

0.375 * (2 ** 3) = 3(十进制)

转换为二进制:11

除以(2**3),也就是右移三位:0.011(二进制)

设计代码如下:

代码执行结果如下:

>>> ================================ RESTART ================================

>>>

Enter a decimal number between 0 and 1: .375

Remainder = 0.375

Remainder = 0.75

Remainder = 0.5

011

.011

The binary representation of the decimal 0.375 is .011

>>> ================================ RESTART ================================

>>>

Enter a decimal number between 0 and 1: .1

Remainder = 0.1

Remainder = 0.2

Remainder = 0.4

Remainder = 0.8

Remainder = 0.6

Remainder = 0.2

Remainder = 0.4

Remainder = 0.8

Remainder = 0.6

Remainder = 0.2

Remainder = 0.4

Remainder = 0.8

Remainder = 0.6

Remainder = 0.2

Remainder = 0.4

Remainder = 0.8

Remainder = 0.6

Remainder = 0.200000000001

Remainder = 0.400000000001

Remainder = 0.800000000003

Remainder = 0.600000000006

Remainder = 0.200000000012

Remainder = 0.400000000023

Remainder = 0.800000000047

Remainder = 0.600000000093

Remainder = 0.200000000186

Remainder = 0.400000000373

Remainder = 0.800000000745

Remainder = 0.60000000149

Remainder = 0.20000000298

Remainder = 0.40000000596

Remainder = 0.800000011921

Remainder = 0.600000023842

Remainder = 0.200000047684

Remainder = 0.400000095367

Remainder = 0.800000190735

Remainder = 0.60000038147

Remainder = 0.200000762939

Remainder = 0.400001525879

Remainder = 0.800003051758

Remainder = 0.600006103516

Remainder = 0.200012207031

Remainder = 0.400024414062

Remainder = 0.800048828125

Remainder = 0.60009765625

Remainder = 0.2001953125

Remainder = 0.400390625

Remainder = 0.80078125

Remainder = 0.6015625

Remainder = 0.203125

Remainder = 0.40625

Remainder = 0.8125

Remainder = 0.625

Remainder = 0.25

Remainder = 0.5

0001100110011001100110011001100110011001100110011001101

.0001100110011001100110011001100110011001100110011001101

The binary representation of the decimal 0.1 is .0001100110011001100110011001100110011001100110011001101

关于不能够表示为num/(2 ** n)的这种形式,判断结束条件当然不能够以能够整除为条件。因为数据的存储在计算机中的位数是有限制的。在一定精度内,这种判断可以使用一个比较小的精度值与之比较作为结束的判断条件。

常用的算法:

逐次逼近

1,选择合适的步长

太小计算时间长

太大可能计算不出结果

2,给出一个最小精度作为判断条件

二分查找

1,选择中间数

判断

根据判断决定是否再次二分查找

结束条件:达到允许精度

2,特点

缩短周期

更加智能化

适合处理有序序列

牛顿-莱布尼茨

1,g - p(g)/p’(g)是多项式方程的猜想更优解

2,特点:

高效

需要数学处理作为前提

求解平方根:

逐次逼近法:

执行结果:

>>> ================================ RESTART ================================

>>>

root of number 25.000000 is 4.999000

>>> ================================ RESTART ================================

>>>

root of number 24.000000 is 4.897959

结果还算是精确,由于步长选择比较小运算时间较长。

二分查找:

执行结果:

>>> ================================ RESTART ================================

>>>

12.5

6.25

3.125

4.6875

5.46875

5.078125

4.8828125

4.98046875

5.029296875

5.0048828125

4.99267578125

4.99877929688

5.00183105469

5.00030517578

5.00030517578

牛顿-莱布尼茨:

执行结果:

>>> ================================ RESTART ================================

>>>

13.0

7.46153846154

5.40602696273

5.01524760194

5.00002317825

5.00002317825

尝试做一个复杂运算,求12345的平方根:

关于迭代的概括:

1,用相同的方法反复验证>>> ================================ RESTART ================================

>>>

6173.0

3087.499919

1545.74914984

776.867784296

396.37925959

213.761837095

135.756512451

113.345688237

111.130142813

111.108057708

111.108057708

11次迭代便得出一个很好的解,足以看出算法优秀的重要性。如果采用逐次逼近,这将会是很大的工作量。

2,猜测的方式可以灵活使用多种算法。

函数:

关于函数,解决的问题不仅仅是功能的重用还有一个功能的抽象。函数可以把一个功能抽象出来,让其他人在不需要考虑函数的实现细节的基础上使用它。这种抽象可以称之为黑盒抽象,这不仅让代码重用变得更加简单也让代码的调试变得更加容易。

能够开始学习函数的设计,需要有基本的Python语言知识以及循环结构的了解,这些之前已经整理。之前的循环结构的确是能够在一定程度上解决代码重用的问题,但是解决的不够完美,如果我们需要重复多个循环那我们需要把整个循环体代码拷贝多次。这也带来了另外一个问题——变量的管理以及代码修改的困难。很可能我们使用的多个拷贝代码段中的变量会相互影响,当需要改变某一个语句的时候我们也可能需要修改多次。函数在使用上则要比这方便的多。

下面在举例演示一下函数的使用,通过一个简单的函数实现求两个数值中的最大值。

代码如下:

在IDLE中load之后,运行效果如下:

>>> ================================ RESTART ================================

>>>

>>> MaxNum(223,112)

223

>>> MaxNum(-6,-10)

-6

>>> x = 1

>>> y = 2

>>> MaxNum(123,456)

456

>>> MaxNum(x,y)

2

上面不仅能够看到代码可以重用,结果不受上次调用的影响,而且能够看到在IDLE环境中的x,y的赋值不会影响到函数中的x和y的数值。这是因为函数有着自己独立的变量空间,而且互不影响。关于每次调用的互不影响,递归的算法可以很好地说明,这个后面有时间在做整理。关于独立的变量空间,可以把上面的代码修改一下,如下:

LOAD到IDLE中测试使用如下:

>>> ================================ RESTART ================================

>>>

>>> MaxNum(123,321)

321

>>> MinNum(123,456)

123

>>> x = 1

>>> AddX(x)

3

通过以上例子,可以很好地说明函数的参数的特点。在其他的语言中,参数可能会更加准确的描述为形参。

函数运行的机理与步骤总结:

1,获取参数值

2,把参数值传入表达式中并执行运算

3,返回。如果存在return语句,那么函数执行结束前会返回return语句操作的对象。如果没有,那么函数返回none。

4,形参与传入的参数值脱离关系。

形参相关总结:

1,每次函数调用都会创建自己独立的局部变量

2,全局变量与局部变量不会冲突

3,同样的形参名字可以存在于不同的函数而且彼此不会冲突

关于函数的调试:

以函数的方式进行程序的设计时,输入输出得到了很好地控制。如果函数最终的执行不是我们想要的结果,通常比较好的一种方式是在函数中间加入print语句来查看中间部分变量的变化。这部分具体的描述在之前也已经整理,在博客中也可以找得到。

另一个非常重要的注意点是:在你不知道到底是什么原因导致错误之前,不要随便改动代码。

函数的引用:

如果把一个或者几个函数写到了一个文件,那么这个文件就被称为一个模块。引用这个模块的函数的方法是使用import表达式,通常有三种使用的方式。

方式一: import block

这种方式在使用block模块中的函数fun时需要以以下方式调用:

Block.fun(参数)

方式二:from block import fun as my_fun

这样,我们在自己的代码中可以使用my_fun(参数)的方式来完成方式一的功能。

方式三:from block import *

使用这种方式,可以加模块名直接使用fun(参数)的形式。

需要注意的是,import不仅仅引入模块中的函数同时也引入了模块中的全局量。如果在之前的环境中有与之重名的全局量会被其覆盖,这是需要注意的事情。

想做一个简单的学习总结,没想到看似简单的东西内容确实不少。好的是我这是在整理自己的学习手记,要是真的做为提供给别人的一份教程,那我的工作量真得能够把自己吓住了。最后,祝过路人学习进步、事业有成!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/477402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++(类和对象上篇)

本节目标&#xff1a; 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 目录 1、面向过程和面向对象初步认识 2、类的引入 4.类的访问限定符及封装 4.1访问限定…

为了做低代码平台,这些年我们对.NET的DataGridView做的那些扩展

我们的低代码开发平台从一开始决定做的时候&#xff0c;就追求未来能够支持多种类型的客户端&#xff0c;目前支持Winform&#xff0c;Web&#xff0c;H5&#xff0c;FlutterAPP&#xff0c;当然了&#xff0c;未来也有可能会随着实际的需要淘汰掉一些客户端的。 为了系统更易…

springboot - 实现动态刷新配置

自定义的配置数据源&#xff0c;继承自Spring框架的 MapPropertySource 类&#xff0c;从一个名为 my.properties 的文件中读取配置信息&#xff0c;并在每10秒钟刷新一次。 这里不加Component&#xff0c;是因为&#xff1a; FilePropertiesSource filePropertiesSource new…

辨析 总结PMP各种BS结构

OBS 组织分解结构、BOM 物料清单、WBS工作分解结构、RBS 资源分解结构、RBS 风险分解结构、RAM 责任分匹配矩阵辨析 组织分解结构 OBS&#xff08;Organizational Breakdown Structure&#xff09; 描述了执行组织的层次结构&#xff0c;以便把工作包同执行组织单元相关联 物料…

电子邮件SDK:MailBee.NET 12.3.1 Crack

MailBee.NET 对象捆绑包包括SMTP、POP3、IMAP、EWS、安全、反垃圾邮件、Outlook 转换器、地址验证器、PDF组件以及BounceMail、HTML、MIME、ICalVCard组件&#xff0c;这些组件是一项常用功能。 MailBee.NET Objects是一组强大且功能丰富的 .NET 组件&#xff0c;用于创建、发送…

Haffman编码(算法导论)

上次算法导论课讲到了Haffman树&#xff0c;笔者惊叹于Haffman编码的压缩效果&#xff0c;故想自己亲自动手尝试写一个极简的Haffman压缩程序。 首先&#xff0c;我们来了解一下什么是Haffman编码 Haffman编码 赫夫曼编码可以很有效地压缩数据&#xff1a;通常可以节省20%&am…

UNIX环境高级编程——进程关系

9.1 引言 本章详细说明进程组以及会话的概念&#xff0c;还将介绍登录shell&#xff08;登录时所调用的&#xff09;和所有从登录shell启动的进程之间的关系。 9.2 终端登录 9.3 网络登录 9.4 进程组 每个进程除了有一进程ID之外&#xff0c;还属于一个进程组&#xff0c;进…

一曲微茫度余生 ——川剧《李亚仙》唱响香港西九戏曲中心

2023年4月28日晚&#xff0c;香港西九戏曲中心灯火辉煌。重庆市川剧院携手成都市川剧研究院带来的川剧《李亚仙》首场演出在这个为戏曲而设的世界级舞台重磅上演。 此次访演受香港西九戏曲文化中心的邀请&#xff0c;原重庆市文化和旅游发展委员会党委书记、主任刘旗带队&…

『LogDashboard』.NET开源的日志面板——登录授权页面扩展

&#x1f4e3;读完这篇文章里你能收获到 了解LogDashboard扩展开源项目——LogDashboard.Authorization掌握LogDashboard扩展内置登录页的使用方式 文章目录 一、LogDashbaord介绍1. 功能支持2. 快速开始 二、LogDashboard.Authorization1. 功能介绍2. 项目接入3. 更多示例 一…

Python语法学习

目录 Openmv用micro python开发的原因 print函数 列表 元组 判断 if...else... if...elif...else 循环 for循环 while循环 强制类型转换 点灯之路 点个不同颜色的闪烁LED 本文章仅作为个人的Openmv学习笔记&#xff0c;有问题欢迎指正~ Openmv用micro python开发…

【MPC|云储能】基于模型预测控制(MPC)的微电网调度优化的研究(matlab代码)

目录 1 主要内容 2 程序难点及问题说明 3 部分程序 4 下载链接 1 主要内容 该程序分为两部分&#xff0c;日前优化部分——该程序首先根据《电力系统云储能研究框架与基础模型》上面方法&#xff0c;根据每个居民的实际需要得到响应储能充放电功率&#xff0c;优化得到整体…

性能测评:阿里云服务器ECS通用型g8i实例CPU内存安全存储

阿里云服务器ECS通用型实例规格族g8i采用2.7 GHz主频的Intel Xeon(Sapphire Rapids) Platinum 8475B处理器&#xff0c;3.2 GHz睿频&#xff0c;g8i实例采用阿里云全新CIPU架构&#xff0c;可提供稳定的算力输出、更强劲的I/O引擎以及芯片级的安全加固。阿里云百科分享阿里云服…

真题详解(DNS)-软件设计(六十三)

真题详解&#xff08;有向图&#xff09;-软件设计&#xff08;六十二)https://blog.csdn.net/ke1ying/article/details/130443040 顺序存储&#xff1a;元素和存储空间相对位置来表示数据元素之间逻辑关系。 RFB&#xff1a;远程访问图形用户界面的简单协议。 在ISO/IEC9126软…

【五一创作】跑alpaca-lora语言模型的常见问题(心得)

训练部署alpaca-lora语言模型常见问题 Alpaca-Lora是一个开源的自然语言处理框架&#xff0c;使用深度学习技术构建了一个端到端的语言模型。在训练和部署alpaca-lora语言模型时&#xff0c;可能会遇到一些常见问题。本文将介绍一些这些问题及其解决方法。 1. bitsandbytes版…

计算机视觉毕业后找不到工作怎么办?怒刷leetcode,还是另寻他路?

文章目录 一、计算机视觉毕业后找不到工作怎么办&#xff1f;二、大环境&#xff1a;前两年的泡沫太大三、还是要把自己的基本功搞扎实&#xff0c;真正的人才什么时候都紧缺四、转换思路&#xff0c;另投他坑五、要有毅力&#xff0c;心态放平六、最后的建议 一、计算机视觉毕…

Python毕业设计之django社区报修维修预约上门服务系统

开发语言&#xff1a;Python 框架&#xff1a;django Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm 目 录 摘 要 I Pick to II 1绪论 1 1.1项目研究的背景 1 1.2开发意义 1 1.3项…

「数据架构」介绍下一代主数据管理(MDM)

主数据管理是旨在创建和维护权威、可靠、可持续、准确、及时和安全的环境的过程和技术框架。这个环境代表了一个单一版本的事实&#xff0c;作为跨不同的系统、业务单元和用户社区的可接受的记录系统。 尽管MDM不是新的&#xff0c;但是最近人们对开发MDM解决方案的兴趣大增。这…

正则表达式 Regular Expression

情景引入改代码查找文件词法分析器网站注册密码信息爬取 简介在线测试工具RegulexRegExr 语法普通字符非打印字符特殊字符限定符定位符修饰符元字符 实例匹配邮箱 情景引入 改代码 修改代码格式问题&#xff0c;或者重命名代码里的某个变量等&#xff0c;都可以使用 VS Code …

Mysql 管理

目录 0 课程视频 1 系统数据库 -> 安装完mysql ->自带四个数据库 2 常用工具 -> 写脚本用 2.1 mysql 客户端工具 2.2 mysqladmin 2.3 mysqlbinlog -> 二进制日志 -> 运维讲解 2.4 mysqlshow 2.5 mysqldump 备份用 ->导出 2.6 mysqlimport/source -…

一篇带你了解大厂都在用的DDD领域驱动设计

一、DDD到底是什么 DDD全称Domain Driven Design&#xff0c;领域驱动设计。 为了解决快速变化、复杂系统的设计问题的 领域驱动设计是Eric Evans在2004年发表的Domain Driven Design&#xff08;领域驱动设计&#xff0c;DDD)著作中提出的一种从系统分析到软件建模的一套方…