I got some ExcelValues, the fields are named from 700-751 and 800-851. Now, I want to get the results and store them.
for (int countDur = 0; countDur<= 51; countDur++)
{
string excelFieldMember = $"N7{countDur}";
string excelFieldNonMember = $"N8{countDur}";
}
An exception occurs, when the index countDur is less than 10 because the result for countDur = 0 is not 700, it is 70 then, and so on.
So I used
if(countDur < 10)
But I think there is a smarter way to reach this. I know there is a string.Format() method and because the fields are int values, I have a IoString() method where I can paste a parameter for this.
My question is, what do I have to paste in as a parameter? I can't find it in the C# documentation.
If the value is lower than 10, I want to have a 0 written before the index countDur gets pasted.
You want this:
for (int countDur = 0; countDur<= 51; countDur++)
{
string excelFieldMember = $"N7{countDur:D2}";
string excelFieldNonMember = $"N8{countDur:D2}";
}
This fills the number with trailing zeros, so that you get 700 instead of 70.
MSDN: The Decimal ("D") Format Specifier
Though you are looking for a way to use the ToString why not just start the for loop from the index you need, instead of from 0:
for (int countDur = 700; countDur <= 751; countDur++)
{
string excelFieldMember = $"N{countDur}";
string excelFieldNonMember = $"N{countDur+100}";
}
In any case, the use of "magic numbers" is prone to bugs if the fields change. See how you can get the value rather than have it stored hard-coded for the loop. (Same goes for the +100 for the non-member fields)
Try this, I think it's what you need
string excelFieldMember = $"N7{countDur.ToString("D2")}";
string excelFieldNonMember = $"N8{countDur.ToString("D2")}";
Related
Here is my code. I get a red line under StockPrices saying that it can not implicitly convert type decimal to int. Which I understand since StockPrices Array is set as a decimal. I can't figure out how to convert it. (If you find any other issues, please call it out. I'm still learning!)
public int FindNumTimesNegativePriceChange()
{
int difference = 0;
decimal[] negativeChange = new decimal[StockPrices];
for (int i = 0; i < StockPrices.Length - 1; ++i)
{
difference = (int)(StockPrices[i + 1] - StockPrices[i]);
if (difference < 0)
{
negativeChange++;
}
}
return negativeChange;
Currently no result is returned.
If you want a new array with the same length as an existing array, use the Length property for the source array, not the array itself:
new decimal[StockPrices.Length];
But I'm not sure that is what you are looking for at all.
You want a counter, so difference only needs to be an int in this case.
The next issue is that you are explicitly casting decimal values to an int which means you will lose precision. Other data types would throw an exception in this case but decimal allows it and will truncate the values, not round them.
For stock prices, commonly the changes are less than 1, so in this business domain precision is usually important.
If it is your intention to only count whole integer losses then you should include a comment in the code, mainly because explicit casting like this is a common code mistake, comments are a great way to prevent future code reviewers from editing your logic to correct what looks like a mistake.
Depending on your source code management practises, it can be a good idea to include a reference to the documentation / task / change request that is the authority for this logic.
public int FindNumTimesNegativePriceChange()
{
int difference = 0;
int negativeChange = 0;
for (int i = 0; i < StockPrices.Length - 1; ++i)
{
// #11032: Only counting whole dollar changes
difference = (int)(StockPrices[i + 1] - StockPrices[i]);
if (difference < 0)
{
negativeChange++;
}
}
return negativeChange;
}
A final peer review item, this method processes a single input, but currently that input needs to be managed outside of the scope of this method. In this case StockPrices must be declared at the member level, but this logic is easier to isolate and test if you refactor it to pass through the source array:
public int FindNumTimesNegativePriceChange(decimal[] stockPrices)
{
decimal difference = 0;
int negativeChange = 0;
for (int i = 0; i < stockPrices.Length - 1; ++i)
{
difference = stockPrices[i + 1] - stockPrices[i];
if (difference < 0)
{
negativeChange++;
}
}
return negativeChange;
}
This version also computes the difference (delta) as a decimal
Fiddle: https://dotnetfiddle.net/XAyFnm
I have a number like 601511616
If all number's length is multiple of 3, how can a split the number into an array without making a string
Also, how can I count numbers in the int without making a string?
Edit: Is there a way to simply split the number, knowing it's always in a multiple of 3... good output should look like this: {616,511,601}
You can use i % 10 in order to get the last digit of integer.
Then, you can use division by 10 for removing the last digit.
1234567 % 10 = 7
1234567 / 10 = 123456
Here is the code sample:
int value = 601511616;
List<int> digits = new List<int>();
while (value > 0)
{
digits.Add(value % 10);
value /= 10;
}
// digits is [6,1,6,1,1,5,1,0,6] now
digits.Reverse(); // Values has been inserted from least significant to the most
// digits is [6,0,1,5,1,1,6,1,6] now
Console.WriteLine("Count of digits: {0}", digits.Count); // Outputs "9"
for (int i = 0; i < digits.Count; i++) // Outputs "601,511,616"
{
Console.Write("{0}", digits[i]);
if (i > 0 && i % 3 == 0) Console.Write(","); // Insert comma after every 3 digits
}
IDEOne working demonstration of List and division approach.
Actually, if you don't need to split it up but only need to output in 3-digit groups, then there is a very convenient and proper way to do this with formatting.
It will work as well :)
int value = 601511616;
Console.WriteLine("{0:N0}", value); // 601,511,616
Console.WriteLine("{0:N2}", value); // 601,511,616.00
IDEOne working demonstration of formatting approach.
I can't understand your question regarding how to split a number into an array without making a string - sorry. But I can understand the question about getting the count of numbers in an int.
Here's your answer to that question.
Math.Floor(Math.Log10(601511616) + 1) = 9
Edit:
Here's the answer to your first question..
var n = 601511616;
var nArray = new int[3];
for (int i = 0, numMod = n; i < 3; numMod /= 1000, i++)
nArray[i] = numMod%1000;
Please keep in mind there's no safety in this operation.
Edit#3
Still not perfect, but a better example.
var n = 601511616;
var nLength = (int)Math.Floor(Math.Log10(n) + 1)/ 3;
var nArray = new int[nLength];
for (int i = 0, numMod = n; i < nLength; numMod /= 1000, i++)
nArray[i] = numMod%1000;
Edit#3:
IDEOne example http://ideone.com/SSz3Ni
the output is exactly as the edit approved by the poster suggested.
{ 616, 511, 601 }
Using Log10 to calculate the number of digits is easy, but it involves floating-point operations which is very slow and sometimes incorrect due to rounding errors. You can use this way without calculating the value size first. It doesn't care if the number of digits is a multiple of 3 or not.
int value = 601511616;
List<int> list = new List<int>();
while (value > 0) // main part to split the number
{
int t = value % 1000;
value /= 1000;
list.Add(t);
}
// Convert back to an array only if it's necessary, otherwise use List<T> directly
int[] splitted = list.ToArray();
This will store the splitted numbers in reverse order, i.e. 601511616 will become {616, 511, 601}. If you want the numbers in original order, simply iterate the array backwards. Alternatively use Array.Reverse or a Stack
Since you already know they are in multiples of 3, you can just use the extracting each digit method but use 1000 instead of 10. Here is the example
a = 601511616
b = []
while(a):
b.append(a%1000)
a = a//1000
print(b)
#[616, 511, 601]
I'm trying to create a small application that reads in an excel file of postcodes and then automatically checks certain websites for 3G signal coverage. however, this block of code is producing the error mentioned in the topic title.
//Find the input field on the three postcode checker
int x;
for (x = 0; x < 100; x++)
{
IWebElement input = driver.FindElement(By.Name("postcode"));
string postcodeInput = (dataGridView1.SelectedCells[x].Value.ToString());
string returnKey = OpenQA.Selenium.Keys.Return;
input.SendKeys(postcodeInput);
input.SendKeys(returnKey);
IWebElement output = driver.FindElement(By.TagName("h5"));
string postcodeOutput = output.Text;
dataGridView1.Rows[x].Cells[1].Value = postcodeOutput;
input.Clear();
}
driver.Quit();
The line VS highlights is:
string postcodeInput = (dataGridView1.SelectedCells[x].Value.ToString());
Any one have any ideas as to where I'm going wrong?
Thanks
Don't hardcode 100 in the limit value check of your for loop. Use the actual count from your grid like this:
for (x = 0; x < dataGridView1.SelectedCells.Count; x++)
It may be that your grid's selected cell collection doesn't have what you expect. But hardcoding a value like this is never a good idea, and is why you are getting an "index was out of range" error.
Im trying to do a permutation. of five in this case, so 5,4,3,2,1 . Eventually I want it to permute up to 100 which can be stored in my intX class. the calculation is fine, but I want to add up all individual numbers of the output, using the script below.
so 5! = 5x4x3x2x1 = 120 ----> 1+2+0 = 3. BUT My script below gives the output 147:
120
1
2
0
147
What am I doing wrong? I allready tried all converts, I started with just using the string[pointer] thingy, I tried different arrays etc.. but it all keeps coming up with 147. Is it some kind of representation thing?
static void Main(string[] args)
{
IntX total=1;
IntX totalsum = 0;
int perm = 5;
for (int i = perm; i > 0; i--)
{
total = total * i;
}
Console.WriteLine(total);
string answerstring = Convert.ToString(total);
char[] answerArray = answerstring.ToArray();
for (int x = 0; x < answerArray.Length; x++)
{
totalsum += Convert.ToInt32(answerArray[x]);
Console.WriteLine(answerArray[x]);
}
Console.WriteLine(totalsum);
}
The problem is the way you are converting your answerArray elements back to numbers
Convert.ToInt32(answerArray[x])
The above line takes the char 1 and converts it to an int. This is not the same as parsing it as an int. 1 is ascii character 49 so internally the char has an int representation of 49 and so that is what it is converted to (since this is just trying to do a type conversion rather than any kind of processing)
Similarly 2 = 50 and 0 = 48 so you get the total of 147.
What you want to do is use Integer.Parse to parse strings as numbers. I believe it should implicitly convert the char to a string before parsing it.
So your loop would be:
for (int x = 0; x < answerArray.Length; x++)
{
totalsum += int.Parse(answerArray[x].ToString());
Console.WriteLine(answerArray[x]);
}
You can also do it the way others suggested with subtracting chars. This works because the ascii value of 1 is 1 higher than the ascii value for 0. 2 is 2 higher, etc.
Of course this only works with single digit chars. If you ever want to convert more than two digit numbers into int from a string you'll need int.parse.
For what its worth I suspect that the character subtraction method is the most efficient since it is effectively just doing some very simple type conversion and subtraction. The parse method is likely to do a lot more stuff and so be a bit more heavyweight. I dont' you will notice a performance difference though.
The problem lies in here:
for (int x = 0; x < answerArray.Length; x++)
{
//Casting char to int, not what you want!
//totalsum += Convert.ToInt32(answerArray[x]);
//Parsing char to int, what you do want!
totalsum += int.Parse(answerArray[x]);
Console.WriteLine(answerArray[x]);
}
Instead of converting to an integer (which will take the ASCII character value), try using answerArray[x] - '0'.
(int)'0' is not equal to 0. You should use ((int)answerArray[x] - (int)'0')
Why bother changing it to a char array? You already have the information that you need.
while (total > 0)
{
ones_digit = total % 10;
totalsum += ones_digit;
total -= ones_digit;
total /= 10;
}
Convert.ToInt32 returns the Unicode values of characters 1, 2 and 0 which are 49, 50 and 48. That's why the sum comes out as 147.
And is there an elegant linqy way to do it?
What I want to do is create string of given length with made of up multiples of another string up to that length
So for length - 9 and input string "xxx" I get "xxxxxxxxx" (ie length 9)
for a non integral multiple then I'd like to truncate the line.
I can do this using loops and a StringBuilder easily but I'm looking to see if the language can express this idea easily.
(FYI I'm making easter maths homework for my son)
No, nothing simple and elegant - you have to basically code this yourself.
You can construct a string with a number of repeated characters, but ot repeated strings,
i.e.
string s = new string("#", 6); // s = "######"
To do this with strings, you would need a loop to concatenate them, and the easest would then be to use substring to truncate to the desired final length - along the lines of:
string FillString(string text, int count)
{
StringBuilder s = new StringBuilder();
for(int i = 0; i <= count / text.Length; i++)
s.Add(text);
return(s.ToString().Substring(count));
}
A possible solution using Enumerable.Repeat.
const int TargetLength = 10;
string pattern = "xxx";
int repeatCount = TargetLength / pattern.Length + 1;
string result = String.Concat(Enumerable.Repeat(pattern, repeatCount).ToArray());
result = result.Substring(0, TargetLength);
Console.WriteLine(result);
Console.WriteLine(result.Length);
My Linqy (;)) solution would be to create an extension method. Linq is language integrated query, so why the abuse? Im pretty sure it's possible with the select statement of linq since you can create new (anonymous) objects, but why...?