some more

This commit is contained in:
Ben Harris 2021-11-08 23:55:59 -05:00
parent 4cc4feeb8a
commit aeb5e3d1fc
40 changed files with 1868 additions and 0 deletions

View File

@ -0,0 +1,141 @@
###############################
# Core EditorConfig Options #
###############################
; This file is for unifying the coding style for different editors and IDEs.
; More information at:
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
root = true
[*]
indent_style = space
[Acronym.cs]
indent_size = 4
###############################
# .NET Coding Conventions #
###############################
# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true
# this. preferences
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
# Modifier preferences
dotnet_style_require_accessibility_modifiers = always:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
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_auto_properties = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
###############################
# C# Code Style Rules #
###############################
# var preferences
csharp_style_var_for_built_in_types = true:none
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_elsewhere = true:none
# Expression-bodied members
csharp_style_expression_bodied_methods = true:suggestion
csharp_style_expression_bodied_constructors = true:suggestion
csharp_style_expression_bodied_operators = true:suggestion
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
# Pattern-matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:none
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
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 = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true

View File

@ -0,0 +1,29 @@
{
"blurb": "Convert a long phrase to its acronym",
"authors": [
"ErikSchierboom"
],
"contributors": [
"bressain",
"j2jensen",
"jwood803",
"mattcbaker",
"robkeim",
"vgrigoriu",
"wolf99",
"yvincent"
],
"files": {
"solution": [
"Acronym.cs"
],
"test": [
"AcronymTests.cs"
],
"example": [
".meta/Example.cs"
]
},
"source": "Julien Vanier",
"source_url": "https://github.com/monkbroc"
}

View File

@ -0,0 +1 @@
{"track":"csharp","exercise":"acronym","id":"6ed3c77ff23240e99ef77ef22d25f07a","url":"https://exercism.org/tracks/csharp/exercises/acronym","handle":"benharri","is_requester":true,"auto_approve":false}

View File

@ -0,0 +1,8 @@
using System;
using System.Linq;
public static class Acronym
{
public static string Abbreviate(string phrase) =>
string.Concat(phrase.ToUpper().Split(new char[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.First()));
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,58 @@
using Xunit;
public class AcronymTests
{
[Fact]
public void Basic()
{
Assert.Equal("PNG", Acronym.Abbreviate("Portable Network Graphics"));
}
[Fact]
public void Lowercase_words()
{
Assert.Equal("ROR", Acronym.Abbreviate("Ruby on Rails"));
}
[Fact]
public void Punctuation()
{
Assert.Equal("FIFO", Acronym.Abbreviate("First In, First Out"));
}
[Fact]
public void All_caps_word()
{
Assert.Equal("GIMP", Acronym.Abbreviate("GNU Image Manipulation Program"));
}
[Fact]
public void Punctuation_without_whitespace()
{
Assert.Equal("CMOS", Acronym.Abbreviate("Complementary metal-oxide semiconductor"));
}
[Fact]
public void Very_long_abbreviation()
{
Assert.Equal("ROTFLSHTMDCOALM", Acronym.Abbreviate("Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me"));
}
[Fact]
public void Consecutive_delimiters()
{
Assert.Equal("SIMUFTA", Acronym.Abbreviate("Something - I made up from thin air"));
}
[Fact]
public void Apostrophes()
{
Assert.Equal("HC", Acronym.Abbreviate("Halley's Comet"));
}
[Fact]
public void Underscore_emphasis()
{
Assert.Equal("TRNT", Acronym.Abbreviate("The Road _Not_ Taken"));
}
}

39
csharp/acronym/HELP.md Normal file
View File

@ -0,0 +1,39 @@
# Help
## Running the tests
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
## Skipped tests
Initially, only the first test will be enabled.
This is to encourage you to solve the exercise one step at a time.
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
## Submitting your solution
You can submit your solution using the `exercism submit Acronym.cs` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [C# track's documentation](https://exercism.org/docs/tracks/csharp)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

34
csharp/acronym/README.md Normal file
View File

@ -0,0 +1,34 @@
# Acronym
Welcome to Acronym on Exercism's C# Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Convert a phrase to its acronym.
Techies love their TLA (Three Letter Acronyms)!
Help generate some jargon by writing a program that converts a long name
like Portable Network Graphics to its acronym (PNG).
## Source
### Created by
- @ErikSchierboom
### Contributed to by
- @bressain
- @j2jensen
- @jwood803
- @mattcbaker
- @robkeim
- @vgrigoriu
- @wolf99
- @yvincent
### Based on
Julien Vanier - https://github.com/monkbroc

View File

@ -0,0 +1,21 @@
{
"blurb": "Learn about flag enumerations by checking permissions of user accounts on an internet forum.",
"contributors": [
"valentin-p",
"yzAlvin"
],
"authors": [
"ErikSchierboom"
],
"files": {
"solution": [
"AttackOfTheTrolls.cs"
],
"test": [
"AttackOfTheTrollsTests.cs"
],
"exemplar": [
".meta/Exemplar.cs"
]
}
}

View File

@ -0,0 +1 @@
{"track":"csharp","exercise":"attack-of-the-trolls","id":"3f816afb82fb47c79c44fcba68c32e27","url":"https://exercism.org/tracks/csharp/exercises/attack-of-the-trolls","handle":"benharri","is_requester":true,"auto_approve":false}

View File

@ -0,0 +1,36 @@
using System;
enum AccountType
{
Guest,
User,
Moderator
}
[Flags]
enum Permission
{
None = 0,
Read = 1,
Write = 2,
Delete = 4,
All = 7
}
static class Permissions
{
public static Permission Default(AccountType accountType) =>
accountType switch
{
AccountType.Guest => Permission.Read,
AccountType.User => Permission.Read | Permission.Write,
AccountType.Moderator => Permission.All,
_ => Permission.None
};
public static Permission Grant(Permission current, Permission grant) => current | grant;
public static Permission Revoke(Permission current, Permission revoke) => current & ~revoke;
public static bool Check(Permission current, Permission check) => current.HasFlag(check);
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,177 @@
using Xunit;
using Exercism.Tests;
public class AttackOfTheTrollsTests
{
[Fact]
public void Permissions_read_write_can_be_combined_as_flags()
{
Assert.Equal("Read, Write", (Permission.Read | Permission.Write).ToString());
}
[Fact]
public void Combining_none_delete_permissions_is_same_as_delete_permission()
{
Assert.Equal("Delete", (Permission.Delete | Permission.None).ToString());
}
[Fact]
public void Combining_read_write_delete_permissions_is_same_as_all_permission()
{
Assert.Equal("All", (Permission.Read | Permission.Write | Permission.Delete).ToString());
}
[Fact]
[Task(1)]
public void Default_for_guest()
{
Assert.Equal(Permission.Read, Permissions.Default(AccountType.Guest));
}
[Fact]
[Task(1)]
public void Default_for_user()
{
Assert.Equal(Permission.Read | Permission.Write, Permissions.Default(AccountType.User));
}
[Fact]
[Task(1)]
public void Default_for_moderator()
{
Assert.Equal(Permission.Read | Permission.Write | Permission.Delete, Permissions.Default(AccountType.Moderator));
}
[Fact]
[Task(1)]
public void Default_for_unknown()
{
Assert.Equal(Permission.None, Permissions.Default((AccountType)123));
}
[Fact]
[Task(2)]
public void Grant_read_to_none()
{
Assert.Equal(Permission.Read, Permissions.Grant(Permission.None, Permission.Read));
}
[Fact]
[Task(2)]
public void Grant_read_to_read()
{
Assert.Equal(Permission.Read, Permissions.Grant(Permission.Read, Permission.Read));
}
[Fact]
[Task(2)]
public void Grant_all_to_none()
{
Assert.Equal(Permission.All, Permissions.Grant(Permission.None, Permission.All));
}
[Fact]
[Task(2)]
public void Grant_delete_to_read_and_write()
{
Assert.Equal(Permission.All, Permissions.Grant(Permission.Read | Permission.Write, Permission.Delete));
}
[Fact]
[Task(2)]
public void Grant_read_and_write_to_none()
{
Assert.Equal(Permission.Read | Permission.Write, Permissions.Grant(Permission.None, Permission.Read | Permission.Write));
}
[Fact]
[Task(3)]
public void Revoke_none_from_read()
{
Assert.Equal(Permission.Read, Permissions.Revoke(Permission.Read, Permission.None));
}
[Fact]
[Task(3)]
public void Revoke_write_from_write()
{
Assert.Equal(Permission.None, Permissions.Revoke(Permission.Write, Permission.Write));
}
[Fact]
[Task(3)]
public void Revoke_delete_from_all()
{
Assert.Equal(Permission.Read | Permission.Write, Permissions.Revoke(Permission.All, Permission.Delete));
}
[Fact]
[Task(3)]
public void Revoke_read_and_write_from_write_and_delete()
{
Assert.Equal(Permission.Delete, Permissions.Revoke(Permission.Write | Permission.Delete, Permission.Read | Permission.Write));
}
[Fact]
[Task(3)]
public void Revoke_all_from_read_and_write()
{
Assert.Equal(Permission.None, Permissions.Revoke(Permission.Read | Permission.Write, Permission.All));
}
[Fact]
[Task(4)]
public void Check_none_for_read()
{
Assert.False(Permissions.Check(Permission.None, Permission.Read));
}
[Fact]
[Task(4)]
public void Check_write_for_write()
{
Assert.True(Permissions.Check(Permission.Write, Permission.Write));
}
[Fact]
[Task(4)]
public void Check_all_for_write()
{
Assert.True(Permissions.Check(Permission.All, Permission.Write));
}
[Fact]
[Task(4)]
public void Check_read_and_write_for_read()
{
Assert.True(Permissions.Check(Permission.Read | Permission.Write, Permission.Read));
}
[Fact]
[Task(4)]
public void Check_all_for_read_and_write()
{
Assert.True(Permissions.Check(Permission.Read | Permission.Write, Permission.Read | Permission.Write));
}
[Fact]
[Task(4)]
public void Check_read_and_write_for_read_and_write()
{
Assert.True(Permissions.Check(Permission.Read | Permission.Write, Permission.Read | Permission.Write));
}
[Fact]
[Task(4)]
public void Check_read_and_write_for_read_and_delete()
{
Assert.False(Permissions.Check(Permission.Read | Permission.Write, Permission.Read | Permission.Delete));
}
[Fact]
[Task(4)]
public void Check_read_and_write_and_delete_for_all()
{
Assert.True(Permissions.Check(Permission.Read | Permission.Write | Permission.Delete, Permission.All));
}
}

View File

@ -0,0 +1,39 @@
# Help
## Running the tests
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
## Skipped tests
Initially, only the first test will be enabled.
This is to encourage you to solve the exercise one step at a time.
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
## Submitting your solution
You can submit your solution using the `exercism submit AttackOfTheTrolls.cs` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [C# track's documentation](https://exercism.org/docs/tracks/csharp)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

View File

@ -0,0 +1,26 @@
# Hints
## 1. Get default permissions for an account type
- Define the `Permission` enum with values for the following permission types: `None`, `Read`, `Write` and `Delete`.
- Using the enum flags would allow to use bitwise operations out of the box for the `Permission` enum, [see `enum` `Flags`][docs-enum-flags].
- The `All` enum member can be defined as a combination of the `Read`, `Write` and `Delete` enum members.
- Define the `AccountType` enum with values for the following account types: `Guest`, `User` and `Moderator`.
- To handle each account type, one could use an `if` statement, but the [`switch` statement][docs.microsoft.com-switch-keyword] is a great alternative.
- Combining flags means setting a specific bit to `1` using one of the [bitwise operators][docs.microsoft.com-bitwise-and-shift-operators].
## 2. Grant a permission
- Combining flags means setting a specific bit to `1` using one of the [bitwise operators][docs.microsoft.com-bitwise-and-shift-operators].
## 3. Revoke a permission
- Removing a flag means setting a specific bit to `0` using a combination of two [bitwise operators][docs.microsoft.com-bitwise-and-shift-operators].
## 4. Check for a permission
- Checking a permission can be done by checking the result of applying one of the [bitwise operators][docs.microsoft.com-bitwise-and-shift-operators].
[docs.microsoft.com-bitwise-and-shift-operators]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators
[docs.microsoft.com-switch-keyword]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch
[docs-enum-flags]: https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=net-5.0

View File

@ -0,0 +1,123 @@
# Attack of the Trolls
Welcome to Attack of the Trolls on Exercism's C# Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
## Attributes
A [C# `Attribute`](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/) provides a way to decorate a declaration to associate metadata to: a class, a method, an enum, a field, a property or any [other supported](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/#attribute-targets) declarations.
You can apply an attribute by adding it on the line before the declaration using a `ClassAttribute` and a `FieldAttribute`:
```csharp
[Class]
class MyClass
{
[Field]
int myField;
}
```
This declarative metadata only associates additional structured information to the code and does not modify its behavior, but that metadata is used by other part of the code to change how its target would behave or add, change or remove, restrict some its functionalities.
There is many [predefined and reserved attributes](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/general#conditional-attribute), for example: `Flags`, `Obsolete`, `Conditional`, each has a specific that can be looked up on the C# documentation. Note that the full name of an attribute like [`Flags`](https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=net-5.0) is `FlagsAttribute` by convention, but the suffix _Attribute_ can be omitted when applied on a declaration.
## Flag Enums
The C# [`enum` type](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum) represents a fixed set of named constants (an enumeration).
Normally, one `enum` member can only refer to exactly one of those named constants. However, sometimes it is useful to refer to more than one constant. To do so, one can annotate the `enum` with the [`Flags` attribute](https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=net-5.0). A _flags_ enum's constants are interpreted as bitwise _flags_ and therefor indicates the enum supports the bitwise operators and additional features like the method `Enum.HasFlag()`.
A flags enum can be defined as follows (using binary integer notation `0b`):
```csharp
[Flags]
enum PhoneFeatures
{
Call = 0b00000001,
Text = 0b00000010
}
```
A `PhoneFeatures` instance which value is `0b00000011` has both its `Call` _and_ `Text` flags set.
By default, the `int` type is used for enum member values. One can use a different integer type by specifying the type in the enum declaration:
```csharp
[Flags]
enum PhoneFeatures : byte
{
Call = 0b00000001,
Text = 0b00000010
}
```
## Instructions
In this exercise you'll be checking permissions of user accounts on an internet forum. The forum supports three different permissions:
- Read
- Write
- Delete
There are three types of accounts, each with different default permissions:
- Guests: can read posts.
- Users: can read and write posts.
- Moderators: can read, write and delete posts, they have all the permissions.
Sometimes individual permissions can be modified, it is possible for example to give a guest account the permission to also write posts or revoking all permissions from an account would result in having none of the permissions.
## 1. Get default permissions for an account type
First, define an `AccountType` enum to represent the three account types: `Guest`, `User` and `Moderator`.
Next, define a `Permission` enum to represent the three permission types: `Read`, `Write`, `Delete`, and two extra ones: `All` for having all permissions and `None` for having none of the permissions.
Then implement the (_static_) `Permissions.Default()` method to return the default permissions for a specific account type:
```csharp
Permissions.Default(AccountType.Guest)
// => Permission.Read
```
## 2. Grant a permission
Implement the (_static_) `Permissions.Grant()` method that grants (adds) a permission:
```csharp
Permissions.Grant(current: Permission.None, grant: Permission.Read)
// => Permission.Read
```
## 3. Revoke a permission
Implement the (_static_) `Permissions.Revoke()` method that revokes (removes) a permission:
```csharp
Permissions.Revoke(current: Permission.Read, grant: Permission.Read)
// => Permission.None
```
## 4. Check for a permission
Implement the (_static_) `Permissions.Check()` method that takes the current account's permissions and checks if the account is authorized for a given permission:
```csharp
Permissions.Check(current: Permission.Write, check: Permission.Read)
// => false
```
## Source
### Created by
- @ErikSchierboom
### Contributed to by
- @valentin-p
- @yzAlvin

View File

@ -0,0 +1,141 @@
###############################
# Core EditorConfig Options #
###############################
; This file is for unifying the coding style for different editors and IDEs.
; More information at:
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
root = true
[*]
indent_style = space
[Isogram.cs]
indent_size = 4
###############################
# .NET Coding Conventions #
###############################
# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true
# this. preferences
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
# Modifier preferences
dotnet_style_require_accessibility_modifiers = always:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
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_auto_properties = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
###############################
# C# Code Style Rules #
###############################
# var preferences
csharp_style_var_for_built_in_types = true:none
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_elsewhere = true:none
# Expression-bodied members
csharp_style_expression_bodied_methods = true:suggestion
csharp_style_expression_bodied_constructors = true:suggestion
csharp_style_expression_bodied_operators = true:suggestion
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
# Pattern-matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:none
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
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 = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true

View File

@ -0,0 +1,26 @@
{
"blurb": "Determine if a word or phrase is an isogram.",
"authors": [
"robkeim"
],
"contributors": [
"ErikSchierboom",
"j2jensen",
"vgrigoriu",
"wolf99",
"yvincent"
],
"files": {
"solution": [
"Isogram.cs"
],
"test": [
"IsogramTests.cs"
],
"example": [
".meta/Example.cs"
]
},
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Isogram"
}

View File

@ -0,0 +1 @@
{"track":"csharp","exercise":"isogram","id":"755364f0829c48248514e3c9066bfcd8","url":"https://exercism.org/tracks/csharp/exercises/isogram","handle":"benharri","is_requester":true,"auto_approve":false}

39
csharp/isogram/HELP.md Normal file
View File

@ -0,0 +1,39 @@
# Help
## Running the tests
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
## Skipped tests
Initially, only the first test will be enabled.
This is to encourage you to solve the exercise one step at a time.
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
## Submitting your solution
You can submit your solution using the `exercism submit Isogram.cs` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [C# track's documentation](https://exercism.org/docs/tracks/csharp)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

10
csharp/isogram/Isogram.cs Normal file
View File

@ -0,0 +1,10 @@
using System.Linq;
public static class Isogram
{
public static bool IsIsogram(string word)
{
var w = word.ToLower().Where(char.IsLetter).ToList();
return w.Distinct().Count() == w.Count;
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,82 @@
using Xunit;
public class IsogramTests
{
[Fact]
public void Empty_string()
{
Assert.True(Isogram.IsIsogram(""));
}
[Fact]
public void Isogram_with_only_lower_case_characters()
{
Assert.True(Isogram.IsIsogram("isogram"));
}
[Fact]
public void Word_with_one_duplicated_character()
{
Assert.False(Isogram.IsIsogram("eleven"));
}
[Fact]
public void Word_with_one_duplicated_character_from_the_end_of_the_alphabet()
{
Assert.False(Isogram.IsIsogram("zzyzx"));
}
[Fact]
public void Longest_reported_english_isogram()
{
Assert.True(Isogram.IsIsogram("subdermatoglyphic"));
}
[Fact]
public void Word_with_duplicated_character_in_mixed_case()
{
Assert.False(Isogram.IsIsogram("Alphabet"));
}
[Fact]
public void Word_with_duplicated_character_in_mixed_case_lowercase_first()
{
Assert.False(Isogram.IsIsogram("alphAbet"));
}
[Fact]
public void Hypothetical_isogrammic_word_with_hyphen()
{
Assert.True(Isogram.IsIsogram("thumbscrew-japingly"));
}
[Fact]
public void Hypothetical_word_with_duplicated_character_following_hyphen()
{
Assert.False(Isogram.IsIsogram("thumbscrew-jappingly"));
}
[Fact]
public void Isogram_with_duplicated_hyphen()
{
Assert.True(Isogram.IsIsogram("six-year-old"));
}
[Fact]
public void Made_up_name_that_is_an_isogram()
{
Assert.True(Isogram.IsIsogram("Emily Jung Schwartzkopf"));
}
[Fact]
public void Duplicated_character_in_the_middle()
{
Assert.False(Isogram.IsIsogram("accentor"));
}
[Fact]
public void Same_first_and_last_characters()
{
Assert.False(Isogram.IsIsogram("angola"));
}
}

37
csharp/isogram/README.md Normal file
View File

@ -0,0 +1,37 @@
# Isogram
Welcome to Isogram on Exercism's C# Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Determine if a word or phrase is an isogram.
An isogram (also known as a "nonpattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times.
Examples of isograms:
- lumberjacks
- background
- downstream
- six-year-old
The word *isograms*, however, is not an isogram, because the s repeats.
## Source
### Created by
- @robkeim
### Contributed to by
- @ErikSchierboom
- @j2jensen
- @vgrigoriu
- @wolf99
- @yvincent
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Isogram

View File

@ -0,0 +1,141 @@
###############################
# Core EditorConfig Options #
###############################
; This file is for unifying the coding style for different editors and IDEs.
; More information at:
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
root = true
[*]
indent_style = space
[Pangram.cs]
indent_size = 4
###############################
# .NET Coding Conventions #
###############################
# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true
# this. preferences
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
# Modifier preferences
dotnet_style_require_accessibility_modifiers = always:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
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_auto_properties = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
###############################
# C# Code Style Rules #
###############################
# var preferences
csharp_style_var_for_built_in_types = true:none
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_elsewhere = true:none
# Expression-bodied members
csharp_style_expression_bodied_methods = true:suggestion
csharp_style_expression_bodied_constructors = true:suggestion
csharp_style_expression_bodied_operators = true:suggestion
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
# Pattern-matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:none
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
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 = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true

View File

@ -0,0 +1,24 @@
{
"blurb": "Determine if a sentence is a pangram.",
"authors": [
"robkeim"
],
"contributors": [
"ErikSchierboom",
"j2jensen",
"wolf99"
],
"files": {
"solution": [
"Pangram.cs"
],
"test": [
"PangramTests.cs"
],
"example": [
".meta/Example.cs"
]
},
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Pangram"
}

View File

@ -0,0 +1 @@
{"track":"csharp","exercise":"pangram","id":"ba4b5ba8db7344b6bf2e38401d8cf533","url":"https://exercism.org/tracks/csharp/exercises/pangram","handle":"benharri","is_requester":true,"auto_approve":false}

39
csharp/pangram/HELP.md Normal file
View File

@ -0,0 +1,39 @@
# Help
## Running the tests
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
## Skipped tests
Initially, only the first test will be enabled.
This is to encourage you to solve the exercise one step at a time.
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
## Submitting your solution
You can submit your solution using the `exercism submit Pangram.cs` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [C# track's documentation](https://exercism.org/docs/tracks/csharp)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

View File

@ -0,0 +1,7 @@
using System.Linq;
public static class Pangram
{
public static bool IsPangram(string input) =>
Enumerable.Range('a', 26).All(l => input.ToLower().Contains((char)l));
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,64 @@
using Xunit;
public class PangramTests
{
[Fact]
public void Empty_sentence()
{
Assert.False(Pangram.IsPangram(""));
}
[Fact]
public void Perfect_lower_case()
{
Assert.True(Pangram.IsPangram("abcdefghijklmnopqrstuvwxyz"));
}
[Fact]
public void Only_lower_case()
{
Assert.True(Pangram.IsPangram("the quick brown fox jumps over the lazy dog"));
}
[Fact]
public void Missing_the_letter_x()
{
Assert.False(Pangram.IsPangram("a quick movement of the enemy will jeopardize five gunboats"));
}
[Fact]
public void Missing_the_letter_h()
{
Assert.False(Pangram.IsPangram("five boxing wizards jump quickly at it"));
}
[Fact]
public void With_underscores()
{
Assert.True(Pangram.IsPangram("the_quick_brown_fox_jumps_over_the_lazy_dog"));
}
[Fact]
public void With_numbers()
{
Assert.True(Pangram.IsPangram("the 1 quick brown fox jumps over the 2 lazy dogs"));
}
[Fact]
public void Missing_letters_replaced_by_numbers()
{
Assert.False(Pangram.IsPangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog"));
}
[Fact]
public void Mixed_case_and_punctuation()
{
Assert.True(Pangram.IsPangram("\"Five quacking Zephyrs jolt my wax bed.\""));
}
[Fact]
public void Case_insensitive()
{
Assert.False(Pangram.IsPangram("the quick brown fox jumps over with lazy FX"));
}
}

30
csharp/pangram/README.md Normal file
View File

@ -0,0 +1,30 @@
# Pangram
Welcome to Pangram on Exercism's C# Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma,
"every letter") is a sentence using every letter of the alphabet at least once.
The best known English pangram is:
> The quick brown fox jumps over the lazy dog.
The alphabet used consists of ASCII letters `a` to `z`, inclusive, and is case
insensitive. Input will not contain non-ASCII symbols.
## Source
### Created by
- @robkeim
### Contributed to by
- @ErikSchierboom
- @j2jensen
- @wolf99
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Pangram

View File

@ -0,0 +1,21 @@
{
"blurb": "Learn about expressions by improving legacy code.",
"contributors": [
"ErikSchierboom",
"yzAlvin"
],
"authors": [
"mikedamay"
],
"files": {
"solution": [
"TheWeatherInDeather.cs"
],
"test": [
"TheWeatherInDeatherTests.cs"
],
"exemplar": [
".meta/Exemplar.cs"
]
}
}

View File

@ -0,0 +1 @@
{"track":"csharp","exercise":"the-weather-in-deather","id":"0448b30e8a064038ab0cbdf0d024c363","url":"https://exercism.org/tracks/csharp/exercises/the-weather-in-deather","handle":"benharri","is_requester":true,"auto_approve":false}

View File

@ -0,0 +1,39 @@
# Help
## Running the tests
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
## Skipped tests
Initially, only the first test will be enabled.
This is to encourage you to solve the exercise one step at a time.
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
## Submitting your solution
You can submit your solution using the `exercism submit TheWeatherInDeather.cs` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [C# track's documentation](https://exercism.org/docs/tracks/csharp)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

View File

@ -0,0 +1,11 @@
# Hints
- Expression bodied members are discussed [here][expression-bodied-members].
- Ternary operators are discussed [here][ternary-operators].
- Switch expressions are discussed [here][switch-expressions].
- Throw expressions are covered [here][throw-expressions].
[expression-bodied-members]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members
[ternary-operators]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator
[switch-expressions]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression
[throw-expressions]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/throw#the-throw-expression

View File

@ -0,0 +1,82 @@
# The Weather in Deather
Welcome to The Weather in Deather on Exercism's C# Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
## Expression Bodied Members
Many types of struct and class members (fields being the primary exception) can use the expression-bodied member syntax. Defining a member with an expression often produces more concise and readable code than traditional blocks/statements.
Methods and read-only properties are amongst the members that can be defined with expression bodies.
```csharp
public int Times3(int input) => input * 3;
public int Interesting => 1729;
```
## Conditionals Ternary
Ternary operators allow if-conditions to be defined in expressions rather than statement blocks. This echoes functional programming approaches and can often make code more expressive and less error-prone.
The ternary operator combines 3 expressions: a condition followed by an expression to be evaluated and returned if the condition is true (the `if` part, introduced by `?`) and an expression to be evaluated and returned if the condition is false (the `else` part, introduced by `:`).
```csharp
int a = 3, b = 4;
int max = a > b ? a : b;
// => 4
```
## Throw Expressions
`throw` expressions are an alternative to `throw` statements and in particular can add to the power of ternary and other compound expressions.
```csharp
string trimmed = str == null ? throw new ArgumentException() : str.Trim();
```
## Switch Expressions
A switch expression can match a value to one case in a set of patterns and return the associated value or take the associated action. The association is denoted by the `=>` symbol. In addition, each pattern can have an optional case guard introduced with the `when` keyword. The case guard expression must evaluate to true for that "arm" of the switch to be selected. The cases (also known as _switch arms_) are evaluated in text order and the process is cut short and the associated value is returned as soon as a match is found.
```csharp
double xx = 42d;
string interesting = xx switch
{
0 => "I suppose zero is interesting",
3.14 when DateTime.Now.Day == 14 && DateTime.Now.Month == 3 => "Mmm pie!",
3.14 => "π",
42 => "a bit of a cliché",
1729 => "only if you are a pure mathematician",
_ => "not interesting"
};
// => interesting == "a bit of a cliché"
```
## Instructions
You have been asked to improve some legacy code relating to a weather station.
The weather station accepts readings, and outputs some indicators such as temperature and pressure.
## 1. Improve the conciseness and readability of appropriate methods
Refactor any appropriate methods of the `WeatherStation` class using expression bodied members. Use ternary operations and switch expressions where appropriate to improve expressiveness and potentially reduce errors.
Ensure that all tests continue to pass.
## Source
### Created by
- @mikedamay
### Contributed to by
- @ErikSchierboom
- @yzAlvin

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
public class WeatherStation
{
private Reading reading;
private readonly List<DateTime> recordDates = new();
private readonly List<decimal> temperatures = new();
public void AcceptReading(Reading reading)
{
this.reading = reading;
recordDates.Add(DateTime.Now);
temperatures.Add(reading.Temperature);
}
public void ClearAll()
{
this.reading = new Reading();
recordDates.Clear();
temperatures.Clear();
}
public decimal LatestTemperature => reading.Temperature;
public decimal LatestPressure => reading.Pressure;
public decimal LatestRainfall => reading.Rainfall;
public bool HasHistory => recordDates.Count > 1;
public Outlook ShortTermOutlook =>
reading.Equals(new Reading()) ?
throw new ArgumentException(nameof(reading)) :
reading.Pressure < 10m && reading.Temperature < 30m ?
Outlook.Cool :
reading.Temperature > 50 ?
Outlook.Good :
Outlook.Warm;
public Outlook LongTermOutlook
{
get
{
if (reading.WindDirection == WindDirection.Southerly
|| reading.WindDirection == WindDirection.Easterly
&& reading.Temperature > 20)
{
return Outlook.Good;
}
if (reading.WindDirection == WindDirection.Northerly)
{
return Outlook.Cool;
}
if (reading.WindDirection == WindDirection.Easterly
&& reading.Temperature <= 20)
{
return Outlook.Warm;
}
if (reading.WindDirection == WindDirection.Westerly)
{
return Outlook.Rainy;
}
throw new ArgumentException();
}
}
public State RunSelfTest() =>
reading.Equals(new Reading()) ? State.Bad : State.Good;
}
/*** Please do not modify this struct ***/
public struct Reading
{
public decimal Temperature { get; }
public decimal Pressure { get; }
public decimal Rainfall { get; }
public WindDirection WindDirection { get; }
public Reading(decimal temperature, decimal pressure,
decimal rainfall, WindDirection windDirection)
{
Temperature = temperature;
Pressure = pressure;
Rainfall = rainfall;
WindDirection = windDirection;
}
}
/*** Please do not modify this enum ***/
public enum State
{
Good,
Bad
}
/*** Please do not modify this enum ***/
public enum Outlook
{
Cool,
Rainy,
Warm,
Good
}
/*** Please do not modify this enum ***/
public enum WindDirection
{
Unknown = 0, // default
Northerly,
Easterly,
Southerly,
Westerly
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,154 @@
using System;
using Xunit;
using Exercism.Tests;
public class TheWeatherInDeatherTests
{
[Fact]
[Task(1)]
public void GetReading()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(20m, 25m, 0.01m, WindDirection.Unknown));
decimal[] expected = { 20, 25, 0.01m };
decimal[] actual = { ws.LatestTemperature, ws.LatestPressure, ws.LatestRainfall };
Assert.Equal(expected, actual);
}
[Fact]
[Task(1)]
public void HasHistory_no()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(20m, 25m, 0.01m, WindDirection.Unknown));
Assert.False(ws.HasHistory);
}
[Fact]
[Task(1)]
public void HasHistory_yes()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(20m, 25m, 0.01m, WindDirection.Unknown));
ws.AcceptReading(new Reading(21m, 25m, 0.00m, WindDirection.Unknown));
Assert.True(ws.HasHistory);
}
[Fact]
[Task(1)]
public void ClearAll()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(20m, 25m, 0.01m, WindDirection.Unknown));
ws.AcceptReading(new Reading(21m, 25m, 0.00m, WindDirection.Unknown));
ws.ClearAll();
object[] expected = { false, 0m };
object[] actual = { ws.HasHistory, ws.LatestTemperature };
Assert.Equal(expected, actual);
}
[Fact]
[Task(1)]
public void ShortTermOutlook_exception()
{
var ws = new WeatherStation();
Assert.Throws<ArgumentException>(() => ws.ShortTermOutlook);
}
[Fact]
[Task(1)]
public void ShortTermOutlook_cool()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(7m, 7m, 0m, WindDirection.Unknown));
Assert.Equal(Outlook.Cool, ws.ShortTermOutlook);
}
[Fact]
[Task(1)]
public void ShortTermOutlook_good()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(55m, 7m, 0m, WindDirection.Unknown));
Assert.Equal(Outlook.Good, ws.ShortTermOutlook);
}
[Fact]
[Task(1)]
public void ShortTermOutlook_warm()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(40m, 7m, 0m, WindDirection.Unknown));
Assert.Equal(Outlook.Warm, ws.ShortTermOutlook);
}
[Fact]
[Task(1)]
public void RunSelfTest_good()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(40m, 7m, 0m, WindDirection.Unknown));
Assert.Equal(State.Good, ws.RunSelfTest());
}
[Fact]
[Task(1)]
public void RunSelfTest_bad()
{
var ws = new WeatherStation();
Assert.Equal(State.Bad, ws.RunSelfTest());
}
[Fact]
[Task(1)]
public void LongTermOutlook_exception()
{
var ws = new WeatherStation();
Assert.Throws<ArgumentException>(() => ws.LongTermOutlook);
}
[Fact]
[Task(1)]
public void LongTermOutlook_cool()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(7m, 7m, 0m, WindDirection.Northerly));
Assert.Equal(Outlook.Cool, ws.LongTermOutlook);
}
[Fact]
[Task(1)]
public void LongTermOutlook_good()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(21m, 7m, 0m, WindDirection.Easterly));
Assert.Equal(Outlook.Good, ws.LongTermOutlook);
}
[Fact]
[Task(1)]
public void LongTermOutlook_good2()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(7m, 7m, 0m, WindDirection.Southerly));
Assert.Equal(Outlook.Good, ws.LongTermOutlook);
}
[Fact]
[Task(1)]
public void LongTermOutlook_warm()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(7m, 7m, 0m, WindDirection.Easterly));
Assert.Equal(Outlook.Warm, ws.LongTermOutlook);
}
[Fact]
[Task(1)]
public void LongTermOutlook_rainy()
{
var ws = new WeatherStation();
ws.AcceptReading(new Reading(21m, 7m, 0m, WindDirection.Westerly));
Assert.Equal(Outlook.Rainy, ws.LongTermOutlook);
}
}