C# IF statement about a int check vs string in a DataTable - c#

I have a DataTable where I have a column "Number" number is a string.
I would like to do
if (row["Number"].ToString() >= 1 && row["Number"].ToString() <= 100)
So if the column number is higher than 1 or lower than 100 do this.
Is there anyway to do this?

You can parse the string into an int by using int.TryParse:
int rowNumber;
if (!int.TryParse((string)row["Number"], out rowNumber)
{
// Not an int
}
if (rowNumber >= 1 && rowNumber <= 100)
{
// Do stuff
}

Related

Building an exponent calculator

I'm relatively new to programming in C#. I'm building an exponent calculator, and I got it working, but while debugging I came across an issue that I do not understand why I get the output that I get.
This is the class and method in question when I get the output I know is wrong. (note i did later fix it by making it total *= lower in the for loop)
using System;
namespace stars
{
public class Exponent
{
public int Exp(int lower, int power)
{
int total = lower;
if ( power == 0 )
{
//returns 1 for any exponent of 0
Console.WriteLine(" 1");
return 1;
}
else if ( lower == 0 )
{
//returns 0 for any base of 0
Console.WriteLine("0");
return 0;
}
else if ( ( power % 1 ) == 0 ) // check for integer exponent
{
for ( int i = 1; !( i > power ); i++ ) //math
{
lower *= lower;
}
Console.WriteLine(lower);
return total;
}
else
{
Console.WriteLine("error");
}
}
}
}
at the last elseif, where I have my forloop, to (incorrectly) calculate the value of some integer to the power of another integer, I (incorrectly) perform the calculation lower = lower * lower, where lower is the base number.
i.e. 5^4,, 5 = lower, 4 = power
anyways, when I run it at 5^4, the result is 0. Why does it come out to 0? I figured it would work like this
5 * 5 = 25 ---> 25 * 25 = 625 ----> 625 * 625... etc
or is the end value so large that the compiler spits out 0.
First of all you should modify total in your routine and don't modify lower changing given parameter is often leads to errors.
Something like this:
public class Exponent
{
// static: we don't want this
public static int Exp(int lower, int power)
{
// Special cases
if (power == 0 || lower == 1)
return 1;
else if (lower == 0)
return 0;
else if (power < 0) //DONE: you've forgot about this case
throw new ArgumentOutOfRangeException(nameof(power));
// we don't want "power % 1 == 0" case - int power is always integer
// General case: math
int total = lower;
// "!( i > power )" - let's put at simpler (and correct) - "i < power"
for (int i = 1; i < power; ++i)
total *= lower;
return total;
}
}
...
// 5**4 == 625
Console.Write(Exponent.Exp(5, 4));
There are lot of issues in the code, I have fixed them. Though you have to consider other scenarios also. like if lowerand power are negative numbers, if numbers are big, it will not give you the required result.
public static int Exp(int lower, int power)
{
int total = lower;
if (power == 0) {
//returns 1 for any exponent of 0
Console.WriteLine(" 1");
return 1;
}
else if (lower == 0)
{
//returns 0 for any base of 0
Console.WriteLine("0");
return 0;
}
for (int i = 1; i < power; i++) //math
{
total *= lower;
}
Console.WriteLine(total);
return total;
}
There's quite a bit wrong styling wise with the code, and there's obviously an error somewhere or else you'd get the correct output. Let's break it down.
First I'll rewrite your code to be cleaner and easier to read:
public int Exp(int lower, int power)
{
int total = lower;
// 0 to the power of y is always 0
if ( lower == 0 )
return 0;
// x to the power of 0 is always 1
if ( power == 0 )
return 1;
// Your parameters for the Method explicitly state that
// 'power' is always an int, so no need to check
for ( int i = 1; i < power; i++ )
lower *= lower;
return total;
}
The cleanups I did:
Removed unnecessary 'else if's from code, as you are returning from within your 'if' anyways
Removed unnecessary braces reducing clutter
Moved comments to before check, as it is customary to comment code above it not below it
Now the problem is a lot more obvious: You're doing lower *= lower instead of total *= lower. So correct code would be this:
public int Exp(int lower, int power)
{
int total = lower;
// 0 to the power of y is always 0
if ( lower == 0 )
return 0;
// x to the power of 0 is always 1
if ( power == 0 )
return 1;
// Your parameters for the Method explicitly state that
// 'power' is always an int, so no need to check
for ( int i = 1; i < power; i++ )
total *= lower;
return total;
}

How would one do > x < in C#

I'm attempting to make a random number generator that then selects one of three options based on the random number. I would like to use > x < as the second choice of three but it gives me an error:
Operator '>' cannot be applied to operands of type 'bool' and 'int'
Here's the code:
int rand;
Random myRandom = new Random();
rand = myRandom.Next(0, 90);
if (rand < 33)
{
}
if (33 > rand < 66)
{
}
if (rand > 66)
{
}
Well the simplest option is to use else if so you only need to check one condition anyway - which means it would handle 33 as well (currently not handled):
if (rand < 33)
{
Console.WriteLine("rand was in the range [0, 32]");
}
else if (rand < 66)
{
Console.WriteLine("rand was in the range [33, 65]");
}
else
{
Console.WriteLine("rand was in the range [66, 89]");
}
If you do need to test two conditions, however, you just want && to check that they're both true:
// I've deliberately made this >= rather than 33. If you really don't want to do
// anything for 33, it would be worth making that clear.
if (rand >= 33 && rand < 66)
If you find yourself doing this a lot, you might want to have an extension method so you can say:
if (rand.IsInRange(33, 66))
where IsInRange would just be:
public static bool IsInRange(this int value, int minInclusive, int maxExclusive)
{
return value >= minInclusive && value < maxExclusive;
}
You should use the and && operator as in
if (rand > 33 && rand < 66)
{
}
This makes sure the rand is less than AND greater then the values specified
To check the both bounds of the value you need two comparisons.
You probably want to use the <= operator instead of < in that comparison, otherwise the code will do nothing for the values 33 and 66:
if (rand < 33)
{
}
if (33 <= rand && rand < 66)
{
}
if (rand >= 66)
{
}
You can also use else to get rid of some comparisons:
if (rand < 33)
{
}
else if (rand < 66)
{
}
else
{
}
Note: You have a random value between 0 and 89, so if you want each if statement to be used in one third of the cases, you would use values 30 and 60 instead of 33 and 66.

Split numeric part from alphanumeric string using C#

I have alphanumeric string list.
For example:
1A
2B
7K
10A
I want to get only the numeric part and then compare them, if it is less than 10 I need not to add it in another list.
What I want to know the regex to split the numeric part from the string.
Any help.
What I have done till now is:
if (x == y) // also handles null
return 0;
if (x == null)
return -1;
if (y == null)
return +1;
int ix = 0;
int iy = 0;
while (ix < x.Length && iy < y.Length)
{
if (Char.IsDigit(x[ix]) && Char.IsDigit(y[iy]))
{
// We found numbers, so grab both numbers
int ix1 = ix++;
int iy1 = iy++;
while (ix < x.Length && Char.IsDigit(x[ix]))
ix++;
while (iy < y.Length && Char.IsDigit(y[iy]))
iy++;
string numberFromX = x.Substring(ix1, ix - ix1);
string numberFromY = y.Substring(iy1, iy - iy1);
// Pad them with 0's to have the same length
int maxLength = Math.Max(
numberFromX.Length,
numberFromY.Length);
numberFromX = numberFromX.PadLeft(maxLength, '0');
numberFromY = numberFromY.PadLeft(maxLength, '0');
int comparison = _CultureInfo
.CompareInfo.Compare(numberFromX, numberFromY);
if (comparison != 0)
return comparison;
}
else
{
int comparison = _CultureInfo
.CompareInfo.Compare(x, ix, 1, y, iy, 1);
if (comparison != 0)
return comparison;
ix++;
iy++;
}
}
But I don't want to be so complex in my approach.
So I need a regex to split.
Try IsDigit method of char
var number = int.Parse(new string(someString.Where(char.IsDigit).ToArray()));
if(number<10)
{
someList.Add(number);
}
using All and IsDigit you can take only numeric part of the string, then parse it to int and compare :) There is no need to use Regexes
You can use the code below to split an input string and get the result of number group and alpha group. If one group is not there, the result will be empty string.
string input = "10AAA";
Match m = Regex.Match(input, #"(\d*)(\D*)");
string number = m.Groups[1].Value;
string alpha = m.Groups[2].Value;
you can try it with this one:
string txt="10A";
string re1="(\\d+)"; // Integer Number 1
Regex r = new Regex(re1);
Match m = r.Match(txt);
Are you trying to do this?
int num;
string stringWithNumbers = "10a";
if (int.TryParse(Regex.Replace(stringWithNumbers, #"[^\d]", ""), out num))
{
//The number is stored in the "num" variable, which would be 10 in this case.
if (num >= 10)
{
//Do something
}
}
else
{
//Nothing numeric i the string
}

Error There is no row at position 1

I am getting an exception
System.ArgumentOutOfRangeException: There is no row at position 1.
RBTree`1.GetNodeByIndex(Int32 userIndex)**
There is no row at position can be 0 or 1 or 2 . I guess i am trying to read or write some array elements which are outside of your array boundary. The code snippet is shown below
public void ManageAlarm(string textName, int leaveValue)
{
try
{
int indices = team.Find(textName);
if (indices >= 0)
{
DataRow row = teamTable.Rows[indices];
row[m_leaveValues] = leaveValue;
}
}
What should i do here to prevent this alert trace
You need to check the rows count in m_tblAlert before you access rows in it. m_tblAlert.Rows.Count must be greater then indx
public void ManageDuplicateAlarm(string alertName, int dupValue)
{
try
{
int indx = m_alerts.Find(alertName);
if (indx >= 0 && m_tblAlert.Rows.Count > indx)
{
DataRow row = m_tblAlert.Rows[idx];
m_dcDuplicates.ReadOnly = false;
row[m_dcDuplicates] = dupValue;
m_dcDuplicates.ReadOnly = true;
}
}
Edit more exlanation on OP comment
You are checking indx >= 0 to make sure that that -1 could not be row index for statement m_tblAlert.Rows[idx]; Similarly you need to check if the value return by m_alerts.Find(alertName) must be valid row number i.e it should not be greater then the number of rows you have in data table.

Get last 'N' quarters in C#

Suppose the current quater is 3 and the year is 2011. How can I get the last 5 quarters
Desired output:
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
The Q and '-' is appended.
I am trying as under
int generateQuater = 5;
int currentQuater = 3;//GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
lstQuaterYear.Add(string.Concat('Q',currentQuater, '-', currentYear));
for (int i = generateQuater; i > 0; i++)
{
//code to be placed
}
Thanks
You have to decrease your loop variable. The rest is not too difficult math.
Its also not necessary to handle the first iteration in any special way:
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear--;
}
}
As a pure LINQ expression:
public IEnumerable<String> GetQuarters(int start, int year, int count)
{
return (from q in Enumerable.Range(0, count)
select String.Format("Q{0}-{1}", (start - q) + (((q + 1) / 4) * 4) , year - ((q + 1) / 4)));
}
The math is somewhat ugly but does work, to use it you can just do:
foreach (String quarter in GetQuarters(3, 2011, 5))
{
Console.WriteLine(quarter);
}
Your for loop should go from 0 to your variable, when you're increasing i.
The inner code could be something like:
currentQuarter--;
if(currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
Don't forget to refactor it :)
int count = 5;
int currentQuarter = GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = count; i > 0; i--)
{
lstQuaterYear.Add(string.Concat('Q', currentQuarter, '-', currentYear));
currentQuarter--;
if (currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
}
One way is to check for year roll over and then set the quarter to 4 and decrement the year:
int quarter=3;
int year=2011;
int count=5;
for(int i=0;i<count;i++)
{
lstQuaterYear.Add(string.Format("Q{0} {1}", quarter, year);
quarter--;
if(quarter==0)
{
quarter=4;
year--;
}
}
Alternatively you could calculate a totalQuartal=year+quartal-1. Then decrement it on each step. And finally use year=totalQuartal/4 and quartal=totalQuartal%4+1. But I think the first way is easier to understand.
public static IEnumerable Generate(int number, int currentYear, int currentQuarter)
{
int counter = number;
int quarter = currentQuarter;
int year = currentYear;
while (counter-- > 0)
{
yield return String.Format("Q{0}-{1}", year, quarter);
quarter = quarter>1?quarter-1:4;
year = quarter==4?year-1:year;
}
}
Here is my version (sorry, it is in VB.NET).
The idea is to :
easily find out the quarter based on a date (easy : divide it by 4 ... and add 1 to avoid zeros)
go back in time from the current date, removing 3 month at each time
printout the formatted quarter
the code :
Private Shared Function GetQuarterForDate(ByVal d As DateTime) As Integer
Return (d.Month \ 4) + 1 'integer division
End Function
Private Shared Function GetLastNQuarters(ByVal N As Integer) As IEnumerable(Of String)
Dim myDate = DateTime.Now
Dim res As New List(Of String)()
Do While N > 0
'using yield would be nicer in C# ... does not exist in VB
res.Add(String.Format("Q{0}-{1}", GetQuarterForDate(myDate), myDate.Year))
myDate = myDate.AddMonths(-3)
N = N - 1
Loop
Return res
End Function
<TestMethod()>
Public Sub CanRetrieveQuarter()
Dim quarters = GetLastNQuarters(5)
For Each q In quarters
Console.WriteLine(q)
Next
End Sub
That last "test method" prints out :
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
In case you should do some operations on the quarter period, like check if moment is within a quarter, you can use the Quarter class of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public ITimePeriodCollection GetPastQuarters( int count )
{
TimePeriodCollection quarters = new TimePeriodCollection();
Quarter quarter = new Quarter();
for ( int i = 0; i < count; i++ )
{
quarters.Add( quarter );
quarter = quarter.GetPreviousQuarter();
}
return quarters;
} // GetPastQuarters

Categories