Skip to content

Conversation

@kellanburns
Copy link

Worked by myself. Implemented the generics extra credit option.

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

Summary

Summary
Generated on: 11/04/2025 - 07:52:41
Coverage date: 11/04/2025 - 07:52:39
Parser: MultiReport (2x Cobertura)
Assemblies: 1
Classes: 3
Files: 3
Line coverage: 86.8% (66 of 76)
Covered lines: 66
Uncovered lines: 10
Coverable lines: 76
Total lines: 129
Branch coverage: 80% (24 of 30)
Covered branches: 24
Total branches: 30
Method coverage: Feature is only available for sponsors
Tag: 366_19061593110

Coverage

Calculate - 86.8%
Name Line Branch
Calculate 86.8% 80%
Calculate.Calculator`1 88.2% 80%
Calculate.CalculatorOperations 100% 100%
Calculate.Program 82.8% 75%

Copy link

@steeley21 steeley21 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instructions

Create a Console project called "Calculate.". ✔
Define a Program Class
Define two init-only setter properties, WriteLine and ReadLine, that contain delegates for writing a line of text and reading a line of text respectively ✔
Write a test that sets these properties at construction time and then invokes the properties and verifies the expected behavior occurs. ✔
Set the default behavior for the WriteLine and ReadLine properties to invoke System.Console versions of the methods and add an empty default constructor. ✔
Define a Calculator class ✔
Define static Add, Subtract, Multiple, and Divide methods that have two parameters and return a third parameter. ✔
Define a read-only property, MathematicalOperations, of type System.Collections.Generics.IReadOnlyDictionary<TKey,TValue> that:
is initialized to a System.Collections.Generics.Dictionary<<TKey,TValue> instance that. ✔
Uses char for the key corresponding to the operators +, -, *, and /. ✔
Has values that correspond with the Add, Subtract, Multiple, and Divide methods. ✔
Implement a TryCalculate method following "TryParse" pattern ✔
Valid calculation expressions include such strings as "3 + 4", "42 - 2", etc. ✔
If there is no whitespace around the operator, you can assume the calculation is invalid and return false. Similarly if the operands are not integers. ✔
Use string.Split(), pattern matching, logical and operators to parse the string in their entirety ✔
Index into the MathematicalOperations method using the operator parsed during pattern matching to find the corresponding implementation and invoke it. ✔
Implement the Program class to instantiate the calculator and invoke it based on user input from the console. ✔
Be sure to use the WriteLine/ReadLine properties on Program for testing the input and output of your program. ✔

Extra Credit

Do one of the following two options (or both if you want extra, extra credit) :)

Refactor the redirect portion of the Program class into 'ProgramBase`
Move ProgramBase into a ConsoleUtilities assembly to be used in other console-based projects
Use generics the mathematical operations methods and consider using generic constraints (requires .NET 7.0)✔

Fundamentals

Place all shared project properties into a Directory.Build.props file.
Place all shared project items into a Directory.Build.targets file. (optional)
nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, always use Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

Nice work!

if (parts.Length != 3)
return false;

var leftText = parts[0];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nitpick, but I'd recommend not using vars here for better readability in tracking the calculation parts.

Copy link

@thigiang16 thigiang16 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a Console project called "Calculate.". ✔
Define a Program Class
Define two init-only setter properties, WriteLine and ReadLine, that contain delegates for writing a line of text and reading a line of text respectively ✔
Write a test that sets these properties at construction time and then invokes the properties and verifies the expected behavior occurs. ✔
Set the default behavior for the WriteLine and ReadLine properties to invoke System.Console versions of the methods and add an empty default constructor. ✔
Define a Calculator class ✔
Define static Add, Subtract, Multiple, and Divide methods that have two parameters and return a third parameter. ✔
Define a read-only property, MathematicalOperations, of type System.Collections.Generics.IReadOnlyDictionary<TKey,TValue> that:
is initialized to a System.Collections.Generics.Dictionary<<TKey,TValue> instance that. ✔
Uses char for the key corresponding to the operators +, -, *, and /. ✔
Has values that correspond with the Add, Subtract, Multiple, and Divide methods. ✔
Implement a TryCalculate method following "TryParse" pattern ✔
Valid calculation expressions include such strings as "3 + 4", "42 - 2", etc. ✔
If there is no whitespace around the operator, you can assume the calculation is invalid and return false. Similarly if the operands are not integers. ✔
Use string.Split(), pattern matching, logical and operators to parse the string in their entirety ✔
Index into the MathematicalOperations method using the operator parsed during pattern matching to find the corresponding implementation and invoke it. ✔
Implement the Program class to instantiate the calculator and invoke it based on user input from the console. ✔
Be sure to use the WriteLine/ReadLine properties on Program for testing the input and output of your program. ✔
Extra Credit
Do one of the following two options (or both if you want extra, extra credit) :)

Refactor the redirect portion of the Program class into 'ProgramBase`
Move ProgramBase into a ConsoleUtilities assembly to be used in other console-based projects
Use generics the mathematical operations methods and consider using generic constraints (requires .NET 7.0) ✔
Fundamentals
Place all shared project properties into a Directory.Build.props file.
Place all shared project items into a Directory.Build.targets file. (optional)
nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, always use Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

The program and tests are well-structured. I like how the operations are separated into CalculatorOperations, which makes the code easier to read and maintain. One small improvement would be to reduce the use of var for better readability. You could also add an extra test for unsupported operators, negative numbers, extra spaces, or malformed expressions to strengthen coverage. Overall, good work!

@Hellothereyoko
Copy link

Create a Console project called "Calculate.". ✔
Define a Program Class
Define two init-only setter properties, WriteLine and ReadLine, that contain delegates for writing a line of text and reading a line of text respectively ✔
Write a test that sets these properties at construction time and then invokes the properties and verifies the expected behavior occurs. ✔
Set the default behavior for the WriteLine and ReadLine properties to invoke System.Console versions of the methods and add an empty default constructor. ✔
Define a Calculator class ✔
Define static Add, Subtract, Multiple, and Divide methods that have two parameters and return a third parameter. ✔
Define a read-only property, MathematicalOperations, of type System.Collections.Generics.IReadOnlyDictionary<TKey,TValue> that:
is initialized to a System.Collections.Generics.Dictionary<<TKey,TValue> instance that. ✔
Uses char for the key corresponding to the operators +, -, *, and /. ✔
Has values that correspond with the Add, Subtract, Multiple, and Divide methods. ✔
Implement a TryCalculate method following "TryParse" pattern ✔
Valid calculation expressions include such strings as "3 + 4", "42 - 2", etc. ✔
If there is no whitespace around the operator, you can assume the calculation is invalid and return false. Similarly if the operands are not integers. ✔
Use string.Split(), pattern matching, logical and operators to parse the string in their entirety ✔
Index into the MathematicalOperations method using the operator parsed during pattern matching to find the corresponding implementation and invoke it. ✔
Implement the Program class to instantiate the calculator and invoke it based on user input from the console. ✔
Be sure to use the WriteLine/ReadLine properties on Program for testing the input and output of your program. ✔

Extra Credit

Do one of the following two options (or both if you want extra, extra credit) :)

Refactor the redirect portion of the Program class into 'ProgramBase`
Move ProgramBase into a ConsoleUtilities assembly to be used in other console-based projects
Use generics the mathematical operations methods and consider using generic constraints (requires .NET 7.0)✔

Fundamentals

Place all shared project properties into a Directory.Build.props file.
Place all shared project items into a Directory.Build.targets file. (optional)
nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, always use Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

One point of praise I'd like to point out: your testing coverage. What methods do you use in ensuring testing coverage? I always feel like I end up missing something there... It'd help me out to pick your brain on this; cuz your coverage rate is pretty dang good! Keep up the good work!

Copy link
Collaborator

@Joshua-Lester3 Joshua-Lester3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instructions

  • Create a Console project called "Calculate". ❌ Doesn't explicitly specify this.
  • Define a Program Class
    • Define two init-only setter properties, WriteLine and ReadLine, that contain delegates for writing a line of text and reading a line of text respectively ✔
    • Write a test that sets these properties at construction time and then invokes the properties and verifies the expected behavior occurs. ✔
    • Set the default behavior for the WriteLine and ReadLine properties to invoke System.Console versions of the methods and add an empty default constructor. ❌ not empty
  • Define a Calculator class ✔
    • Define static Add, Subtract, Multiply, and Divide methods that have two parameters and return a third parameter. ✔
    • Define a read-only property, MathematicalOperations, of type System.Collections.Generics.IReadOnlyDictionary<TKey,TValue> that:
      • is initialized to a System.Collections.Generics.Dictionary<<TKey,TValue> instance that. ✔
        • Uses char for the key corresponding to the operators +, -, *, and /. ✔
        • Has values that correspond with the Add, Subtract, Multiply, and Divide methods. ✔
    • Implement a TryCalculate method following "TryParse" pattern ✔
      • Valid calculation expressions include such strings as "3 + 4", "42 - 2", etc. ✔
      • If there is no whitespace around the operator, you can assume the calculation is invalid and return false. Similarly if the operands are not integers. ✔
      • Use string.Split(), pattern matching, logical and operators to parse the string in their entirety ✔
      • Index into the MathematicalOperations method using the operator parsed during pattern matching to find the corresponding implementation and invoke it. ✔
  • Implement the Program class to instantiate the calculator and invoke it based on user input from the console. ✔
  • Be sure to use the WriteLine/ReadLine properties on Program for testing the input and output of your program. ✔

Extra Credit

Do one of the following two options (or both if you want extra, extra credit) :)

  • Refactor the redirect portion of the Program class into 'ProgramBase` ❌
    • Move ProgramBase into a ConsoleUtilities assembly to be used in other console-based projects
  • Use generics the mathematical operations methods and consider using generic constraints (requires .NET 7.0) ✔

Fundamentals

  • Place all shared project properties into a Directory.Build.props file.
  • Place all shared project items into a Directory.Build.targets file. (optional)
  • nullable reference types is enabled ✔
  • Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
  • Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
  • and enabled .NET analyzers for both projects ✔
  • For this assignment, always use Assert.AreEqual<T>() (the generic version) ✔
  • All of the above should be unit tested ❌ Not fully unit tested
  • Choose simplicity over complexity ✔

Comment on lines +46 to +53
public static int Main()
{
var prog = new Program();
var calc = new Calculator<int>();

int runResult = prog.Run<int>(calc);

return runResult;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of a nit: I think return codes are supposed to be for status of finished application. I think code 0 is success and anything else is failure. Not something we grade on though :)

Comment on lines +44 to +58
public void TryCalculate_EvaluatingInvalidExpressions_ReturnsFalse()
{
var calc = new Calculator<int>();

bool sum = calc.TryCalculate("6+ 7", out _);
bool difference = calc.TryCalculate("6-7", out _);
bool product = calc.TryCalculate("6 *7", out _);
bool quotient = calc.TryCalculate("six / 7", out _);

// Using 'IsFalse' here to avoid compiler warnings
Assert.IsFalse(sum);
Assert.IsFalse(difference);
Assert.IsFalse(product);
Assert.IsFalse(quotient);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd separate these out into different tests. Same goes for other similar unit tests. Unit tests should usually only have one reason to fail. This has quite a few

{
ArgumentNullException.ThrowIfNull(calculator);

while (true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider that having an infinite loop creates a certain kind of interactive experience like a REPL vs if you did not have the loop the app would exit on each invocation and could be used like in an automated tool call fashion.

public sealed class ProgramTests
{
[TestMethod]
public void Program_Constructor_DefinesNonNullDelegates()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm not sure how useful this test is and could probably be removed. I think the other tests will reveal if the program defines the delegates correctly just by using them.


var op = opText[0];

if (!T.TryParse(leftText, CultureInfo.InvariantCulture, out var left))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The Essential C# guideline says "AVOID omitting braces, except for the simplest of single-line if statements." All these single line if statements make me think what does simplest mean? I mean these are pretty simple but is the one on line 35 simpler?


namespace Calculate;

public static class CalculatorOperations

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we need this extra class or if putting this in the Calculator class itself makes more sense?

Copy link

@quattro004 quattro004 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good overall just a few minor comments and suggestions. Nice work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants