Урок 16. Функции.
Часть 1

18 Февраля 2023

Задача 16.1 📚

Создайте функцию, которая будет выводить на консоль сумму следующих чисел:

				
					let numberOne = 78
let numberTwo = 44
				
			

Функция должна быть без параметров и без возвращаемых значений. 

				
					let numberOne = 78
let numberTwo = 44

func printSumOfNumbers()  {
    let sum = numberOne + numberTwo
    print(sum)
}
				
			

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

Давайте рассмотрим не совсем удачное имя для функции:

				
					func sum() {
    let sum = numberOne + numberTwo
    print(sum)
}
				
			

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

Обратите внимание на синтаксис, следующий код будет не корректным:

				
					let numberOne = 78
let numberTwo = 44
func printSumOfNumbers (){
    let sum = numberOne + numberTwo
    print(sum)}
				
			

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

Задача 16.2 📚

Создайте функцию, которая будет возвращать рандомное значение от 0 до 100 типа Double. 

				
					func getRandomInt() -> Double {
    Double.random(in: 1...100)
}
				
			
Имя функции говорит нам о том что мы получаем данные. Функция возвращает тип Double. Параметры для функции в данном контексте не нужны. Так как внутри функции всего одна очевидная строка с типом Double то компилятор понимает что возвращает функция, поэтому  return писать не нужно. Обратите внимание на синтаксис, скобки с параметрами должны плотно прилегать к имени функции. Скобки лучше размещать на разных строчках, следующий код будет выглядеть менее читабельно:
				
					func getRandomInt() -> Double { Double.random(in: 1...100) }
				
			

Такой код тяжелее воспринимается глазом, и нужно будет затратить больше времени на понимание что здесь происходит, поэтому старайтесь не экономить строчки кода на таких моментах. Лучше сделать объемней, но понятней.

Задача 16.3 📚

Для решения используйте цикл for in где в качестве диапазона определите от 1 до переданного пользователем значения.

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

				
					func printPrimeNumbers(value: Int) {
    for number in 1...value {
        print(number)
    }
}
				
			

Функция принимает в качестве параметра целое число. Что бы получить каждый элемент мы используем диапазон for in с начальным значением 1 и конечным value, то есть диапазон будет зависеть от входного параметра. 

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

Представленный синтаксис корректный, и желательно придерживаться его. Если у вас съехал код и вы не знаете какие отступы должны быть, то выделите код и зажмите control + i. Таким образом все встанет на свои места.

Задача 16.4 📚

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

				
					func checkName(user: String) -> Bool {
    user.count <= 4
}
				
			

Так как выражение user.count <= 4 само по себе возвращает логическое значение, то ключевое слово return здесь писать не нужно, так же как и создавать лишние свойства. 

Создавать условные конструкции так же не нужно:

				
					func checkName(user: String) -> Bool {
    if user.count <= 4 {
        return true
    } else {
        return false
    }
}
				
			

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

				
					func checkName(user: String) -> Bool {
    user.count <= 4 ? true : false
}
				
			

Одним словом если вы видите в ваших выражениях и true и false одновременно, то стоит задуматься об оптимизации. 

Задача 16.5 📚

Для решения используйте цикл for in где в качестве диапазона определите от 1 до переданного пользователем значения.

Создайте функцию, которая будет принимать в качестве параметра целое число, и возвращать массив со всеми простыми числами этого значения. Например если мы передадим в функцию 5 то при вызове данной функции она вернет массив [1, 2, 3, 4, 5].

Присвойте результат работы функции новому свойству.

				
					func getNumbers(from value: Int) -> [Int] {
	var numbers: [Int] = []
	
	for number in 1...value {
		numbers.append(number)
	}
	return numbers
}

let numbers = getNumbers(from: 5)
				
			
Данная функция getNumbers(from:) принимает один целочисленный аргумент value и возвращает массив целых чисел [Int]. Функция заполняет массив числами от 1 до value включительно, используя цикл for и метод append() для добавления чисел в массив. Когда функция вызывается с аргументом 5 в строке let numbers = getNumbers(from: 5), она создает массив чисел [1, 2, 3, 4, 5] и сохраняет его в константу numbers. Не совсем удачным решением будет использование цикла while:
				
					func getNumbers(from value: Int) -> [Int] {
	var numbers: [Int] = []
	var count = 1
	
	while number <= value {
		numbers.append(number)
		count += 1
	}
	
	return numbers
}

let numbers = getNumbers(from: 5)
				
			

Такое решение в целом тоже рабочее, но когда вам известен диапазон, то лучше использовать цикл for in, таким образом у вас будет из коробки свойство, которое считает итерации, и не придется создавать дополнительного свойства number.

В этой функции мы инициализируем переменную count со значением 1, а затем используем цикл while, чтобы добавить числа от 1 до value включительно в массив numbers. Как только count становится больше value, цикл завершается, и функция возвращает массив numbers.

 

Задача 16.6 📚

Для решения этой задачи вам потребуется цикл for in и новый словарь. Внутри цикла определите условную конструкцию if. Не забудьте вернуть новый словарь. 

Создайте функцию, которая будет принимать следующий словарь со студентами:

				
					let students = ["Tim": Int.random(in: 1...100),
                "Sem": Int.random(in: 1...100),
                "Taylor": Int.random(in: 1...100),
                "Stan": Int.random(in: 1...100)]
				
			

Ключом является имя студента, а значением его проходной балл. 

Функция должна возвращать словарь с теми же студентами, но в качестве значения должен выступать статус либо hight либо low (для этого можно определить перечисление), если у студента баллы выше или равны 90 то мы для него определяем группу hight, если ниже то low. 

Присвойте результат работы функции новому свойству. 

				
					let students = ["Tim": Int.random(in: 1...100),
                "Sem": Int.random(in: 1...100),
                "Taylor": Int.random(in: 1...100),
                "Stan": Int.random(in: 1...100)]

// Определяем перечисление для статусов
enum Status {
    case high
    case low
}

// Функция, которая принимает словарь со студентами и возвращает словарь со статусами
func getStatuses(students: [String: Int]) -> [String: Status] {
    var statuses: [String: Status] = [:]
    
    for (name, score) in students {
        if score >= 90 {
            statuses[name] = .high
        } else {
            statuses[name] = .low
        }
    }
    
    return statuses
}

let studentStatuses = getStatuses(students: students)
				
			

Здесь мы сначала определяем перечисление Status, которое будет использоваться для определения статуса студента (high и low). Затем мы определяем функцию, которая принимает словарь со студентами и возвращает словарь со статусами. Внутри функции мы перебираем словарь со студентами, то есть проходим по каждому элементу словаря, и определяем статус для каждого студента на основе его проходного балла. После цикла мы возвращаем словарь со статусами. 

Будет ошибкой если вы определите дополнительное условие в ветке else:

				
					        if score >= 90 {
            statuses[name] = .high
        } else if score < 90 {
            statuses[name] = .low
        }
				
			

Условие в ветке else лишнее, потому что первая ветка исключает все варианты выше 90, остальные все попадут в ветку else.

Если вы реализовали цикл следующим образом, то это тоже будет считаться рабочим вариантом:

				
					for student in students {
	if student.value >= 90 {
		statuses[student.key] = .high
	} else {
		statuses[student.key] = .low
	}
}
				
			

Но, на мой взгляд, этот код менее читабельный чем первый предложенный. 

Можно использовать так же тернарный оператор в решении, это намного сократит ваш код:

				
					for (name, score) in students {
	statuses[name] = score >= 90 ? .high : .low
}
				
			

Может быть и вот такое решение:

				
					for (name, score) in students {
	score >= 90
	? statuses.updateValue(.high, forKey: name)
	: statuses.updateValue(.low, forKey: name)
}
				
			

Метод updateValue по не существующему ключу добавить новое значение, таким образом образуется пара. 

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

Поддержите наш проект, и помогите изменить подход к обучению!

Развивайся вместе с нами

Поддержите наш проект, и помогите изменить подход к обучению!

Address List

Social Networks

Поддержите наш проект, и помогите изменить подход к обучению!