본문 바로가기
개인공부

[iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 5편

by 싸디아재 2025. 3. 25.
728x90
반응형

 

마지막 기능 구현은 오답을 저장하여 퀴즈 마지막에 정답과 함께 출력하여 복습하는 기능이었다.

오늘은 간단한 것들을 추가해 보려고 한다. UX 개선이라고 해야할까?

 

목차

9. 점수 결과에 따른 피드백 메세지 / if... else if...

10. 카테고리별 퀴즈 데이터 만들기 / for... in...

 

 

9. 점수 결과에 따른 피드백 메세지 / if... else if...

아래와 같이 간단하게 코드를 작성하였다. 아래 코드는 정답률을 보여주는 코드 하단에 위치하면 될 것 같다.

print(String(format: "\n정답율: %.1f%%\n", answerPercentage))

 

answerPercentage가 Double 타입이라 >= 비교와 정확학 작동한다.

if answerPercentage >= 90 {
            print("\n훌륭한 성적을 거두셨습니다! 고생했어요!\n")
        } else if answerPercentage >= 80 {
            print("\n성실한 성적을 거두셨습니다! 잘했어요!")
        } else if answerPercentage >= 50 {
            print("\n보통적인 성적을 거두셨습니다! 잘했어요!")
        } else if answerPercentage >= 40 {
            print("\n보통적인 성적을 거두셨습니다! 조금 더 노력해 보세요!")
        } else if answerPercentage >= 10 {
            print("\n불합리한 성적을 거두셨습니다! 조금 더 노력해 보세요!")
        }

적용 후 빌드를 해서 정상 작동하는지 확인해보자.

 

 

총 다섯개 퀴즈 중 몇개를 풀고 싶으세요?:
5
퀴즈 5를 랜덤하게 드리겠습니다!
이스탄불은 대한민국 도시 중 하나이다. (O/X)
x
>>>> 오답입니다!

정답: 0개 / 오답: 1개

2024년도 12월 3일 발동한 비상계엄은 불법이다. (O/X)
o
답변: o
>>>> 정답입니다!

정답: 1개 / 오답: 1개

대한민국의 수도는 서울이다. (O/X)
o
답변: o
>>>> 정답입니다!

정답: 2개 / 오답: 1개

챗GPT는 바보다. (O/X)
o
>>>> 오답입니다!

정답: 2개 / 오답: 2개

대전은 대한민국의 도시 중 하나이다. (O/X)
x
>>>> 오답입니다!

정답: 2개 / 오답: 3개

===. 퀴즈가 종료되었습니다!  ===
총 정답: 2개
총 오답: 3개

정답율: 40.0%


보통적인 성적을 거두셨습니다! 조금 더 노력해 보세요!

오답 질문들을 복습해볼까요?

문제: 이스탄불은 대한민국 도시 중 하나이다.
정답: X
-----------------------------------
문제: 챗GPT는 바보다.
정답: X
-----------------------------------
문제: 대전은 대한민국의 도시 중 하나이다.
정답: O
-----------------------------------
Program ended with exit code: 0

 

정상 작동하는 것으로 보인다. 혹시 모르니 100% 달성을 해보고 결과를 확인해봐야 겠다.

확인 결과 모두 정상으로 보인다.

 

10. 카테고리별 퀴즈 데이터 만들기 / for... in...

나름 퀴즈 게임인데도 불구하고 질문들이 카테고리별로 나눠져있지 않다. 이를 카테고리별로 데이터를 만들어볼까 한다.

간단하게 코딩이 가능하다.

 

먼저 카테고리 만들기.

let quizCategories = [
    "일반상식": [
        ("지구는 태양을 돈다.", "O"),
        ("물은 불보다 가볍다.", "O"),
        ("사람은 4개의 심장을 가지고 있다.", "X")
    ],
    "IT 지식": [
        ("Swift는 애플에서 만든 언어이다.", "O"),
        ("HTML은 프로그래밍 언어다.", "X"),
        ("Xcode는 안드로이드 앱을 개발하는 툴이다.", "X")
    ],
    "역사": [
        ("광복절은 8월 15일이다.", "O"),
        ("조선은 고구려보다 먼저 생겼다.", "X"),
        ("세종대왕은 훈민정음을 만들었다.", "O")
    ]
]

 

그리고 사용자에게 카테고리 선택을 받는 것을 추가한다.

print("퀴즈 카테고리를 선택하세요:")
for category in quizCategories.keys {
    print("- \(category)")
}

var selectedCategory = ""

if let input = readLine(), quizCategories.keys.contains(input) {
    selectedCategory = input
    print("👉 '\(selectedCategory)' 카테고리의 퀴즈를 시작합니다!")
} else {
    print("존재하지 않는 카테고리입니다. 기본값 '일반상식'으로 진행합니다.")
    selectedCategory = "일반상식"
}

 

그리고 해당 카테고리 퀴즈만 랜덤하게 출제하기로 하자.

let selectedQuizList = quizCategories[selectedCategory]!
let shuffledQuizList = Array(selectedQuizList.shuffled().prefix(numQuiz))

 

시간이 걸리긴 했지만 해결을 했다.

import Foundation

var goodAnswer = 0
var wrongAnswer = 0
var wrongQuestions: [(String, String)] = []
var answerPercentage = 0.0
var numQuiz = 0
var selectedCategory = ""

    func runQuiz(question: String, correctAnswer: String) {
        print("\(question) (O/X)")
        if let answer = readLine() {
            if answer.uppercased() == correctAnswer.uppercased() {
                print("답변: \(answer)")
                print(">>>> 정답입니다!")
                goodAnswer += 1
            } else {
                print(">>>> 오답입니다!")
                wrongAnswer += 1
                wrongQuestions.append((question, correctAnswer))
            }
        }
        print("\n정답: \(goodAnswer)개 / 오답: \(wrongAnswer)개\n")
    }

print(">>>>> 퀴즈 시작 <<<<<\n")

let quizCategory = [
    "일반상식": [
        ("지구는 태양을 돈다.", "o"),
        ("물은 불보다 가볍다.", "o"),
        ("사람은 4개의 심장을 가지고 있다.", "x"),
        ("2024년도 12월 3일 발동한 비상계엄은 불법이다.", "O"),
        ("이스탄불은 대한민국 도시 중 하나이다.", "X"),
        ("챗GPT는 바보다.", "X")
    ],
    "IT 지식": [
        ("Swift는 애플ㅇ서 만든 언어이다.", "o"),
        ("HTML은 프로그래밍 언어다.", "x"),
        ("Xcode는 안드로이드 앱을 개발하는 툴이다.", "x"),
        ("iPhone은 안드로이드 기반이다.", "x"),
        ("Windows OS를 개발한 회사는 Microsoft이다.", "o")
    ],
    "역사": [
        ("광복절은 8월 15일이다.", "o"),
        ("조선은 고구려보다 먼저 생겼다.", "x"),
        ("세종대왕은 훈민정음을 만들었다.", "o"),
        ("대략 조선이 건국된 1392년부터 대한제국이 멸망된 1910년까지를 조선시대로 잡고 있다.", "o"),
        ("고구려는 서기전 1세기부터 668년까지 존속한 고대 왕국으로, 압록강 중류 지역에서 시작되다", "o")
    ] ]

for category in quizCategory.keys {
    print("카테고리를 선택해 주세요.:\n")
    print("\(category)\n")
    
    if let input = readLine(), quizCategory.keys.contains(input) {
        selectedCategory = input
        print("\(selectedCategory)을 선택하셨습니다! 카테고리의 퀘즈를 시작하겠습니다!\n")
    } else {
        print("존재하지 않는 카테고리 입니다. 기본값 '일반상식'으로 진행하겠습니다.\n")
        selectedCategory = "일반상식"
    }
    
    print("총 다섯개 퀴즈 중 몇개를 풀고 싶으세요?:")
    
    if let input = readLine(), let inputNum = Int(input) {
        numQuiz = inputNum
        print("퀴즈 \(numQuiz)를 랜덤하게 드리겠습니다!")
        
        let selectedQuizList = quizCategory[selectedCategory]
        let shuffledQuizList = Array(selectedCategory.shuffled().prefix(numQuiz))
        
        for (question, correctAnswer) in shuffledQuizList {
            runQuiz(question: question, correctAnswer: correctAnswer)
        }
        
        answerPercentage = Double(goodAnswer) / Double(goodAnswer + wrongAnswer) * 100
        print("===. 퀴즈가 종료되었습니다!  ===")
        print("총 정답: \(goodAnswer)개")
        print("총 오답: \(wrongAnswer)개")
        
        print(String(format: "\n정답율: %.1f%%\n", answerPercentage)) //print("정답율: \(answerPercentage)%")
        
        if answerPercentage >= 90 {
            print("\n훌륭한 성적을 거두셨습니다! 고생했어요!\n")
        } else if answerPercentage >= 80 {
            print("\n성실한 성적을 거두셨습니다! 잘했어요!")
        } else if answerPercentage >= 50 {
            print("\n보통적인 성적을 거두셨습니다! 잘했어요!")
        } else if answerPercentage >= 40 {
            print("\n보통적인 성적을 거두셨습니다! 조금 더 노력해 보세요!")
        } else if answerPercentage >= 10 {
            print("\n불합리한 성적을 거두셨습니다! 조금 더 노력해 보세요!")
        }
        
        if !wrongQuestions.isEmpty {
            print("\n오답 질문들을 복습해볼까요?\n")
            for (question, correctAnswer) in wrongQuestions {
                print("문제: \(question)")
                print("정답: \(correctAnswer)")
                print("-----------------------------------")
            }
        } else {
            print("모든 문제를 맞추셨습니다! 복습이 필요없어요!")
        }
    }
}

 

에러가 발생하는데 처음보는 에러다...

에러는 for (question, correctAnser) in ... 부분에서 발생을 했는데 자세히 읽어봐야 겠다. 검색도 좀 해보고...

/Users/chriskim/Desktop/NewProject/New line Tool/New line Tool/main.swift:221:42 Tuple pattern cannot match values of non-tuple type 'String.Element' (aka 'Character')

 

let selectedQuizList = quizCategory[selectedCategory]
        let shuffledQuizList = Array(selectedCategory.shuffled().prefix(numQuiz))
        
        for (question, correctAnswer) in shuffledQuizList {
            runQuiz(question: question, correctAnswer: correctAnswer)

 

'String.Element' non-tuple 타입과 Tuple 패턴 값이 매칭이 안된다는 소리인가...? 무슨 소리지...?

찾아보니 튜플을 다루지 않고 실제로는 문자(Character)를 다루고 있었다는 뜻이란다... 음... 그럼 어디를 수정해야 될까?

 

결국 원인은 아래 코드가 문제였다고 한다.

let shuffledQuizList = Array(selectedCategory.shuffled().prefix(numQuiz))

여기서의 selectedCategory는 카테고리 이름, 즉 "일반상식" 같은 문자열이라! 그건 맞지...

아! 그 다음 .shuffled()를 하게되면 "일", "반", "상", "식"이 되겠고 그럼 이걸 for question, correctAnswer in shuffledQuizList로 돌리려다보니 문자 하나를 (question, correctAnswer) 튜플로 받으려다보니 에러가 발생한다는 거군...

 

그럼 selectedCategory 문자열임으로 퀴즈 배열은 quizCategory[selectedCategory]로 꺼내 써야하는게 맞겠지?

아래와 같이 코드를 수정해보자.

let selectedQuizList = quizCategory[selectedCategory]!
let shuffledQuizList = Array(selectedQuizList.shuffled().prefix(numQuiz))

 

그리고 코드 블록에 적용해보자.

let selectedQuizList = quizCategory[selectedCategory]!  // 튜플 배열
let shuffledQuizList = Array(selectedQuizList.shuffled().prefix(numQuiz))

for (question, correctAnswer) in shuffledQuizList {
    runQuiz(question: question, correctAnswer: correctAnswer)
}

 

최종 코드는 아래와 같다.

import Foundation

var goodAnswer = 0
var wrongAnswer = 0
var wrongQuestions: [(String, String)] = []
var answerPercentage = 0.0
var numQuiz = 0
var selectedCategory = ""

    func runQuiz(question: String, correctAnswer: String) {
        print("\(question) (O/X)")
        if let answer = readLine() {
            if answer.uppercased() == correctAnswer.uppercased() {
                print("답변: \(answer)")
                print(">>>> 정답입니다!")
                goodAnswer += 1
            } else {
                print(">>>> 오답입니다!")
                wrongAnswer += 1
                wrongQuestions.append((question, correctAnswer))
            }
        }
        print("\n정답: \(goodAnswer)개 / 오답: \(wrongAnswer)개\n")
    }

print(">>>>> 퀴즈 시작 <<<<<\n")

let quizCategory = [
    "General": [
        ("지구는 태양을 돈다.", "o"),
        ("지구는 태양을 돈다.", "o"),
        ("물은 불보다 가볍다.", "o"),
        ("사람은 4개의 심장을 가지고 있다.", "x"),
        ("2024년도 12월 3일 발동한 비상계엄은 불법이다.", "O"),
        ("이스탄불은 대한민국 도시 중 하나이다.", "X"),
        ("챗GPT는 바보다.", "X")
    ],
    "IT": [
        ("Swift는 애플에서 만든 언어이다.", "o"),
        ("HTML은 프로그래밍 언어다.", "x"),
        ("Xcode는 안드로이드 앱을 개발하는 툴이다.", "x"),
        ("iPhone은 안드로이드 기반이다.", "x"),
        ("Windows OS를 개발한 회사는 Microsoft이다.", "o")
    ],
    "History": [
        ("광복절은 8월 15일이다.", "o"),
        ("조선은 고구려보다 먼저 생겼다.", "x"),
        ("세종대왕은 훈민정음을 만들었다.", "o"),
        ("대략 조선이 건국된 1392년부터 대한제국이 멸망된 1910년까지를 조선시대로 잡고 있다.", "o"),
        ("고구려는 서기전 1세기부터 668년까지 존속한 고대 왕국으로, 압록강 중류 지역에서 시작되다", "o")
    ] ]

print("카테고리를 선택해 주세요.:")
for category in quizCategory.keys {
    print("- \(category)")
}
if let input = readLine(), quizCategory.keys.contains(input) {
    selectedCategory = input
    print("\(selectedCategory)을 선택하셨습니다! 카테고리의 퀴즈를 시작하겠습니다!\n")
} else {
    print("존재하지 않는 카테고리 입니다. 기본값 '일반상식'으로 진행하겠습니다.\n")
    selectedCategory = "일반상식"
}

print("총 다섯개 퀴즈 중 몇개를 풀고 싶으세요?:")

if let input = readLine(), let inputNum = Int(input) {
    numQuiz = inputNum
    print("퀴즈 \(numQuiz)를 랜덤하게 드리겠습니다!")
    
    let selectedQuizList = quizCategory[selectedCategory]!
    let shuffledQuizList = Array(selectedQuizList.shuffled().prefix(numQuiz))
    
    for (question, correctAnswer) in shuffledQuizList {
        runQuiz(question: question, correctAnswer: correctAnswer)
    }
    
    answerPercentage = Double(goodAnswer) / Double(goodAnswer + wrongAnswer) * 100
    print("===. 퀴즈가 종료되었습니다!  ===")
    print("총 정답: \(goodAnswer)개")
    print("총 오답: \(wrongAnswer)개")
    
    print(String(format: "\n정답율: %.1f%%\n", answerPercentage)) //print("정답율: \(answerPercentage)%")
    
    if answerPercentage >= 90 {
        print("\n훌륭한 성적을 거두셨습니다! 고생했어요!\n")
    } else if answerPercentage >= 80 {
        print("\n성실한 성적을 거두셨습니다! 잘했어요!")
    } else if answerPercentage >= 50 {
        print("\n보통적인 성적을 거두셨습니다! 잘했어요!")
    } else if answerPercentage >= 40 {
        print("\n보통적인 성적을 거두셨습니다! 조금 더 노력해 보세요!")
    } else if answerPercentage >= 10 {
        print("\n불합리한 성적을 거두셨습니다! 조금 더 노력해 보세요!")
    }
    
    if !wrongQuestions.isEmpty {
        print("\n오답 질문들을 복습해볼까요?\n")
        for (question, correctAnswer) in wrongQuestions {
            print("문제: \(question)")
            print("정답: \(correctAnswer)")
            print("-----------------------------------")
        }
    } else {
        print("모든 문제를 맞추셨습니다! 복습이 필요없어요!")
    }
}

 

5시간 동안 머리를 굴렸더니 살짝 어지럽다...

조금 쉬었다가 다음 단계로 넘어가야겠다... 커피 한잔 마시고... 아주 쌔게...

728x90
반응형