How to add a user generated number of nested parameters? - c#

I want to find a way to have nested parameters by a user generated x-number of times.
An example of this is that I've made a few classes, lets call them Milk() and Coffee()
Lets say the user wants a coffee, with two milks, I'd make this object.
var item = new Milk(new Milk(new Coffee()))
what if the user wants a coffee, with only one milk? then it would look like this:
var item = new Milk(new Coffee());
Or just coffee on its own:
var item = new Coffee();
I want to find a way to make this. I've considered looping through the amount specified, but I have no idea how to continually add nested parameters and save it to the variable.
This is the code I have but I know it doesnt come close to what Im trying to do.
for (int i = 0; i < numericUpDownMilk.Value; i++)
{
item += new Milk();
}
I know this wont work because its not adding to the parameter. I want it to be added to the specific parameter, nested.
EDIT:
There will be an messagebox stating an error if there isnt any Coffee()selected, also, its not possible for the item to have a Coffee within a Coffee, or a milk within a coffee.
so no
new Coffee(new Coffee())
or
new Coffee(new Milk())
It's always one coffee and zero or more milks wrapping it.

As others have noted, this is a very strange way to represent milks and coffees, but let's take you at your word that this is sensible in your business domain.
The way to do what you want is: first, since the return can be either a Milk or a Coffee, you need to somehow represent that in the type system. You could make a common base class, or a common interface. Let's suppose you have a common base class:
abstract class Beverage {}
sealed class Coffee : Beverage {}
sealed class Milk : Beverage {}
Once you have the types sorted out, start with the signature:
public static Beverage MakeCoffee(int milks)
{ /* a miracle happens */ }
Now try to fill in the miracle. What happens? Well, you start with a coffee:
public static Beverage MakeCoffee(int milks)
{
Beverage b = new Coffee();
And now we wrap it in some number of milks:
for (int i = 0; i < milks; i += 1)
b = new Milk(b);
return b;
}
And we're done.
Exercise: Implement the constructor on Milk
Exercise: Implement public override string ToString() on Milk and Coffee such that you get back out the string Milk(Milk(Coffee)) when you call it on a coffee with two milks.
Exercise: Now do Tea, Cream and Lemon.
Exercise: (Hard!) How would you implement the rule that Cream or Milk can wrap Coffee but you can't put Cream and Lemon into Tea at the same time?

Wait, wait, wait - stop, slow down.
First, I need to explain what you're actually doing with that code:
var item = new Milk(new Milk(new Coffee()))
... this is creating a new Coffee. Fine so far. And then it's using that new Coffee as an argument for the constructor to create a new Milk. And then it's using that new Milk object as an argument for creating another milk object.
Okay, so let's back up several steps. You talk about how to know how many milks the person wants with their coffee, right?
Try this on for size:
class Coffee
{
int numberOfMilks;
}
Now, if you want a coffee with two milks, you could just use this:
Coffee order = new Coffee();
order.numberOfMilks = 2;
Make sense? You don't need to create a "Milk Object" or "Multiple Milk Objects" - the number of milks is just a property of the coffee they're ordering.
EDIT: Okay, for the OP and anyone needing an answer to the question as-is? First, give a brief prayer of forgiveness to the gods of code quality. (Seriously, I'm having trouble figuring out why this would be what you have to do, but... oh well.)
There's no difference between:
Milk a = new Milk(new Milk());
and
var intermediate = new Milk();
Milk a = new Milk(intermediate);
After all, in the first version, it's creating a new Milk object... and then feeding that into a second Milk object's constructor. The only difference in the second version is that it breaks it into two commands instead of train-car'ing them together.
Okay, so that should hopefully light the way. Because you can always do something like:
Milk nestedMilks = new Milk();
for (int i = 1; i < nestedAmount; i++)
{
nestedMilks = new Milk(nestedMilks);
}
Coffee final = new Coffee(nestedMilks);
... you can do something like that. Should is another thing altogether. (Not sure you on earth having all those instances be nested like that makes sense.)

a very simple, basic implementation:
// have a base class (or an interface), that Milk, Coffee, etc derive from (or implement)
// the main thing is the abstraction part.
public abstract class Ingredient
{
// define anything common in here, and/or something all subclasses MUST implement
}
// let Milk, Coffe, etc extend that class
public class Milk : Ingredient
{
// special fields, properties, methods for Milk
}
now somewhere else you can make use of a generic List
List<Ingredient> ingredients = new List<Ingredient>();
ingredients.Add(new Coffee(Coffe.Types.DECAF)); // arguments just as example
ingredients.Add(new Milk(Milk.Types.ZEROLACTOSE));
ingredients.Add(new Milk(Milk.Types.REGULAR));
In your case it could be:
for (int i = 0; i < numericUpDownMilk.Value; i++)
{
ingredients.Add(new Milk());
}

Related

A general way of accessing Lists by a method

I have a lot of lists and I need to display them and to check items of the lists too.
I don't want to create a method for each list, instead I would like to access them like void Display() and call the lists in my main method Display(name of the list)
I have a list named Family and with the method I check if the input of the user is equal or not to it. As the result of checking, the user gets points for it.
My question is, is there a way to make this method general that I can access them like the example above, so I don't need as many methods as list, instead just one?
public void Check()
{
for (int i = 0; i < 99; i++)
{
if (ListOne.Family.Contains(UserInput()))
{
Console.WriteLine("Correct!");
points++;
// Exit if max points reached
if (points == ListOne.Family.Count)
break;
}
else
Console.WriteLine("Wrong!");
}
}
The above example isn't necessarily the way to approach it, simply because of the lack of flexibility with the design. For example, if you try using generics you'll get something like this:
public void Check<T> (List<T> myList) where T : class
{
var listType = typeof(T);
switch (listType.Name)
{
case "List1":
break;
case "List2":
break;
}
}
The switch is code smell because if you have to add many lists, the switch becomes difficult to manage. Instead use the conditional to polymorphism approach and follow the strategy pattern or a simple factory pattern:
https://www.dofactory.com/net/strategy-design-pattern
https://www.dofactory.com/net/factory-method-design-pattern

On which level should I test my logic

I have a TextGenerator class, which generates random text using MarkovChain class. Logic to create next word from MarkovChain lives in ChainNavigator class:
public class TextGenerator
{
public List<string> MakeText(int requiredTextLength, string sourceText)
{
var chain = new MarkovChain(sourceText);
var chainNavigator = new ChainNavigator(chain);
var nextWord = chainNavigator.GetNextWord(/*params here*/);
}
}
internal class ChainNavigator
{
internal string GetNextWord(/*params here*/) { }
}
MarkovChain is generated from source text. Source text's last word would not have any 'next state', as it does not have any words after it. When generating long text, ChainNavigator would reach last word and would not know what to return.
I want to test that TextGenerator starts new sentence, when it reaches last word, and this test can be written in 2 places.
On one hand, it makes sense to test this in TextGenerator as it's my external interface:
[TestClass]
public class TextGeneratorTest
{
[TestMethod]
public void ShouldAppendADot_WhenEndOfChainReached()
{
var generator = new TextGenerator();
var sourceText = "free men can remain free or sell their freedom";
var firstWord = "their";
var requiredTextLength = 2;
var text = generator.MakeText(requiredTextLength, sourceText, firstWord);
Assert.AreEqual("freedom.", text[1]);
}
}
On the other hand, the actual tested logic belongs to ChainNavigator class and it would make sense to test it here:
[TestMethod]
public void AppendADot_WhenEndOfChainReached()
{
var sourceText = "free men can remain free or sell their freedom";
var chain = new Chain(sourceText);
var navigator = new ChainNavigator(chain);
var nextWord = navigator.GetNextWord("their", 1);
Assert.AreEqual("freedom.", nextWord);
}
Doing it in both places looks like a duplication. Where is it better to do it?
Your confusion is actually a common one. The source of this is the term "unit" in "unit test". A lot of people will tell you, that the "unit" is something like a single class or even just a single method. People have been telling this for decades now, but it is mostly wrong. The misconception stems from the fact that you rarely see real applications being tested in books, articles, and blogs. Since it hard to show the general principles of unit testing with a full blown application, examples will usually be limited to a very small number of classes. Even Kent Beck is using the famous Money class example, which is mostly limited to a single class, in his book.
Test at the highest level that is not bound to external details. In your limited example TestGenerator might just be the perfect level. It lets you test your business logic fully, without the test breaking when you change the inner structure. Should you ever decide to split the ChainNavigator into multiple classes or join the ChainNavigator with MarkovChain, your test would not need to know and would not break.

Unable to implement Interfaces

I'm an 18 year old apprentice in c# programming (specificly in OOP 'structure')
I'm currently trying to learn the use/usefullness of Interfaces, but.. I have a VERY hard time trying to actually use Interfaces, I've decided to start working on problems from Project Euler. What I want to do with these problems is to try and implement Interfaces or anything I need to learn so that I get some experience with it.
I'm currently at Problem 2 but I can't think of a way to implement Interfaces.
So in general what I would like to ask is, what and how can I do this (please don't give me the final result, I am only looking for an idea or help to get started)
I feel like I'm stuck in a hole, unable to continue, so I would love some inspiration, examples or litteraly anything where I can get good and concise information! :)
In advance, thank you very much for your help/constructive criticism.
-Kindest Regards, Niklas
Fibonacci sequence is... well... a sequence. Hence, it can:
Return an item by index
Return next number
I would suggest creating an interface ISequence with a single method GetNextElement().
public interface ISequence
{
int GetNextElement();
}
Then you can implement this interface in a FibonacciSequence class:
public class FibonacciSequence : ISequence
{
private int _lastElement1 = 0;
private int _lastElement2 = 1;
public int GetNextElement()
{
int result = _lastElement1 + _lastElement2;
_lastElement1 = _lastElement2;
_lastElement2 = result;
return result;
}
}
This will allow you to implement other sequences such as arithmetic progression, etc.
P.S. I must admit, that doing interfaces for that particular problem is not the best idea, but for learning purposes - why not! :)
Interfaces are, in my opinion, a software engineering tool. Can you use them on things like Project Euler questions? Absolutely! They are a tool, after all.... But the usefulness of them are minimal and very debatable.
If you want to learn how interfaces apply to the real world, I strongly recommend that you study Design Patterns.
Some resources to get you started:
Wikipedia - Free resource but you are left to your devices
Head First Design Patterns - Best software engineering book I've read... Covers design patterns well and shows actual usages of Interfaces. Note that book's programming language is Java but this truly does not matter. OOP is OOP no matter the language.
This is not all there is to say about Interfaces, mind you, but it's a common real world scenario that you see interfaces used.
Instead of using ISequence and the like, I'd rather implement something like that:
public static class Sequences {
// Instead of reinveting the wheel (ISequence etc.), let's return
// IEnumerable<long> which is specially designed for such a cases
public static IEnumerable<long> Fibonacci(long first, long second) {
yield return first;
yield return second;
while (true) {
long result = first + second;
first = second;
second = result;
yield return result;
}
}
}
...
// Test: 10 first Fibonacci numbers:
// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
Console.Write(String.Join(", ", Sequences.Fibonacci(1, 2).Take(10)));
...
// Now having Fibonacci as IEnumerable<long>
// you can easily answer a lot of questions via Linq:
long result = Sequences.Fibonacci(1, 2)
.TakeWhile(item => item < 4000000) // up to 4 millions
.Where(item => item % 2 == 0) // take even items only
.Sum(); // sum them up
implementing any interfaces just for the sake of implementing interfaces is a bad practice.
Interfaces are in essence a contract - a blueprint if you will that describes what features code implementing the interface (i.e. the concretion) should provide.
Interfaces can be a difficult topic to fully get a handle on without an appreciation of their applications.
Here are few of them:
Multiple inheritance
C# doesn't support multiple inheritance i.e. deriving from more than one class so implementing multiple interfaces is really your only choice here.
Mocking frameworks
Mocking frameworks are used where you wish to mimic the behaviour of an object but not actually run it. You might want to do this when unit testing some software without connecting to a real service or database for example. You simply drop in the interface and then describe what outputs are expected for given input and it will create a mock object that behaves exactly like the concretion.
IOC
Inversion of control is a mechanism whereby interfaces are used in lieu of concretions throughout the relevant code base. Exact implementations vary from framework to framework but usually they involve some sort of factory whereby you define which interface you're using and the concretion and then the concretion implementing the interface gets passed round through the layers as required. The good thing is you can readily swap out concretions in the factory without having to update upstream code.
Some sample code where a routine can handle either concretion due to variables and parameters being defined as interfaces rather than concretions:
public class Teaching
{
public void RunTests()
{
ObjectA a = new ObjectA();
ObjectB b = new ObjectB();
IContract c = new ObjectA();
IContract d = new ObjectB();
Test1(a);
Test1(b); // Won't compile
Test2(b);
Test2(a); // Won't compile
// Test3 can handle either concretion
Test3(c);
Test3(d);
}
private void Test1(ObjectA obj)
{
Console.WriteLine(obj.GetExcited("Yeah"));
}
private void Test2(ObjectB obj)
{
Console.WriteLine(obj.GetExcited("Yeah"));
}
private void Test3(IContract obj)
{
Console.WriteLine(obj.GetExcited("Yeah"));
}
}
public class ObjectA : IContract
{
public string GetExcited(string data)
{
return data + "!";
}
}
public class ObjectB : IContract
{
public string GetExcited(string data)
{
return data + "!!";
}
}
public interface IContract
{
string GetExcited(string data);
}

How should I structure the logic of an object oriented Role-playing game?

Please look at this method in my player class of my game:
public void eatSomethingt(Items eatable)
{
foreach (Items i in items)
{
if (i is Ieatable && i.name == eatable.name) //Give items an ID in the future
{
Ieatable k = i as Ieatable;
k.eat(this);
items.Remove(i);
break;
}
}
}
Basically this will go through the list of items a player has and compare them to check if the parameter being passed in is eatable, if it is, check if the player have one. If it gets into the IF statement then the item will be removed from the players back-pack(items)
The problem is with the line: k.eat(this) It is sent to this method:
public void eat(Player p)
{
Console.WriteLine(p.Name + " Ate the " + name);
p.life = p.life + amountHealed;
}
This feels slightly 'ping-pong'ish as it's the Fruit class that feeds the item to the player. As my Fruitclass implements the interface iEatable (which surely makes sense to do) I have to place an eat method in the classes that implement it.
I think it should be a method of the player:
And to be more correct IEatable should be IEdible or even IConsumable
public class Player
{
.
.
public string Name {get;set;}
public int Life {get;set;}
.
.
public void eat(IEdible food)
{
Console.WriteLine(Name + " Ate the " + food.name);
life += food.amountHealed;
}
}
Strife for code that looks like a natural language. For example, it does make sense to tell the Console to Write(a)Line. It makes no sense to tell a food to eat. The food itself should be eaten. Also, food is rarely animated - it doesn't start any interaction with the environment, thus ask yourself whether it should really have any methods? The only thing I come up with now is possibly a Rot method, but that can also be implemented in a bacteria class that causes the food to rot. The most OOP way of solving this task seems to be:
Food should be a struct with no methods
Delegate all the work to the Player
Secondly, why pass a Items instance instead of something that is an IEdible? Instead, define the method like that:
public void eatSomething(IEnumerable<IEdible> eatable)
That way any attempt to pass something that can't be eaten are caught at compile time. It also removes the first condition of the if statement.
Thirdly, use LINQ to shorten your code.

Best approach to programming highly complex business/math rules

I have to take a piece of data, and apply a large number of possible variables to it. I really don't like the idea of using a gigantic set of if statements, so i'm looking for help in an approach to simplify, and make it easier to maintain.
As an example:
if (isSoccer)
val = soccerBaseVal;
else if (isFootball)
val = footballBaseVal;
.... // 20 different sports
if (isMale)
val += 1;
else
val += 5;
switch(dayOfWeek)
{
case DayOfWeek.Monday:
val += 12;
...
}
etc.. etc.. etc.. with possibly in the range of 100-200 different tests and formula variations.
This just seems like a maintenance nightmare. Any suggestions?
EDIT:
To further add to the problem, many variables are only used in certain situations, so it's more than just a fixed set of logic with different values. The logic itself has to change based on conditions, possibly conditions applied from previous variables (if val > threshold, for instance).
So yes, i agree about using lookups for many of the values, but I also have to have variable logic.
A common way to avoid large switching structures is to put the information into data structures. Create an enumeration SportType and a Dictionary<SportType, Int32> containing the associated values. The you can simply write val += sportTypeScoreMap[sportType] and you are done.
Variations of this pattern will help you in many similar situations.
public enum SportType
{
Soccer, Football, ...
}
public sealed class Foo
{
private static readonly IDictionary<SportType, Int32> sportTypeScoreMap =
new Dictionary<SportType, Int32>
{
{ Soccer, 30 },
{ Football, 20 },
...
}
private static readonly IDictionary<DayOfWeek, Int32> dayOfWeekScoreMap =
new Dictionary<DayOfWeek, Int32>
{
{ DayOfWeek.Monday, 12 },
{ DayOfWeek.Tuesday, 20 },
...
}
public Int32 GetScore(SportType sportType, DayOfWeek dayOfWeek)
{
return Foo.sportTypeScoreMap[sportType]
+ Foo.dayOfWeekScoreMap[dayOfWeek];
}
}
Use either a switch statement or filter function.
By filter function, I mean something like:
func filter(var object, var value)
{
if(object == value)
object = valueDictionary['value'];
}
Then apply the filter with:
filter(theObject, soccer)
filter(theObject, football)
Note that the filter works much better using a dictionary, but it is not required.
Cribbing from The Pragmatic Programmer, you could use a DSL to encapsulate the rules and write a process engine. For your presented problem, a solution might look like:
MATCH{
Soccer soccerBaseVal
IsMale 5
!IsMale 1
}
SWITCH{
Monday 12
Tuesday 13
}
Then match everything in the first col of MATCH, and the first item in each SWITCH you come to. You can make whatever syntax you feel like, then just write a bit of script to cram that into code (or use Xtext because it looks pretty cool).
Here are a few ideas:
1 Use lookup tables:
var val = 0;
SportType sportType = GetSportType();
val += sportvalues[sportType];
You can load the table from the database.
2 Use the factory pattern:
var val = 0;
val += SportFactory.Create(sportType).CalculateValue();
The Dynamic Factory Pattern is useful in situations were new (sport) types are added frequently to the code. This pattern uses reflection to prevent the factory class (or any global configuration) from being changed. It allows you to simply add a new class to your code.
Of course the use of an dynamic factory, or even a factory can be overkill in your situation. You're the only one who can tell.
As a first step I would probably break up each logical processing area into its own method: (May not be the best names as a first pass)
EnforceSportRules
ProcessSportDetails
EnforceGenderRules
Next, depending on how complex the rules are, I may break each section into its own class and have them processed by a main class (like a factory).
GenderRules
GenderContext
I have nothing special to offer you than to first recommend not to just leave it as a big block-- break it into sections, make comment dividers between important parts.
Another suggestion is if you are going to have many very short tests as in your example, break from convention and put the val incrementors on the same line as the evaluatation and indent so they align with eachother.
if (isSoccer) val = soccerBaseVal;
if (isMale) val += 1;
else val += 5;
switch(dayOfWeek){
case DayOfWeek.Monday: val += 12;
...
}
Excess whitespace can make those hundred things into several hundred lines, making vertical scrolling excessive and difficult to get an overall view of the thing.
If you are really just adding values in this sort, I would either create an enumeration with defined indices that correspond to stored values in an array. Then you can do something like this:
enum Sport
{
football = 0,
soccer = 1,
//...
}
int sportValues[] = {
/* footballValue */,
/* soccerValue */,
/* ...Values */
};
int ApplyRules(Sport sport, /* other params */)
{
int value = startingValue;
value += sportValues[(int)sport];
value += /* other rules in same fashion */;
}
Consider implementing the Strategy Pattern which utilizes inheritance/polymorphism to make managing individual functions sane. By seperating each function into its own dedicated class you can forego the nightmare of having miles-long case blocks or if statements.
Not sure if C# supports it yet (or ever will) but VB.NET integrates XML Comment CompletionList directives into intellisense, which--when combined with the Strategy Pattern--can give you the ease of use of an Enum with the open-ended extensibility of OO.

Categories