DADAHAE's Log
비싼 장난감 가지고 노는 중 (❁´▽`❁)*✲゚*
[TIL] 22-09-23: 오픈소스, Swift(반복문, 조건문)
2022-09-23 금요일
2주차

 

 

 

1교시, 2교시, 3교시

Open Source

세상에 공짜는 없어요

 

오픈 소스는 왜 중요한가?

open source(Linux) ↔ closed source (MS)

시작부터 오픈소스로 내놓는 회사도 있고, 어느 정도 커지면 내놓는 경우도 있다. 오픈소스로 낼 때 보안적인 것을 조심해야 한다.

활용한 오픈소스의 라이선스에 따라 출처 설명과 소스코드 공개 필요하다.

 

 

오픈소스

Open Source
  • 원래 오픈 소스 소프트웨어(Open Source Software, OSS)를 뜻하는 용어
  • 오픈 소스 소프트웨어는 공개적으로 엑세스할 수 있게 설계되어 누구나 자유롭게 확인, 수정, 배포할 수 있는 코드
    • 확인만 할 수 있게 오픈한 코드는 오픈소스가 아니다. 수정할 수 있어야 오픈소스이다.
  • 오픈 소스 소프트웨어는 동료 평가(peer review)와 커뮤니티 기반 프로덕션에 의지하므로, 분산된 동시에 협업 방식으로 개발
    • 혼자 다 만드는게 아니라 누구든지 코드를 확인하고 수정할 수 있으므로 불특정 다수가 함께 만든다. like wikipedia
  • 단일 작성자 또는 기업이 아닌 커뮤니티가 개발하므로 독점적 소프트웨어보다 저렴하고, 유연하며, 지속성이 있다.
    • 독점적 소프트웨어(private, colsed)

우리가 쓰는 스위프트도 오픈소스이다.

자바스크립트로 프로젝트를 하면 npm이라는 사이트를 들을 수 있다.

 

 

오픈 소스 소프트웨어

Open Source Software
  • 오픈 소스 소프트웨어는 최종 사용자가 소스 코드를 합법적으로 사용할 수 있도록 특별한 라이센스를 통해 릴리즈
  • 대표적인 OSS 라이센스
    • 추가 비용없이 소스 코드 형식으로 제공
      • 사용자는 소프트웨어를 구성하는 코드를 볼 수 있으며, 원하는 경우 얼마든지 변경 가능
    • 소스 코드를 새 소프트웨어에 다른 용도로 사용 가능
      • 누구든 해당 소스 코드를 활용해 자신의 프로그램을 만들고 이를 배포 가능
  • 오픈 소스 소프트웨어가 반드시 무료로 제공되는 실행 가능한 소프트웨어라는 의미는 아니다.
  • 그러나 그 소스 코드는 무료로 제공되어야 한다!

 

자유 소프트웨어

Free Software
  • 프리 소프트웨어 운동
    • 1970년대 해커 문화에서 시작
    • 대표적인 인물 : Richard Stallman
    • 무료가 아니라 사용자의 자유를 강조함
  • 소스 코드를 변경하고, 변경한 소프트웨어를 공유하려면 원래 프로젝트에 해당 변경 사항을 다시 공유해야만 한다. (OSS와 다른 점)
  • → 뜯어고친 것도 공개해야지.
  • OSS와 가치 공유로 “프리 오픈 소스 소프트웨어(Free and Open Source Software, FOSS)”라는 용어가 널리 사용되었다.

 

오픈 소스 개발 모델의 작동방식

  • 오픈 소스 개발 모델은 오픈 소스 커뮤니티 프로젝트에서 오픈 소스 프로젝트를 개발하기 위한 프로세스
  • 이러한 소프트웨어 오픈 소스 라이센스로 출시되어, 누구든지 소스 코드를 보고 수정이 가능하다.
  • 대부분의 오픈 소스 프로젝트는 Github에서 호스팅되며, 여기에서 저장소(Repository)에 접속하거나 커뮤니티 프로젝트에 참여할 수 있다.
    • 깃허브 중심으로 호스팅된다.
    • 대표적인 예시) Linux, Kubernetes

 

오픈 소스의 가치

  • 동료평가
  • 투명성
  • 안전성
  • 유연성
  • 비용절감
  • 협업

 



 

4교시, 5교시, 6교시

Swift

제어 흐름

목표

Swift의 제어 흐름

  • 앞서 배운 것
    • 다양한 종류의 연산자
  • 이번에 배울 것
    • 대부분의 프로그래밍 기술은 하나 이상의 조건을 기반으로 결정해가는 코드를 작성하는 것이다.
      • 어떤 코드를 실행할 지
      • 몇 번을 수행할 지
      조건이 숫자로 딱 나눠진다~
    • 이는 프로그램의 흐름을 통제하는 것이므로 제어흐름(control flow)이라고 한다.
    • 일반적으로 제어흐름은 코드를 몇 번 실행할지에 대한 반복 제어(looping control)와 어떤 코드를 실행할지에 대한 조건부 제어 흐름(conditional flow control)으로 나뉜다.

 

🦁 이 기간에 무엇인가 해결되지 않는다고 생각해도 포기하지 말자. 꽃 피우는 시기는 각자 다 다르다.

 

 

 


 

 

반복 제어 흐름

for-in 반복문

아주 대표적이고, 다른 프로그래밍 언어에서도 for가 나오면 반복문이다. for만 나오는 언어가 많다.

Swift에서는 for에 in까지 합쳐진 것으로 사용한다.

  • 반복문은 지정된 조건에 만족할 때까지 반복적으로 수행하는 구문이다.
  • for-in 반복문은 어떤 컬렉션숫자 범위에 포함된 일련의 항목들을 반복하는 데 사용한다.
    • ‘1…5’, ‘1..<10’ 이런게 들어간다고 보면 된다.
  • for-in 반복문은 배열이나 딕셔너리같은 컬렉션을 가지고 작업할 때 특히 더 유용하다.
for 상수명 in 컬렉션 또는 범위 {
	// 실행될 코드
}
  • 상수명(constant name)
    • 반복문이 실행되는 컬렉션 또는 범위의 현재 항목(또는 값)을 담게 될 상수
  • 컬렉션(collectin) 또는 범위(scope)
    • 문자열들의 배열, 범위 연산자, 문자열 자체 등

 

 

범위(scope)를 쓰는 예시를 들어보겠다.

for index in 1...5 {
	print(index)
}

위 코드를 살펴보자.

현재 반복문의 범위는 1…5이다. 반복문 내부의 코드가 총 5번 수행된다. 1,2,3,4,5의 숫자가 차례로 index에 할당되고 index 변수는 반복문 내부에서 사용된다.

현재 반복문 내부 코드는 index를 출력하라고 한다. 그럼 출력결과는 어떻게 나올까?

1
2
3
4
5

범위 1…5에서 가장 처음 숫자 1이 index에 할당된다. print(index) 코드가 수행되고 나면 다음 차례인 2가 index에 할당된다. 이를 5까지 반복하면 위와 같이 출력이 나옴을 확인할 수 있다.

 

 

또 다른 예시가 있다.

for index in 1...5 {
	print("Value of index is \\(index)")
}

/* 출력결과

Value of index is 1
Value of index is 2
Value of index is 3
Value of index is 4
Value of index is 5
*/
  • for index in 1…5
    • 현재의 항목을 index라는 이름의 상수에 할당한다.
    • 이 구문에서는 닫힌 연산자 범위를 이용하여 1에서부터 5까지의 숫자 범위로 반복할 것을 선언하고 있다.
  • print("Value of index is \(index)")
    • 반복문 안에서는 index 상수에 할당된 현재 값을 사용한다.

 

컬렉션(Collection)을 쓰는 예시를 살펴보자.

var integers = [1,2,3]    // 배열 (Array)
let people = ["dadahae": 24, "kangvic": 24, "bomi":25]   // Dictionary
// key = ["dadahae", "kangvic", "bomi"]
// value = [24, 24, 25]

for integer in integers {
	print(integer)
}

// Dictionary의 item은 key와 value로 구성된 튜플 타입입니다.
for (name, age) in people {
	print("\\(name): \\(age)")
}

배열, 딕셔너리와 같은 애들을 컬렉션(Collection)이라고 부른다.

  • (name, age)
    • Tuple
    • Dictionary 타입인 people에서 key, value 2가지 값을 동시에 가져온다.
    • 반복문에서 딕셔너리의 key, value의 값을 name, age의 변수로 가진다.

위 코드의 출력 결과를 살펴보자.

1
2
3
dadahae: 24
kangvic: 24
bomi: 25

잘~ 출력된다.

 

 

다시 돌아와서 for-in 반복문은...

  • 현재 항목에 대한 참조체를 저장하기 위해서 상수명을 반드시 선언해야 하는 것은 아니다.
    • 옵션이라는 뜻이다.
  • 현재 항목에 대한 참조체가 for 반복문 안에서 필요하지 않다면 밑줄 문자로 대체할 수 있다.
    • 안쓸거면 밑줄로 대체하자.
var count = 0

for _ in 1...5 {
	// 현재 값에 대한 참조체가 필요없다.
	count += 1
}

 

 

 

while 반복문

  • for 반복문은 프로그램 내에서 몇 번 반복해야 하는지 알고 있을 때 유용하다.
  • whlie 반복문은 어떤 조건에 만족할 때까지 반복해야 하는 코드가 있는데, 그 조건을 충족할 때까지 몇번을 반복해야 하는지를 알 수 없는 경우를 위해 제공된다.
  • while 반복문은 지정된 조건에 만족할 때까지 일련의 작업을 반복한다.
while 조건문 {
	// 실행될 스위프트 구문
}
  • 조건문
    • true 또는 false를 반환하는 표현식
  • 실행될 스위프트 구문
    • 조건문이 true인 동안에 실행될 코드

 

예시를 살펴보자.

var myCount = 0

while myCount < 100 {
	myCount += 1
}

myCount가 0,1,2,3,4, … , 98, 99일 때까지 내부 코드를 반복하고, myCount가 100이되면 while 구문이 끝이 난다.

  • while myCount < 100
    • myCount 변수가 100보다 작은지 평가한다.
    • 만약 100보다 크다면 괄호 안의 코드를 건너뛰고 아무런 작업을 하지 않고 반복문을 종료하게 된다.
  • myCount += 1
    • myCount 변수가 100보다 크지 않다면 괄호 안의 코드가 실행되며, 프로그램 흐름을 while 구문으로 되돌려서 myCount의 값을 평가하는 작업을 반복하게 된다.
    • 이 과정은 myCount의 값이 100보다 크거나 같을 때 반복되며, 그 순간이 되면 반복문이 종료된다.
🦁 ‘myCount < 100’이 헷갈린다면 ‘myCount < (99+1)’로 작성해보자. 생각하기 더 편해진다.

 

 

while integers.count > 1 {
	integers.removeLast()
}

‘integers.count > 1’가 조건문으로 들어간다면… while 내부에 integers 값에 변화를 주는 구문이 있어야 한다.

 

 

 

repeat-while 반복문

  • repeat-while 반복문은 Swift 1.x 버전의 do .. while 반복문을 대체한 것이다.
    • repeat-while은 Swift 1.x 버전에서는 없었고, 2.x 버전부터 나왔다.
  • repeat-while 반복문은 while 반복문을 거꾸로 한 것이라고 생각하면 이해하기 쉽다.
    • whlie 반복문 : 반복문 안의 코드를 실행하기 전에 표현식을 평가한다.
    • repeat-while 반복문 : 반복문 안의 코드가 언제나 적어도 한 번은 실행되야 하는 상황을 위해 사용한다.
  • 예를 들어, 배열 안의 항목들 중에 특정 항목을 찾을 때까지 둘러봐야할 경우, 적어도 배열의 첫 번째 항목을 검사해봐야 한다.
repeat {
	// 실행될 스위프트 구문
} while 조건문
var index = 10

repeat {
	index -= 1
} while (index > 0)

/* index의 변화

10
9
8
7
6
5
4
3
2
1
0

*/

 

 

repeat {
	integers.removeLast()
} while integres.count > 0

나중에 위 코드가 문제가 되는 이유를 알 수 있을 것이다.

 

 

 


 

 

반복문에서 빠져나오기

break 구문

  • 반복문을 만들었는데 반복문이 종료되는 조건에 만족하기 전에 어떤 조건에서 반복문을 빠져나와야 할 경우가 있다.
    • 예시1 - 무한 반복을 만들었을 경우
    • 예시2 - 네트워크 소켓의 활성화를 지속적으로 점검해야 할 경우, 네트워크 활성화가 감지되면 모니터링하는 반복문에서 빠져나와 다른 작업 실행
  • break 구문은 반복문에서 빠져나와 반복문 다음의 코드로 이동하여 실행을 계속하게 한다.
var temp = 0

for index in 0..<100 {
	temp += index

	if temp > 100 {
		break
	}

	print("temp = \\(temp)")
}

 

 


 

 

다음번 반복문 처리로 건너뛰기

Continue 구문

  • continue 구문은 반복문의 나머지 코드를 건너뛰고 반복문의 처음으로 돌아가게 한다.
var index = 1

while index < 20 {
	index += 1

	if (index % 2) != 0 {   // (1)
		continue
	}

	print("index = \\(index)")  // (2)
}
  • (1)
    • index의 값을 2로 나눈 나머지가 있으면 continue 구문이 실행되어 반복문 안에서 이후 내용을 건너뛰고 while 반복문의 시작 지점으로 돌아가서 (index의 값이 20보다 작아질 때까지) 다시 반복문을 수행한다.
  • (2)
    • index의 값이 짝수일 때만 호출된다.

 

 


 

 

조건부 흐름 제어

if 구문 사용하기

  • If 구문은 C, Objective-C, C++, 자바 등 다른 프로그래밍 언어의 if 구문과 유사하다.
  • Swift의 if 구문은 다른 프로그램 언어와 다르게, if 구문 안의 실행될 코드가 한 줄이라고 해도, 중괄호{..}가 필수다.
  • 기본적으로 조건식(Boolean expression)이 true로 판단되면 구문 내의 코드가 실행된다.
  • 구문내의 코드는 중괄호{..}로 묶인다.
  • 조건식이 false로 판단되면 구문 내의 코드는 건너뛴다.
if 조건식 {
	// 조건식이 true일 때 실행될 스위프트 구문
}

 

 

let x = 10

if x > 9 {
	print("x is greater than 9!")
}

 

 

if … else … 구문 사용하기

  • 변형된 if 구문은 if 구문의 조건식이 false로 판단될 때 수행할 코드를 지정할 수 있게 해준다.
if 조건식 {
	// 조건식이 true일 때 실행될 스위프트 구문
} else {
	// 조건식이 false일 때 실행될 스위프트 구문
}
let x = 10

if x > 9 {
	print("x is greater than 9!")
} else {
	print("x is less than 9!")
}

 

 

 

if … else if … 구문 사용하기

  • 다양한 조건을 바탕으로 결정해야 할 때 쓸 수 있다.
  • 많은 양의 조건문이 있는 경우에는 번거로울 수 있다. 이런 경우 swifch 구문을 활용할 수 있다.
if 조건식1 {
	// 조건식1이 true일 때 실행될 스위프트 구문
} else if 조건식2 {
	// 조건식2가 true일 때 실행될 스위프트 구문
} else if 조건식3 {
	// 조건식3이 true일 때 실행될 스위프트 구문
}

여기에 else를 마지막에 넣어서 그 외의 값을 처리해줄 수 있다.

 

let x = 9

if x == 10 {
	print("x is 10")
} else if x == 9 {
	print("x is 9")
} else if x == 8 {
	print("x is 8")
}

뭐… 조건이 많아지면… 좀 지/저/분 해지지 않을까? 이럴 경우 swifch 문으로 대체해서 쓸 수 있다.

 

let someInteger = 100

if someInteger < 100 {
	print("100 미만")
} else if someInteger > 100 {
	print("100 초과")
} else {
	print("100")
} // 100
  • 스위프트의 조건에는 항상 Bool 타입이 들어와야 한다.
  • someInteger는 Bool 타입이 아닌 Int 타입이기 때문에 컴파일 오류가 발생한다.

 

 

guard 구문

  • guard 구문은 불리언 표현식을 포함하여, true일 때만 guard 구문 다음에 위치한 코드가 실행된다.
    • gurad 구문 다음이라는 것은.. guard의 중괄호 바깥을 의미한다.
    • guard 구문이 false이면 guard 구문 뒤의 코드는 실행되지 않는다. 일종의 방어막이라고 생각하면 쉽다! guard!!!
  • guard 구문은 불리언 표현식이 false일 때 수행될 else 절을 반드시 포함해야 한다.
    • else 절의 코드는 반드시 현재의 코드 흐름에서 빠져나가는 문구(return, break, continue, throw 구문)을 포함한다.
    • else 블록은 자신을 반환하지 않는 다른 함수나 메서드를 호출할 수도 있다.
  • 기본적으로 guard 구문은 특정 조건을 만족하지 않은 경우에 현재의 함수 또는 반복문에서 빠져나올 수 있게 해준다.
guard 조건문(불리언 표현식) else {
	// 조건문이 false일 때 실행될 스위프트 구문
	< 종료구문 >
}

// 조건문이 true일 때 실행될 스위프트 구문

 

 

func multiplyByTen(value: Int?) {
	guard let number = value, number < 10 else {
		print("Number is too high")
		return
	}

	let result = number * 10
	print(result)
}

가드 문에서 false가 나면 else 안에 코드를 실행하고 그냥 끝!! 함수 mulityplyByTen 이 끝난다.

 

 

swifch 구문

  • Swift의 switch 구문은 다른 프로그래밍 언어와 몇 가지 중요한 차이점이 있다.
  • if … else if … 구문으로 두세개 이상의 조건을 만들 경우 switch 구문이 대안이 될 수 있다.
  • switch 구문의 표현식(expression)은 값을 가지거나 값ㅇ르 반환하는 표현식이다. 이 값은 switch 구문이 동작하게 하는 값이다.
  • 그 값과 일치할 수 있는 값을 case 구문으로 제공한다. 각각의 일치하는 값은 표현식의 값과 동일한 타입이어야 한다.
  • case 조건과 일치하는 값일 경우에 수행될 코드 구문이 case 줄 아래에 작성된다.
  • default절은 표현식과 일치하는 case 구문이 없을 경우에 어떻게 해야 하는지를 정의하는 부분이다.
switch 표현식 {
	case 일치하는 값1:
		// 코드 구문
	case 일치하는 값2:
		// 코드 구문
	case 일치하는 값3, 일치하는 값4:
		// 코드 구문
	default:
		// 코드 구문
}
  • switch의 표현식과 case는 같은 타입이어야 한다. MUST!
  • case 값3, 값4:
    • ‘값3 또는 값4’ 라는 뜻이다.

 

  • value 값이 정수니까 case 다음 값도 정수형이어야 한다.
let value = 4

switch (value) {
	case 0:
		print("zero")
	case 1:
		print("one")
	case 2:
		print("two")
	case 3:
		print("three")
	case 4:
		print("four")
	case 5:
		print("five")
	default:
		print("Integer out of range")
}

 

  • 범위 연산자를 활용하면 더욱 쉽고 유용하다.
switch (someInteger) {
	case 0:
		print("zero")
	case 1..<100:
		print("1~99")
	case 100:
		print("100")
	case 101...Int.max:
		print("over 100")
	default:
		print("unknown")
} // 100

 

  • 정수 외의 대부분의 기본 타입을 사용할 수 있다.
switch "dadahae" {
	case "kangvic":
		print("kangvic")
	case "bomi":
		print("bomi")
	case "dorang":
		print("dorang")
	case "dadahae":
		print("dadahae❤️")
	default:
		print("unknown")
} // dadahae❤️

Swift의 switch 문에서 case에 값 대신 조건문을 쓸 수도 있다! 그러면 if문 보다 깔끔하게 사용할 수 있다.

 

 

switch - case 구문 결합하기

  • 각각의 case 구문은 자신만의 실행 코드를 가지고 있다.
  • 하지만 서로 다른 매칭(case)에 대해 동일한 코드가 실행되어야 한다.
  • 이러한 경우 각각의 일치하는 경우들을 공통으로 실행될 구문과 묶을 수 있다.
let valeu = 1

switch (value) {
	case 0,1,2:
		print("zero, one or two")
	case 3:
		print("three")
	case 4:
		print("four")
	case 5:
		print("five")
	default:
		print("Integer out of range")
}

스위치 문에서 콤마는 OR 이라는 뜻이다. 헷갈리지 말자꼬이~

 

 

switch 구문에서 범위 매칭하기

  • switch 구문 안에 있는 case 구문에 범위 매칭을 구현할 수도 있다.
let temperature = 83

switch (temperature) {
	case 0...49:
		print("Cold")
	case 50...79:
		print("Warm")
	case 80...110:
		print("Hot")
	default:
		print("Temperature out of range")
}

 

switch - where 구문 사용하기

  • where 구문은 case 구문에 부가적인 조건을 추가하기 위해서 사용될 수 있다.
let temperatrue = 54

switch (temperature) {
	// 값의 범위 조건에 일치하는지 검사할 뿐만 아니라 그 숫자가 홀수인지 짝수인지도 검사한다.
	case 0...49 where temperature % 2 == 0:
		print("Cold and even")
	case 50...79 where temperature % 2 == 0:
		print("Warm and even")
	case 80...110 where temperature % 2 == 0:
		print("Hot and even")
	default:
		print("Temperature out of range")
}

조건절이 의외로 유용하다. 아주 강력하다!

 

 

switch - fallthrough 구문 사용하기

  • case 구문은 break을 쓸 필요가 없다.
    • 다른 언어들과 달리 case 조건에 일치하면 자동으로 구문 밖으로 빠져나간다.
  • fallthrough 구문을 사용하면 switch 구현부에 예외상황 효과를 주어, 실행 흐름이 그 다음의 case 구문으로 계속 진행하게 할 수 있다.
  • Swift의 switch 구문에서는 break는 거의 사용되지 않지만, default에서 아무런 작업도 할 필요가 없는 경우에 유용하다.
let temperature = 54

switch (temperature) {
	case 0...49 where temperature % 2 == 0:
		print("Cold and even")
		fallthrough

	case 50...79 where temperature % 2 == 0:
		print("Warm and even")
		fallthrough

	case 80...110 where temperature % 2 == 0:
		print("Hot and even")
		fallthrough

	default:
		break
}

 

 

 


 

남은 시간에는 지금까지 배운 내용으로 풀 수 있는 문제를 10개나 풀었다!! 

 

 

🦁 2주차도 끝

  Comments,     Trackbacks