Why does this simple code not work (ArgumentOutOfRangeException) - c#

int i = 0;
int x = 10;
List<int> group = new List<int>();
while (i < x)
{
RichTextBoxShowTafel.AppendText(Convert.ToString(group[i]));
i++;
}
Why does this not work? I want to display the first 10 numbers of the List called: "group".
edit:
I actually want to create variables and print it in a row...

You never put anything in the group variable. You only instantiated an empty list.
And you'd be better off doing this:
foreach (int item in group)
{
RichTextBoxShowTafel.AppendText(item.ToString());
}

Because group is empty? As it has no elements, you can't access group[0], which is what you do in the first iteration

This is because group is empty!
When your loop first executes then i = 0 then you try Convert.ToString(groups[i]) which will always fail as there is no index of 0 in group

You should add elements in the list before you try to get them. The is the reason you got ArgumentOutOfRangeException. You can avoid the exception by adding element first.
int i = 0;
int x = 10;
List<int> group = new List<int>();
while (i < x)
{
group.Add(i);
RichTextBoxShowTafel.AppendText(Convert.ToString(group[i]));
i++;
}

If you are expecting group to be populated with numbers, you will have to do that yourself. Declaring and initializing it List<int> group = new List<int>(); only creates it. There is nothing inside. If you want to try putting variables in you can do something like this:
for(int j = 0; j < 10; j++)
{
group.Add(j);
}

Related

Adding the calculated sum of a list to another list

I have a list of int .. How can i sum all the numbers in the list and get the result ?
List<int> FineListy = new List<int>();
Your code has a number of issues.
List<int> FineListy = new List<int>();
for (int i = 0; i < fineList.Count(); i++)
{
if (fineList[i] > 0)
{
FineListy.Add((fineList[i] += fineList[i]));
}
}
Firstly: C# naming conventions are such that local variables should start with lowercase letters and be camelCased. I recommend naming your variables totalsList and fineList respectively. For the sake of simplicity, I will use your current naming conventions below.
Next, you're doing FineListy.Add(fineList[i] += fineList[i]); which is the same as:
fineList[i] = fineList[i] * 2;
FineListy.Add(fineList[i]);
And you're doing it in a loop, so you will simply get a list of all items multiplied by 2.
Now you could fix this like so:
int total = 0;
for (int i = 0; i < fineList.Count; ++i)
{
if (fineList[i] > 0)
{
total += fineList[i];
}
}
FineListy.Add(total);
But you can use LINQ to do the same in a single line (I've split it across multiple lines to make it easier to read):
var total = fineList
.Where(v => v > 0)
.Sum();
FineListy.Add(total);
Or simply:
FineListy.Add(fineList.Where(v => v > 0).Sum());
If you have a list of int, why not use sum function??
int sum = FineListy.Sum();
This will add up all the numbers and give you the expected result.Now i see you do an If check to see if the number is not 0.So,create a new list then and pass the numbers to the list only if it's greater than 0
List<int> NewList = new List<int>;
foreach (var number in IntegerList)
{
if (number > 0)
{
NewList.Add(number);
}
}
Finally get the sum total :
int sum = NewList.Sum();
Or one-line LINQ solution :
var result = fineList.Where(a => a > 0).Sum();
NewList.Add(result );
Yes, it doubles, because that's what you do here :
FineListy.Add((fineList[i] += fineList[i]));
You say : "Add me fineList[i] + fineList[i] to my resulting collection FineListy"
So you got all elements doubled.
If you want to add values you don't need list just a variable to store it and LINQ .Sum() method
P.S.
I mean either one of these two (as others suggested):
FineListy.Add(fineList.Sum());
Or
int sum = fineList.Sum();

for loop "index was out of range" c# webdriver

I am getting "index out of range" from this loop. But I need to use new elements that loop founds, how do I do that? Please help to fix the problem
int linkCount = driver.FindElements(By.CssSelector("a[href]")).Count;
string[] links = new string[linkCount];
for (int i = 0; i < linkCount; i++)
{
List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
links[i] = linksToClick[i].GetAttribute("href");
}
I think that you could refactor your code:
var linkElements = driver.FindElements(By.CssSelector("a[href]")).ToList();
var links = new List<string>();
foreach (var elem in linkElements)
{
links.Add(elem.GetAttribute("href"));
}
If that works, you could simplify the query:
var instantLinks = driver.FindElements(By.CssSelector("a[href]"))
.Select(e => e.GetAttribute("href"))
.ToList();
You can rewrite your code to bypass the for loop:
string[] links = driver.FindElements(By.CssSelector("a[href]")).Select(l => l.GetAttribute("href")).ToArray();
This should also avoid the index out of range problem, and cut down the amount of code you have to write.
First of all i dont see a point in assigning linkstoclick values inside loop... And Reason for error must be that linksToClick list's length is more than that of linkCount.
int linkCount = driver.FindElements(By.CssSelector("a[href]")).Count;
List<string> links = new List<string>();
for (int i = 0; i < linkCount; i++)
{
List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
if (linksToClick.Count < i)
links.Add(linksToClick[i].GetAttribute("href"));
}
This might help with the out of range exception.
Doing this allows you to create a list of type: string without having to explicitly define the size of the list
the first one gets all of your elements by tag name ...let's assume 5.
in the loop, your driver get's all the elements by css selector, and you might have a different number here. let's say 4.
then, you might be trying to set the fifth element in a four element array.
boom.
Easiest fix to debug:
int linkCount = driver.FindElements(By.TagName("a")).Count;
string[] links = new string[linkCount];
// WRITE OUT HOM MANY links you have
for (int i = 0; i < linkCount; i++)
{
List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
// ASSERT THAT YOU HAVE THE SAME AMOUNT HERE
If (links.Count != linksToClick.Count)
// your logic here
links[i] = linksToClick[i].GetAttribute("href");
}

How to increment the index of a list for saving the next number in next index of list

I want to save the result of zarb function which repeats for 1000 times in a list with size 1000. Then I must to increase the index of the list for every calculation to avoid to save the next calculation at the same index of previous one. How can I do that?
var results = new List<float>(1000);
for (int z = 0; z < 1000; z++)
{
results.Add(zarb(sc,z));
//increase the index of resukts
}
foreach (var resultwithindex in results.Select((r, index) => new { result = r, Index = index }).OrderByDescending(r => r.result).Take(20))
{
MessageBox.Show(string.Format("{0}: {1}", resultwithindex.Index, resultwithindex.result));
}
Zarb function
public float zarb(int userid, int itemid)
{
float[] u_f = a[userid];
float[] i_f = b[itemid];
for (int i = 0; i < u_f.Length; i++)
{
result += u_f[i] * i_f[i];
}
return result;
}
No you don't. The Add method (surprisingly) adds an item into the list. It doesn't replace anything. You should read MSDN documentation for List<T>. Also, don't be afraid of trying and seeing the results before asking—you'll save time.
Maybe I don't understand the question, but you do not need index for list. The add method will deal with the it.

Adding unique items to List or other object

I'm trying to find an efficient way to add unique numerical values to a list. Currently, I am using a Dictionary<int,int> object. The first value is a generated number; doesn't matter what it is as long as it's generation can be repeated under identical circumstances. The second item is the original. So, I would have this:
Dictionary<int,int> orderedList = new Dictionary<int,int>(MaxNoOfTimes);
for (i = 0; i<MaxNoOfTimes, i++)
{
int j = getNewValue();
retry:
try
{
orderedList.Add(j,i);
}
catch (ArgumentException ex)
{
goto retry;
}
And while this works, it seems inelegent and I think it is very slow due to the exception handling. The value for MaxNoOftimes can get to several 1000 (in reality there's no actual limit but more then several 1000 would be rare). Is there a faster way? After I am finished with adding the values to the orderedList I create a SortList from the orderedList.
How about that:
for (i = 0; i<MaxNoOfTimes, i++)
{
int j = getNewValue();
while(orderedList.ContainsKey(j))
{
j = getNewValue();
}
orderedList.Add(j, i);
}
How about:
Hashset<int> orderedSet = new Hashset<int>();
while(orderedSet.Count < maxNoTimes)
{
int j = getNewValue();
orderedSet.Add(j);
}
Since, you said you need the ordinal of each value to, then this is probably what you want when ordering:
var orderedDictionary = orderedSet.ToDictionary(i => orderedSet.ToList().IndexOf(i), i => i).OrderBy(i => i.Value);

passing arrays in c#

Hi i am working on Grade Calculation. My problem here is if the length of string array is longer that int array it works skipping the last 2 grades.
ex:
int[] unit = new int[] {1,-3,3,4};
string[] letter_grade = new string[] {"A", "B","B","W","D","F"};
but if length of int array longer than that of string array its not working its throwing error Index was outside the bounds of the array.
int[] unit = new int[] {1,-3,3,4,5,6,7};
string[] letter_grade = new string[] {"A", "B","B"};
so my question how do i make it work for both??
int length = unit.Length;
int no_units = length;
double totalGrade_Points = 0.0;
int totalno_units = 0;
totalGPA = 0;
for (int i = 0; i < unit.Length; i++)
{
entrygot = findGpaListentry(letter_grade[i]); //Index was outside the bounds of the array.
if (entrygot != null)
{
//some code calculation
}
}
For array indexing you must have starting and stopping condition defined very well. For accessing two arrays either they must be equal or they are compared under certain valid conditions. Have a look at this:
for(int i=0;i<unit.length;i++){
entrygot = findGpaListentry(letter_grade[i]);// only if letter_grade is valid under all values of i i.e unit.length
}
// either you have to check as if;
if(lenght_of_letter_grade < i-1)
//then access
entrygot = findGpaListentry(letter_grade[i]);
You can't just check if the array item is null, because you would be out of the bounds of the array and you will get an exception before the null check occurs.
I would check the length of the array on each iteration...
for (int i = 0; i < unit.Length; i++)
{
if (currentArray.Length < i - 1) { break; }
// other code...
}
I think in your case, the number of elements will never be large hence performance wont be an issue. So I think you should be using a List instead of an array. With an array you will have to be insert checks each time some logic changes or you add other functionalities.
foreach loop is best for your scenerio.
foreach (string s in letter_grade)
{
entrygot = findGpaListentry(s);
if (entrygot != null)
{
//some code calculation
}
}

Categories

Resources