Процесс перехода от проблемы к коду.Как ты этому научился?

StackOverflow https://stackoverflow.com/questions/137375

  •  02-07-2019
  •  | 
  •  

Вопрос

Я преподаю / помогаю студенту программировать.

Я помню, что следующий процесс всегда помогал мне, когда я начинал;Это выглядит довольно интуитивно, и мне интересно, был ли у кого-нибудь еще подобный подход.

  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 ) {
             // .... 
    }


}

Неужели вы пошли на подобный подход?..Научил ли вас кто-нибудь подобному подходу или вы открыли себя ( как это сделал я :( )

Это было полезно?

Решение

Я делал нечто подобное.

  • Выясните правила / логику.
  • Прикинь математику.
  • Затем попробуйте закодировать его.

После того, как вы занимаетесь этим в течение пары месяцев, это просто усваивается.Вы не осознаете, что делаете это, пока не столкнетесь со сложной проблемой, которая требует от вас ее решения.

Другие советы

Я использую подход, основанный на тестировании.

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.Всегда следите за дублированием и удаляйте его.Вы закончили, когда все тесты пройдены, и вы больше не можете думать ни о каких тестах.

Это не гарантирует, что вы создадите наиболее эффективный алгоритм, но до тех пор, пока вы знаете, что тестировать, и все проходит успешно, это гарантирует, что вы получаете правильные ответы.

олдскульный способ ОО:

  • запишите описание проблемы и ее решения
  • обведите существительные, это объекты-кандидаты
  • нарисуйте прямоугольники вокруг глаголов, это сообщения-кандидаты
  • сгруппируйте глаголы с существительными, которые "совершали" бы действие;перечислите любые другие существительные, которые потребовались бы для оказания помощи
  • посмотрите, можете ли вы переформулировать решение, используя форму существительное.глагол (другие существительные)
  • закодируйте это

[этот метод предшествует CRC-картам, но это было так давно (более 20 лет), что я не помню, где я этому научился]

при изучении программирования я не думаю, что TDD полезен.TDD хорош позже, когда у вас появится некоторое представление о том, что такое программирование, но для начала важнее всего иметь среду, в которой вы пишете код и видите результаты в кратчайшие сроки.

Я бы мгновенно перешел от постановки задачи к коду.Взломай его по кругу.Помогите студенту увидеть различные способы составления программного обеспечения / алгоритмов структурирования.Научите студента изменить свое мнение и переработать код.Попробуйте немного рассказать об эстетике кода.

Как только они смогут взломать код....затем представьте идею формальной реструктуризации с точки зрения рефакторинга.Затем представьте идею TDD как способ сделать процесс немного более надежным.Но только после того, как они почувствуют себя комфортно, манипулируя кодом, чтобы делать то, что они хотят.На этом этапе несколько проще указать тесты.Причина в том, что TDD - это Дизайн.Когда вы учитесь, вас на самом деле волнует не столько дизайн, сколько то, что вы можете делать, с какими игрушками у вас есть, чтобы играть, как они работают, как вы сочетаете их вместе.Как только у вас появляется представление об этом, вы начинаете думать о дизайне, и вот тогда TDD действительно начинает действовать.

С этого момента я бы начал вводить микрошаблоны, ведущие к шаблонам проектирования

Я начинаю с самого верха и продвигаюсь вниз.По сути, я начну с написания высокоуровневой процедуры, набросаю детали внутри нее, а затем начну заполнять детали.

Допустим, у меня была эта проблема (заимствована из project euler)

Сумма квадратов первых десяти натуральных чисел равна, 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 нет функций "сумма квадратов", "квадрат сумм" или "список к функциям".Итак, следующим шагом было бы создание каждого из них.При создании каждой из этих функций я могу обнаружить, что мне нужно больше абстрагироваться.Я стараюсь, чтобы все было просто, чтобы каждая функция действительно выполняла только одно действие.Когда я создаю какую-то функциональность, которая поддается тестированию, я пишу для нее модульный тест.Когда я начинаю замечать логическую группировку для некоторых данных и функций, которые воздействуют на них, я могу поместить это в объект.

Я наслаждался TDD с тех пор, как мне его представили.Помогает мне спланировать мой код, и это просто успокаивает меня, когда все мои тесты возвращаются с "успехом" каждый раз, когда я изменяю свой код, давая мне знать, что сегодня я иду домой вовремя!

Принятие желаемого за действительное, вероятно, является самым важным инструментом для решения сложных проблем.Если вы сомневаетесь, предположите, что существует функция для решения вашей проблемы (сначала создайте заглушку).Вы вернетесь к нему позже, чтобы расширить его.

Хорошая книга для начинающих, ищущих процесс: Разработка, основанная на тестировании:На примере

У моего отца была куча трафаретов блок-схем, которыми он заставлял меня пользоваться, когда впервые учил меня программированию.по сей день я рисую квадраты и ромбы, чтобы выстроить логический процесс анализа проблемы.

Я думаю, что существует около дюжины различных эвристик, о которых я знаю, когда дело доходит до программирования, и поэтому я склонен время от времени просматривать список того, что я пытаюсь сделать.С самого начала важно знать, каков желаемый конечный результат, а затем попытаться работать в обратном направлении, чтобы найти его.

Я помню класс алгоритмов, охватывающий некоторые из этих способов, например:

  • Сведите это к известной проблеме или тривиальной задаче
  • Разделяй и властвуй (классическим примером здесь является сортировка слиянием)
  • Используйте структуры данных, которые имеют правильные функции (примером здесь является HeapSort).
  • Рекурсия (знание тривиальных решений и способность сводиться к ним)
  • Динамическое программирование

Организация решения, а также тестирование его в нестандартных ситуациях, напримересли кто-то считает, что L должно быть числом, это то, что я обычно использую для проверки идеи в псевдокоде, прежде чем писать ее.

Шаблоны проектирования могут быть удобным набором инструментов для использования в конкретных случаях, например, когда требуется адаптер или организация работы в соответствии с состоянием или стратегией решения.

ДА..ну, TDD еще не существовало (или не было настолько популярным), когда я начинал.Был бы TDD способом перейти от описания проблемы к коду?...Разве это не немного продвинуто?Я имею в виду, когда "будущий" разработчик едва ли понимает, что такое язык программирования, разве это не было бы контрпродуктивно?

Как насчет hamcrest, который осуществляет переход от алгоритма к коду?

Я думаю, что есть лучший способ изложить вашу проблему.

Вместо того чтобы определять его как "систему", определите, что ожидается от пользователя в терминах входных и выходных данных.

"В окне пользователь должен выбрать товар из списка, и поле должно показать ему, сколько это стоит".

Затем вы можете рассказать ему о некоторых факторах, определяющих затраты, включая образцы товаров и то, какой должна быть их стоимость в конечном итоге.

(это также очень похоже на идею TDD)

Имейте в виду, если вы получите скидку 5%, а затем еще 5%, вы не получите скидку 10%.Скорее всего, вы платите 95% от 95%, что составляет 90,25% или 9,75% скидки.Таким образом, вам не следует добавлять процент.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top