Last active
September 27, 2020 16:27
-
-
Save Ruffo324/89d47de91a8e0232b94a911d3c3e1d7a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
namespace ConsoleApp1 | |
{ | |
/// <summary> | |
/// Target: | |
/// 1) Read in Number of students | |
/// 2) Create array with number of elements for age (int) & weight (double) | |
/// 3) Reading of age & weight | |
/// 4) Search for the most difficult students (mobbing!) | |
/// 5) Count how many students are 16 years old. | |
/// X) Calculate average age | |
/// XX) Determine total weight of the class | |
/// </summary> | |
internal class Program | |
{ | |
private static readonly (int min, int max) RandomAgeRange = (min: 10, max: 95); | |
private static readonly (double min, double max) RandomWeightRange = (min: 45f, max: 185f); | |
private static readonly ConsoleColor OriginalConsoleForeground = Console.ForegroundColor; | |
private delegate bool TryParseMethod<TResult>(string? str, out TResult parsedResult); | |
/// <summary> | |
/// Overload/Wrapper of <see cref="Console.ReadLine" />. | |
/// Prints the given <paramref name="prefix" /> first on the same line. | |
/// <example>"Age > "</example> | |
/// </summary> | |
private static string ReadLine(string prefix = "> ") | |
{ | |
Console.Write(prefix); | |
return Console.ReadLine() ?? string.Empty; | |
} | |
/// <summary> | |
/// Read the console input until the user input is parsable to <typeparamref name="TResult" />. | |
/// Use the <paramref name="fallback" /> parameter, to define fallback/default values after X tries. | |
/// </summary> | |
private static TResult ParseUntilValid<TResult>(TryParseMethod<TResult> tryParse, string? retryMessage = null, (TResult fallbackValue, int afterTries)? fallback = null, | |
string? inputPrefix = null) | |
where TResult : unmanaged | |
{ | |
inputPrefix ??= "> "; | |
TResult parsedValue; | |
string userInput; | |
var tries = fallback?.afterTries ?? -1; | |
while (!tryParse(userInput = ReadLine(tries == decimal.Zero ? $"([ENTER] for default) {inputPrefix}" : inputPrefix), out parsedValue)) | |
{ | |
if (tries == -1 || --tries > 0) | |
{ | |
var input = userInput; | |
RunInColor(ConsoleColor.Red, () => Console.WriteLine(retryMessage ?? $"User input \"{input}\" does not match the excepted type \"{typeof(TResult)}\"!")); | |
} | |
else | |
{ | |
return fallback?.fallbackValue | |
?? throw new ArgumentNullException(nameof(fallback), $"{nameof(fallback)}.{nameof(fallback.Value.fallbackValue)} is not allowed to be null."); | |
} | |
} | |
return parsedValue; | |
} | |
private static void PrintLine(char lineChar = '#') | |
=> Console.WriteLine(string.Empty.PadRight(Console.BufferWidth, lineChar)); | |
private static void TryWriteCentered(string text) | |
=> Console.WriteLine(text.Length > Console.BufferWidth ? text : string.Empty.PadLeft((Console.BufferWidth - text.Length) / 2) + text); | |
private static void EmptyLine() | |
=> Console.WriteLine(); | |
private static void WholeProgram() | |
{ | |
PrintLine(); | |
TryWriteCentered("Simple students coding session task"); | |
TryWriteCentered("BUT SLIGHTLY OVER ENGINEERED!"); | |
PrintLine(); | |
EmptyLine(); | |
// Read amount of students. | |
Console.WriteLine("Number of students in class?"); | |
var studentsInClass = ParseUntilValid<int>(int.TryParse); | |
var students = Enumerable.Repeat<(int number, int age, double weight)>((default, default, default), studentsInClass); | |
Console.WriteLine("Automatic generate random values? ['true' / 'false'] (false is default)"); | |
var autoFill = ParseUntilValid<bool>(bool.TryParse, fallback: (false, 0)); | |
if (autoFill) | |
{ | |
var random = new Random(); | |
var randomAge = new Func<int>(() => random.Next(RandomAgeRange.min, RandomAgeRange.max)); | |
var randomWeight = new Func<double>(() => random.NextDouble() * (RandomWeightRange.max - RandomWeightRange.min) + RandomWeightRange.min); | |
students = students.Select((s, i) => (number: i + 1, age: randomAge(), weight: randomWeight())).ToList(); | |
} | |
else | |
{ | |
const int inputPadding = 10; | |
var getAge = new Func<int>(() => ParseUntilValid<int>(int.TryParse, inputPrefix: $"{"Age".PadRight(inputPadding)} > ")); | |
var getWeight = new Func<double>(() => ParseUntilValid<double>(double.TryParse, inputPrefix: $"{"Weight".PadRight(inputPadding)} > ")); | |
students = students.Select((s, i) => | |
{ | |
PrintLine('-'); | |
Console.WriteLine($"Enter properties of student no. \"{i + 1}\"."); | |
return (number: i + 1, age: getAge(), weight: getWeight()); | |
}).ToList(); | |
PrintLine('-'); | |
} | |
// Print students overview. | |
PrintLine(); | |
TryWriteCentered($"Students data {(autoFill ? "generated" : "collected")}."); | |
PrintLine(); | |
var pad = new Func<double, string>(d => $"{d}".PadRight(5)); | |
foreach (var (number, age, weight) in students) | |
{ | |
Console.WriteLine("Nr. " + pad(number) + "Age: " + pad(age) + "Weight: " + pad(weight)); | |
} | |
PrintLine(); | |
EmptyLine(); | |
EmptyLine(); | |
TryWriteCentered("NO. 4) Fattiest/heaviest student:"); | |
TryWriteCentered($"{students.Max(s => s.weight)} KG"); | |
EmptyLine(); | |
TryWriteCentered("NO. 5) Number of students who are 16 years old:"); | |
TryWriteCentered($"{students.Count(s => s.age == 16)} students."); | |
EmptyLine(); | |
TryWriteCentered("NO. 6/X) Average age of the class:"); | |
TryWriteCentered($"{students.Average(s => s.age)} years."); | |
EmptyLine(); | |
TryWriteCentered("NO. 7/XX) Total weight of class:"); | |
TryWriteCentered($"{students.Sum(s => s.weight)} KG"); | |
EmptyLine(); | |
PrintLine(); | |
RunInColor(ConsoleColor.Cyan, () => TryWriteCentered("Have a nice day!")); | |
} | |
private static void RunInColor(ConsoleColor color, Action action) | |
{ | |
Console.ForegroundColor = color; | |
action(); | |
Console.ForegroundColor = OriginalConsoleForeground; | |
} | |
private static void Main() | |
{ | |
do | |
{ | |
Console.Clear(); | |
WholeProgram(); | |
PrintLine(); | |
RunInColor(ConsoleColor.Red, () => Console.WriteLine("Press 'e' to exit. Otherwise the program run's again.")); | |
} while (Console.ReadLine()?.ToLower() != "e"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment