Skip to content

Instantly share code, notes, and snippets.

@myssun0325
Last active March 7, 2018 08:28
Show Gist options
  • Save myssun0325/b3fc1761b762cd437ecbb87146728469 to your computer and use it in GitHub Desktop.
Save myssun0325/b3fc1761b762cd437ecbb87146728469 to your computer and use it in GitHub Desktop.
//
// 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()
@myssun0325
Copy link
Author

myssun0325 commented Mar 6, 2018

  1. 단위 값 입력 받기
  2. 입력받은 값 변환하여 저장하기(extract함수를 구현하여 값과 단위를 입력받은 오리지널 값으로부터 추출하여 튜플에 저장.)
  3. 저장된 튜플의 단위를 판별하여 convert함수(미터 또는 센티미터) 호출하여 변환하기
  4. 변환된 값을 printConvertedValue(_:) 함수를 통해 출력하기

@godrm
Copy link

godrm commented Mar 6, 2018

  • convertUnit()에서 let inputValue = unitLength 는 어떤 의도가 있는걸까요?
    이미 매개변수가 있는데 새로운 변수를 만드는게 의미가 있나요?
  • checkLetters 대신에 CharacterSet 을 활용해보세요.
  • convertToMeter() 함수와 convertToCentimeter() 함수를 일반화할 수 있을까요?
  • "cm", "m" 처럼 문자열도 반복되서 사용되는 데 의미있는 코드로 바꿀 수 있을까요?
    위의 피드백을 개선하면서 다음 단계에 도전해보세요.

@myssun0325
Copy link
Author

myssun0325 commented Mar 7, 2018

Step3 개선사항

  • 중복된 let inputValue 변수 생성 삭제
  • checkLetters 대신 CharacterSet 활용하기
  • 스위프트 API가이드라인 반영 : extractValue(from: unitLength) -> extracValueFrom(unitLength)
  • convertToMeter()함수와 convertToCentimeter() 함수의 일반화 : convert()함수로 만들기
  • "cm", "m" 문자열 반복 개선 -> enum을 사용하여 case로 만들고 곱해지는 연산프로퍼티를 통해 단위에 따라 곱해지는 multiplier 구분

@godrm
Copy link

godrm commented Mar 7, 2018

  • 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