diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.pbxproj b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e529fed --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.pbxproj @@ -0,0 +1,313 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 7F3CC6772A8B62D400ECA079 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F3CC6762A8B62D400ECA079 /* main.swift */; }; + 7FB2DEFC2A8DFF7800A1BA03 /* ReportCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB2DEFB2A8DFF7800A1BA03 /* ReportCard.swift */; }; + 7FB2DF002A8E042500A1BA03 /* MyCreditManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB2DEFF2A8E042500A1BA03 /* MyCreditManager.swift */; }; + 7FB2DF052A8FB77300A1BA03 /* Grade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB2DF042A8FB77300A1BA03 /* Grade.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 7F3CC6712A8B62D400ECA079 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 7F3CC6732A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MyCreditManager_2_kbs96117; sourceTree = BUILT_PRODUCTS_DIR; }; + 7F3CC6762A8B62D400ECA079 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 7FB2DEFB2A8DFF7800A1BA03 /* ReportCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportCard.swift; sourceTree = ""; }; + 7FB2DEFF2A8E042500A1BA03 /* MyCreditManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCreditManager.swift; sourceTree = ""; }; + 7FB2DF042A8FB77300A1BA03 /* Grade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Grade.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7F3CC6702A8B62D400ECA079 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7F3CC66A2A8B62D400ECA079 = { + isa = PBXGroup; + children = ( + 7F3CC6752A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */, + 7F3CC6742A8B62D400ECA079 /* Products */, + ); + sourceTree = ""; + }; + 7F3CC6742A8B62D400ECA079 /* Products */ = { + isa = PBXGroup; + children = ( + 7F3CC6732A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */, + ); + name = Products; + sourceTree = ""; + }; + 7F3CC6752A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */ = { + isa = PBXGroup; + children = ( + 7F3CC6762A8B62D400ECA079 /* main.swift */, + 7FB2DEFE2A8E03F900A1BA03 /* Class */, + 7FB2DEFA2A8DFF5B00A1BA03 /* Models */, + ); + path = MyCreditManager_2_kbs96117; + sourceTree = ""; + }; + 7FB2DEFA2A8DFF5B00A1BA03 /* Models */ = { + isa = PBXGroup; + children = ( + 7FB2DEFB2A8DFF7800A1BA03 /* ReportCard.swift */, + 7FB2DF042A8FB77300A1BA03 /* Grade.swift */, + ); + path = Models; + sourceTree = ""; + }; + 7FB2DEFE2A8E03F900A1BA03 /* Class */ = { + isa = PBXGroup; + children = ( + 7FB2DEFF2A8E042500A1BA03 /* MyCreditManager.swift */, + ); + path = Class; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7F3CC6722A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7F3CC67A2A8B62D400ECA079 /* Build configuration list for PBXNativeTarget "MyCreditManager_2_kbs96117" */; + buildPhases = ( + 7F3CC66F2A8B62D400ECA079 /* Sources */, + 7F3CC6702A8B62D400ECA079 /* Frameworks */, + 7F3CC6712A8B62D400ECA079 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MyCreditManager_2_kbs96117; + productName = MyCreditManager_2_kbs96117; + productReference = 7F3CC6732A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7F3CC66B2A8B62D400ECA079 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1430; + TargetAttributes = { + 7F3CC6722A8B62D400ECA079 = { + CreatedOnToolsVersion = 14.3.1; + }; + }; + }; + buildConfigurationList = 7F3CC66E2A8B62D400ECA079 /* Build configuration list for PBXProject "MyCreditManager_2_kbs96117" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7F3CC66A2A8B62D400ECA079; + productRefGroup = 7F3CC6742A8B62D400ECA079 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7F3CC6722A8B62D400ECA079 /* MyCreditManager_2_kbs96117 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 7F3CC66F2A8B62D400ECA079 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FB2DF002A8E042500A1BA03 /* MyCreditManager.swift in Sources */, + 7FB2DF052A8FB77300A1BA03 /* Grade.swift in Sources */, + 7F3CC6772A8B62D400ECA079 /* main.swift in Sources */, + 7FB2DEFC2A8DFF7800A1BA03 /* ReportCard.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7F3CC6782A8B62D400ECA079 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 13.3; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7F3CC6792A8B62D400ECA079 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 13.3; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 7F3CC67B2A8B62D400ECA079 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 7F3CC67C2A8B62D400ECA079 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7F3CC66E2A8B62D400ECA079 /* Build configuration list for PBXProject "MyCreditManager_2_kbs96117" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7F3CC6782A8B62D400ECA079 /* Debug */, + 7F3CC6792A8B62D400ECA079 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7F3CC67A2A8B62D400ECA079 /* Build configuration list for PBXNativeTarget "MyCreditManager_2_kbs96117" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7F3CC67B2A8B62D400ECA079 /* Debug */, + 7F3CC67C2A8B62D400ECA079 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7F3CC66B2A8B62D400ECA079 /* Project object */; +} diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/UserInterfaceState.xcuserstate b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..c23d0cd Binary files /dev/null and b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/WorkspaceSettings.xcsettings b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..bbfef02 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/project.xcworkspace/xcuserdata/BOMBSGIE.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,14 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + ShowSharedSchemesAutomaticallyEnabled + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..5a137cb --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcschemes/xcschememanagement.plist b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..c924775 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117.xcodeproj/xcuserdata/BOMBSGIE.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MyCreditManager_2_kbs96117.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Class/MyCreditManager.swift b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Class/MyCreditManager.swift new file mode 100644 index 0000000..33731ef --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Class/MyCreditManager.swift @@ -0,0 +1,239 @@ +// +// MyCreditManager.swift +// MyCreditManager_2_kbs96117 +// +// Created by BOMBSGIE on 2023/08/17. +// + +import Foundation + +final class MyCreditManager { + + private var reportCards: [ReportCard] = [] + + private let inputError: String = "입력이 잘못되었습니다. 다시 확인해주세요." + private var documentDirectory: URL { FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! } + + private var reportCardsFileURL: URL { documentDirectory.appendingPathComponent("reportCards.json") } + + init() { + loadReportCards(filePath: reportCardsFileURL) + } + + func startMainMenu() { + print("원하는 기능을 입력하세요.") + print("1: 학생추가, 2: 학생삭제, 3: 성적추가(변경), 4: 성적삭제, 5: 평점보기, X: 종료") + guard let input = readLine() else {return} + + switch input { + case "1": addStudent() + case "2": deleteStudent() + case "3": updateReport() + case "4": deleteReport() + case "5": showingReport() + case "X": + saveReportCards(reportCards: reportCards, filePath: reportCardsFileURL) + print("프로그램을 종료합니다...") + break + default: + print("뭔가 입력이 잘못되었습니다. 1~5 사이의 숫자 혹은 X를 입력해주세요.") + startMainMenu() + } + + + } + + + + private func addStudent(){ + print("추가할 학생의 이름을 입력해주세요.") + + guard let name = readLine(), validateInput(input: name) else { + print("\(inputError)") + startMainMenu() + return + } + + if checkDuplicateName(studentName: name) { + print("\(name)은 이미 존재하는 학생입니다. 추가하지 않습니다.") + } else { + reportCards.append(ReportCard(sudentName: name, reports: [:])) + print("\(name) 학생을 추가했습니다.") + } + startMainMenu() + } + + + private func deleteStudent() { + print("삭제할 학생의 이름을 입력해주세요.") + + guard let name = readLine(), validateInput(input: name) else { + print("\(inputError)") + startMainMenu() + return + } + + if checkDuplicateName(studentName: name) { + reportCards.removeAll {$0.sudentName == name} + print("\(name) 학생을 삭제하였습니다.") + } else { + printStudentNotFount(name: name) + } + startMainMenu() + } + + + private func updateReport() { + print( + """ + 성적을 추가할 학생의 이름, 과목 이름, 성적(A+, A0, F 등)을 띄어쓰기로 구분하여 차례로 작성해주세요. + 입력예) Mickey Swift A+ + 만약에 학생의 성적 중 해당 과목이 존재하면 기존 점수가 갱신됩니다. + """) + guard let input = readLine() else { return } + let inputs: [String] = input.components(separatedBy: " ") + + guard inputs.count == 3 else { + print("\(inputError)") + startMainMenu() + return + } + + let name: String = inputs[0] + let subject: String = inputs[1] + + guard let grade = Grade(rawValue: inputs[2]), validateInput(input: name) && validateInput(input: subject) else { + print("\(inputError)") + startMainMenu() + return + } + + guard checkDuplicateName(studentName: name) else { + printStudentNotFount(name: name) + startMainMenu() + return + } + + if let studentIndex: Int = reportCards.firstIndex(where: {$0.sudentName == name}) { + reportCards[studentIndex].reports[subject] = grade + print("\(name) 학생의 \(subject) 과목이 \(grade.rawValue)로 추가(변경) 되었습니다.") + } + + startMainMenu() + } + + private func deleteReport() { + print("성적을 삭제할 학생의 이름, 과목 이름을 띄어쓰기로 구분하여 차례로 작성해주세요.") + guard let input = readLine() else { return } + let inputs: [String] = input.components(separatedBy: " ") + + guard inputs.count == 2 && validateInput(input: inputs[0]) && validateInput(input: inputs[1]) else { + print("\(inputError)") + startMainMenu() + return + } + + let name = inputs[0] + let subject = inputs[1] + + + guard let studentIndex: Int = reportCards.firstIndex(where: {$0.sudentName == name}) else { + printStudentNotFount(name: name) + startMainMenu() + return + } + + if let _ = reportCards[studentIndex].reports[subject] { + reportCards[studentIndex].reports.removeValue(forKey: subject) + print("\(name) 학생의 \(subject) 과목의 성적이 삭제되었습니다.") + + } else { + print("\(name) 학생의 \(subject) 과목의 성적이 존재하지 않습니다.") + } + + startMainMenu() + } + + private func showingReport() { + print("평점을 알고싶은 학생의 이름을 입력해주세요.") + guard let name = readLine(), validateInput(input: name) else { + print("\(inputError)") + startMainMenu() + return + } + + + guard let studentIndex: Int = reportCards.firstIndex(where: {$0.sudentName == name}) else { + printStudentNotFount(name: name) + startMainMenu() + return + } + + if !reportCards[studentIndex].reports.isEmpty { + let report = reportCards[studentIndex].reports + let totalScore: Double = report.map {$0.value.score}.reduce(0,+) + let averageScore: String = String(format: "%.2f", totalScore / Double(report.count)) + var roundedAverage: String { + averageScore.hasSuffix("0") ? String(averageScore.dropLast()) : averageScore + } + + report.forEach { subject, grade in + print("\(subject): \(grade.rawValue)") + } + print("평점: \(roundedAverage)") + + + } else { + print("\(name) 학생의 성적이 존재하지 않습니다.") + } + startMainMenu() + } + + +} + + +//MARK: - Extension MyCreditManager +extension MyCreditManager { + + private func checkDuplicateName(studentName: String) -> Bool { + return reportCards.contains { $0.sudentName == studentName} + } + + + private func validateInput(input: String) -> Bool{ + let vaildCharcterSet = CharacterSet.alphanumerics + return input.rangeOfCharacter(from: vaildCharcterSet) != nil && !input.contains(" ") + } + + + private func printStudentNotFount(name: String) { + print("\(name) 학생을 찾지 못했습니다.") + } + + //MARK: - File Persistence로 배열 저장 및 저장된 데이터 불러오는 함수 + private func saveReportCards(reportCards: [ReportCard], filePath: URL) { + do { + let encoder = JSONEncoder() + let jsonData = try encoder.encode(reportCards) + try jsonData.write(to: filePath) + } catch { + print("File Persistence 저장 안됨 \(error)") + } + } + + private func loadReportCards(filePath: URL) { + do { + let jsonData = try Data(contentsOf: filePath) + let decoder = JSONDecoder() + let loadedReportCards = try decoder.decode([ReportCard].self, from: jsonData) + reportCards = loadedReportCards + } catch { + reportCards = [] + } + } + + +} + + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/Grade.swift b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/Grade.swift new file mode 100644 index 0000000..40effb6 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/Grade.swift @@ -0,0 +1,35 @@ +// +// Grade.swift +// MyCreditManager_2_kbs96117 +// +// Created by BOMBSGIE on 2023/08/18. +// + +import Foundation + +enum Grade: String, Codable { + + case aPlus = "A+" + case aZero = "A0" + case bPlus = "B+" + case bZero = "B0" + case cPlus = "C+" + case cZero = "C0" + case dPlus = "D+" + case dZero = "D0" + case f = "F" + + var score: Double { + switch self { + case .aPlus: return 4.5 + case .aZero: return 4.0 + case .bPlus: return 3.5 + case .bZero: return 3.0 + case .cPlus: return 2.5 + case .cZero: return 2.0 + case .dPlus: return 1.5 + case .dZero: return 1.0 + case .f: return 0.0 + } + } +} diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/ReportCard.swift b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/ReportCard.swift new file mode 100644 index 0000000..1e42381 --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/Models/ReportCard.swift @@ -0,0 +1,14 @@ +// +// ReportCard.swift +// MyCreditManager_2_kbs96117 +// +// Created by BOMBSGIE on 2023/08/17. +// + +import Foundation + +struct ReportCard: Codable { + var sudentName: String + var reports: [String: Grade] +} + diff --git a/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/main.swift b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/main.swift new file mode 100644 index 0000000..452224a --- /dev/null +++ b/MyCreditManager_2_kbs96117/MyCreditManager_2_kbs96117/main.swift @@ -0,0 +1,12 @@ +// +// main.swift +// MyCreditManager_2_kbs96117 +// +// Created by BOMBSGIE on 2023/08/15. +// + +import Foundation + +let myCreditManager: MyCreditManager = MyCreditManager() +myCreditManager.startMainMenu() +