8

我正在教/帮助学生编程。

我记得当我开始时,以下过程总是对我有帮助;它看起来很直观,我想知道其他人是否有类似的方法。

  1. 阅读问题并理解它(当然)。
  2. 识别可能的“功能”和变量。
  3. 写下我将如何一步一步做(算法)
  4. 把它翻译成代码,如果有什么你不能做的,创建一个为你做的函数并继续前进。

随着时间的推移和实践,我似乎已经忘记了从问题描述到编码解决方案是多么困难,但是,通过应用这种方法,我设法学习了如何编程。

所以对于像这样的项目描述:

系统必须根据以下规则计算商品的价格(规则的描述......客户、折扣、可用性等......等等)

我的第一步是了解问题所在。

然后识别项目、规则、变量等。

伪代码类似于:

function getPrice( itemPrice, quantity , clientAge, hourOfDay ) : int 
   if( hourOfDay > 18 ) then
      discount = 5%

   if( quantity > 10 ) then
      discount = 5%

   if( clientAge > 60 or < 18 ) then
      discount = 5%


        return item_price - discounts...
end

然后将其传递给编程语言..

public class Problem1{
    public int getPrice( int itemPrice, int quantity,hourOdDay ) {
        int discount = 0;
        if( hourOfDay > 10 ) {
             // uh uh.. U don't know how to calculate percentage... 
             // create a function and move on.
            discount += percentOf( 5, itemPriece );
            .
            .
            .
            you get the idea..

        }
     }
    public int percentOf( int percent, int i ) {
             // .... 
    }


}

您是否采用了类似的方法?..有人教您类似的方法还是您发现了自己(就像我一样:()

4

13 回答 13

11

我通过测试驱动的方法。

1. 我写下(在纸上或纯文本编辑器上)满足问题需要的测试或规范列表。

- simple calculations (no discounts and concessions) with:
    - single item
    - two items
    - maximum number of items that doesn't have a discount
- calculate for discounts based on number of items
    - buying 10 items gives you a 5% discount
    - buying 15 items gives you a 7% discount
    - etc.
- calculate based on hourly rates
    - calculate morning rates
    - calculate afternoon rates
    - calculate evening rates
    - calculate midnight rates
- calculate based on buyer's age
    - children
    - adults
    - seniors
- calculate based on combinations
    - buying 10 items in the afternoon

2. 寻找我认为最容易实现的项目并为其编写测试。例如单品看起来很简单

该示例使用 Nunit 和 C#。

[Test] public void SingleItems()
{
    Assert.AreEqual(5, GetPrice(5, 1));
}

使用以下方法实现:

public decimal GetPrice(decimal amount, int quantity)
{
    return amount * quantity; // easy!
}

然后转到这两个项目。

[Test]
public void TwoItemsItems()
{
    Assert.AreEqual(10, GetPrice(5, 2));
}

实现仍然通过了测试,所以继续下一个测试。

3. 时刻注意重复并将其删除。当所有测试都通过并且您不再想任何测试时,您就完成了。

这并不能保证您将创建最有效的算法,但只要您知道要测试什么并且一切都通过,它将保证您得到正确的答案。

于 2008-09-26T02:52:43.553 回答
5

老式的 OO 方式:

  • 写下对问题及其解决方案的描述
  • 圈出名词,这些是候选对象
  • 在动词周围画框,这些是候选信息
  • 将动词与会“做”动作的名词组合在一起;列出任何其他需要帮助的名词
  • 看看你是否可以使用 noun.verb(other nouns) 形式重述解决方案
  • 编码

[这种方法先于 CRC 卡,但是已经很久了(超过 20 年),我不记得我在哪里学的了]

于 2008-09-26T03:29:19.427 回答
4

在学习编程时,我认为 TDD 没有帮助。当您对编程的内容有了一些概念后,TDD 会很好,但对于初学者来说,拥有一个可以编写代码并在最快的周转时间内查看结果的环境是最重要的。

我会立即从问题陈述到代码。破解它。帮助学生了解编写软件/结构化算法的不同方式。教学生改变主意并重新编写代码。尝试教授一些关于代码美学的知识。

一旦他们可以破解代码......然后在重构方面引入正式重组的想法。然后介绍 TDD 的想法,作为一种使过程更加健壮的方法。但只有当他们对操纵代码做他们想做的事情感到舒服时。在那个阶段,能够指定测试会更容易一些。原因是 TDD 是关于设计的。在学习时,你并不真正关心设计,而是关心你能做什么,你必须玩什么玩具,它们是如何工作的,你如何将它们组合在一起。一旦您对此有所了解,您就会想考虑设计,而这正是 TDD 真正发挥作用的时候。

从那里我将开始引入微模式导致设计模式

于 2008-09-26T03:42:00.533 回答
3

我做了类似的事情。

  • 弄清楚规则/逻辑。
  • 弄清楚数学。
  • 然后尝试编写代码。

在这样做了几个月后,它就被内化了。直到遇到需要您分解的复杂问题时,您才意识到自己在做这件事。

于 2008-09-26T02:17:43.093 回答
3

我从顶部开始,一路向下。基本上,我将从编写一个高级程序开始,勾勒出其中的细节,然后开始填写细节。

说我有这个问题(来自项目欧拉)

前十个自然数的平方和为,1^2 + 2^2 + ... + 10^2 = 385

前十个自然数之和的平方是,(1 + 2 + ... + 10)^2 = 55^2 = 3025

因此,前十个自然数的平方和与和的平方之差为 3025 385 = 2640。

求前一百个自然数的平方和与和的平方之间的差。

所以我是这样开始的:

(display (- (sum-of-squares (list-to 10))
            (square-of-sums (list-to 10))))

现在,在 Scheme 中,没有平方和、平方和或 list-to 函数。因此,下一步将是构建其中的每一个。在构建这些功能中的每一个时,我可能会发现我需要更多地抽象出来。我尽量让事情简单化,这样每个函数只做一件事。当我构建一些可测试的功能时,我会为它编写一个单元测试。当我开始注意到某些数据的逻辑分组以及作用于它们的函数时,我可能会将其推入对象中。

于 2008-09-26T03:40:08.150 回答
3

自从 TDD 被介绍给我以来,我一直都很喜欢它。帮助我计划我的代码,并且每次我修改我的代码时让我的所有测试都返回“成功”,让我放心,让我知道我今天准时回家!

于 2008-11-26T23:34:49.480 回答
2

一厢情愿可能是解决复杂问题的最重要工具。如有疑问,请假设存在一个函数来解决您的问题(首先创建一个存根)。稍后您将返回到它以扩展它。

于 2008-09-26T02:21:20.820 回答
2

一本适合寻找过程的初学者的好书: 测试驱动开发:示例

于 2008-09-26T03:04:54.820 回答
2

我父亲有一堆流程图模板,当他第一次教我编程时,他曾经让我使用这些模板。直到今天,我都画正方形和菱形来构建一个如何分析问题的逻辑过程。

于 2008-09-26T03:48:34.027 回答
2

我认为在编程方面我知道大约有十几种不同的启发式方法,因此我有时会根据我正在尝试做的事情来浏览列表。一开始,重要的是要知道期望的最终结果是什么,然后尝试向后工作以找到它。

我记得一个算法课程涵盖了其中一些方式,例如:

  • 将其简化为已知问题或琐碎问题
  • 分而治之(MergeSort 是这里的经典示例)
  • 使用具有正确功能的数据结构(此处以 HeapSort 为例)
  • 递归(知道琐碎的解决方案并能够减少到那些)
  • 动态规划

组织解决方案并针对奇怪的情况对其进行测试,例如,如果有人认为 L 应该是一个数字,我通常会在编写之前用伪代码来测试这个想法。

设计模式可以是一组方便的工具,用于特定情况,例如需要适配器或将事物组织到状态或策略解决方案中。

于 2008-11-26T23:59:09.990 回答
1

是的.. 好吧,当我开始的时候,TDD 并不存在(或者不那么流行)。TDD 会是从问题描述到代码传递的方式吗?...这不是有点高级吗?我的意思是,当一个“未来的”开发人员几乎不了解编程语言是什么时,会不会适得其反?

hamcrest 怎么样从算法到代码的过渡。

于 2008-09-26T03:16:09.347 回答
1

我认为有更好的方式来说明你的问题。

与其将其定义为“系统”,不如定义用户输入和输出方面的预期。

“在一个窗口上,用户应该从列表中选择一个项目,一个盒子应该告诉他它的成本是多少。”

然后,你可以给他一些决定成本的因素,包括样品项目以及它们最终的成本应该是多少。

(这也是一个非常类似于 TDD 的想法)

于 2009-09-26T02:01:30.080 回答
-3

请记住,如果您获得 5% 的折扣,然后再获得 5% 的折扣,那么您不会获得 10% 的折扣。相反,您支付 95% 的 95%,即 90.25% 或 9.75% 的折扣。因此,您不应该添加百分比。

于 2008-09-26T02:59:57.547 回答