USF MSDS501 计算数据科学中文讲义 2.1 编程导论

来源:ApacheCN『USF MSDS501 计算数据科学中文讲义』翻译项目

原文:Introduction to programming

译者:飞龙

协议:CC BY-NC-SA 4.0

<!--break-->

计算机科学不仅关于计算机,就跟天文学不仅关于望远镜一样。

-- Edsger Dijkstra

我记得面对我的第一个编程任务(1980 年的 BASIC!),我完全没做出来。我甚至不知道如何开始解决这个问题。我很难过,尽管编码对我来说很快就会变得非常自然。我最初的困难的原因现在显而易见:教师完全没有提供将问题转换为正在运行的程序的技术或策略。我必须自己解决这个问题。

在介绍性课程中关注编程语言语法的方法是可以理解的。 解决问题不是一种精确,定义好的技能。 它更像是一种通过练习磨练的整体能力。 因此,教学和评分是具有挑战性的。 立即跳转到一些简单的编程语言语句的语法,要容易得多。 这种方法具体,原则上易于理解,但完全忽略了我们什么时候以及为什么需要这些语句。 可以在这种环境中作为学生而生存的教授,在教其他程序员时通常会继续使用孤注一掷的方法。

在本课程中,我想通过专注于解决问题和学习编写复杂的 Python 代码来纠正这一问题。要做到这一点,我们将遵循一个整体的问题解决策略,包括设计“工作计划”或“算法”,无论是纸上还是头脑中(当你获得更多经验时)。在我们进入编码阶段很久之前,该计划就帮助我们思考问题。计划的一部分是确定一个解决我们问题的合适操作顺序。这是一个棘手的问题,因此我们将通过以下方式缩小解决方案空间的范围:(1)将自己限制在一组通用的操作和数据结构中,(2)应用成熟的方法,我们称之为“向后工作”和“简化为一个已知的解决方案“,最后,(3)利用这个入门课程的主题特性,采用一个适用于大多数数据科学问题的程序大纲。当我们最终进入 Python 编程时,我们将自己局限于该语言的有用子集。目标是教你编程,而不是教你完整的 Python 语言。

请允许我首先区分编程(问题解决)和编码(用特定编程语言表达我们的解决方案)。

编程是什么?

当我们考虑编程时,我们会立即考虑编程语言,因为我们使用特定的语言语法表达自己。 但是,这就像向物理学家询问他们讨论物理学的语言。 编程主要是将“单词问题”(项目描述)转换为执行计划。 当然,编码(输入代码)的最终行为是必需的,但学习在精神上解决编程问题是最困难的过程,也是最重要的过程。

自然语言也是如此。 学习证明数学定理比学习用某种自然语言编写证明更难。 实际上,大多数数学语法在自然语言中都是相同的,就像编程语言一样。 像在数据科学计划中一样,用 Python 或 R 表达您的想法是编程过程中最简单的部分。 也就是说,编写正确的代码通常是该过程中最令人沮丧和耗时的部分,即使对于有经验的程序员也是如此。

编程更多是要表达什么而不是如何表达。 用计算机解决问题意味着识别一系列操作,每个操作都解决了整个问题的一部分。 每个操作本身可能是一系列子操作。 用 Python 或 R 表达这些操作并不困难。 确定哪些操作及其相对顺序是困难的部分。

让我们从解决编程问题的整体策略入手。

解决问题的策略

无论我们尝试编写什么软件,我们都可以遵循解决问题的整体策略。

在任何问题解决的情况下,第一步是充分理解问题并清楚地确定目标。 这可能听起来很明显,但是我们对这个问题的理解中的任何模糊性都可能使我们走错方向。 在数据科学环境中,目标通常是我们试图回答的问题,例如“哪个销售区域的同比增长最快?”(摘要统计量),“哪些交易是欺诈性的?”(分类器)或“未来某个日期股票价格是多少?”(预测器)。 我们应该能够使用英语单词精确地表达目标和预期输出。 如果我们不能这样做,那么 Python 或 R 中没有任何编码的专业知识可以解决问题。 我们很快就会看到一些例子。

问题解决过程的第二步(或可能是第一步的一部分)是手动写出一些输入 - 输出对。 这样做有助于我们了解程序需要做什么以及如何执行。 我们将要看到,这种技术不仅适用于整体输入和输出,而且适用于设计函数(可重用的代码段)。 **如果我们无法手动识别和执行操作,我们无法使用代码自动执行操作。**此外,列出一堆案例通常会突出特殊情况,例如“当输入为负时,输出应为空”。 换句话说,程序不应该以负数作为输入而崩溃。 程序员称之为测试驱动设计

在求职面试设置中,此步骤意味着立即尝试绘制问题的几个实例。 例如,如果要求以某种方式处理数字列表,首先将三个或四个数字放在板上或纸上。 这自然会带来一些面试官期待你提出的重要问题,比如数据的来源以及它是否适合内存等......

第三步是弄清楚我们实现目标所需的数据或输入,即我们的原材料。 没有正确的数据,我们无法解决问题。 例如,我曾指导过一个学生实习团队,其目标是确定某个网站的哪些客户会升级到专业帐户。 学生只有已升级的用户数据,没有拒绝升级的用户数据。哎呀! 如果您只有苹果的数据,则无法构建苹果与橙子分类器。 如果您没有所需的所有数据,那么将此要求确定为问题解决过程的一部分非常重要。 数据采集通常需要编程,我们将回顾下面的主题,作为我们通用计划大纲的一部分。

在这一点上,我们实际上已经设定了解决问题所需的阶段,我们根本没有考虑过代码。 我们从最终结果开始,然后确定了我们需要的数据。 输入 - 输出对巧妙地包含了我们需要执行的计算。 一开始,我们有已知的数据,最后,我们有预期的输出或作品。 好的,进入编程步骤。

第四步是确定计算预期结果的操作顺序。 有时这被称为算法并且涉及规划输入数据上的特定操作和子操作,逐渐将其转换为预期输出。

前四个步骤是所谓的费曼技巧的关键部分,其中包括写下已分配任务或问题的完整说明,就像你对非专家解释它那样。直到你可以简单地写下来,而不会混淆语言或术语,你自己不明白这个问题。在你完成这个阶段之前,没有必要继续下去。(教师经常开玩笑,学习新主题的最佳方法是教授关于该主题的课程!)

第五步中,我们将计划中的操作转换为实际的可执行代码。 这一步需要整本书,但这里总结了我的建议。 从最简单的子操作开始,确保它们先工作。 然后编写使用这些子操作的较大操作。 如果出现问题,您就会知道新代码中的子操作可能没有经过测试。 在这个阶段,我们通常会发现第四步中的设计问题,因此我们通常会重复四五次。 测试功能和修复错误称为调试

最后,第六步是检查我们的整体结果的正确性。 最明显的检查是比较程序的输出与步骤 3 中的已知输入-输出对。 然后,最重要的是,在第 3 步到第 5 步中使用未考虑的输入来测试程序。 这是对程序通用性的重要测试。 如果程序输出错误,则返回第 4 步来查看错误。

而现在,出于现实因素。世界是一个非常混乱的地方,因为我们开始知道最少的问题,所以我们通常需要通过一些或所有这些步骤重复或反弹。 例如,假设我们正在构建一个苹果与橙子分类器,上面的过程使程序不能很好地区分这两个水果。 也许我们只有大小和形状的数据。 我们可能会认为分类器需要颜色数据,所以它回到第二步(可能是第三步),然后是第六步再次检查结果。

制定计划和程序

程序是一系列操作,用于转换数据或执行计算,它最终产生预期输出。编程是设计程序的行为:识别操作及其适当的顺序。 换句话说,编程就是为计算机提出一个工作计划,我们经常用半精确的英文描述,叫做伪代码。这是上一节中的第四步

另一方面,编码是将这种高级伪代码转换为编程语言语法的行为。 随着您获得更多经验,在没有伪代码步骤的情况下,直接从工作计划变成代码变得更容易。

在第一次学习编程时,将已建立的模式,模板,策略和常见的数据转换操作用作拐杖,是有帮助的。 例如,在下一节中将查看数据科学程序的模板,它们在整个程序中的大多数情况下都可以使用! 在 Python 中的编程模式中,我们将看到许多模式,您可以拼凑起来创建程序。

如上所述,您还可以使用两种策略或一般准则来处理程序设计过程:

  • 从最终结果开始,向后工作,询问每个步骤的先决条件。 换句话说,步骤 i 之前的一个或多个处理步骤,计算步骤 i 所需的数据或值。 例如,在计算平均值之前,我们无法打印某些数字的平均值。 在我们对这些数字求和之前,我们无法计算平均值。 我们不能综合,直到我们将这些数字加载到内存等...
  • *使用已知解决方案将新问题归约或简化为现有问题的变体。*要应用这种新方法,请询问您尝试解决的问题与您有解决方案的其他问题之间的区别。

这两种技术在建筑,工程和数学方面都是众所周知的。 例如,想象一下你想在离地面 10 英尺的地方竖立一尊沉重的雕像。 结构工程师可能会认为沉重的雕像需要一个直的金属底座。 然后,为了支撑所有这些重量,四个 10 英尺的钢梁应该支撑金属底座。 钢梁应在地面上有深层混凝土基座,等等。这是从最终结果倒退的。

作为重用的一个例子,建造一座新吊桥的工程师不会像以前从未建造过这样的东西那样。 他们可能会采用并调整现有的设计来适应新的情况。

另外,计划重用通常用于开其他学科的玩笑。 例如,来自物理学家笑话的集合,这里有一个变体:

一位物理学家和一位数学家正坐在教职员休息室里。 突然间,咖啡机着火了。 物理学家抓起一个水桶,跳向水槽,把水桶装满水,灭火。 第二天,同样的两个人坐在同一个休息室。 咖啡机再次着火。 这一次,数学家站起来,拿起一个桶,把桶交给物理学家,从而将问题归约到先前解决的问题

练习:给定一个包含十进制数字的字符串,例如s = "501",打印出各个数字的总和。 在这种情况下,输出应为6 = 5 + 0 + 1。 提示:int('9')产生值 9。从期望的结果,求和,向后工作,找出你需要的东西。 例如,结果是数字的总和。 这意味着我们需要数字。 要获取数字,我们可以遍历字符串的字符,或者我们可以将字符串转换为字符列表并迭代它。 在我们迭代时,我们可以求和数字值。 总而言之,我们需要初始化一个临时结果变量,可能称为n

练习:在A中给出数字列表,原地反转数字(意思是没有单独的A的副本,以及不创建新的列表来返回)。 首先在白板上写一个例子。 此练习对于在图像项目中的翻转图像非常有用。

如果您遇到困难,或只是检查您的答案,您可以查看我的答案

现在我们已经有了解决问题的整体策略,让我们来看一个程序大纲,它将帮助我们上手您需要构建的任何数据科学程序。

数据科学程序模板

经验丰富的程序员从一组通用心智模板中抽取起点。 有桌面 GUI 应用程序,机器学习分类器,Web 服务器等模板....模板提供程序的整体结构,程序员只需根据特定问题进行定制。

依靠心智模板甚至物理模板非常常见,而不仅仅是编程。 律师拥有合同的通用模板,编剧有各种电影类型的通用脚本。 例如,大多数动作电影都是这样的:遇见坏人;遇见英雄;追逐场景;英雄克服了很大的困难来打败坏人和他的仆从。由于所需的精度,编程与编写法律文档最相似。 丢失的单词或标点可能导致程序崩溃或合同签字人破产。(例如,参见毁坏 NASA 火箭的错别字)。

获得作为程序员的经验,意味着识别代码中的模式,并在脑海中创建通用模板来供将来使用。 在开始使用时,您可以通过重用现有的代码库和使用相关模板,来依赖其他程序员的经验。 这将我们引领到以下通用数据科学程序模板,该模板适用于您可能遇到的大多数问题:

1.获取数据,这意味着找到合适的文件或从 Web 收集数据并存储在文件或数据库中 2.从磁盘或数据库加载数据,并放入组织成数据结构的内存 2.规范化,过滤,清理或以其他方式准备数据 3.处理数据,这可能意味着训练机器学习模型,转换数据,计算摘要统计量或优化成本函数 4.输出结果,可以是任何东西,从简单地将答案打印,到保存数据到磁盘以及生成奇特的可视化

为特定问题编写程序意味着要弄清楚每个步骤是什么,尽管并非所有程序都会使用每一步。

**致谢。**与 Kathi Fisler 的对话,为这里总结的有原则的,有计划的编程方法提供了很多灵感。 有关设计秘籍的更多信息,请参阅[通过自举从计算到代数的解决单词问题的转移技巧](https://cs.brown.edu/~sk/Publications/Papers/Published/sfkf-trans-word-prob-comp-alg-BS/ paper.pdf)。

转载于:https://my.oschina.net/wizardforcel/blog/3068321

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值