Point II 어떤 것을 입력하든 문자열로 입력되기 때문에 형 변환이 필요 int() : 정수형 변환, str() : 문자열 변환 등…
var1 = input() #4 입력
var1 = int(var1)
var2 = int(input()) #3 입력
print(3+var1+var2) #10 출력
2. 논리 자료형(Boolean Data)
Point I 논리 자료형 : 참(True) 혹은 거짓(False)을 나타내는 자료형
True, False
Point II 비교 연산자 : 숫자나 문자의 값을 비교하는 연산자 주어진 진술이 참이면 True, 거짓이면 False
A == B #A와 B가 같다
A != B #A와 B가 다르다
A >= B #A가 B보다 크거나 같다
A <= B #A가 B보다 작거나 같다
A > B #A가 B보다 크다
A < B #A가 B보다 작다
print(3 == 3) #True
print(3 != 3) #False
Point III 논리 연산자 : 논리 자료형 사이의 연산
AND : 각 논리가 모두 True이면 결과가 True
OR : 각 논리 중 True가 존재하면 결과가 True
NOT : 논리값을 뒤집는 연산
3. 조건문
조건에 따라 특정 명령을 수행하는 구문
Point I if문 : 조건이 참이면 명령을 수행
if a >= 5:
print("a는 5 이상입니다!")
Point II elif문 : 이전 조건이 거짓인 상황에서 조건이 참이면 명령을 수행
if a >= 5:
print("a는 5 이상입니다!")
elif a >= 3:
print("a는 3 이상 5 미만입니다!")
Point III else문 : 위의 조건에 해당하지 않는 모든 경우에 수행
if a >= 5:
print("a는 5 이상입니다!")
elif a >= 3:
print("a는 3 이상 5 미만입니다!")
else:
print("a는 3 미만입니다!")
yum: Yellowdog Updater Modified, rpm 기반의 시스템을 위한 자동 업데이트 및 패키지 설치/삭제 도구
Command 'yum' not found, did you mean: / See 'snap info <snapname>' for additional versions.
root@ubuntu:/home/sehee# yum help
Command 'yum' not found, did you mean:
command 'gum' from snap gum (0.12.0) command 'sum' from deb coreutils (8.30-3ubuntu2) command 'zum' from deb perforate (1.2-5.1) command 'uum' from deb freewnn-jserver (1.1.1~a021+cvs20130302-7build1) command 'num' from deb quickcal (2.4-1)
See 'snap info <snapname>' for additional versions.
ubuntu nginx에 yum 설치가 되어 있지 않기 때문에 생긴 오류
E: Unable to locate package yum
root@ubuntu:/etc/apt# sudo apt-get install yum
Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package yum
deb http://archive.ubuntu.com/ubuntu bionic main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu bionic-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu bionic-updates main restricted universe multiverse
업데이트 후 확인
sudo apt-get update
root@ubuntu:/etc/apt# sudo apt-get install yum
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 5628 (unattended-upgr) N: Be aware that removing the lock file is not a solution and may break your system. E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
sudo killall apt apt-get
# 진행 중인 파일이 없다면
sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock*
sudo dpkg --configure -a
Cocoa Touch Class > (Choose options for your new file) Class: StockRankViewController > Next > Create
좌측 Main Tab의 View Controller > 우측 Custom Class - Class 및 Identity - Storyboard ID: StockRankViewController 설정
* Storyboard ID에서 검색이 용이하도록(class 이름 자체가 unique한 id이므로 동일하게 설정해도 무방)
Main storyboard에서 우측 상단 + 버튼 클릭하여 UI components(objects) 선택
Collection View 추가
Auto rayout 설정
자식 뷰(Collection View)를 부모 뷰(View)에 연관되게 설정하기 위함
control 버튼을 누른 상태에서 Collection View → View 드래그
Shift를 누른 상태에서 클릭하여 다중 선택(상단 네개 Space to Safe Area 모두 클릭) 이후 Enter
View를 Code로 연결하기
해당하는 스토리보드(Collection View) 클릭 후 우측 상단 =(리스트) 아이콘 클릭
Assistant 클릭하여 새로운 view 생성
control 누른 상태에서 연결하고 싶은 뷰(Collection View) → 코드 드래그
name: collectionView > connect
import UIKit
class StockRankViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
Connection View Cell 내에 Label, Image View 추가 (option 누르고 드래그할 경우 복제)
//
// SymbolRollerViewController.swift
// SymbolRoller
//
// Created by sehee on 2022/06/26.
//
import UIKit
class SymbolRollerViewController: UIViewController {
let symbols: [String] = ["sun.min", "moon", "cloud", "wind", "snowflake"]
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// button.tintColor = UIColor.systemPink
// TO-DO:
// - 심볼에서, 하나를 임의로 추출해서
// 이미지와 텍스트를 설정
// DRY: Do not repeat yourself
reload()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func reload() {
let symbol = symbols.randomElement()!
imageView.image = UIImage(systemName: symbol)
label.text = symbol
}
@IBAction func buttonTapped(_ sender: Any) {
reload()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
ViewController: 페이지를 나타내기 위한 객체
option + shift + 8
° 기호
option + command + =
설정값 변경 전(주황색 표시) 업데이트
//
// WeatherViewController.swift
// SimpleWeather
//
// Created by sehee on 2022/06/26.
//
import UIKit
class WeatherViewController: UIViewController {
@IBOutlet weak var cityLabel: UILabel!
@IBOutlet weak var weatherImageView: UIImageView!
@IBOutlet weak var temperatureLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
let cities = ["Seoul", "Tokyo", "LA", "Seattle"]
let weathers = ["cloud.fill", "sun.max.fill", "wind", "cloud.sun.rain.fill"]
@IBAction func changeeButtonTapped(_ sender: Any) {
print("도시, 온도, 날씨 이미지 변경하자!")
cityLabel.text = cities.randomElement()
let imageName = weathers.randomElement()!
weatherImageView.image = UIImage(systemName: imageName)?.withRenderingMode(.alwaysOriginal)
// alwaysTemplate의 경우 default Tint color 적용
let randomTemp = Int.random(in: 10..<30)
temperatureLabel.text = "\(randomTemp)°"
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
Create a new Xcode project > File > New > Playground
iOS - Blank > Next > Save As: HelloSwift
01. 변수, 상수
command + /: 주석 변경
변수/상수에 커서 + option (누르면 ? 표시) + 클릭하면 타입 정보 조회 가능
import UIKit
var greeting = "Hello, playground"
// ---------- 01. 변수, 상수 ----------
// var: 변수(variable) 선언
var num = 5
num = 1
// let: 상수(constant) 선언(값 수정 불가)
var name = "Jason"
name = "Jay"
// String
let quote = "I'm mother father genius, Man"
// Integer
let num2 = 5
let otherNum = num2 + 2 // 7
let halfOfNum = otherNum / 2 // 3
// 내장함수
let num3 = 360
// 3의 배수인지 확인하는 코드
print(num3.isMultiple(of: 3))
// 0~300 사이중 랜덤으로 수를 뽑아내는 메소드
let random = Int.random(in: 0...300)
// Double: 소수점을 포함하는 숫자를 표현
let score = 3.6
02. bool-array
// ---------- 02. bool-array ----------
// Boolean
let isMan = true
let isHuman = false
var isSingle = true
isSingle.toggle()
isSingle
// String Interpolation
let difficulty = "쉽다"
let maximumAge = 80
let message = "\(maximumAge) 할머니도 배우는 iOS 개발은 \(difficulty)"
// 배열과 딕셔너리
// Array
let ages = [3, 20, 60]
let colors = ["green", "red", "yellow"]
let color = colors[0]
// Dictionary (Key: Value)
let languageCode = [
"한국" : "ko",
"미국" : "en",
"일본" : "ja",
]
// 비어 있는 배열과 딕셔너리 초기화
var emptyArr: [Int] = []
var emptyDic: [String: Any] = [:]
03. enum
// ---------- 03. enum ----------
// 서로 관계있는 값들을 모아서 표현한 것
enum WeekDay {
case mon
case tue
case wed
case thu
case fri
}
var today: WeekDay = .mon
// var tod: String = "mon" // error(mom)시 찾기 힘듦
enum MediaType {
case audio
case video
}
var mediaType: MediaType = .audio
// 위에서 만들어본 미디어 타입에, 파일 확장자도 문자열로 받을 수 있게 수정
enum MediaType2 {
case audio(String)
case video(String)
}
var mp3: MediaType2 = .audio("mp3")
var h264: MediaType2 = .video("h264")
04. 조건문, 반복문
// ---------- 04. 조건문, 반복문 ----------
let age = 10
// if문의 조건절에는 boolean 타입을 사용 (e.g. age > 20)
if age > 20 {
print("성인 입니다")
} else {
print("미성년 입니다")
}
if age >= 10 && age < 20 {
print("10대 입니다")
} else if age >= 20 && age < 30 {
print("20대 입니다")
} else if age >= 30 && age < 40 {
print("30대 입니다")
} else if age >= 40 && age < 50 {
print("40대 입니다")
} else {
print("......")
}
enum Weather {
case sun
case cloud
case rain
}
var weather: Weather = .sun
switch weather {
case .sun:
print("맑아요")
case .cloud:
print("흐려요")
case .rain:
print("비와요")
}
// 배열과 딕셔너리 아이템을 순차적으로 체크할 때 사용
let ages2 = [3, 20, 60]
let languageCode2 = [
"한국" : "ko",
"미국" : "en",
"일본" : "ja",
]
for age in ages2 {
print("age: \(age)")
}
for (key, value) in languageCode2 {
print("\(key)의 언어코드는 \(value)")
}
// 일정 횟수를 단순 반복
print("전방에 다짐 10번 발사~~!")
for _ in 0..<10 {
print("나는 iOS 개발자다!")
}
// while: 특정 조건을 이용해서 반복
var count = 10
print("Ready!")
while count > 0 {
print("\(count)...")
count -= 1
}
print("START!")
05. 옵셔널
// ---------- 05. 옵셔널 ----------
// 값이 있을수도 있고 없을수도 있음을 표현
// Dictionary (Key: Value)
let languageCode3 = [
"한국" : "ko",
"미국" : "en",
"일본" : "ja",
]
// let 상수 타입은 String? (타입 + ?)
let krCode = languageCode3["한국"] // "ko"
let jpCode = languageCode3["일본"] // "ja"
let deCode = languageCode3["독일"] // nil
// 이름이 있을 수도 있고 없을 수도 있는 타입 선언 - String?
var name2: String? = nil
name2 = "Jason"
name2 = nil
06. 함수, 클로저
// ---------- 06. 함수, 클로저 ----------
// 함수는 func 키워드를 사용해서 선언
func printGugu(dan: Int) {
for i in 1...9 {
print("\(dan) * \(i) = \(dan * i)")
}
}
printGugu(dan: 5)
func rollDice() -> Int {
return Int.random(in: 1...6)
}
let random2 = rollDice()
// 클로저: 이름이 존재하지 않는 함수
// 함수
func call(name: String) {
print("hello, \(name)")
}
call(name: "Jason")
// 상수에 함수를 할당하고, 해당 상수를 호출
let callName = call
callName("Aha")
// 상수에 클로저 할당하고, 해당 상수 호출
let helloName = { (name: String) in
print("hello, \(name)")
}
helloName("Oho")
// 클로저 형태: 함수와 거의 동일, in을 통해 파라미터 및 반환 타입과 실제 클로저 코드 분리
// { (name: String) -> Bool in ~ some code ~ }
// filter
let members = ["Jason", "Greg", "Tiffany"]
let nameHasT = members.filter { name in
return name.hasPrefix("T")
}
// map
let prices = [1000, 2000, 3000]
let doubledPrices = prices.map { price in
return price * 2
}
// reduce
let revenues = [100, 200, 300]
let totalRevenue = revenues.reduce(0) { partialResult, next in
return partialResult + next
}
07. 클래스 구조체1
// ---------- 07. 클래스 구조체1 ----------
struct Album {
// 멤버 변수들 - stored property
let title: String
let artist: String
var isReleased = false
// 생성자: 클래스 또는 구조체를 생성할 때 사용하는 특별한 함수(init 키워드로 선언)
// init(title: String, artist: String) {
// self.title = title
// self.artist = artist
// }
func description() -> String {
return "\(title) by \(artist)"
}
// 구조체 내부 멤버 변수의 값을 변경하는 경우, mutating 키워드 이용
mutating func release() {
self.isReleased = true
}
}
var easyOnMe = Album(title: "Easy On Me", artist: "Adele")
print(easyOnMe.description())
print(easyOnMe.isReleased)
easyOnMe.release()
print(easyOnMe.isReleased)
// 클래스: 상속 가능 참조(reference) 생성자를 기본으로 만들어주지 않음
// 구조체: 상속 불가능 복사(copy)
class Employee {
var name: String
var hours: Int
init(name: String, hours: Int) {
self.name = name
self.hours = hours
}
func work() {
print("I'm working now...")
}
func summary() {
print("I work \(self.hours) hours a day. ")
}
}
class iOSDeveloper: Employee {
override func work() {
print("I'm developing iOS app now.")
}
override func summary() {
print("I work \(self.hours/2) hours a day.")
}
}
struct Phone {
var modelName: String
var manufacturer: String
var version: Double = 1.0
}
let normalWorker = Employee(name: "Kim", hours: 8)
normalWorker.work()
normalWorker.summary()
// I'm working now...
// I work 8 hours a day.
let developer = iOSDeveloper(name: "Jason", hours: 8)
developer.work()
developer.summary()
// I'm developing iOS app now.
// I work 4 hours a day.
// Reference vs. Copy
var iPhone1 = Phone(modelName: "iPhone 13", manufacturer: "Apple")
var iPhone2 = iPhone1
iPhone2.modelName = "iPhone 14"
print(iPhone2.modelName)
print(iPhone1.modelName)
// iPhone 14
// iPhone 13
var jrDeveloper1 = iOSDeveloper(name: "John", hours: 8)
var jrDeveloper2 = jrDeveloper1
jrDeveloper1.name = "Billy"
print(jrDeveloper1.name)
print(jrDeveloper2.name)
// Billy
// Billy
08. 클래스 구조체2
// ---------- 08. 클래스 구조체2 ----------
// stored property: 클래스, 구조체가 값을 저장하고 있는 프로퍼티
// computed property: 따로 값 저장하지 않음, stored property를 활용학거나 특정값을 전달할 때 사용하는 프로퍼티
struct Watch {
let model: String
let manufacturer: String
var description: String {
return "\(model) by \(manufacturer)"
}
}
struct Person {
let firstName: String
let lastName: String
var fullName: String {
return "\(firstName) \(lastName)"
}
}
let appleWatch = Watch(model: "Watch 7", manufacturer: "Apple")
print(appleWatch.description)
// Watch 7 by Apple
let jason = Person(firstName: "Jason", lastName: "Lee")
print(jason.fullName)
// Jason Lee
09. 프로토콜
// ---------- 09. 프로토콜 ----------
// 제공하고 싶은 역할(기능, 속성)을 미리 정의해 놓은 것
// 이후에 다른 타입이 해당 프로토콜의 역할을 제공하고 싶으면, conform해서 제공함
protocol Coach {
var name: String { get set }
var currentTeam: String { get }
func training()
func direct()
}
struct Mourinho: Coach {
var name: String = "Jose Mourinho"
var currentTeam: String = "AS Roma"
func training() {
print("Traing Player")
}
func direct() {
print("Direct Game")
}
}
let mourinho = Mourinho()
print("\(mourinho.name), \( mourinho.currentTeam)")
mourinho.training()
mourinho.direct()
// Jose Mourinho, AS Roma
// Traing Player
// Direct Game
10. 익스텐션
// ---------- 10. 익스텐션 ----------
// 기존 타입에 새로운 역할(기능 및 속성)을 추가하고 싶을 때 사용
extension String {
func contains(s: String) -> Bool {
return self.range(of: s) != nil
}
func replace(target: String, with: String) -> String {
return self.replacingOccurrences(of: target, with: with)
}
}
let testString = "Hello iOS Developer!!"
let replaced = testString.replace(target: "Hello", with: "안녕하세요")
print(replaced)
// 안녕하세요 iOS Developer!!
print(testString.contains(s: "iOS"))
// true