How to pass value in ArrayList from method to method - c#

public Program()
{
amount_bike = new ArrayList();
}
public void push(int value)
{
this.amount_bike.Add(value);
}
public int amount_bike_pop()
{
if (this.amount_bike.Count == 0)
{
return -100000;
}
int lastItem = (int)this.amount_bike[this.amount_bike.Count - 1];
this.amount_bike.RemoveAt(this.amount_bike.Count - 1);
return lastItem;
}
public static void Bike_status()
{
bool exit = false;
Program available = new Program();
available.push(0);
available.push(0);
available.push(50);
WriteLine("E-bike available for rent is : " + available.amount_bike_pop() + " bikes.");
WriteLine("Rented E-bike is : " + available.amount_bike_pop() + " bikes.");
WriteLine("Broke E-bike is : " + available.amount_bike_pop() + " bikes.");
WriteLine("\n");
WriteLine("Please enter a number: 1 is back to pervoius menu or 0 to Exit");
int input = Convert.ToInt32(ReadLine());
while (exit == false)
{
if (input == 1)
{
Clear();
exit = true;
continue;
}
else if (input == 0)
{
Clear();
Exit();
}
else
{
Clear();
Bike_status();
}
}
}
public static void Add_bike()
{
}
I study data structures and Algorithms. In this code, I keep the value in an ArrayList named "available" in the Bike_status method. I need to pass a value in an ArrayList to the Add_bike method. How do I pass a value from one method to another? Actually, I need to pass valus such as 50 to plus some number that I push in Console.ReadLine.

Try to slow down.at starting point of programming sometimes it's confusing.
How do I pass a value from one method to another?
The simple answer is easy ,you want something to use in the function then in your method(s) you create parameter and pass the things you want to it.
like
//edit method to get int value -> public static void Bike_status()
public static void Bike_status(int value)
//edit when to call
else
{
Clear();
Bike_status(input);//send int value in
}
But really, what is that do you really want to learn?
if it OOP? I recommend you study this
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/
To put it simply you has bicycle shop class separate from main program then use the method in that class
e.g.
//bicycle class
public class Bicycles{
public int ID {get;set;}
pulibc string status {get;set; }
public Bicycles(int p_id, string p_status)
{
ID = p_id;
status=p_status;
}
}
//bicycle shop class
public class BicyclesShop{
public List<Bicycle> available {get;set;} // class member
public BicyclesShop() // go search keyword "constructor"
{
available = new List<Bicycle> ();
}
//other method
public void Add_bike()
{
// I can access available object !
// do anything with this class member(s) !
}
public void Bike_status(int inputVal)
{
// do something with inputVal , change some properties?
}
//other methods
public int amount_bike_pop()
{
return available.Count();
}
public int amount_bike_broken_pop()
{
return available.Where(o=>o.status =="Broken").Count(); // go search linq
}
}
//To use in Main program method
BicyclesShop bs =new BicyclesShop();
bs.available.Add( new Bicycle(1 ,"OK") ); //add bicycle #1 in list
bs.available.Add( new Bicycle(2),"Broken" ); //add bicycle #2 in list
WriteLine("Broke E-bike is : " + bs.amount_bike_broken_pop() + " bikes.");

Related

Crash when class write to console

I'm going to get another user and enter which month he wants and find the quarter.
Thought of writing the code inside a class as I need more training on how to use classes.
The program asks whose month it is and I can enter. But now when I type "January" only programs crash.
I assume that it should show which quarter "january" is in
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Write a month");
var mc = new MyClass();
mc.month = Convert.ToString(Console.ReadLine());
}
public class MyClass
{
public string month;
public string Prop
{
get
{
return month;
}
set
{ if (Prop == "january")
{
Console.WriteLine("1.quarter");
}
}
}
}
}
}
Consider presenting a menu which in the case below uses a NuGet package Spectre.Console and docs. This gives you an opportunity to work with classes and ensures, in this case input is a valid month along with reties and how to exit.
First a class for the menu.
public class MonthItem
{
public int Index { get; }
public string Name { get; }
public MonthItem(int index, string name)
{
Index = index;
Name = name;
}
public override string ToString() => Name;
}
Class which creates the menu
class MenuOperations
{
public static SelectionPrompt<MonthItem> SelectionPrompt()
{
var menuItemList = Enumerable.Range(1, 12).Select((index) =>
new MonthItem(index, DateTimeFormatInfo.CurrentInfo.GetMonthName(index)))
.ToList();
menuItemList.Add(new MonthItem(-1, "Exit"));
SelectionPrompt<MonthItem> menu = new()
{
HighlightStyle = new Style(Color.Black, Color.White, Decoration.None)
};
menu.Title("[yellow]Select a month[/]");
menu.PageSize = 14;
menu.AddChoices(menuItemList);
return menu;
}
}
Present menu, get selection and show details or exit.
static void Main(string[] args)
{
while (true)
{
Console.Clear();
var menuItem = AnsiConsole.Prompt(MenuOperations.SelectionPrompt());
if (menuItem.Index != -1)
{
AnsiConsole.MarkupLine($"[b]{menuItem.Name}[/] index is [b]{menuItem.Index}[/]");
Console.ReadLine();
}
else
{
return;
}
}
}
I tested your code and your program is not crashing. The program is actually completing and therefore the console is closing due to execution completing. So you can see what I mean try changing your code to this. You will see your code loop and the console will not close. It will also display what the user types in for mc.month
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Write a month");
var mc = new MyClass();
mc.month = Convert.ToString(Console.ReadLine());
Console.WriteLine(mc.month);
}
}
On a side note, not really how I would use a class. You might want to also rethink that. Don't normally see writelines in class.

C# - How to create a common method to update different properties in a object without creating multiple methods

This is my object
public class Totals {
public int Total1 { get; set; }
public int Total2 { get; set; }
public int Total3 { get; set; }
public int Total4 { get; set; }
}
Incrementing the values of Total1 and Total2 using calculateTotals method
private Totals calculateTotals(Totals t) {
if (//condition) {
t.Total1 += 1;
} else {
t.Total2 += 1;
}
return t;
}
**Incrementing value of Total3 and Total4 of the same object with same conditions at a different location using different method calculateOtherTotals, at this point I only need to update Total3 and Total4 **
private Totals calculateOtherTotals(Totals t) {
if (//condition) {
t.Total3 += 1;
} else {
t.Total4 += 1;
}
return t;
}
I am new to c# , I need to increment the values Total1,Total2 and Total3,Total4 separately and the code which I have is working fine
Is there a way to improve my code?, how can I avoid creating two different methods which pretty much does the same logic on different properties? is there a way to create only 1 method to achieve my functionality?
You could do it this way, but essentially the amount of code doesn't change.
This adds a judgment:
Totals calculateTotals(Totals t, bool Flag)
{
//function1:
if (Flag)
{
if (true)
{ //(condition) {
t.Total1++;
}
else
{
t.Total2++;
}
}
//function2:
else
{
if (true)
{ //(condition) {
t.Total3++;
}
else
{
t.Total4++;
}
}
return t;
}
Call it like this:
Totals totals = new Totals();
totals.Total1=0;
totals.Total2=0;
totals.Total3=0;
totals.Total4=0;
calculateTotals(totals,true);//function1:
calculateTotals(totals,false);//function2:
Reflection is one way, though its slow and not a Domain Specific Language:
Type totalsType = typeof(Totals);
var totalToIncrement = condition;
PropertyInfo prop = totalsType.GetProperty("Total" + totalToIncrement);
prop.SetValue(null, 76);
Or perhaps you want to abstract the properties you're incrementing:
private Totals calculateTotals(Totals t)
{
bool condition = true;
AbstractAdds(ref t.Total1, ref t.Total2, condition);
return t;
}
private void AbstractAdds(ref int a, ref int b, bool condition = false)
{
if (condition)
{
a++;
}
else
{
b++;
}
}
}
public class Totals
{
public int Total1;//{ get; set; }
public int Total2;//{ get; set; }
public int Total3;//{ get; set; }
public int Total4;//{ get; set; }
}
I'd personally have a List<int> or int[3] and make the condition calculate the index 0-3:
var index = calcCondition;
Totals[index]++;
This way its extensible for more totals and you get inbuilt functions like LINQ, eg Totals.Sum().
Is there a way to improve my code?, how can I avoid creating two different methods which pretty much does the same logic on different properties? is there a way to create only 1 method to achieve my functionality?
Then it depends on how you want your method (function) to be. (E.g., how you define what your function will do and how your class and properties are characteristic—which, currently, many who want to help you still wonder about.)
Let me give another clear example.
Assume that you answer your additional requirement are:
My object has only 4 properties of "Total"
I want these new function to increment value only 1 when call, no need to add more than 1
This function is called from another class to modify my object value
I want my cool function name calculateOtherTotals being private, because of some unexplained reason such as “I don't like others knowing it exists”.
Then
public OtherClass{
Public Totals ExposeThePrivateCalculateOtherTotals(Totals t, bool IncrementT1 , bool IncrementT2 , bool IncrementT3, bool IncrementT4)
{
calculateOtherTotals(t, IncrementT1 , IncrementT2 , IncrementT3, IncrementT4);
}
Private Totals calculateOtherTotals(Totals t, bool IncrementT1 , bool IncrementT2 , bool IncrementT3, bool IncrementT4) {
if( IncrementT1 ) t.Total1 += 1; //choose your style
if( IncrementT2==true ) ++t.Total2;//choose your style
if( IncrementT3!=false ) t.Total3++; //choose your style
t.Total4 += IncrementT4==true?1:0;//choose your style
return t;
}
}
//In main (how to use)
Totals t= new Totals();
OtherClass doMyFunc = new OtherClass();
t = doMyFunc.ExposeThePrivateCalculateOtherTotals(t, true, false,false,false); // result of operation => t.total1 += 1;
t = doMyFunc.ExposeThePrivateCalculateOtherTotals(t, false, true,false,false); // result of operation => t.total2 += 1;

Getting the callstack from a method 'A' (MethodBase/MethodInfo) being called from 'B' or 'C' without the stacktrace

Well, I would like to do my own benchmarking system like spark in Minecraft (https://github.com/lucko/spark):
I'm using Harmony lib (https://github.com/pardeike/Harmony) which allows me to interact/modify methods and allows me to add a Prefix/Postfix on each call that will help me out with this stack.
The basic structure has something similar to (https://github.com/pardeike/Harmony/issues/355):
[HarmonyPatch]
class MyPatches
{
static IEnumerable<MethodBase> TargetMethods()
{
return AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly())
.SelectMany(type => type.GetMethods())
.Where(method => method.ReturnType != typeof(void) && method.Name.StartsWith("Do"));
}
static void Prefix(out Stopwatch __state, MethodBase __originalMethod)
{
__state = Stopwatch.StartNew();
// ...
}
static void Postfix(Stopwatch __state, MethodBase __originalMethod)
{
__state.Stop();
// ....
}
}
The problem here is that the __originalMethod doesn't take care if it was called from A or B.
So for example, we had patched string.Join method. And the we call from A or B, where A or B, is the full callstack of this method.
So first, we need to assign a ID to this call, and we need to create a Tree-based structure (which is hard to serialize later), from here (https://stackoverflow.com/a/36649069/3286975):
public class TreeModel : Tree<TreeModel>
{
public int ID { get; set; }
public TreeModel() { }
public TreeModel(TreeModel parent) : base(parent) { }
}
public class Tree<T> where T : Tree<T>
{
protected Tree() : this(null) { }
protected Tree(T parent)
{
Parent=parent;
Children=new List<T>();
if(parent!=null)
{
parent.Children.Add(this as T);
}
}
public T Parent { get; set; }
public List<T> Children { get; set; }
public bool IsRoot { get { return Parent==null; } }
public T Root { get { return IsRoot?this as T:Parent.Root; } }
public T RecursiveFind(Predicate<T> check)
{
if(check(this as T)) return this as T;
foreach(var item in Children)
{
var result=item.RecursiveFind(check);
if(result!=null)
{
return result;
}
}
return null;
}
}
Now, the thing is that we need to fill the Tree as long as we iterate all the method and instructions got from Harmony. Forget about Harmony for a second, I will explain only two facts about it.
The lib allows you first to get all patched methods through IEnumerable<MethodBase> TargetMethods() so, you have the Assembly X passed through reflection and filtered all methods that are allowed to be patched (some of them broke Unity, so I decided to skip methods from UnityEngine., UnityEditor. and System.* namespaces).
And we have also the ReadMethodBody method (https://harmony.pardeike.net/api/HarmonyLib.PatchProcessor.html#HarmonyLib_PatchProcessor_ReadMethodBody_System_Reflection_MethodBase_) from a given MethodBase it returns all IL stack instructions.
So we can start to iterate over and over in order to get all instructions and fill the entire tree. This is what I wrote last night:
internal static class BenchmarkEnumerator
{
internal static Dictionary<MethodBase, int> Mappings { get; } = new Dictionary<MethodBase, int>();
internal static Dictionary<int, TreeModel> TreeIDs { get; } = new Dictionary<int, TreeModel>();
internal static Dictionary<MethodBase, BenchmarkTreeModel> TreeMappings { get; } = new Dictionary<MethodBase, BenchmarkTreeModel>();
private static HashSet<int> IDUsed { get; } = new HashSet<int>();
public static int GetID(this MethodBase method)
{
return GetID(method, out _);
}
public static int GetID(this MethodBase method, out bool contains)
{
// A > X = X1
// B > X = X2
if (!Mappings.ContainsKey(method))
{
var id = Mappings.Count;
Mappings.Add(method, Mappings.Count);
IDUsed.Add(id);
contains = false;
return id;
}
contains = true;
return Mappings[method];
}
public static int GetFreeID()
{
int id;
Random rnd = new Random();
do
{
id = rnd.Next();
} while (IDUsed.Contains(id));
IDUsed.Add(id);
return id;
}
public static BenchmarkCall GetCall(int id)
{
return TreeIDs[id]?.Call;
}
public static BenchmarkCall GetCall(this MethodBase method)
{
return TreeIDs[Mappings[method]]?.Call;
}
}
The BenchmarkEnumerator class allow us to differentiate between A or B, but it doesn't care about the full hierarchy, only from the parent MethodBase itself, so I need to write something complex to take in care of the full call stack, which I said I have a problem to understand.
Then we have the TargetMethods:
private static IEnumerable<MethodBase> TargetMethods()
{
Model = new BenchmarkTreeModel();
var sw = Stopwatch.StartNew();
//int i = 0;
return Filter.GetTargetMethods(method =>
{
try
{
var instructions = PatchProcessor.ReadMethodBody(method);
var i = method.GetID(out var contains);
var tree = new TreeModel
{
ID = i
};
if (contains)
{
//var lastId = i;
i = GetFreeID();
tree.ID = i;
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
tree.Parent = null;
tree.Children = TreeMappings[method].Forest.First().Children; // ??
//DictionaryHelper.AddOrAppend(TreeMappings, method, tree);
TreeMappings[method].Forest.Add(tree);
TreeIDs.Add(i, tree);
Model.Forest.Add(tree);
// UNIT TESTING: All contained methods at this point will have a parent.
// string.Join is being added as a method by a instruction, so when we try to patch it, it will have already a reference on the dictionary
// Here, we check if the method was already added by a instruction CALL
// Logic: If the method is already contained by the mapping dictionary
// then, we will exit adding a new that will have the same childs but a new ID
return false;
}
TreeIDs.Add(i, tree);
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
foreach (var pair in instructions)
{
var opcode = pair.Key;
if (opcode != OpCodes.Call || opcode != OpCodes.Callvirt) continue;
var childMethod = (MethodBase)pair.Value;
var id = childMethod.GetID(out var _contains);
var subTree = new TreeModel(tree)
{
ID = id
};
if (_contains)
{
id = GetFreeID();
subTree.ID = id;
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}"); // TODO: Check this
subTree.Parent = TreeIDs[i];
subTree.Children = TreeMappings[childMethod].Forest.First().Children;
TreeIDs.Add(id, subTree);
continue;
}
TreeIDs.Add(id, subTree);
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}");
tree.Children.Add(subTree);
TreeMappings.Add(childMethod, new BenchmarkTreeModel());
TreeMappings[childMethod].Forest.Add(subTree);
}
TreeMappings.Add(method, new BenchmarkTreeModel());
TreeMappings[method].Forest.Add(tree);
Model.Forest.Add(tree);
return true;
//var treeModel = new TreeModel();
}
catch (Exception ex)
{
//Debug.LogException(new Exception(method.GetMethodSignature(), ex));
return false;
}
}, sw);
//return methods;
}
The GetMethodSignature is something like:
public static string GetMethodSignature(this MethodBase method)
{
if (method == null) return null;
return method.DeclaringType == null ? method.Name : $"{method.DeclaringType.FullName}.{method.Name}";
}
I think I'll replace it with the MethodBase.ToString instead (what do you think?)
Also, we have the BenchmarkCall class which allow us to take in care how many times the call was done and how many time it has spent at all:
[Serializable]
public class BenchmarkCall
{
public string Method { get; set; }
public double SpentMilliseconds { get; set; }
public long SpentTicks { get; set; }
public double MinSpentMs { get; set; } = double.MaxValue;
public double MaxSpentMs { get; set; } = double.MinValue;
public long MinSpentTicks { get; set; } = long.MaxValue;
public long MaxSpentTicks { get; set; } = long.MinValue;
public double AvgMs => SpentMilliseconds / TimesCalled;
public double AvgTicks => SpentTicks / (double)TimesCalled;
public BenchmarkCall()
{
}
public BenchmarkCall(MethodBase method)
{
Method = method.GetMethodSignature();
}
public override string ToString()
{
if (TimesCalled > 0)
return "BenchmarkCall{\n" +
$"Ticks[SpentTicks={SpentTicks},MinTicks={MinSpentTicks},MaxTicks={MaxSpentTicks},AvgTicks={AvgTicks:F2}]\n" +
$"Ms[SpentMs={SpentMilliseconds:F2},MinMs={MinSpentMs:F2},MaxMs={MaxSpentMs:F2},AvgMs={AvgMs:F2}]\n" +
"}";
return "BenchmarkCall{}";
}
}
}
So I think that my next movement will be to differentiate between X method being called from A or B (Xa or Xb) taking care of the full hierarchy (which I'm not sure how to do) instead of the parent method that calls it, maybe the code I wrote has some to do it with it, but I'm not sure (last night I was so tired, so I didn't code it taking care those facts), build up a list of method signatures with different IDs, and then fill up the tree, ID 1 is Xa and ID 2 is Xb (where I have problems also filling up the tree).
Also I'll need to use the Transpiler in order to alter all code instructions, so if a method has:
void method() {
X1();
X2();
}
We will need to add 2 methods (like prefix/postfix) to measure each instruction call:
void method() {
Start(1);
X1();
End(1);
Start(2);
X2();
End(2);
}
This will be a hard task, but I hope somebody could guide me with this out.

Best way to get the lowest item in a list

Situation: I got 3 classes that work with each other.
1: Main (the GUI)
2: Compare (to compare the values)
3: CompareData (inherits the list values)
I want to take two values: a string and a double, and put them in a list. Of course there will be more than just one list item at the end. After the list got filled, I'd like to get the lowest double with it's string and put them in a label.
Here is what I've got so far:
Main:
public class GlobaleDaten //The second List: VglDaten is the one for my situation
{
public static List<Daten> AlleDaten = new List<Daten>();
public static List<Vgl> VglDaten = new List<Vgl>();
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[...Some Code thats not relevant...]
//addListAb adds values in a ListBox and should also
//place them into the list VglDaten
public void addListAb()
{
listBox.Items.Add(Abzahlungsdarlehenrechner.zgName + " " + "[Abzahlungsdarlehen]" + " " +Abzahlungsdarlehenrechner.zmErg.ToString("0.00") + "€" + " " + Abzahlungsdarlehenrechner.zgErg.ToString("0.00") + "€");
Vgl comp = new Vgl();
comp.name = Abzahlungsdarlehenrechner.zgName;
comp.gErg = Abzahlungsdarlehenrechner.zgErg;
GlobaleDaten.VglDaten.Add(comp);
}
//bVergleich should compare these values from the list
//and show the lowest value in a label
public void bVergleich_Click( object sender, RoutedEventArgs e)
{
if (listBox.Items.Count <= 0)
{
MessageBox.Show("Bitte erst Einträge hinzufügen.");
}
else
{
VglRechner vglr = new VglRechner();
vglr.Compare();
lVergleich.Content = VglRechner.aErg + " " + "€";
}
}
CompareData:
//Only used for storing the values
public class Vgl : Window
{
public string name { get; set; }
public double gErg { get; set; }
}
Compare:
public class VglRechner
{
public static string aName;
public static double aErg;
public void Compare(Vgl comp)
{
//I'm not sure if this is the right way to compare the values
//correct me if I'm wrong please :)
double low = GlobaleDaten.VglDaten.Min(c => comp.gErg);
aErg = low;
aName = comp.name;
}
}
Using Enumerable.Min is the right way to get the lowest value but you won't get the string which belonged to that value in this way, so the Vgl instance.
You could use this approach:
Vgl lowestItem = GlobaleDaten.VglDaten.OrderBy(c => c.gErg).First();
aErg = lowestItem.gErg;
aName = lowestItem.name;

How to add a value to a key(object) in a dictionary if object has same name (C#)

So, I have a dictionary called Potions. I need to check if a key in potions has the same name as an object passed as an argument. Now I'm able to do that but I can't figure out how to add a value to that particular key if the item object and the key have the same name. This code works fine for the first instance of an object. But when I add another instance object with the same name as a key, I get a key not found exception. I understand that the 2 objects wont be the same.How can I extract the object reference inside the dictionary? Or is there another way?
public static void addItem(Potion item)
{
if (Potions.Count >0)
{
foreach(KeyValuePair<Potion,int> pair in Potions)
{
if (pair.Key.itemName == item.itemName)
{
containsItem = true;
}
}
if (containsItem)
{
Potions[item] += 1;
Debug.Log (Potions[item]);
containsItem = false;
}
else
{
Potions.Add(item,1);
}
}
else
{
Potions.Add (item,1);
}
foreach(KeyValuePair<Potion,int> pair in Potions)
{
Debug.Log (pair.Key.itemName + " : " + pair.Value);
}
}
I would actually offer an alternative implementation.
enum Potion
{
Health,
Mana
}
class PotionBag
{
readonly int[] _potions = new int[Enum.GetValues(typeof(Potion)).Length];
public void Add(Potion potion)
{
_potions[(int)potion]++;
}
public void Use(Potion potion)
{
if (GetCount(potion) == 0)
throw new InvalidOperationException();
_potions[(int)potion]--;
}
public int GetCount(Potion potion)
{
return _potions[(int)potion];
}
}
You can override Equals and GetHashCode, but that might have other implications. Instead, you can use an IEqualityComparer when you create the dictionary, like so:
class Potion {
public string Name;
public int Color;
}
class PotionNameEqualityComparer : IEqualityComparer<Potion> {
public bool Equals(Potion p1, Potion p2) {
return p1.Name.Equals(p2.Name);
}
public int GetHashCode(Potion p1) {
return p1.Name.GetHashCode();
}
}
void Main() {
var d = new Dictionary<Potion, int>(new PotionNameEqualityComparer());
var p1 = new Potion() { Name = "Health", Color = 1 };
var p2 = new Potion() { Name = "Health", Color = 2 };
d.Add(p1, 1);
d[p2]++; // works, and now you have two health potions.
// Of course, the actual instance in the dictionary is p1;
// p2 is not stored in the dictionary.
}
You're using Potion as the key, but according to your code, what matters to you is itemName. So, I'd recommend you to change your dictionary to <string, int>. Also, as commented, when using a custom class it's recommend to override Equals and GetHashCode.
Your code could be something like this:
public static void addItem(Potion item)
{
if(Potions.ContainsKey(item.itemName))
Potions[item.itemName] += 1;
else
Potions.Add (item.itemName,1);
foreach(KeyValuePair<string,int> pair in Potions)
{
Console.WriteLine(pair.Key + " : " + pair.Value);
}
}
That wont work since you're using the item that you're adding as a key, and it's not the same object.
Why not save the key in a placeholder and then look for it, after the loop?
Potion key = null;
foreach(KeyValuePair<Potion,int> pair in Potions)
{
if (pair.Key.itemName == item.itemName)
{
key = pair.Key
}
}
if(key != null):
Potions[key] += 1

Categories