Last active
March 7, 2018 08:28
-
-
Save myssun0325/b3fc1761b762cd437ecbb87146728469 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.swift | |
// UnitConverter | |
// | |
// Created by moon on 2018. 3. 5.. | |
// Copyright © 2018년 moon. All rights reserved. | |
// | |
import Foundation | |
typealias UnitValue = (value: Double, unit: Unit) | |
enum Unit: String { | |
case cm | |
case m | |
var multiplier: Double { | |
switch self { | |
case .cm: | |
return 0.01 | |
case .m: | |
return 100.0 | |
} | |
} | |
} | |
func main() { | |
let unitLength = getLength() | |
convertUnit(unitLength) | |
} | |
// Get length and unit from a user. | |
func getLength() -> String { | |
print("Enter length and unit. (ex: 120cm, 1.86m): ", terminator: "") | |
guard let length = readLine() else { | |
return "Input Error!!" | |
} | |
return length | |
} | |
func convertUnit(_ unitLength: String) { | |
// extract value only | |
guard let value = extractValueFrom(unitLength) else { | |
print("Extracting Value Error!!!") | |
return | |
} | |
// extract unit | |
guard let unit = Unit(rawValue: extractUnitFrom(unitLength)) else { | |
print("Unit Error!!!") | |
return | |
} | |
// convert cm <-> m | |
if let result = convert(value, unit) { | |
print("\(result.value)\(result.unit)") | |
} else { | |
print("Converting Error!!!") | |
} | |
} | |
// 함수 일반화하기 | |
// return nil if converting fails | |
func convert(_ value: Double, _ unit: Unit) -> UnitValue? { | |
var result: UnitValue? | |
switch unit { | |
case .cm: | |
result = ((value * unit.multiplier), .m) | |
case .m: | |
result = ((value * unit.multiplier), .cm) | |
} | |
return result | |
} | |
// return unit only | |
func extractUnitFrom(_ unitLength: String) -> String { | |
var unit = String() | |
for letter in String(unitLength.reversed()) { | |
if Int(String(letter)) == nil { | |
unit.insert(letter, at: unit.startIndex) | |
} else { | |
break | |
} | |
} | |
return unit | |
} | |
// return value only | |
func extractValueFrom(_ unitLength: String) -> Double? { | |
let checkLetters = CharacterSet(charactersIn: "01234567890.") | |
var value = String() | |
for letter in unitLength { | |
if CharacterSet(charactersIn: String(letter)).isSubset(of: checkLetters) { | |
value.append(letter) | |
} | |
} | |
guard let number = Double(value) else { | |
return nil | |
} | |
return number | |
} | |
main() |
Author
myssun0325
commented
Mar 6, 2018
•
- 단위 값 입력 받기
- 입력받은 값 변환하여 저장하기(extract함수를 구현하여 값과 단위를 입력받은 오리지널 값으로부터 추출하여 튜플에 저장.)
- 저장된 튜플의 단위를 판별하여 convert함수(미터 또는 센티미터) 호출하여 변환하기
- 변환된 값을 printConvertedValue(_:) 함수를 통해 출력하기
- convertUnit()에서
let inputValue = unitLength
는 어떤 의도가 있는걸까요?
이미 매개변수가 있는데 새로운 변수를 만드는게 의미가 있나요? - checkLetters 대신에 CharacterSet 을 활용해보세요.
- convertToMeter() 함수와 convertToCentimeter() 함수를 일반화할 수 있을까요?
- "cm", "m" 처럼 문자열도 반복되서 사용되는 데 의미있는 코드로 바꿀 수 있을까요?
위의 피드백을 개선하면서 다음 단계에 도전해보세요.
Step3 개선사항
- 중복된
let inputValue
변수 생성 삭제 - checkLetters 대신 CharacterSet 활용하기
- 스위프트 API가이드라인 반영 : extractValue(from: unitLength) -> extracValueFrom(unitLength)
- convertToMeter()함수와 convertToCentimeter() 함수의 일반화 :
convert()
함수로 만들기 - "cm", "m" 문자열 반복 개선 -> enum을 사용하여 case로 만들고 곱해지는 연산프로퍼티를 통해 단위에 따라 곱해지는 multiplier 구분
if Int(String(letter)) == nil
형태로 nil과 비교하기 보다는 optional binding 을 찾아보세요.- 스스로 문법을 공부하면서 코드를 개선하는 경험을 반복해보세요.
- 함수 분리는 어느정도 된 것 같으니 다음 단계로 넘어가서 구조체로 만들어보세요.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment