diff --git a/IZT6ZK/.editorconfig b/IZT6ZK/.editorconfig new file mode 100644 index 0000000..3cdab5c --- /dev/null +++ b/IZT6ZK/.editorconfig @@ -0,0 +1,269 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_collection_expression = when_types_loosely_match +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_anonymous_function = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_style_namespace_declarations = file_scoped:suggestion +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_top_level_statements = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = warning +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +[*.{cs,vb}] +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_readonly_field = true:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_allow_multiple_blank_lines_experimental = true:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_code_quality_unused_parameters = all:suggestion +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent \ No newline at end of file diff --git a/IZT6ZK/Assists/ConsoleHelper.cs b/IZT6ZK/Assists/ConsoleHelper.cs new file mode 100644 index 0000000..84ac131 --- /dev/null +++ b/IZT6ZK/Assists/ConsoleHelper.cs @@ -0,0 +1,64 @@ +using IZT6ZK.Db; +using IZT6ZK.Models; +using IZT6ZK.Records; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Assists; +internal class ConsoleHelper +{ + public static void WriteQuit() + { + Console.WriteLine("\nWrite 'quit' if you want to quit."); + } + public static void WriteQuitAll() + { + Console.WriteLine("Write 'quit all' if you want to quit all of the questions.\n"); + } + public static string ReadAndWrite(string whatWeWantToAskFromUser) + { + Console.WriteLine($"\nWrite {whatWeWantToAskFromUser}: "); + var input = Console.ReadLine(); + return input ?? ""; + } + + public static void WriteOutAllTopics(List allTopics) + { + Console.WriteLine("\nThe possible topics: "); + + foreach (var allTopic in allTopics) + { + Console.WriteLine($"{allTopic.TopicId}: {allTopic.TopicName}"); + } + } + + public static void WriteOutAllQuestions(List allQuestions) + { + Console.WriteLine("\nThe possible questions: "); + + foreach (var allQuestion in allQuestions) + { + Console.WriteLine($"{allQuestion.QuestionId}: {allQuestion.Question}"); + } + } + + public static void WriteOutTheResultOfTheQuiz(List questionRecords, List allQuestions) + { + Console.WriteLine("Your result: "); + var correctAnswers = questionRecords.Count(x => x.CorrectAnswer == x.UserAnswer); + var incorrectAnswers = questionRecords.Count(x => x.CorrectAnswer != x.UserAnswer); + var quitedQuestions = allQuestions.Count - questionRecords.Count; + + foreach (var questionRecord in questionRecords) + { + Console.WriteLine(questionRecord.ToString()); + } + + Console.WriteLine($"\nNumber of correct answers: {correctAnswers}"); + Console.WriteLine($"Number of incorrect answers: {incorrectAnswers}"); + Console.WriteLine($"Number of quitted questions: {quitedQuestions}\n"); + } +} diff --git a/IZT6ZK/Assists/ValidateInputs.cs b/IZT6ZK/Assists/ValidateInputs.cs new file mode 100644 index 0000000..cc5f670 --- /dev/null +++ b/IZT6ZK/Assists/ValidateInputs.cs @@ -0,0 +1,48 @@ +using IZT6ZK.StateMachine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Assists; +internal class ValidateInputs +{ + public static string ValidateInputsIfEmptyOrQuit(string input) + { + if (string.IsNullOrEmpty(input) || string.IsNullOrWhiteSpace(input)) + { + Console.WriteLine("Write something please!"); + return String.Empty; + } + + input = input.Trim(); + + if (input == "quit") + { + return "quit"; + } + return input; + } + + public static string ValidateInputsIfEmptyOrQuitOrQuitAll(string input) + { + if (string.IsNullOrEmpty(input) || string.IsNullOrWhiteSpace(input)) + { + Console.WriteLine("Write something please!"); + return String.Empty; + } + + input = input.Trim(); + + if (input == "quit") + { + return "quit"; + } + if (input == "quit all") + { + return "quit all"; + } + return input; + } +} diff --git a/IZT6ZK/Commands/CommandsDict.cs b/IZT6ZK/Commands/CommandsDict.cs new file mode 100644 index 0000000..03c26bb --- /dev/null +++ b/IZT6ZK/Commands/CommandsDict.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; + +internal class CommandsDict +{ + public static Dictionary commandsDict = new Dictionary() + { + {"help", new HelpCommand() }, + {"exit", new ExitCommand() }, + {"start all", new StartAllQuestionsCommand() }, + {"start one topic", new StartJustTheTopicQuestionsCommand()}, + {"create question", new CreateQuestionCommand() }, + {"create topic", new CreateTopicCommand() }, + {"update question", new UpdateQuestionsTopic() }, + {"update topic", new UpdateTopic() }, + {"delete question", new DeleteQuestionCommand() }, + {"delete topic", new DeleteTopicCommand() }, + }; +} diff --git a/IZT6ZK/Commands/CreateQuestionCommand.cs b/IZT6ZK/Commands/CreateQuestionCommand.cs new file mode 100644 index 0000000..3500c0c --- /dev/null +++ b/IZT6ZK/Commands/CreateQuestionCommand.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using IZT6ZK.Assists; +using IZT6ZK.Db; +using IZT6ZK.StateMachine; + +namespace IZT6ZK.Commands; + +internal class CreateQuestionCommand : ICommands +{ + public void Execute() + { + DbManager dbManager = new DbManager(); + string? input = null; + List? inputQuestionAndAnswers = new List(); + + string? inputWantTopic = null; + string? inputTopicId = null; + int wantedTopicId = 0; + + bool loopGoing = true; + var stateQuestionReading = CreateQuestionStateMachine.QuestionReading; + + ConsoleHelper.WriteQuit(); + + while (loopGoing) + { + switch (stateQuestionReading) + { + case CreateQuestionStateMachine.QuestionReading: + input = ConsoleHelper.ReadAndWrite("your question"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.Answer1Reading; + break; + + case CreateQuestionStateMachine.Answer1Reading: + input = ConsoleHelper.ReadAndWrite("the first answer"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.Answer2Reading; + break; + + case CreateQuestionStateMachine.Answer2Reading: + input = ConsoleHelper.ReadAndWrite("the second answer"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + else if (inputQuestionAndAnswers.Contains(input)) + { + Console.WriteLine("Please write something else than the other answers!"); + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.Answer3Reading; + break; + + case CreateQuestionStateMachine.Answer3Reading: + input = ConsoleHelper.ReadAndWrite("the third answer"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + else if (inputQuestionAndAnswers.Contains(input)) + { + Console.WriteLine("Please write something else than the other answers!"); + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.Answer4Reading; + break; + + case CreateQuestionStateMachine.Answer4Reading: + input = ConsoleHelper.ReadAndWrite("the fourth answer"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + else if (inputQuestionAndAnswers.Contains(input)) + { + Console.WriteLine("Please write something else than the other answers!"); + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.CorrectAnswerReading; + break; + + case CreateQuestionStateMachine.CorrectAnswerReading: + input = ConsoleHelper.ReadAndWrite("the correct answer"); + input = ValidateInputs.ValidateInputsIfEmptyOrQuit(input); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + else if (!inputQuestionAndAnswers.Contains(input)) + { + Console.WriteLine("Please write a correct answer from the previous answers!"); + break; + } + inputQuestionAndAnswers.Add(input); + stateQuestionReading = CreateQuestionStateMachine.WantToReadTopic; + break; + + + case CreateQuestionStateMachine.WantToReadTopic: + Console.WriteLine("\nDo you want to add topic for your question? Yes or No"); + inputWantTopic = Console.ReadLine(); + inputWantTopic = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputWantTopic); + inputWantTopic = inputWantTopic.ToLower(); + + if (input == String.Empty) + { + break; + } + else if (input == "quit") + { + stateQuestionReading = CreateQuestionStateMachine.QuitFromCreateQuestion; + break; + } + else if (inputWantTopic == "no") + { + stateQuestionReading = CreateQuestionStateMachine.EverythingWasFineQuestionCreate; + break; + } + else if (inputWantTopic == "yes") + { + stateQuestionReading = CreateQuestionStateMachine.TopicReading; + break; + } + Console.WriteLine("Please write Yes or No!"); + break; + + case CreateQuestionStateMachine.TopicReading: + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.Count == 0) + { + Console.WriteLine("There is no topic in the database!"); + stateQuestionReading = CreateQuestionStateMachine.EverythingWasFineQuestionCreate; + break; + } + ConsoleHelper.WriteOutAllTopics(allTopics); + + inputTopicId = ConsoleHelper.ReadAndWrite("the id of the topic"); + inputTopicId = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputTopicId); + + int.TryParse(inputTopicId, out wantedTopicId); + var topicEntity = dbManager.SelectTopic(wantedTopicId); + + if (topicEntity != null) + { + stateQuestionReading = CreateQuestionStateMachine.EverythingWasFineQuestionCreateWithTopic; + break; + } + Console.WriteLine("Please write an existing topic id!"); + break; + + + case CreateQuestionStateMachine.EverythingWasFineQuestionCreateWithTopic: + dbManager.CreateQuestion(inputQuestionAndAnswers[0], inputQuestionAndAnswers[1], inputQuestionAndAnswers[2], inputQuestionAndAnswers[3], inputQuestionAndAnswers[4], inputQuestionAndAnswers[5], wantedTopicId); + Console.WriteLine("\nCongratulations, you created a question!\n"); + loopGoing = false; + break; + + case CreateQuestionStateMachine.EverythingWasFineQuestionCreate: + dbManager.CreateQuestion(inputQuestionAndAnswers[0], inputQuestionAndAnswers[1], inputQuestionAndAnswers[2], inputQuestionAndAnswers[3], inputQuestionAndAnswers[4], inputQuestionAndAnswers[5], null); + Console.WriteLine("\nCongratulations, you created a question!\n"); + loopGoing = false; + break; + + case CreateQuestionStateMachine.QuitFromCreateQuestion: + Console.WriteLine("You quitted! \n"); + loopGoing = false; + break; + + default: + loopGoing = false; + break; + } + } + } +} diff --git a/IZT6ZK/Commands/CreateTopicCommand.cs b/IZT6ZK/Commands/CreateTopicCommand.cs new file mode 100644 index 0000000..1d3b11a --- /dev/null +++ b/IZT6ZK/Commands/CreateTopicCommand.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using IZT6ZK.Assists; +using IZT6ZK.Db; + +namespace IZT6ZK.Commands; + +internal class CreateTopicCommand : ICommands +{ + public void Execute() + { + DbManager dbManager = new DbManager(); + string? inputTopicName = null; + + ConsoleHelper.WriteQuit(); + + while (true) + { + inputTopicName = ConsoleHelper.ReadAndWrite("your topic's name (for example: cats)"); + inputTopicName = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputTopicName); + + if (inputTopicName == String.Empty) + { + continue; + } + if (inputTopicName == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.FirstOrDefault(x => x.TopicName.ToLower() == inputTopicName.ToLower()) is not null) + { + Console.WriteLine("This topic already exists!"); + continue; + } + dbManager.CreateTopic(inputTopicName); + Console.WriteLine("\nCongratulations, you created a topic!\n"); + break; + } + } +} diff --git a/IZT6ZK/Commands/DeleteQuestionCommand.cs b/IZT6ZK/Commands/DeleteQuestionCommand.cs new file mode 100644 index 0000000..8907ee4 --- /dev/null +++ b/IZT6ZK/Commands/DeleteQuestionCommand.cs @@ -0,0 +1,73 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; +internal class DeleteQuestionCommand : ICommands +{ + public void Execute() + { + var dbManager = new DbManager(); + string? inputQuestionId; + + ConsoleHelper.WriteQuit(); + + while (true) + { + var allQuestions = dbManager.SelectAllQuestions(); + + if (allQuestions.Count == 0) + { + Console.WriteLine("There are no questions in the database!\n"); + break; + } + + ConsoleHelper.WriteOutAllQuestions(allQuestions); + + inputQuestionId = ConsoleHelper.ReadAndWrite("the question's id, you want to delete"); + inputQuestionId = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputQuestionId); + + if (inputQuestionId == String.Empty) + { + continue; + } + if (inputQuestionId == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + int.TryParse(inputQuestionId, out var questionId); + var questionEntity = dbManager.SelectQuestion(questionId); + + if (questionEntity != null) + { + Console.WriteLine("Are you sure? Yes or No"); + var yesOrNo = Console.ReadLine(); + yesOrNo = yesOrNo.Trim().ToLower(); + + if (yesOrNo == "no") + { + Console.WriteLine("You didn't delete the question!"); + continue; + } + else if (yesOrNo == "yes") + { + dbManager.DeleteQuestion(questionEntity); + Console.WriteLine("\nCongratulations, you deleted the question!\n"); + break; + } + else + { + Console.WriteLine("Please write 'yes' or 'no'!"); + continue; + } + } + Console.WriteLine("Please write an existing question id!"); + continue; + } + } +} diff --git a/IZT6ZK/Commands/DeleteTopicCommand.cs b/IZT6ZK/Commands/DeleteTopicCommand.cs new file mode 100644 index 0000000..0701dc5 --- /dev/null +++ b/IZT6ZK/Commands/DeleteTopicCommand.cs @@ -0,0 +1,75 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; +internal class DeleteTopicCommand : ICommands +{ + public void Execute() + { + DbManager dbManager = new DbManager(); + string? inputTopicId; + + ConsoleHelper.WriteQuit(); + + while (true) + { + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.Count == 0) + { + Console.WriteLine("There are no topics in the database!\n"); + break; + } + + ConsoleHelper.WriteOutAllTopics(allTopics); + + inputTopicId = ConsoleHelper.ReadAndWrite("the topic's id, you want to delete"); + inputTopicId = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputTopicId); + + if (inputTopicId == String.Empty) + { + continue; + } + if (inputTopicId == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + + int.TryParse(inputTopicId, out var topicId); + var topicEntity = dbManager.SelectTopic(topicId); + + if (topicEntity != null) + { + Console.WriteLine("Are you sure? Yes or No"); + var yesOrNo = Console.ReadLine(); + yesOrNo = yesOrNo.Trim().ToLower(); + + if (yesOrNo == "no") + { + Console.WriteLine("You didn't delete the topic!"); + continue; + } + else if (yesOrNo == "yes") + { + dbManager.DeleteTopic(topicEntity); + Console.WriteLine("\nCongratulations, you deleted the topic!\n"); + break; + } + else + { + Console.WriteLine("Please write 'yes' or 'no'!"); + continue; + } + } + Console.WriteLine("Please write an existing topic id!"); + continue; + + } + } +} diff --git a/IZT6ZK/Commands/ExitCommand.cs b/IZT6ZK/Commands/ExitCommand.cs new file mode 100644 index 0000000..11c1269 --- /dev/null +++ b/IZT6ZK/Commands/ExitCommand.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; + +internal record class ExitCommand : ICommands +{ + public void Execute() + { + Console.WriteLine("Goodbye dear Visitor! Have a nice day!"); + Environment.Exit(0); + } +} diff --git a/IZT6ZK/Commands/HelpCommand.cs b/IZT6ZK/Commands/HelpCommand.cs new file mode 100644 index 0000000..58971d4 --- /dev/null +++ b/IZT6ZK/Commands/HelpCommand.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; + +internal class HelpCommand : ICommands +{ + public void Execute() + { + Console.WriteLine("You can use these commands: "); + foreach (var command in CommandsDict.commandsDict.Keys) + { + Console.Write($"{command} | "); + } + Console.WriteLine("\n"); + } +} diff --git a/IZT6ZK/Commands/ICommands.cs b/IZT6ZK/Commands/ICommands.cs new file mode 100644 index 0000000..0661377 --- /dev/null +++ b/IZT6ZK/Commands/ICommands.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; + +internal interface ICommands +{ + void Execute(); +} diff --git a/IZT6ZK/Commands/StartAllQuestionsCommand.cs b/IZT6ZK/Commands/StartAllQuestionsCommand.cs new file mode 100644 index 0000000..fa173de --- /dev/null +++ b/IZT6ZK/Commands/StartAllQuestionsCommand.cs @@ -0,0 +1,77 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using IZT6ZK.Records; + +namespace IZT6ZK.Commands; + +internal class StartAllQuestionsCommand : ICommands +{ + public void Execute() + { + var dbManager = new DbManager(); + var allQuestions = dbManager.SelectAllQuestions(); + bool loopGoing = true; + + var questionRecords = new List(); + + ConsoleHelper.WriteQuit(); + ConsoleHelper.WriteQuitAll(); + + foreach (var question in allQuestions) + { + if (question == null) + { + Console.WriteLine("There is no question, sorry!"); + break; + } + + while (loopGoing) + { + Console.WriteLine(question.ToString()); + + var inputAnswer = Console.ReadLine(); + + inputAnswer = ValidateInputs.ValidateInputsIfEmptyOrQuitOrQuitAll(inputAnswer); + + if (inputAnswer == string.Empty) + { + continue; + } + if (inputAnswer == "quit") + { + Console.WriteLine("\nYou quitted the question!\n"); + break; + } + if (inputAnswer == "quit all") + { + Console.WriteLine("\nYou quitted all of the questions!\n"); + loopGoing = false; + break; + } + if (inputAnswer != question.Answer1 && inputAnswer != question.Answer2 + && inputAnswer != question.Answer3 && inputAnswer != question.Answer4) + { + Console.WriteLine("There is no such answer! Try again!"); + continue; + } + if (inputAnswer.Equals(question.CorrectAnswer)) + { + Console.WriteLine("Correct answer!\n"); + questionRecords.Add(new QuestionRecordForStatistic(question.Question, question.CorrectAnswer, inputAnswer)); + break; + } + + Console.WriteLine("Incorrect answer! You can try again after you finished this round.\n"); + questionRecords.Add(new QuestionRecordForStatistic(question.Question, question.CorrectAnswer, inputAnswer)); + break; + } + } + + if (questionRecords.Count == 0) + { + return; + } + Console.WriteLine("End of the questions.\n"); + ConsoleHelper.WriteOutTheResultOfTheQuiz(questionRecords, allQuestions); + } +} diff --git a/IZT6ZK/Commands/StartJustTheTopicQuestionsCommand.cs b/IZT6ZK/Commands/StartJustTheTopicQuestionsCommand.cs new file mode 100644 index 0000000..748a9d3 --- /dev/null +++ b/IZT6ZK/Commands/StartJustTheTopicQuestionsCommand.cs @@ -0,0 +1,124 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using IZT6ZK.Models; +using IZT6ZK.Records; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; +internal class StartJustTheTopicQuestionsCommand : ICommands +{ + public void Execute() + { + var dbManager = new DbManager(); + string? inputTopicId = null; + int wantedTopicId = 0; + + List allQuestionsFromATopic = new List(); + bool outerLoopGoing = true; + bool innerLoopGoing = true; + + var questionRecords = new List(); + + ConsoleHelper.WriteQuit(); + ConsoleHelper.WriteQuitAll(); + + while (outerLoopGoing) + { + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.Count == 0) + { + Console.WriteLine("There is no topic, sorry!"); + break; + } + + ConsoleHelper.WriteOutAllTopics(allTopics); + + inputTopicId = ConsoleHelper.ReadAndWrite("the id of the topic"); + inputTopicId = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputTopicId); + + if (inputTopicId == string.Empty) + { + continue; + } + if (inputTopicId == "quit") + { + Console.WriteLine("You quitted\n"); + outerLoopGoing = false; + break; + } + + int.TryParse(inputTopicId, out wantedTopicId); + allQuestionsFromATopic = dbManager.SelectAllQuestionsFromOneTopic(wantedTopicId); + + if (dbManager.SelectTopic(wantedTopicId) == null) + { + Console.WriteLine("Please write an existing topic id!"); + continue; + } + + if (allQuestionsFromATopic.Count == 0) + { + Console.WriteLine("Sadly there is no question in this topic!\n"); + continue; + } + + foreach (var question in allQuestionsFromATopic) + { + while (innerLoopGoing) + { + Console.WriteLine(question.ToString()); + + var inputAnswer = Console.ReadLine(); + inputAnswer = ValidateInputs.ValidateInputsIfEmptyOrQuitOrQuitAll(inputAnswer); + + if (inputAnswer == string.Empty) + { + continue; + } + if (inputAnswer == "quit") + { + Console.WriteLine("\nYou quitted the question!\n"); + break; + } + if (inputAnswer == "quit all") + { + Console.WriteLine("\nYou quitted all of the questions!\n"); + innerLoopGoing = false; + outerLoopGoing = false; + break; + } + if (inputAnswer != question.Answer1 && inputAnswer != question.Answer2 + && inputAnswer != question.Answer3 && inputAnswer != question.Answer4) + { + Console.WriteLine("There is no such answer! Try again!"); + continue; + } + if (inputAnswer.Equals(question.CorrectAnswer)) + { + Console.WriteLine("Correct answer!\n"); + questionRecords.Add(new QuestionRecordForStatistic(question.Question, question.CorrectAnswer, inputAnswer)); + break; + } + + Console.WriteLine("Incorrect answer! You can try again after you finished this round.\n"); + questionRecords.Add(new QuestionRecordForStatistic(question.Question, question.CorrectAnswer, inputAnswer)); + break; + } + } + outerLoopGoing = false; + break; + + } + if (questionRecords.Count == 0) + { + return; + } + Console.WriteLine("End of the questions.\n"); + ConsoleHelper.WriteOutTheResultOfTheQuiz(questionRecords, allQuestionsFromATopic); + } +} diff --git a/IZT6ZK/Commands/UpdateQuestionsTopic.cs b/IZT6ZK/Commands/UpdateQuestionsTopic.cs new file mode 100644 index 0000000..27bc324 --- /dev/null +++ b/IZT6ZK/Commands/UpdateQuestionsTopic.cs @@ -0,0 +1,95 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; +internal class UpdateQuestionsTopic : ICommands +{ + public void Execute() + { + var dbManager = new DbManager(); + string? inputQuestionId; + + ConsoleHelper.WriteQuit(); + + while (true) + { + var allQuestions = dbManager.SelectAllQuestions(); + + if (allQuestions.Count == 0) + { + Console.WriteLine("There is no question in the database!"); + break; + } + ConsoleHelper.WriteOutAllQuestions(allQuestions); + + inputQuestionId = ConsoleHelper.ReadAndWrite("the question's id, you want to update"); + inputQuestionId = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputQuestionId); + + if (inputQuestionId == String.Empty) + { + continue; + } + if (inputQuestionId == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + + int.TryParse(inputQuestionId, out var questionId); + var questionEntity = dbManager.SelectQuestion(questionId); + + if (questionEntity != null) + { + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.Count == 0) + { + Console.WriteLine("There is no topic in the database!"); + break; + } + ConsoleHelper.WriteOutAllTopics(allTopics); + + Console.WriteLine("You can write 'null' if you don't want to assign a topic to the question."); + var newTopicId = ConsoleHelper.ReadAndWrite("the new topic id"); + newTopicId = ValidateInputs.ValidateInputsIfEmptyOrQuit(newTopicId); + + if (newTopicId == String.Empty) + { + continue; + } + if (newTopicId == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + if (newTopicId == "null") + { + questionEntity.TopicId = null; + dbManager.UpdateQuestion(questionEntity); + Console.WriteLine("\nCongratulations, you updated the question's topic!\n"); + break; + } + + int.TryParse(newTopicId, out var topicId); + var topicEntity = dbManager.SelectTopic(topicId); + + if (topicEntity != null) + { + questionEntity.TopicId = topicId; + dbManager.UpdateQuestion(questionEntity); + Console.WriteLine("\nCongratulations, you updated the question's topic!\n"); + break; + } + Console.WriteLine("Please write an existing topic id!"); + continue; + } + Console.WriteLine("Please write an existing question id!"); + continue; + } + } +} diff --git a/IZT6ZK/Commands/UpdateTopic.cs b/IZT6ZK/Commands/UpdateTopic.cs new file mode 100644 index 0000000..6d0838a --- /dev/null +++ b/IZT6ZK/Commands/UpdateTopic.cs @@ -0,0 +1,76 @@ +using IZT6ZK.Assists; +using IZT6ZK.Db; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Commands; +internal class UpdateTopic : ICommands +{ + public void Execute() + { + var dbManager = new DbManager(); + string? inputTopic; + + ConsoleHelper.WriteQuit(); + + while (true) + { + var allTopics = dbManager.SelectAllTopic(); + + if (allTopics.Count == 0) + { + Console.WriteLine("There is no topic in the database!"); + break; + } + + ConsoleHelper.WriteOutAllTopics(allTopics); + + inputTopic = ConsoleHelper.ReadAndWrite("the topic's id, you want to update"); + inputTopic = ValidateInputs.ValidateInputsIfEmptyOrQuit(inputTopic); + + if (inputTopic == String.Empty) + { + continue; + } + if (inputTopic == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + + int.TryParse(inputTopic, out var topicId); + var topicEntity = dbManager.SelectTopic(topicId); + + if (topicEntity != null) + { + var newTopicName = ConsoleHelper.ReadAndWrite("the new topic name"); + newTopicName = ValidateInputs.ValidateInputsIfEmptyOrQuit(newTopicName); + + if (newTopicName == String.Empty) + { + continue; + } + if (newTopicName == "quit") + { + Console.WriteLine("You quitted!\n"); + break; + } + if (allTopics.FirstOrDefault(x => x.TopicName.ToLower() == newTopicName.ToLower()) is not null + && topicEntity.TopicName.ToLower() != newTopicName.ToLower()) + { + Console.WriteLine("\nThis topic already exists!"); + continue; + } + topicEntity.TopicName = newTopicName; + dbManager.UpdateTopic(topicEntity); + Console.WriteLine("\nCongratulations, you updated the topic!\n"); + break; + } + Console.WriteLine("Please write an existing topic id!"); + continue; + } + } +} diff --git a/IZT6ZK/Db/DbManager.cs b/IZT6ZK/Db/DbManager.cs new file mode 100644 index 0000000..46553a1 --- /dev/null +++ b/IZT6ZK/Db/DbManager.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata; +using System.Text; +using System.Threading.Tasks; +using IZT6ZK.Models; +using Microsoft.EntityFrameworkCore; + +namespace IZT6ZK.Db; + +internal class DbManager : IDbManager +{ + + public void CreateQuestion(string question, string answer1, string answer2, string answer3, string answer4, string correctAnswer, int? topicId) + { + + using var Db = new MyDbContext(); + + Db.Questions.Add(new QuestionEntity() { Question = question, Answer1 = answer1, Answer2 = answer2, Answer3 = answer3, Answer4 = answer4, CorrectAnswer = correctAnswer, TopicId = topicId }); + Db.SaveChanges(); + } + + public void CreateTopic(string topicName) + { + using var Db = new MyDbContext(); + + Db.Add(new TopicEntity() { TopicName = topicName }); + Db.SaveChanges(); + } + + public void DeleteQuestion(QuestionEntity question) + { + using var Db = new MyDbContext(); + + Db.Questions.Remove(question); + Db.SaveChanges(); + } + + public void DeleteTopic(TopicEntity topicEntity) + { + using var Db = new MyDbContext(); + + Db.Topics.Remove(topicEntity); + Db.SaveChanges(); + } + + public List SelectAllQuestions() + { + using var Db = new MyDbContext(); + + var allQuestions = Db.Questions.ToList(); + return allQuestions; + } + + public List SelectAllQuestionsFromOneTopic(int topicId) + { + using var Db = new MyDbContext(); + + var allQuestionsFromTopic = Db.Questions.Where(x => x.TopicId == topicId).ToList(); + return allQuestionsFromTopic; + + } + + public List SelectAllTopic() + { + using var Db = new MyDbContext(); + + var allTopics = Db.Topics.ToList(); + return allTopics; + } + + public QuestionEntity SelectQuestion(int questionId) + { + using var Db = new MyDbContext(); + + var question = Db.Questions.Where(x => x.QuestionId == questionId).FirstOrDefault(); + return question; + } + + public TopicEntity SelectTopic(int topicId) + { + using var Db = new MyDbContext(); + + var topic = Db.Topics.Where(x => x.TopicId == topicId).FirstOrDefault(); + return topic; + } + + public void UpdateQuestion(QuestionEntity questionEntity) + { + using var Db = new MyDbContext(); + var questionTopic = Db.Questions.Update(questionEntity); + Db.SaveChanges(); + } + + public void UpdateTopic(TopicEntity topicEntity) + { + using var Db = new MyDbContext(); + var topic = Db.Topics.Update(topicEntity); + Db.SaveChanges(); + } +} diff --git a/IZT6ZK/Db/IDbManager.cs b/IZT6ZK/Db/IDbManager.cs new file mode 100644 index 0000000..a779f91 --- /dev/null +++ b/IZT6ZK/Db/IDbManager.cs @@ -0,0 +1,25 @@ +using IZT6ZK.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Db; + +internal interface IDbManager +{ + public void CreateTopic(string topicName); + public TopicEntity SelectTopic(int topicId); + public List SelectAllTopic(); + public void UpdateTopic(TopicEntity topicEntity); + public void DeleteTopic(TopicEntity topicEntity); + + public void CreateQuestion(string question, string answer1, string answer2, string answer3, string answer4, string correctAnswer, int? topicId); + public QuestionEntity SelectQuestion(int questionId); + public List SelectAllQuestionsFromOneTopic(int topicId); + public List SelectAllQuestions(); + public void UpdateQuestion(QuestionEntity questionEntity); + public void DeleteQuestion(QuestionEntity question); + +} diff --git a/IZT6ZK/Db/MyDbContext.cs b/IZT6ZK/Db/MyDbContext.cs new file mode 100644 index 0000000..20f9144 --- /dev/null +++ b/IZT6ZK/Db/MyDbContext.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata; +using System.Text; +using System.Threading.Tasks; +using IZT6ZK.Models; +using Microsoft.EntityFrameworkCore; + +namespace IZT6ZK.Db; + +internal class MyDbContext : DbContext +{ + public DbSet Questions { get; set; } + public DbSet Topics { get; set; } + + public MyDbContext() + { + } + protected override void OnConfiguring(DbContextOptionsBuilder options) + => options + .UseSqlite($"Data Source=questions.db"); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + + entity.ToTable("Questions"); + entity.HasKey(p => p.QuestionId); + + entity.HasOne(p => p.Topic) + .WithMany(p => p.Questions) + .HasForeignKey(p => p.TopicId) + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Topics"); + entity.HasKey(p => p.TopicId); + }); + + + } + + +} diff --git a/IZT6ZK/IZT6ZK.csproj b/IZT6ZK/IZT6ZK.csproj new file mode 100644 index 0000000..009b7ff --- /dev/null +++ b/IZT6ZK/IZT6ZK.csproj @@ -0,0 +1,26 @@ + + + + Exe + net8.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/IZT6ZK/Migrations/20241024182826_InitialCreate.Designer.cs b/IZT6ZK/Migrations/20241024182826_InitialCreate.Designer.cs new file mode 100644 index 0000000..7effbe4 --- /dev/null +++ b/IZT6ZK/Migrations/20241024182826_InitialCreate.Designer.cs @@ -0,0 +1,91 @@ +// +using System; + +using IZT6ZK.Db; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IZT6ZK.Migrations +{ + [DbContext(typeof(MyDbContext))] + [Migration("20241024182826_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); + + modelBuilder.Entity("IZT6ZK.QuestionEntity", b => + { + b.Property("QuestionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Answer1") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer2") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer3") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer4") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CorrectAnswer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Question") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TopicId") + .HasColumnType("INTEGER"); + + b.HasKey("QuestionId"); + + b.HasIndex("TopicId"); + + b.ToTable("Questions", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.TopicEntity", b => + { + b.Property("TopicId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TopicName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("TopicId"); + + b.ToTable("Topics", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.QuestionEntity", b => + { + b.HasOne("IZT6ZK.TopicEntity", "Topic") + .WithMany() + .HasForeignKey("TopicId"); + + b.Navigation("Topic"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IZT6ZK/Migrations/20241024182826_InitialCreate.cs b/IZT6ZK/Migrations/20241024182826_InitialCreate.cs new file mode 100644 index 0000000..fc0bc80 --- /dev/null +++ b/IZT6ZK/Migrations/20241024182826_InitialCreate.cs @@ -0,0 +1,66 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IZT6ZK.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Topics", + columns: table => new + { + TopicId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + TopicName = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Topics", x => x.TopicId); + }); + + migrationBuilder.CreateTable( + name: "Questions", + columns: table => new + { + QuestionId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Question = table.Column(type: "TEXT", nullable: false), + Answer1 = table.Column(type: "TEXT", nullable: false), + Answer2 = table.Column(type: "TEXT", nullable: false), + Answer3 = table.Column(type: "TEXT", nullable: false), + Answer4 = table.Column(type: "TEXT", nullable: false), + CorrectAnswer = table.Column(type: "TEXT", nullable: false), + TopicId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Questions", x => x.QuestionId); + table.ForeignKey( + name: "FK_Questions_Topics_TopicId", + column: x => x.TopicId, + principalTable: "Topics", + principalColumn: "TopicId"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Questions_TopicId", + table: "Questions", + column: "TopicId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Questions"); + + migrationBuilder.DropTable( + name: "Topics"); + } + } +} diff --git a/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.Designer.cs b/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.Designer.cs new file mode 100644 index 0000000..5f453b3 --- /dev/null +++ b/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.Designer.cs @@ -0,0 +1,95 @@ +// +using System; +using IZT6ZK.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IZT6ZK.Migrations +{ + [DbContext(typeof(MyDbContext))] + [Migration("20241124153959_TopicCascadeDelete")] + partial class TopicCascadeDelete + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); + + modelBuilder.Entity("IZT6ZK.Models.QuestionEntity", b => + { + b.Property("QuestionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Answer1") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer2") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer3") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer4") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CorrectAnswer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Question") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TopicId") + .HasColumnType("INTEGER"); + + b.HasKey("QuestionId"); + + b.HasIndex("TopicId"); + + b.ToTable("Questions", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.Models.TopicEntity", b => + { + b.Property("TopicId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TopicName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("TopicId"); + + b.ToTable("Topics", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.Models.QuestionEntity", b => + { + b.HasOne("IZT6ZK.Models.TopicEntity", "Topic") + .WithMany("Questions") + .HasForeignKey("TopicId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("IZT6ZK.Models.TopicEntity", b => + { + b.Navigation("Questions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.cs b/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.cs new file mode 100644 index 0000000..f0e0f08 --- /dev/null +++ b/IZT6ZK/Migrations/20241124153959_TopicCascadeDelete.cs @@ -0,0 +1,41 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IZT6ZK.Migrations +{ + /// + public partial class TopicCascadeDelete : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Questions_Topics_TopicId", + table: "Questions"); + + migrationBuilder.AddForeignKey( + name: "FK_Questions_Topics_TopicId", + table: "Questions", + column: "TopicId", + principalTable: "Topics", + principalColumn: "TopicId", + onDelete: ReferentialAction.SetNull); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Questions_Topics_TopicId", + table: "Questions"); + + migrationBuilder.AddForeignKey( + name: "FK_Questions_Topics_TopicId", + table: "Questions", + column: "TopicId", + principalTable: "Topics", + principalColumn: "TopicId"); + } + } +} diff --git a/IZT6ZK/Migrations/MyDbContextModelSnapshot.cs b/IZT6ZK/Migrations/MyDbContextModelSnapshot.cs new file mode 100644 index 0000000..f36183f --- /dev/null +++ b/IZT6ZK/Migrations/MyDbContextModelSnapshot.cs @@ -0,0 +1,92 @@ +// +using System; +using IZT6ZK.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IZT6ZK.Migrations +{ + [DbContext(typeof(MyDbContext))] + partial class MyDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); + + modelBuilder.Entity("IZT6ZK.Models.QuestionEntity", b => + { + b.Property("QuestionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Answer1") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer2") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer3") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Answer4") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CorrectAnswer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Question") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TopicId") + .HasColumnType("INTEGER"); + + b.HasKey("QuestionId"); + + b.HasIndex("TopicId"); + + b.ToTable("Questions", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.Models.TopicEntity", b => + { + b.Property("TopicId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TopicName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("TopicId"); + + b.ToTable("Topics", (string)null); + }); + + modelBuilder.Entity("IZT6ZK.Models.QuestionEntity", b => + { + b.HasOne("IZT6ZK.Models.TopicEntity", "Topic") + .WithMany("Questions") + .HasForeignKey("TopicId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("IZT6ZK.Models.TopicEntity", b => + { + b.Navigation("Questions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/IZT6ZK/Models/QuestionEntity.cs b/IZT6ZK/Models/QuestionEntity.cs new file mode 100644 index 0000000..39d5c9b --- /dev/null +++ b/IZT6ZK/Models/QuestionEntity.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Models; + +internal class QuestionEntity +{ + public int QuestionId { get; set; } + public string Question { get; set; } + public string Answer1 { get; set; } + public string Answer2 { get; set; } + public string Answer3 { get; set; } + public string Answer4 { get; set; } + public string CorrectAnswer { get; set; } + public TopicEntity? Topic { get; set; } + public int? TopicId { get; set; } + + public override string ToString() + { + return $"{Question}\n- {Answer1}\n- {Answer2}\n- {Answer3}\n- {Answer4}\n"; + } +} diff --git a/IZT6ZK/Models/TopicEntity.cs b/IZT6ZK/Models/TopicEntity.cs new file mode 100644 index 0000000..8de0948 --- /dev/null +++ b/IZT6ZK/Models/TopicEntity.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Models; +internal class TopicEntity +{ + public int TopicId { get; set; } + public string TopicName { get; set; } + public List Questions { get; set; } +} diff --git a/IZT6ZK/Program.cs b/IZT6ZK/Program.cs new file mode 100644 index 0000000..4b831d9 --- /dev/null +++ b/IZT6ZK/Program.cs @@ -0,0 +1,45 @@ +using System.Drawing; +using System.Reflection.Metadata; + +using IZT6ZK; +using IZT6ZK.Assists; +using IZT6ZK.Commands; +using IZT6ZK.Db; + +using Microsoft.EntityFrameworkCore; + +internal class Program +{ + private static void Main(string[] args) + { + using (var db = new MyDbContext()) + { + db.Database.Migrate(); + } + + Console.WriteLine("Welcome dear Visitor in our Quiz app!\n"); + Console.WriteLine("You can make a question or check your knowledge.\n"); + + HelpCommand helpCommand = new HelpCommand(); + helpCommand.Execute(); + + Console.WriteLine("\n\nHave fun!\n"); + + while (true) + { + Console.WriteLine("Main Console, write your command: "); + string? input = Console.ReadLine(); + + try + { + input = input.Trim(); + CommandsDict.commandsDict.First(x => x.Key == input).Value.Execute(); + } + catch + { + Console.WriteLine("No such command exists! Try again! " + + "(Write 'help', if you want to see the commands!)"); + } + } + } +} \ No newline at end of file diff --git a/IZT6ZK/Records/QuestionRecordForStatistic.cs b/IZT6ZK/Records/QuestionRecordForStatistic.cs new file mode 100644 index 0000000..b13b864 --- /dev/null +++ b/IZT6ZK/Records/QuestionRecordForStatistic.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.Records; +public record QuestionRecordForStatistic +{ + public string Question { get; init; } + public string CorrectAnswer { get; init; } + public string UserAnswer { get; set; } + public QuestionRecordForStatistic(string question, string correctAnswer, string userAnswer) + { + Question = question; + CorrectAnswer = correctAnswer; + UserAnswer = userAnswer; + } + + public override string ToString() + { + return $"Question: {Question}; Correct answer: {CorrectAnswer}; Your answer: {UserAnswer}"; + } +} \ No newline at end of file diff --git a/IZT6ZK/StateMachine/CreateQuestionStateMachine.cs b/IZT6ZK/StateMachine/CreateQuestionStateMachine.cs new file mode 100644 index 0000000..67be0ef --- /dev/null +++ b/IZT6ZK/StateMachine/CreateQuestionStateMachine.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IZT6ZK.StateMachine; +internal enum CreateQuestionStateMachine +{ + QuestionReading, + Answer1Reading, + Answer2Reading, + Answer3Reading, + Answer4Reading, + CorrectAnswerReading, + WantToReadTopic, + TopicReading, + QuitFromCreateQuestion, + EverythingWasFineQuestionCreateWithTopic, + EverythingWasFineQuestionCreate, +} diff --git a/Temp.txt b/Temp.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/Temp.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hazifeladatok.sln b/hazifeladatok.sln new file mode 100644 index 0000000..2af160f --- /dev/null +++ b/hazifeladatok.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IZT6ZK", "IZT6ZK\IZT6ZK.csproj", "{F7289DF2-EFB2-434F-AD10-431BBE70227B}" +EndProject +Global + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {88EE8588-86E8-4AF0-B779-9E950EC4DDC0} + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|x64.ActiveCfg = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|x64.Build.0 = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|x86.ActiveCfg = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Debug|x86.Build.0 = Debug|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|Any CPU.Build.0 = Release|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|x64.ActiveCfg = Release|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|x64.Build.0 = Release|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|x86.ActiveCfg = Release|Any CPU + {F7289DF2-EFB2-434F-AD10-431BBE70227B}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal