This commit is contained in:
ipvg 2024-07-19 20:30:50 -04:00
parent 96e36600b4
commit 505772685e
15 changed files with 1544 additions and 0 deletions

27
.editorconfig Normal file
View File

@ -0,0 +1,27 @@
root = true
# [*]
# end_of_line = lf
# insert_final_newline = true
[*.cs]
indent_style = space
indent_size = 4
csharp_new_line_before_open_brace = none
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
# csharp_new_line_before_members_in_object_initializers = false
# csharp_new_line_before_members_in_anonymous_types = false
# csharp_new_line_between_query_expression_clauses = false
#IDE1006
dotnet_naming_style.camel_case.capitalization = camel_case
# symbols
dotnet_naming_symbols.private_symbols.applicable_accessibilities = private
dotnet_naming_symbols.public_symbols.applicable_accessibilities = public, protected
dotnet_naming_symbols.interface_types.applicable_kinds = interface
# rules
dotnet_naming_rule.camel_case_for_private.severity = warning
dotnet_naming_rule.camel_case_for_private.symbols = private_symbols
dotnet_naming_rule.camel_case_for_private.style = camel_case

View File

@ -0,0 +1,364 @@
root = true
# All files
[*]
indent_style = space
# Xml files
[*.xml]
indent_size = 2
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
tab_width = 4
# New line preferences
# end_of_line = crlf
# insert_final_newline = false
#### .NET Coding Conventions ####
[*.{cs,vb}]
# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
file_header_template = 'DevFzn'
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
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_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:warning
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
#### C# Coding Conventions ####
[*.cs]
# 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:suggestion
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_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_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = 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
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
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 ####
[*.{cs,vb}]
# Naming rules
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.events_should_be_pascalcase.symbols = events
dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion
dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields
dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
# Symbol specifications
dotnet_naming_symbols.interfaces.applicable_kinds = interface
dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interfaces.required_modifiers =
dotnet_naming_symbols.enums.applicable_kinds = enum
dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enums.required_modifiers =
dotnet_naming_symbols.events.applicable_kinds = event
dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.events.required_modifiers =
dotnet_naming_symbols.methods.applicable_kinds = method
dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.methods.required_modifiers =
dotnet_naming_symbols.properties.applicable_kinds = property
dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.properties.required_modifiers =
dotnet_naming_symbols.public_fields.applicable_kinds = field
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_fields.required_modifiers =
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_fields.required_modifiers =
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_fields.required_modifiers = static
dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types_and_namespaces.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 =
dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
dotnet_naming_symbols.type_parameters.required_modifiers =
dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_constant_fields.required_modifiers = const
dotnet_naming_symbols.local_variables.applicable_kinds = local
dotnet_naming_symbols.local_variables.applicable_accessibilities = local
dotnet_naming_symbols.local_variables.required_modifiers =
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.parameters.applicable_accessibilities = *
dotnet_naming_symbols.parameters.required_modifiers =
dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_constant_fields.required_modifiers = const
dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
dotnet_naming_symbols.local_functions.applicable_accessibilities = *
dotnet_naming_symbols.local_functions.required_modifiers =
# Naming styles
dotnet_naming_style.pascalcase.required_prefix =
dotnet_naming_style.pascalcase.required_suffix =
dotnet_naming_style.pascalcase.word_separator =
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_style.ipascalcase.required_prefix = I
dotnet_naming_style.ipascalcase.required_suffix =
dotnet_naming_style.ipascalcase.word_separator =
dotnet_naming_style.ipascalcase.capitalization = pascal_case
dotnet_naming_style.tpascalcase.required_prefix = T
dotnet_naming_style.tpascalcase.required_suffix =
dotnet_naming_style.tpascalcase.word_separator =
dotnet_naming_style.tpascalcase.capitalization = pascal_case
dotnet_naming_style._camelcase.required_prefix = _
dotnet_naming_style._camelcase.required_suffix =
dotnet_naming_style._camelcase.word_separator =
dotnet_naming_style._camelcase.capitalization = camel_case
dotnet_naming_style.camelcase.required_prefix =
dotnet_naming_style.camelcase.required_suffix =
dotnet_naming_style.camelcase.word_separator =
dotnet_naming_style.camelcase.capitalization = camel_case
dotnet_naming_style.s_camelcase.required_prefix = s_
dotnet_naming_style.s_camelcase.required_suffix =
dotnet_naming_style.s_camelcase.word_separator =
dotnet_naming_style.s_camelcase.capitalization = camel_case

View File

@ -0,0 +1,612 @@
# Introduction
Decision logic is based on expressions, known as Boolean expressions that
evaluates to "true" or "false". Developers use various types of operators to
create Boolean expressions that meet their coding requirements. When the
expressions are evaluated, the code execution branches based on the result.
The C# language supports a wide range of operators (such as equality,
comparison, and Boolean operators), each of which serves a specific purpose
when implementing decision logic.
Suppose you've been selected to work on a series of C# console applications
that are used to process customer data and user supplied inputs. Each
application requires you to implement decision logic that achieves data
processing requirements and associated business rules. The data processing
requirements and business rules vary for each application. For example,
applications that process customer orders might need to evaluate the status of
the customer before taking any action. To prepare for this upcoming assignment,
you'll complete some practice activities that implement Boolean expressions
and C# operators.
In this module, you learn about Boolean expressions, and you use different
types of operators to evaluate expressions for equality, inequality, and
comparison. You also learn to use a special inline version of an if statement
(a conditional operator) that produces an "either / or" result.
By the end of this module, you are able to write code using any combination of
C# operators to implement decision logic in your applications.
### Learning objectives
In this module, you will:
- Use operators to create Boolean expressions that test for comparison and equality.
- Use built-in methods of the string class to perform better evaluations on strings.
- Use the negation operator to test for the opposite of a given condition.
- Use the conditional operator to perform an inline evaluation.
#### Prerequisites:
- Experience with basic coding tasks such as instantiating variables, using
various data types, and sending output to a console window.
- Experience using the `if-elseif-else` construct.
- Experience using the `Random` class to generate a random number.
- Experience using `dotnet` to create and run simple console applications.
---
## Exercise
### Evaluate an expression
Decision logic is used to establish alternative pathways through your code,
where the decision about which path to follow is based on the evaluation of an
expression. For example, you might write some code that executes one of two
paths based on a user's input. If the user enters the letter "a", your code
will execute one code block. If they enter the letter "b", your code will
execute a different code block. In this example, you're controlling the
execution path based on the value assigned to a string. Your code selects an
execution path based on an expression, how that expression is evaluated, and
the underlying logic used to define the paths.
Examining how to construct and evaluate an expression is a good place to
start.
### What is an expression?
An expression is any combination of values (literal or variable), operators,
and methods that return a single value. A statement is a complete instruction
in C#, and statements are comprised of one or more expressions. For example,
the following `if` statement contains a single expression that returns a
single value:
```cs
if (myName == "Luiz")
```
You might have been thinking that the value returned by an expression would be
a number or maybe a string. It's true that application developers use
different types of expressions for different purposes. In this case, when you
're developing an if selection statement, you'll be using an expression that
returns either true or false. Developers refer to this type of expression as a
Boolean expression. When your code includes a Boolean expression, return value
is always a single `true` or `false` value.
Boolean expressions are important because your code can use these expressions
to decide which block of code to execute.
There are many different types of operators that you can use within a Boolean
expression. For example, the `if` statement above uses the equality operator
`==` to check whether a string variable is assigned a particular value. The
operator that you choose will depend on the available code paths, the
conditions associated with the paths, and the underlying application logic.
### Evaluating equality and inequality
One of the most common code evaluations is a check to see whether two values
are equal. When checking for equality, you'll locate the equality operator `==`
between the two values being checked. If the values on either side of the
equality operator are equivalent, then the expression will return `true`.
Otherwise, it will return `false`.
Conversely, you might also need to check whether two values aren't equal. To
check for inequality, you'll use the inequality operator `!=` between the two
values.
You might wonder why you need both equality and inequality operators. The
reason will become clearer as you learn how to create branching statements and
begin to write real world code. Two operators that perform opposite tasks
allow you to be more expressive and compact.
Now it's time to prepare your coding environment and begin writing code that
evaluates Boolean expressions.
#### Prepare your coding environment
At the Terminal command prompt, to create a new console application in a
specified folder, type dotnet new console -o ./path_to_projects/TestProject
and then press Enter.
### Use the equality operator
Ensure that you IDE open and Program.cs displayed in the Editor.
Type the following code into the Visual Studio Code Editor.
```cs
Console.WriteLine("a" == "a");
Console.WriteLine("a" == "A");
Console.WriteLine(1 == 2);
string myValue = "a";
Console.WriteLine(myValue == "a");
```
The Program.cs file must be saved before building or running the code.
At the Terminal command prompt, to run your code, type `dotnet run` and then
press Enter.
You should see the following output.
```txt
True
False
False
True
```
### Improve the check for string equality using the string's built-in helper methods
You might be surprised that the line `Console.WriteLine("a" == "A");` outputs
`false`. When comparing strings, case matters.
Also, consider this line of code:
```cs
Console.WriteLine("a" == "a ");
```
Here you've added a space character at the end of the string. This expression
will also output false.
In some cases, having a space character before or after the text might be
perfectly acceptable. However, if you need to accept a match that isn't exact,
you can "massage" the data first. "Massaging" the data means that you perform
some cleanup before you perform a comparison for equality.
For example, consider the case when you're collecting user input inside a loop.
After each value is entered, you could provide the user with a prompt to
determine if they want to continue, such as `Do you want to continue (Y/N)?`.
If the user wants to continue, they will probably enter either `y` or `Y`. You
'll want your code to interpret both values equally, even though `y` isn't
equivalent to `Y`.
Before you check two string values for equality, especially when one or both
values were entered by a user, you should:
- Make sure both strings are all upper-case or all lower-case using the
`ToUpper()` or `ToLower()` helper method on any string value.
- Remove any leading or trailing blank spaces using the `Trim()` helper method
on any string value.
You can improve the previous equality check by chaining these two helper
methods on both values, as shown in the following code listing:
Replace the code in the Visual Studio Code Editor with the following code:
```cs
string value1 = " a";
string value2 = "A ";
Console.WriteLine(value1.Trim().ToLower() == value2.Trim().ToLower());
```
Notice that when you run the code this time, it outputs **True**.
### Use the inequality operator
Use the line comment operator `//` to comment out all of the code from the
previous step.
Type the following code into the Visual Studio Code Editor.
```cs
Console.WriteLine("a" != "a");
Console.WriteLine("a" != "A");
Console.WriteLine(1 != 2);
string myValue = "a";
Console.WriteLine(myValue != "a");
```
Save your code file, and then run your code.
You should see the following output.
```txt
False
True
True
False
False
```
As you would expect, the result when using the inequality operator is the
opposite of what you saw when using the equality operator. That means that
your code will branch in the opposite manner as well, which can be exactly
what you want.
### Evaluating comparisons
When working with numeric data types, you might want to determine if a value is larger or smaller than another value. Use the following operators to perform these types of comparisons:
- Greater than `>`
- Less than `<`
- Greater than or equal to `>=`
- Less than or equal to `<=`
Naturally, the `==` and `!=` operators that you used to compare string values
above will also work when comparing numeric data types.
#### Use the Comparison operators
Use the line comment operator `//` to comment out all of the code from the
previous task.
Type the following code into the Visual Studio Code Editor.
```cs
Console.WriteLine(1 > 2);
Console.WriteLine(1 < 2);
Console.WriteLine(1 >= 1);
Console.WriteLine(1 <= 1);
```
Save your code file, and then build and run your code.
You should see the following output:
```txt
False
True
True
True
```
### Methods that return a Boolean value
Some methods return a Boolean value (`true` or `false`). In the following
exercise, you'll use a built-in method of the String class to determine
whether or not a larger string contains a specific word or phrase that's
significant to your application.
> Note
> Some data types have methods that perform helpful utility tasks. The String
data type has many of these. Several return a Boolean value including
`Contains()`, StartsWith(), and EndsWith(). You can learn more about them in
the Microsoft Learn module "Manipulate alphanumeric data using String class
methods in C#".
#### Use a method that returns a Boolean
Use the line comment operator `//` to comment out all of the code from the
previous step.
Type the following code into the editor.
```cs
string pangram = "The quick brown fox jumps over the lazy dog.";
Console.WriteLine(pangram.Contains("fox"));
Console.WriteLine(pangram.Contains("cow"));
```
Save your code file, and then build and run your code.
You should see the following output.
```txt
True
False
```
### What is logical negation?
The term "Logical Negation" refers to the unary negation operator `!.` Some
people call this operator the "not operator". When you place the `!` operator
before a conditional expression (or any code that's evaluated to either `true`
or `false`), it forces your code to reverse its evaluation of the operand.
When logical negation is applied, the evaluation produces `true` , if the
operand evaluates to `false` , and `false` , if the operand evaluates to `true`.
Here is an example that might help you to see the connection between these
ideas. The following two lines of code produce the same result. The second
line is more compact.
```cs
// These two lines of code will create the same output
Console.WriteLine(pangram.Contains("fox") == false);
Console.WriteLine(!pangram.Contains("fox"));
```
#### Use the Logical Negation operator
Use the line comment operator `//` to comment out all of the code from the
previous step.
Type the following.
```cs
string pangram = "The quick brown fox jumps over the lazy dog.";
Console.WriteLine(!pangram.Contains("fox"));
Console.WriteLine(!pangram.Contains("cow"));
```
Save your code file, and then build and run your code.
You should see the following output.
```txt
False
True
```
#### Inequality operator versus logical negation
The inequality operator `!=` includes a `!` character, but should not be
confused with logical negation. The inequality operator returns `true` if its
operands aren't equal, and returns false if the operands are equal. For the
operands of the built-in types, the expression `x != y` produces the same
result as the expression `!(x == y)` (an example of logical negation).
The following code sample demonstrates the use of the `!=` operator:
```cs
int a = 7;
int b = 6;
Console.WriteLine(a != b); // output: True
string s1 = "Hello";
string s2 = "Hello";
Console.WriteLine(s1 != s2); // output: False
```
### Recap
Here's the main takeaways you learned about evaluating Boolean expressions so
far:
- There are many different kinds of expressions that evaluate to either `true`
or `false`.
- Evaluate equality using the `==` operator.
- Evaluating equality of strings requires you to consider the possibility that
the strings have different case and leading or trailing spaces. Depending on
your situation, use the `ToLower()` or `ToUpper()` helper methods, and the
`Trim()` helper method to improve the likelihood that two strings are equal.
- Evaluate inequality using the `!=` operator.
- Evaluate greater than, less than and similar operations using comparison
operators like `>`, `<`, `>=`, and `<=`.
- If a method returns a bool, it can be used as a Boolean expression.
- Use the logical negation operator `!` to evaluate the opposite of a given
expression.
---
## Exercise
### Implement the conditional operator
Suppose you need to quickly determine whether a customer's purchase is
eligible for a promotional discount. The details for the promotion indicate
that when a purchase value is greater than $1000, the purchase is eligible for
a $100 discount. If the purchase amount is $1000 or less, the purchase is
eligible for a $50 discount.
While you could certainly use the `if ... elseif ... else` branching construct
to express this business rule, using the conditional operator to evaluate
eligibility for the promotional discount might be a better choice. The
conditional operator uses a compact format that saves a few lines of code and
possibly makes the intent of the code clearer.
### What is the conditional operator?
The conditional operator `?:` evaluates a Boolean expression and returns one
of two results depending on whether the Boolean expression evaluates to true
or false. The conditional operator is commonly referred to as the ternary
conditional operator.
Here's the basic form:
```cs
<evaluate this condition> ? <if condition is true, return this value> : <if condition is false, return this value>
```
Take a minute to consider how you'd apply the conditional operator to the
promotional discount scenario. Your goal is to display a message to the
customer that shows their discount percentage. The amount of their discount
will be based on whether they've spent more than $1000 on their purchase.
#### Add code that uses a conditional operator
Type the following code into the editor.
```cs
int saleAmount = 1001;
int discount = saleAmount > 1000 ? 100 : 50;
Console.WriteLine($"Discount: {discount}");
```
The Program.cs file must be saved before building or running the code.
When you run the code, you should see the following output:
```txt
Discount: 100
```
#### Use the conditional operator inline
You can compact this code even more by eliminating the temporary variable
discount.
Update your code in the editor as follows:
```txt
int saleAmount = 1001;
// int discount = saleAmount > 1000 ? 100 : 50;
Console.WriteLine($"Discount: {(saleAmount > 1000 ? 100 : 50)}");
```
At the Terminal command prompt, to run your code, type `dotnet run` and then
press Enter.
Notice that the output is the same.
Take a minute to examine the updated `Console.WriteLine()` statement.
Notice that it's necessary to wrap the entire conditional operator statement
in parentheses. The parentheses ensure that the runtime understands your intent,
which is to display the conditional result rather than the result of
evaluating the condition (saleAmount > 1000).
> Note
> While this particular example is compact and shows what is possible, it is a
bit more difficult to read. It's not always a good idea to combine lines of
code, especially when it adversely affects the overall readability of your code.
This is often a subjective judgment call.
### Recap
You should remember the following facts about the conditional operator:
- You can use the conditional operator to reduce the size of your code, but
you should ensure that the resulting code is easily readable.
- You can use the conditional operator when you need to return a value that's
based on a binary condition. Your code will return the first option when the
condition evaluates to true, and it will return the second option when the
condition evaluates to false.
---
## Exercise
### Complete a challenge activity using conditional operators
Code challenges will reinforce what you've learned and help you gain some
confidence before continuing on.
### Conditional operator challenge
In this challenge, you'll implement a conditional operator to simulate a "coin
flip". The resulting decision logic will display either `heads` or `tails`.
### Code challenge: write code to display the result of a coin flip
Here are your challenge requirements:
- Use the Random class to generate a value.
- Consider the range of numbers that is required.
- Based on the value generated, use the conditional operator to display either
`heads` or `tails`.
- There should be a 50% chance that the result is either heads or tails.
Your code should be easy to read, but with as few lines as possible.
You should be able to accomplish the desired result in three lines of code.
---
## Exercise
### Complete a challenge activity using Boolean expressions
Code challenges will reinforce what you've learned and help you gain some
confidence before continuing on.
### Decision logic challenge
In this challenge, you'll implement decision logic based on a series of
business rules. The business rules specify the access that will be granted to
users based on their role-based permissions and their career level. Code
branches will display a different message to the user depending on their
permissions and level.
#### Initialize permission and level values
Ensure that you have an empty Program.cs file open.
Type the following code into the editor:
```cs
string permission = "Admin|Manager";
int level = 55;
```
Review the initial code lines.
Your application will be using a combination of `permission` and `level` to
apply/evaluate the business rules in this challenge scenario. The full list of
conditions for business rules is specified in the next step. Your completed
solution must use `permission` and `level`.
> Tip
> To sufficiently test all of the combinations for permission and level that
are described in the business rules below, you will need to assign additional
values to these variables and run the application multiple times.
#### Implement business rules
> Important
> You will need to use the `Contains()` helper method to determine whether the
value assigned to the `permission` string contains one of the permission
values specified by the "business rules". For example, the expression
`permission.Contains("Admin")` will return `true` when using the initial data
values specified in the code above.
Here are the **Business Rules** that your solution must satisfy:
- If the user is an Admin with a level greater than 55, output the message:
```txt
Welcome, Super Admin user.
```
- If the user is an Admin with a level less than or equal to 55, output the
message:
```txt
Welcome, Admin user.
```
- If the user is a Manager with a level 20 or greater, output the message:
```txt
Contact an Admin for access.
```
- If the user is a Manager with a level less than 20, output the message:
```txt
You do not have sufficient privileges.
```
- If the user is not an Admin or a Manager, output the message:
```txt
You do not have sufficient privileges.
```
Update your Program.cs code to accommodate each of the business rules.
Save your code.
#### Test your solution using the initial data values suggested
1. Build and run your code.
2. Evaluate the output.
When you run your code, including the initial configuration data, you should
see the following output:
```txt
Welcome, Admin user.
```
#### Test for the other business rules
1. Update the values assigned to permission and level.
2. Save and run your code.
3. Evaluate the output to verify that the other business rules are satisfied.
---

View File

@ -0,0 +1,64 @@
void sep(){
Console.WriteLine("+-----+");
}
Console.WriteLine("a" == "a");
Console.WriteLine("a" == "A");
Console.WriteLine(1 == 2);
sep();
string myValue = "a";
Console.WriteLine(myValue == "a");
sep();
Console.WriteLine("a" == "a ");
sep();
string value1 = " a";
string value2 = "A ";
Console.WriteLine(value1.Trim().ToLower() == value2.Trim().ToLower());
sep();
Console.WriteLine("a" != "a");
Console.WriteLine("a" != "A");
Console.WriteLine(1 != 2);
myValue = "a";
Console.WriteLine(myValue != "a");
sep();
Console.WriteLine(1 > 2);
Console.WriteLine(1 < 2);
Console.WriteLine(1 >= 1);
Console.WriteLine(1 <= 1);
sep();
string pangram = "The quick brown fox jumps over the lazy dog.";
Console.WriteLine(pangram.Contains("fox"));
Console.WriteLine(pangram.Contains("cow"));
sep();
// These two lines of code will create the same output
Console.WriteLine(pangram.Contains("fox") == false);
Console.WriteLine(!pangram.Contains("fox"));
sep();
Console.WriteLine(!pangram.Contains("fox"));
Console.WriteLine(!pangram.Contains("cow"));
sep();
int a = 7;
int b = 6;
Console.WriteLine(a != b); // output: True
string s1 = "Hello";
string s2 = "Hello";
Console.WriteLine(s1 != s2); // output: False
sep();
int saleAmount = 1001;
Console.WriteLine($"Discount: {(saleAmount > 1000 ? 100 : 50)}");
saleAmount = 1;
Console.WriteLine($"Discount: {(saleAmount > 1000 ? 100 : 50)}");
sep();

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,7 @@
int num = new Random().Next(1,11);
Console.WriteLine($"{(num%2==0 ? "heads" : "tails")}");
Console.WriteLine("------");
Random coin = new Random();
Console.WriteLine((coin.Next(0, 2) == 0) ? "heads" : "tails");

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,18 @@
string permission = "Admin|Manager";
int level = 53;
if (permission.Contains("Admin")) {
if (level > 55) {
Console.WriteLine("Welcome, Super Admin user.");
} else {
Console.WriteLine("Welcome, Admin user.");
}
} else if (permission.Contains("Manager")) {
if (level >= 20) {
Console.WriteLine("Contact an Admin for access.");
} else {
Console.WriteLine("You do not have sufficient privileges.");
}
} else {
Console.WriteLine("You do not have sufficient privileges.");
}

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,22 @@
string[] users = new String[] { "Admin", "Admin", "Manager", "Manager", "User" };
int[] levels = new int[] { 56, 55, 21, 19, 100 };
int counter = 0;
foreach (string user in users) {
int level = levels[counter++];
switch (user) {
case "Admin":
Console.WriteLine($"Wellcome, {(level > 55 ? "Super " : "")}Admin user.");
break;
case "Manager":
if (level >= 20) {
Console.WriteLine("Contact an Admin for access.");
} else {
Console.WriteLine("You do not have sufficient privileges.");
}
break;
default:
Console.WriteLine("You do not have sufficient privileges.");
break;
}
}

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,316 @@
# Introduction
Selection and iteration statements use code blocks to group-together the code
lines that should be executed, skipped, or iterated over. But that's not the
only purpose for code blocks. Code blocks can also be used to control or limit
variable accessibility. Variable "scope" refers to the portion of an
application where a variable is accessible. Understanding how a code block
affects variable scope is an important part of computer programming.
Suppose you're working on large application that uses nested iteration and
selection statements to process array data. Your application uses variables to
help accomplish common tasks throughout the application. Some variables serve
the same purpose in different portions of the application, and you've made
some attempt to reuse the variable names. As your application grows, you start
seeing unexpected results for calculations, and errors that report a variable
that is uninitialized or doesn't exist. You need to improve the approach
you're using to declare and access variables, and you need to improve your
understanding of variable scope.
In this module, you'll declare variables for use inside and outside the
boundaries of code blocks. You'll remove code blocks in certain situations to
make code more readable. You'll learn how code blocks affect the accessibility
and visibility of your variables.
By the end of this module, you'll be able to use code blocks with more
confidence, understanding how they impact the visibility and accessibility of
your code.
### Learning objectives
**In this module, you will:**
- Understand the impact of declaring and initializing variables inside and
outside of code blocks.
- Improve the readability code blocks in `if` statements.
#### Prerequisites:
- Experience declaring and initializing variables.
- Experience with `if-elseif-else` selection statement structures.
- Experience with `foreach` iteration statements.
- Experience calling methods of classes in the .NET Class Library.
## Exercise
### Code blocks and variable scope
A code block is one or more C# statements that define an execution path. The
statements outside of a code block affect when, if, and how often that block
of code is executed at run time. The boundaries of a code block are typically
defined by squiggly braces, `{}.`
In addition to their effect on execution path, code blocks can also affect the
scope of your variables. The code samples that you examine during this
exercise will help you understand the relationship between code blocks and
variable scope.
### Code blocks impact the scope of a variable declaration
Variable scope refers to a variable's visibility to the other code in your
application. A locally scoped variable is only accessible inside of the code
block in which it's defined. If you attempt to access the variable outside of
the code block, you'll get a compiler error.
The remainder of this unit explores the relationship between code blocks and
variable scope.
#### Prepare your coding environment
At the Terminal command prompt, to create a new console application in a
specified folder, type `dotnet new console -o ./path_to/TestProject` and then
press Enter.
You'll be using this C# console project to create, build, and run code samples
during this module.
#### Create a variable inside of a code block
You will begin by looking at the case when a variable is initialized inside a
code block.
Type the following code into the Visual Studio Code Editor:
```cs
bool flag = true;
if (flag) {
int value = 10;
Console.WriteLine($"Inside the code block: {value}");
}
```
The Program.cs file must be saved before building or running the code.
At the Terminal command prompt, to run your code, type `dotnet run` and then
press Enter.
You should see the following output:
```txt
Inside the code block: 10
```
This is the expected output. But what if you want to access the variable value
outside of the if statement code block?
#### Attempt to access a variable outside the code block in which it's declared
In the code editor, create a new code line below the if statement code block.
On the blank code line you created, add the following line of code:
```cs
Console.WriteLine($"Outside the code block: {value}");
```
Verify that your updated code looks like the following:
```cs
bool flag = true;
if (flag) {
int value = 10;
Console.WriteLine($"Inside the code block: {value}");
}
Console.WriteLine($"Outside the code block: {value}");
```
Save your code file, and then run your code.
Enter `dotnet run` from the Terminal command prompt to run your code.
Notice that when you attempt to run the application, you get a compilation
error:
```txt
Program.cs(7,46): error CS0103: The name 'value' does not exist in the current context
```
The `Program.cs(7,46)` portion of the message tells you that the error is
associated with ***line 7 in the Program.cs file, column 46***.
This error is generated because a variable that's declared inside a code block
is only accessible (can only be seen) within that code block. Since a variable
cannot be accessed outside the code block in which it's declared, `value`
cannot be accessed from line 7 of your code.
A variable that's declared in a method code block is referred to as a local
variable. You may see the term local variable used when reviewing articles
that discuss variable scope.
#### Move the variable declaration above the code block
To access a variable both inside and outside of a code block, you'll need to
declare the variable prior to (above) the code block so that the code outside
the code block can "see" the variable.
Update your code as follows:
```cs
bool flag = true;
int value;
if (flag){
Console.WriteLine($"Inside the code block: {value}");
}
value = 10;
Console.WriteLine($"Outside the code block: {value}");
```
Take a minute to review the updates.
Notice that value is now declared (but not initialized) outside the if code
block.
Save your updates, and then run your code.
Notice that you still get a compilation error.
This time, when you attempt to run the application, you get the following
compilation error:
```txt
Program.cs(6,49): error CS0165: Use of unassigned local variable 'value'
```
The error is associated with line 6 inside the code block because `value` is
uninitialized (has not been assigned a value). If the code line `value = 10;`
was located above the `if` statement code block, the application would compile
correctly and everything would be fine. However, since value hasn't been
initialized, it cannot be accessed inside the code block.
Ensuring that your variables are initialized before attempting to access them
will address this issue.
#### Initialize a variable as part of variable declaration
To initialize value as part of the variable declaration, update your code as
follows:
```cs
bool flag = true;
int value = 0;
if (flag){
Console.WriteLine($"Inside the code block: {value}");
}
value = 10;
Console.WriteLine($"Outside the code block: {value}");
```
This code addresses the "unassigned local variable" compilation error by
initializing `value` as part of your variable declaration.
Save and run your code.
Notice that now, when you run the application, you see the following output:
```txt
Inside the code block: 0
Outside the code block: 10
```
#### Examine the compiler's interpretation of your code
To you avoid runtime errors, the C# compiler analyzes your code
in the code editor* and during the build process. However, the compiler may
not always interpret your code the same way that you do.
Consider the following two code samples that appear to serve the same
purpose:
```cs
// Code sample 1
bool flag = true;
int value;
if (flag) {
value = 10;
Console.WriteLine($"Inside the code block: {value}");
}
Console.WriteLine($"Outside the code block: {value}");
```
```cs
// Code sample 2
int value;
if (true){
value = 10;
Console.WriteLine($"Inside the code block: {value}");
}
Console.WriteLine($"Outside the code block: {value}");
```
You may feel that these two samples should always produce the same result, but
the C# compiler interprets these two code samples differently.
For the first code sample, the compiler interprets `flag` as a Boolean variable
that could be assigned a value of either `true` or `false`. The compiler
concludes that if `flag` is `false`, `value` will not be initialized when the
second `Console.WriteLine()` is executed. Essentially the compiler considers
the following two code execution paths to be possible:
```cs
// path when flag = true
int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");
```
AND
```cs
// path when flag = false
int value;
Console.WriteLine($"Outside the code block: {value}");
```
Since the compiler considers the second path a possibility (for code sample
1), it generates an error message during the build process. In addition, the
code editor if available, warns you of this issue by displaying a red
squiggly line under `value` (below the code block).
For the second code sample, the complier concludes that the contents of the `if`
statement code block will always be executed (`true` is always `true`). The
compiler doesn't generate a build error because it interprets the second code
sample to have a single execution path as follows:
```cs
int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");
```
### Recap
Here are a few important things to remember about code blocks:
- When you declare a variable inside a code block, its visibility is local to
that code block and that variable cannot be accessed outside of the code block.
- To ensure that a variable is visible both inside and outside of a code bloc
k, you must declare the variable prior to the code block (outside and above
the code block).
- Ensure that variables are initialized before your code attempts to access
them (for all potential code execution paths).
---
##

View File

@ -0,0 +1,45 @@
bool flag = true;
int value = 0;
if (flag) {
Console.WriteLine($"Inside the code block: {value}");
}
value = 10;
Console.WriteLine($"Outside the code block: {value}");
//-------------------------------------------------------------
// Code sample 1
bool flag_2a = true;
int value_2a;
if (flag_2a) {
value_2a = 10;
Console.WriteLine($"Inside the code block: {value_2a}");
}
//Console.WriteLine($"Outside the code block: {value_2a}");
//-------------------------------------------------------------
// Code sample 2
int value_2b;
if (true) {
value_2b = 10;
Console.WriteLine($"Inside the code block: {value_2b}");
}
Console.WriteLine($"Outside the code block: {value_2b}");
//if (false){
// value_2b = 10;
// Console.WriteLine($"Inside the code block: {value_2b}");
//}
Console.WriteLine($"Outside the code block: {value_2b}");
//-------------------------------------------------------------
var my_var1 = 5;
if (my_var1 > 0) {
var my_var2 = 6;
my_var1 += my_var2;
}
Console.WriteLine(my_var1);

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# Get Starting C#
Following
[freecodecamp](https://www.freecodecamp.org/learn/foundational-c-sharp-with-microsoft/)
## Foundational C# with Microsoft
- [First Code](./001_first_code/001_csharp.md)
- [Store and retrieve data](./002_Store_retrieve_data_using_literal_and_variable/002_csharp.md)
- [Basic String Formating](./003_Basic_string_formatting/003_csharp.md)
- [Basic operations on numbers](./004_Basic_operation_on_numbers/004_csharp.md)
- [Calculate and print student grades](./005_Calc_and_print_grades/005_csharp.md)
- [Calculate students final GPA](./006_Calc_final_GPA/006_csharp.md)
- [Call methods from the .NET Class Library](./007_Methods_net_class/007_csharp.md)
- [if and if else](./008_if_else/008_csharp.md)
- [array and foreach](./009_arrays_forearc/009_csharp.md)
- [Conventions](./010_conventions/010_csharp.md)
- [Guided Project - foreach](./011_foreach_array_1/011_csharp.md)
- [Challenge Project - foreach](./012_foreach_array_2/012_csharp.md)