Задание 2 cs193p Winter 2015 Умный Калькулятор

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на 

Задание 2 iOS 8_new.pdf

 Задание 2 — очень трудное, но выполнимое. Если вам удастся выполнить его так, как планировал Пол Хэгерти, то есть в соответствии с логикой Swift, а не логикой того языка программирования (C++, C#, Java, Python и т.д.), с которого вы пришли, то можете считать себя «гуру» в Swift и представлять, что вы стоите на «Эвересте» и «снисходительно» смотрите на остальных. Что я имею ввиду под логикой Swift, которую так изобретательно использует Пол Хэгерти? Если вы смотрели предыдущий его курс по iOS 7, то там он в буквальном смысле «жонглирует» nil, чтобы ваш код из одной строчки  выполнял кучу работы. То же самое здесь, он будет также хитроумно использовать Optionals. Почти в каждом пункте Задания 2 он призывает рассмотреть вариант решения, состоящий из одной — двух строк. Помимо этого, Задание 2 содержит множество подсказок, которые помогут вам почувствовать «дух»  Swift.

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

Результаты выполнения заданий можно посылать на форум Swift[ru] для обсуждения. Выкладывайте решения в Github или давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github. Если у кого-то есть затруднения с этим — обращайтесь на форум, проведем ускоренный курс по выкладывание кода на Github. Если состоится обсуждение ( пока этого на форуме почти нет совсем) — будет интересно.

Специально привела возможное решение Задания 1 ( у вас может быть лучше), чтобы каждый, кто даже «застрял» по какой-то причине,  мог «приступить к выполнению Задания 2.

Рекомендации изучающим курс cs193p iOS 8

Я разместила Stanford CS 193P iOS 7 Лекция 11 —  UITableView и iPad (UISplitViewController, Popover)  на этом сайте. В ней описывается работа c  TableView, с refresh control и т.д. Но самое главное — в ней показан пример создания универсального приложения  для iPhone и iPad. Пользовательский интерфейс строится на двух отдельных storyboards: одна для iPhone с использованием TableViewController и NavigationСontroller, другая — для iPad с использованием TableViewController и UISplitViewController.

В iOS 8 мы больше этого не увидим, у нас будет одна универсальная (а точнее адаптивная) storyboard с универсальным и довольно сложным UISplitViewController. Для того, чтобы понять, как работает этот универсальный  UISplitViewController в iOS 8, нужно знать, откуда он такой взялся, и почему был сделан именно так.  У вас есть возможность подступиться к изучению нового сложного  адаптивного UISplitViewController в iOS 8 через изучение более простого варианта UISplitViewController на iOS 7, который Пол Хэгерти очень подробно и обстоятельно описывает и  демонстрирует на примере просмотра фотографий с Flickr. Кстати, теоретическая часть, описывающая UISplitViewController на iOS 7,  рассказывается на пример Графического Калькулятора, который нам предстоит создать на iOS 8 в Задании 3 или 4.

Методы делегата UISplitViewController считались самыми трудоемкими и обременительными во всем iOS 7,  но они — «цветочки» по сравнению с методами делегата нового UISplitViewController в iOS 8 в контексте адаптивной философии (size classesTraitCollection). У вас появилась возможность заранее подготовиться к их изучению.

Лекция 4 CS193P Winter 2015 — Больше Swift и Foundation Frameworks. (часть 2. AnyObject, as?, is, String.Index)

Title iOS 8

STANFORD UNIVERSITY: Разработка iOS 8 приложений с Swift CS193P

 Лекция 4: Больше Swift и Foundation Frameworks

Профессор Пол Хэгарти (Paul Hegarty)

Лекцию на английском языке и слайды можно найти на  iTunes название  “4. More Swift and Foundation Frameworks”.

Русскоязычный неавторизованный конспект лекций принадлежит сайту bestkora.com/IosDeveloper

Начало: 1 — ая часть лекции (0 — 37 минут) находится здесь.
Этот документ:  продолжение: 2 — ая часть лекции (37 минута — конец ) 

Примечание переводчика. В документе почти каждый слайд точно переводится на русский язык. Текст перевода располагается между двумя горизонтальными линиями сразу вслед за слайдом. Далее следует речь профессора, который повторяет то, что изображено на слайдах, а иногда и сам повторяет одну и ту же мысль в разных вариантах. Этот документ содержит живую речь и не подвергался глубокому редактированию. 

————————————- 37 -ая минута лекции ————————-

Давайте поговорим о наследовании init. Потому что это также сложно. Ниже представлены правила при наследовании  init.

Screen Shot 2015-02-15 at 6.16.20 PM


Инициализация

  • Наследование init.

Если  вы не реализуете никакие назначенные inits, то вы унаследуете все назначенные inits вашего superclass
Если  вы переопределите (override)  все назначенные inits вашего superclass, то вы унаследуете все convenience inits вашего superclass
Если  вы не реализуете ни одного  inits в, то вы унаследуете все  inits вашего superclass
Любой  inits, унаследованный по этим правилам, должен удовлетворять всем правилам на предыдущем слайде

  • Required init.

Класс может пометить один или более  init методов как required
Любой subclass должен реализовать эти упомянутые методы ( даже если они были унаследованы по приведенным выше правилам)


Например, ваш superclass имеет три назначенных (designated) инициализатора с различными аргументами. Если вы переопределите (override) все, то тогда вы наследуете все convenience inits вашего superclass.
Также если вы не реализуете ничего, вы наследуете все назначенные (designated) инициализаторы и все convenience inits вашего superclass в этом случае.
Это правила наследования. Людей это ставит в тупик : » Я реализовал один инициализатор, а почему другие не работают?»
Как только вы реализовали один назначенный (designated) инициализатор, вы не наследуете остальные. Либо все, либо ничего, если дело касается назначенных инициализаторов (designateds).
В отношении convenience inits тоже либо все, либо ничего.
Потому что вы должны либо реализовать все, либо не реализовать ничего, чтобы получить в наследство convenience inits.
Любой init, унаследованный по этим правилам должен принимать в внимание правила на предыдущем слайде.
Возможно иметь то, что называется required init. Если вы поставили ключевое слово required перед  init, то это означает, что subclasses должны реализовать этот  init. 
Вы можете наследовать required init по правилам, указанным выше.
Если вы не реализовали ни одного назначенного инициализатор, то вы наследуете все, в том числе и  required init. Это нормально. Но если вы реализовали какой-то из назначенных инициализаторов, то вы должны выполнить и required inits.

Читать далее

Лекция 4 CS193P Winter 2015 — Больше Swift и Foundation Frameworks. (часть 1)

Title iOS 8

STANFORD UNIVERSITY: Разработка iOS 8 приложений с Swift CS193P

 Лекция 4: Больше Swift и Foundation Frameworks

Профессор Пол Хэгарти (Paul Hegarty)

Лекцию на английском языке и слайды можно найти на  iTunes название  “4. More Swift and Foundation Frameworks”.

Русскоязычный неавторизованный конспект лекции приведен ниже.

Вы можете читать PDF-файл конспекта и использовать его offline

Лекция 4 CS193P Winter 2015 iOS 8.pdf

Начало: 1 — ая часть лекции (0 — 37 минут).
Продолжение: 2 — ая часть лекции (37 минута — конец ) — находится здесь.

Добро пожаловать на лекцию 4 CS193p, Stanford Winter of 2015.

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

Screen Shot 2015-02-10 at 6.28.04 PM

Читать далее

Лекция 3 CS193P Winter 2015 — Применяем MVC. (часть 2)

STANFORD UNIVERSITY: Разработка iOS 8 приложений с Swift CS193P

 Лекция 3: Применяем MVC

Профессор Пол Хэгарти (Paul Hegarty)

Лекцию на английском языке и слайды можно найти на  iTunes название  “3. Applying MVC”.

Это — продолжение: 2 — ая часть лекции (36 минута — конец ), код для Swift 1.2 находится на  Github. Код для Swift 2.0 находится на Github.

Начало: 1 — ая часть лекции (0 — 36 минут) можно посмотреть здесь.

—————————— 36 минута лекции ———————————

Screen Shot 2015-02-07 at 7.58.59 AM

Давайте займемся написанием кода для нашей вспомогательной функции

func evaluate(ops: [Op])  -> (result: Double?, remainingOps: [Op])

И первое, что я сделаю в этой рекурсивной функции, — напишу строку кода для случая невозможности выполнения рекурсии с возвращением nil.

return (nil, ops)

Это строка говорит о том, что я (калькулятор) делаю все, что могу, чтобы оценить ops, который вы мне передали, но я не могу это сделать и возвращаю в качестве результата  nil.
Это будет мой возврат кортежа по умолчанию: в случае отсутствия операндов в стеке или недостаточного их количества и т.д.

Читать далее

Лекция 3 CS193P Winter 2015 — Применяем MVC. (часть 1)

Title iOS 8

STANFORD UNIVERSITY: Разработка iOS 8 приложений с Swift CS193P

 Лекция 3: Применяем MVC в iOS

Профессор Пол Хэгарти (Paul Hegarty)

Лекцию на английском языке и слайды можно найти на  iTunes название  “3. Applying MVC”.

Русскоязычный неавторизованный конспект лекции приводится ниже.

Вы можете читать к PDF-файл конспекта и использовать его offline

Лекция 3 CS193P Winter 2015 iOS 8.pdf

Начало: 1 — ая часть лекции (0 — 36 минут).

Продолжение: 2 — ая часть лекции (36 минута — конец ) — находится здесь.

Код для Лекции 3 находится на Github.

Это лекция 3. Она вся будет посвящена демонстрационному приложению Calculator.

Сегодня сделаем наш калькулятор Сalculator более мощным. Но что более важно, мы заставим его следовать парадигме конструирования  MVC. То есть я покажу, как мы разделим наше приложение на 3 лагеря. Ну, а кроме этого я буду продолжать знакомить вас с возможностями языка Swift, как обычно. Собственно это является задачей первых 3-х лекций с демонстрационным приложением Calculator.
Моя задача показать вам все это в действии, потому что вы можете сколько угодно читать о Swift, iOS, но до тех пор, пока вы не увидите это в действии, не превратите это в приложение, реально вы не будете знать Swift и iOS. Моя задача сделать для вас это реальностью.

Читать далее

Лекция 2 CS193P Winter 2015 — Больше Xcode и Swift, MVC. (часть 3 — Autolayout)

STANFORD UNIVERSITY: Разработка iOS 8 приложений с Swift CS193P

 Лекция 2: Больше Xcode и Swift

Профессор Пол Хэгарти (Paul Hegarty)

Лекцию на английском языке и слайды модно найти на  iTunes название “2. More Xcode and Swift, MVC”.

Это продолжение: 3 — ая часть лекции (44 минута — конец ) —  Autolayout , MVC. Код для Swift 1.2 этой части на GitHub. Код для Swift 2.0 этой части на GitHub.

Начало: 1 — ая часть лекции (0 — 30 минут) — находится здесь, код для этой части на GitHub.

Продолжение: 2 — ая часть лекции (30 минута — 44 минута )- находится здесь, код для этой части на GitHub.

Последняя вещь, которую я собираюсь сделать — это выполнить Autilayout над кнопками: цифровая клавиатура и кнопки с операциями.

Читать далее

Задание 1 cs193p Winter 2015 Калькулятор

Содержание

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 1″На русском языке вы можете скачать здесь:

Задание 1 iOS 8.pdf

Решение Задания 1 для Swift 1.2 и Swift 2.0 находится в посте Задание  1 cs193p Winter 2015 Калькулятор для Swift 1.2 и Swift 2.0.

Задание 1 cs193p Winter 2015 Калькулятор Swift 1.2 и Swift 2.0

Содержание

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 1″На русском языке вы можете скачать здесь:

Задание 1 iOS 8.pdf

Начинаем выполнять Задание 1 с кода, полученного в конце Лекции 2 с учетом уточнений для Swift 1.2. Профессор настоятельно рекомендует не копировать код в первых 2-х Заданиях, а непосредственно печатать, так как это даст хороший опыт освоения среды разработки Xcode. Я все-таки привела на Github код демонстрационного примера, соответствующий окончанию Лекции 2. Это позволит совсем начинающим не «застрять» на самом первом этапе.

Ниже приводится решение всех пунктов задания для тех, кто хочет сравнить свой результат с моим, и окончательный код  Задания 1 на Github.

Пункт 2 обязательный

Ваш калькулятор (calculator) уже умеет работать с числами с плавающей точкой (например, если вы последовательно будете нажимать на клавиши 3 ⏎ 4 ÷  то он покажет правильный результат  0.75), тем не менее, пока нет ввода чисел с плавающей точкой. Это надо исправить. Разрешите вводить только правильные числа с плавающей точкой (напримр,  “192.168.0.1”  — неправильное число с плавающей точкой). Вам нужно добавить новую кнопку с точкой “.”. В этом задании не беспокойтесь о точности.

Прежде всего надо сделать небольшое замечание относительно точки «.» как десятичного разделителя.

Замечание. Если вы будете использовать символ  точки «.» в качестве десятичного разделителя в Задании 1, то оно может работать на симуляторе и не работать на вашем реальном устройстве, если Регион на вашем приборе установлен так, что там не применяется «.» для десятичных чисел. В этом случае приложение закончится аварийно. Но приложение должно работать в любом Регионе.

Для того, чтобы не зависеть от Региона, лучше получать разделитель для десятичных чисел непосредственно в вашем калькуляторе :

Screen Shot 2015-03-25 at 8.13.14 PM

Но вернемся к нашему пункту Задания и попытаемся заблокировать повторный ввод десятичного разделителя, который дальше по тексту мы будем условно называть «точкой», хотя, как мы уже знаем, это — не всегда точка. Для блокировки повторного ввода точки проще всего использовать функцию rangeOfString при вводе любой цифры (к которым относится и точка). Для этого нам понадобится всего одна строка

Screen Shot 2015-08-19 at 9.05.30 AM
Случай ввода в калькулятор числа “.5” работает правильно без дополнительного кода.
Если мы пойдем немного дальше, исследуя десятичный разделитель, то нам захочется иметь кнопку не с точкой «.», а с тем знаком, который принят в этом Регионе. Для этого сделаем outlet для кнопки с условным названием «точка»

Screen Shot 2015-03-25 at 8.21.37 PM

Screen Shot 2015-03-24 at 8.45.26 PM
Мы должны установить заголовок этой кнопки равным decimalSeparator и это можно сделать двумя способами :

  1. с использованием метода viewDidLoad () «жизненного цикла» Controller (об этом будет лекция 8); этот метод срабатывает один раз при загрузке Controller
  2. с использованием Наблюдателя didSet{} Свойста @IBOutlet weak var tochka; этот метод вызывается один раз при  установке этого outlet  со  storyboard

Первый способ связан с добавлением метода viewDidLoad ()

Screen Shot 2015-03-24 at 11.32.10 PM

Второй метод использует Наблюдателя Свойства tochka didSet {}

Screen Shot 2015-03-24 at 11.37.09 PM

Я выбрала второй метод и для проверки поставила на кнопке не «.«, а три символа «Poi«, которые должны заменится на десятичный разделитель decimalSeparator, взятый из NSNumberFormatter()

Screen Shot 2015-03-25 at 7.17.51 AM

Пункт 3 обязательный

Добавьте следующие 4 кнопки с операциями:

  • sin : вычисляет sin операнда на вершине стэка.

  • cos : вычисляет cos операнда на вершине стэка.

  • sqrt : вычисляет √ (квадратный корень) операнда на вершине стэка.

  • π: вычисляет (ассоциируется) с величиной π. Например: 3 π × должно показать на дисплее (display) вашего калькулятора величину π, умноженную на 3, точно также  3  π ×,  и  π 3 × должны показывать величину π, умноженную на 3.

Добавляем заголовки к безымянным кнопкам справа и проверяем, что все ли они подсоединены к Action @IBAction func operate(sender: UIButton)  
Screen Shot 2015-08-16 at 11.12.08 AM
Добавляем еще одну функцию performOperation для операции, соответствующей  возвращению константы (входные операнды не нужны)
Screen Shot 2016-03-10 at 4.33.54 PM
Первая функция для констант — у нее в параметре operation нет входных операндов. Вторая функция для унарный операций — у нее в параметре operation один входной операнд. Третья функция для бинарных операций — у нее в параметре operation два входных операнда.
Хочу обратить ваше внимание на наличие у всех функций атрибута @nonobjc. Пока не обращайте на это внимание, но если вам очень любопытно, то посмотрите пост «Дополнение к Лекции 2 — особенности кода Calculator в Swift 1.2 и Swift 2.0 или как не «застрять» на этом месте.»
Добавляем указанные в этом пункте 4 функции: sin, cos, sqrtπ.

Screen Shot 2015-08-16 at 8.14.27 PM
Кроме этого добавим операцию ± замены знака числу, когда оно полностью введено, что составляет часть дополнительного пункта 3 Задания 1.

Теперь объясним, почему при вызове функций performOperation входный параметр оформлен как замыкание без круглых скобок. Дело в том, что если последним входным параметром для функции является замыкание, то его можно вынести за круглые скобки. Для функций performOperation это единственный входной параметр, поэтому скобки исчезают. Такой способ оформления вызова функций в Swift называется trailing closure (хвостовое замыкание), и как увидим дальше, используется повсеместно.

Для функций sincossqrt из стандартной библиотеки известен тип входных параметров (Double) и тип возвращаемого значения (Double), что полностью совпадает с нашими требованиями, поэтому для этих функций можно не использовать замыкание, а оставить название функции в круглых скобках. Отметим, что функции sin и cos в качестве входного параметра используют угол, представленный в радианах.

Screen Shot 2015-08-16 at 10.16.54 PM

Запускаем калькулятор и проверяем  предложенные в этом пункте комбинации
3 π ×  
3 ↲ π x   
π 3  x

Screen Shot 2015-08-17 at 8.31.37 PM

Код этого пункта задания на Github.

Пункт 4 обязательный

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

Добавьте UILabel на верхнюю часть  storyboard, сразу чуть ниже метки дисплея и выравняйте ее по голубым направляющим линиям слева и сверху. Задайте хвостовой, лидирующий зазоры и вертикальный зазор между метками. Кнопки нужно разместить заново: либо с помощью методики «сетки» или просто в верхний левый угол.

Создаем outlet для новой метки с именем history

@IBOutlet weak var history: UILabel!

Screen Shot 2015-08-16 at 10.29.26 PM

 Добавляем метод addHistory для накопления ввода операндов и операций в тексте метки history:

Screen Shot 2015-08-17 at 5.26.20 PM

Этот метод написан с учетом дополнительного пункта 2 этого Задания, в котором предполагается добавлять знак равенства «=» при нажатии пользователем на любой клавише с операциями. Поэтому предполагаем, что знак «=» может находится в тексте метки от предыдущей операции, и убираем его, чтобы избежать повторного употребления.
Метка history формируется при вводе операнда:
Screen Shot 2016-03-10 at 4.51.59 PM
и операции:
Screen Shot 2015-08-17 at 5.40.40 PM
Запускаем. Получаем требуемый результат.
Screen Shot 2015-08-17 at 8.42.36 PM
Замечание. Установленная таким образом метка history при отсутствии в ней информации сжимается, и цифровая клавиатура калькулятора немного поднимается вверх, а при появлении информации в метке history цифровая клавиатура калькулятора немного поднимается вниз. Это не очень хорошо. Нужно поместить пробел » » ( именно » «, а не «») в метку на  storyboard.
Screen Shot 2015-08-17 at 8.46.01 PM
Усекаем головную часть строки history, чтобы видеть последние элементы ввода опрандов и операторов.
Есть еще один момент — лидирующие нули. Сейчас возможен ввод чисел с лидирующими нулями (например, “000” или “0367”).
Я предлагаю для уничтожения лидирующих нулей следующий код
Screen Shot 2015-02-11 at 7.23.41 PM

Код этого пункта задания на Github.

Пункт 5 обязательный

Добавьте кнопку “C”,  которая будет чистить все  (ваш дисплей ввода, новую метку, которую вы только что добавили). При нажатии кнопки “C”. калькулятор должен находится в таком же состоянии как при старте.

Добавляю снизу еще ряд кнопок и одной из них даю название «С». Создаем Action clearAll. Внутри метода помещаем код и не забываем очистить метку history, но не пустой строкой «», а пробелом » «.
Screen Shot 2015-08-19 at 10.24.40 AM

Код этого пункта задания на Github.

Пункт 1 дополнительный (extra credit)

Дайте возможность пользователю нажимать кнопку  “backspace” если он ввел неверную цифру. Это вовсе не кнопка “undo,” так что если пользователь нажал неверную кнопку с операцией , то его ждет неудача! Вам решать как вы будете разруливать случай, когда пользователь кнопкой “backspace” полностью удалил число и все еще находится в процессе ввода числа , но оставлять дисплей (display) абсолютно пустым было бы не очень дружелюбно.                                             

Одной из добавленных снизу кнопок даю название «back«. Создаем Action backSpace
Screen Shot 2015-08-19 at 2.13.51 PM
Внутри метода помещаем код

Screen Shot 2015-08-19 at 2.18.22 PM

Этот метод работает только если пользователь находится в процессе набора числа.

Код этого пункта задания на Github.

Пункт 2 дополнительный (extra credit)

Когда пользователь нажимает кнопку операции (operation button), разместите знак pавно = в конце текстовой метки UILabel, которая добавляется в Обязательном задании ( #4). Таким образом пользователь сможет понять, является ли число на дисплее калькулятора результатом вычислений или это число только что ввел пользователь. Не позволяйте знаку “=” многократно появляться в конце метки UILabel.

Этот пункт выполнен в обязательном пункте 4. Мы добавили знак «=» при нажатии кнопки с операцией
Screen Shot 2015-08-17 at 5.40.40 PM
И предотвратили многократное его появление в методе addHistory
Screen Shot 2015-08-17 at 5.26.20 PM
В результате пользователь сможет понять, является ли число на дисплее калькулятора результатом вычислений или это число только что ввел пользователь.
Screen Shot 2015-02-12 at 1.50.41 PM

Код этого пункта задания на Github.

Пункт 3 дополнительный (extra credit)

 Добавьте +/- операцию, которая меняет знак числа на дисплее (in the display). Будьте более внимательны с этим. Если пользователь находится в середине ввода числа, вы возможно, захотите изменить знак этого числа и позволить ему продолжать его ввод, не прибегайте к “принудительному” “enter” как в других операциях. Но если вы не находитесь в середине ввода числа, то это будет работать просто как любая другая унарная операция ( например, sqrt).

Одной из добавленных снизу кнопок даю название «±«. Создаем Action  plusMinus
Screen Shot 2015-08-18 at 11.27.00 AM
Внутри метода помещаем код
Screen Shot 2015-08-18 at 11.29.41 AM
Код довольно простой: если вы находитесь в процессе ввода числа (userIsInTheMiddleOfTypingANumber ), то вы меняете знак. Если нет, то пересылаете вашу кнопку методу operate. Но для того, чтобы  «±» работала как операция, необходимо добавить ее в операции.
Screen Shot 2015-08-18 at 11.31.35 AM

Код этого пункта задания на Github.

 Пункт 4 дополнительный (extra credit)

Измените вычисляемую переменную экземпляра класса displayValue так, чтобы она была Optional Double, a не Double. Его значение должно быть nil если содержимое display.text не может быть интерпретировано как Double (вам нужно использовать документацию для понимания кода NSNumberFormatter ). Установка этого значения в nil должна очищать display.

Делаем  displayValue так, чтобы она была Optional Double — Double?, a не Double.
Начнем с get {  }
Screen Shot 2015-02-12 at 4.47.43 PM
Замечаем, что текст нашего дисплея тоже Optional, но  String — String?, поэтому вначале «развертываем» display.text и получаем displayText, который имеет тип String. Затем подаем displayText как входной параметр на вход NSNumberFormatter .
Screen Shot 2015-02-12 at 5.11.59 PM
«Pазвертываем» результат преобразования  NSNumberFormatter и получаем displayNumber, который имеет тип NSNumber
Делаем его Double и возвращаем.
Screen Shot 2015-02-12 at 5.19.17 PM
Примечание. Результат преобразования  NSNumberFormatter можно не разворачивать, а использовать так называемую chaining Optionals (цепочку Optionals), это будет в Задании 2. 
Screen Shot 2015-02-13 at 7.34.59 AM
Перейдем к set {  }. Код достаточно простой и понятный: если newValue  не равно nil,  то используем String interpolation (интерполяцию строк) для преобразования числа в строковое значение, в противном случае — очищаем дисплей.
Screen Shot 2015-08-19 at 10.40.21 AM

Замечание 1. Но здесь возникает та же проблема, что и с меткой history, при отсутствии в ней информации она сжимается до нулевых размеров, и появляется, если в ней что-то есть. Нужно поместить пробел » « ( именно » «, а не «») на наш дисплей. Поэтому внесем изменения в код установки displayValue = » «.

Замечание 2. Оставить просто пустым дисплей все-таки не очень дружелюбно, хотя именно в этом и состоит последний дополнительный пункт Задания, поэтому в метке history  с помощью добавления » Errror» мы укажем, что в этом случае возникла ошибка.
Теперь во всем коде ViewController вместо displayValue 0 ставим
displayValue = nil, кроме метода clearAll

 

Screen Shot 2016-03-10 at 5.00.37 PM

Мы присваиваем значение nil вычисляемой переменной displayValue в случае, если у операции нет необходимого числа операндов, если сама операция возвращает значение, которое невозможно преобразовать в Double или если осуществлен ввод текста, который нельзя преобразовать в Double.
Теперь мы можем запускать калькулятор со значением «0» на дисплее, а в случае ошибки экран будет пустым, но появится сообщение об ошибке в строке, отображающей историю ввода операндов и операций.

Screen Shot 2015-08-19 at 3.14.19 PM

 

Замечание 3. Один из пользователей сайта прислал такой комментарий :»при вычитании 8.2 минус 8.5 результат получается -0.300000000001.
Почему возникает этот случай? при этом 5.2-5.3 результат ровно -0.3. я не очень понимаю…»

Ответ. Действительно так, любопытно. Это связано с точностью бинарного представления числа с плавающей точкой. Если вы включите отладчик, то увидите, что число 8.2 представлено как 8.1999999999999993, а 8.5 как 8.5, так что разница будет -0.30000000000000071. Но в Double 15 десятичных значащих цифр. При вычитании близких чисел (8.2 и 8.5) точность представления разности  чисел снижается (может быть до 12 -13 значащих цифр), а нам показывается представление 15 десятичными значащими цифрами, так что цифры 71 находятся за пределами точности числа Double, но именно они и дают нам в конце 1. Кстати, число 5.2 представляется как 5.2000000000000002, а а 5.5 как 5.5, так что разница будет -0.29999999999999982, но в этом случае округление выдаст правильный результат (нам просто повезло). Для преобразования числа (8.2 -8.5) в строку мы используем String interpolation «\(newValue)», которая пытается представить все 15 десятичных цифр после точки, что неверно, так как исходное число содержало только 15 верных значащих цифр 8.20000000000000. К сожалению, мы не можем управлять форматом вывода в String interpolation, но можем получить более гибкий результат с помощью NSNumberFormatter.

Screen Shot 2015-08-19 at 3.41.43 PMМы можем использовать NSNumberFormatter со специальными свойствами при выводе результатов на displayВ NSNumberFormatter можно настраивать максимальное количество цифр после точки ( maximumFractionDigits ).В случае больших чисел нам нужны разделители групп цифр (groupingSeparator), если после точки выводится очень много знаков, то мы бы хотели ограничиться 10 знаками после точки, некоторые функции, например, √ могут возвращать значение Nan при отрицательном аргументе и нам надо указать, что это ошибка Error (notANumberSymbol). Мы получаем NSNumberFormatter со специальными свойствами при помощи функции numberFormatter()

Замечание 3. Необходимо скорректировать функцию addHistory, так как помимо знака «=» мы еще добавили строку «Error» . Необходимо уметь убирать их перед вводом нового значения, предполагая, что они не обязательно могут находится в конце строки

Screen Shot 2015-08-19 at 5.14.33 PM

 

Код этого пункта задания на Github.

————————————————————

Задание 1 для iOS 9  и Swift 2.0

Автоматически преобразуем код Swift 1.2 в Swift 2.0 с помощью меню Edit -> Convert -> To Latest Swift Syntax
Преобразования коснулись только работы со строками
Swift 1.2
Screen Shot 2015-08-19 at 6.53.23 PM
Swift 2.0
Screen Shot 2015-08-19 at 6.56.38 PM
Код для Swift 2.0 находится на Github.
На русском языке вы можете скачать здесь:

Задание 1 iOS 8.pdf

Результаты выполнения заданий можно посылать на форум Swift[ru] для обсуждения. Просьба давать развернутую оценку присланным результатам и сравнивать решения.

Форум для обсуждения лекций и заданий

ВНИМАНИЕ ОБСУЖДЕНИЕ лекций и заданий этих курсов будет проводится на форуме Google Group  Swift[ru].

Там можно задавать вопросы и выкладывать варианты заданий в Github или Dropbox.