Advice on this method that works with chars - c#

Recently I've been told to change one validation towards a database to a new database in a C# application. Instead of the old database I would be using the new one.
The problem is that I can't run the app. I need to publish it so the guys that uses it give me their feedback.
So I decided to share this part of the code that I added.
Not changed, but added. This is something new and a potential thing that can go wrong.
Hopefully someone with more experience will tell me how much my code sucks or if it looks OK.
Thing is... the old database has an int value in a column and the new one has a nvarchar(5).
So I made this to convert the old one in a new one.
string ConvertIDToReg(string kairosID)
{
double n;
if (!Double.TryParse(Convert.ToString(kairosID),
System.Globalization.NumberStyles.Any,
System.Globalization.NumberFormatInfo.InvariantInfo, out n))
{
return "0";
}
char[] regID = kairosID.ToCharArray();
if (regID.Length > 4)
{
return "0";
}
if (reg.Length == 3)
{
regID[4] = regID[3];
regID[3] = regID[2];
regID[2] = regID[1];
regID[1] = regID[0];
regID[0] = "0";
}
return regID.ToString();
}
This is how it should work:
The old ID is something like "1234" but the new one is a 5 char max ID with a 0 in the beginning like "01234" (if the 5th number is not occupied). So basically I want to be able to put a 0 in the beginning if there isn't a 5th number.
If the number exceeds the 5 digits I want to return a 0 as the whole string (this will be handled later)
If the number is not a number (i.e "123ABC") return a 0 all the same.
Should this compile or even work?
What about efficiency? This will run several times. Any help to make this faster will do.

No, this won't compile. You misspelled your second regID (forgot the 'ID'), and are assigning a string to a char at regID[0] = "0";
Change that and it will compile, then blow up when you run it, when regID.Length= 3, because you're trying to access index 3 and 4, which it clearly will not have.
This should do what you're wanting:
string ConvertIDToReg(string kairosID)
{
if (kairosID.Length > 4 || kairosID.Any(c => !char.IsDigit(c)))
return "0";
return kairosID.PadLeft(5, '0');
}
if it's longer than 4 characters or if any character is not a digit, return a zero as a string ("0"). Else return the ID padded to 5 digits. About as simple as i can make it I think. No need to parse it as an int even.

This code should work:
private string ConvertIntToChar(string numValue)
{
int result = 0;
if (int.TryParse(numValue, out result) == false || numValue.Length > 4)
{
return "0";
}
return numValue.PadLeft(5, '0');
}
If value is not of 4 characters then it will add number of "0" required to make the string length equal to 5.

If the string is always some form of an integer i would approach the problem as such. and you wanted to keep every thing else the same. the "D5" tells the ToString method to 0 pad the string so that it is always 5 digits but retains the same numerical value.
string ConvertIDToReg(string kairosID)
{
int id;
if (!Int32.TryParse(kairosID, out id) || id > 9999)
{
return "0";
}
return id.ToString("D5");
}

Related

How to check if a number exists in a specified digit of an integer ( C# )

I want to generally verify if a number/character exists within a specified index of an int value.
Here is pseudocode of what I want
if (octet[1].Exists){
return true;
} else {
return false;
}
// receiving int octet = 103 will return true.
// receiving int octet = 7 will return false.
Is there a function that already does this, or do you have to make one on your own?
Convert to a string then check the length?
var str = octet.ToString();
return str.Length >= 1;
I don't know a function like this, but you can write your own.
In instance:
var func = (int octet, int index) => (octet / (int)(Math.Pow(10, index)) != 0);
I would suggest using a System.Linq binding for this. Here is an example:
octet.ToString().Contains(n);
Where n is the digit you're looking for in string or char form. Hope this helps!
Just parse the int to a string and check if the number you are looking is equal to expected position.
var number = 12345;
if(number.ToString().IndexOf('2') == 1)//check if the value 2 is on the second position of the array
{
Console.WriteLine("yes");
}

Maximum product of 13 adjacent numbers

List<int> arr = new List<int>();
long max = 0;
long mul = 1;
string abc = #"73167176531330624919225119674426574742355349194934
85861560789112949495459501737958331952853208805511
96983520312774506326239578318016984801869478851843
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450";
foreach (char a in abc)
{
if(arr.Count == 13)
{
arr.RemoveAt(0);
}
int value = (int)Char.GetNumericValue(a);
arr.Add(value);
if(arr.Count == 13)
{
foreach(int b in arr)
{
mul = mul * b;
if (mul > max)
{
max = mul;
}
}
mul = 1;
}
}
Console.WriteLine(max);
I am getting 5377010688 which is a wrong answer and when I am trying same logic with given example in project Euler it is working fine, please help me.
Don't say the answer just correct me where I am doing wrong or where the code is not running as it should.
The string constant, as it is written down like above, contains blanks and \r\n's, e.g. between the last '4' of the first line and the first '8' on the second line. Char.GetNumericValue() returns -1 for a blank.
Propably the character sequence with the highest product spans across adjacent lines in your string, therefore there are blanks in between, which count as -1, which disables your code in finding them.
Write your constant like this:
string abc = #"73167176531330624919225119674426574742355349194934" +
"85861560789112949495459501737958331952853208805511" +
"96983520312774506326239578318016984801869478851843" + etc.
The result is then 23514624000, I hope that's correct.
Don't say the answer just correct me where I am doing wrong or where
the code is not running as it should
You have included all characters into calculation but you should not do that. The input string also contains for example carriage return '\n' at the end of each line.
Your actual string look like this:
string abc = #"73167176531330624919225119674426574742355349194934\r\n
85861560789112949495459501737958331952853208805511\r\n
...
How to solve this? You should ignore these characters, one possible solution is to check each char if it is a digit:
if(!char.IsDigit(a))
{
continue;
}

Checking a TextBox for an empty string, an integer or a string

I am checking a text box for the following
If there is no input
If the input is between 0 and 100
If the input is a string other than a number
The code -
if (this.BugCompPct.Text == String.Empty)
else if (Convert.ToInt32(this.BugCompPct.Text) > 100 | Convert.ToInt32(this.BugCompPct.Text) < 0)
//Not sure about checking the last if
What could I put as the if conditional to check for a string other than an integer?
I want only the input to be an integer and nothing else
Thanks
What could I put as the if conditional to check for a string other
than an integer?
Use int.TryParse method to see if the parsing is succesfull.
For empty string use string.IsNullOrWhiteSpace (supported on .Net framework 4.0 and later), For .Net framework 3.5 or lower you can use string.IsNullOrEmpty with string.Trim
Your check will all the conditions could be like:
if (!string.IsNullOrWhiteSpace(BugCompPct.Text))
{
int temp;
if(int.TryParse(BugCompPct.Text,out temp)
{
if(temp >= 0 && temp <= 100)
{
//valid number (int)
}
else
{
//invalid number (int)
}
}
else
{
//Entered text is not a number (int)
}
}
else
{
//string is empty
}
First check if TextBox is empty, then if string is valid number and last check boundaries.
int number = 0;
if (string.IsNullOrEmpty(this.BugCompPct.Text)
{
//not valid
}
else if (Int32.TryParse(this.BugCompPct.Text, out number))
{
if (number > 0 && number < 100)
{
//valid
}
}
every value put into a textbox is as string. I would then advise you to tryparse rather than convert.to.
(Why? tryparse can be handled much easier and won't crash and burn if there are bad values put into it)
just use int.TryParse(txtbox1.text, out i)
You must define integer i above this
then you can use if statements using i (the integer version) to validate it.
To check if its an integer only just use:
if(!int.TryParse(txtbox1.text, out i))
{
// do work
}
then you can use > < in if statements to check how big the number is.
If you are on windows form you should use masked textbox.

Constantly Incrementing String

So, what I'm trying to do this something like this: (example)
a,b,c,d.. etc. aa,ab,ac.. etc. ba,bb,bc, etc.
So, this can essentially be explained as generally increasing and just printing all possible variations, starting at a. So far, I've been able to do it with one letter, starting out like this:
for (int i = 97; i <= 122; i++)
{
item = (char)i
}
But, I'm unable to eventually add the second letter, third letter, and so forth. Is anyone able to provide input? Thanks.
Since there hasn't been a solution so far that would literally "increment a string", here is one that does:
static string Increment(string s) {
if (s.All(c => c == 'z')) {
return new string('a', s.Length + 1);
}
var res = s.ToCharArray();
var pos = res.Length - 1;
do {
if (res[pos] != 'z') {
res[pos]++;
break;
}
res[pos--] = 'a';
} while (true);
return new string(res);
}
The idea is simple: pretend that letters are your digits, and do an increment the way they teach in an elementary school. Start from the rightmost "digit", and increment it. If you hit a nine (which is 'z' in our system), move on to the prior digit; otherwise, you are done incrementing.
The obvious special case is when the "number" is composed entirely of nines. This is when your "counter" needs to roll to the next size up, and add a "digit". This special condition is checked at the beginning of the method: if the string is composed of N letters 'z', a string of N+1 letter 'a's is returned.
Here is a link to a quick demonstration of this code on ideone.
Each iteration of Your for loop is completely
overwriting what is in "item" - the for loop is just assigning one character "i" at a time
If item is a String, Use something like this:
item = "";
for (int i = 97; i <= 122; i++)
{
item += (char)i;
}
something to the affect of
public string IncrementString(string value)
{
if (string.IsNullOrEmpty(value)) return "a";
var chars = value.ToArray();
var last = chars.Last();
if(char.ToByte() == 122)
return value + "a";
return value.SubString(0, value.Length) + (char)(char.ToByte()+1);
}
you'll probably need to convert the char to a byte. That can be encapsulated in an extension method like static int ToByte(this char);
StringBuilder is a better choice when building large amounts of strings. so you may want to consider using that instead of string concatenation.
Another way to look at this is that you want to count in base 26. The computer is very good at counting and since it always has to convert from base 2 (binary), which is the way it stores values, to base 10 (decimal--the number system you and I generally think in), converting to different number bases is also very easy.
There's a general base converter here https://stackoverflow.com/a/3265796/351385 which converts an array of bytes to an arbitrary base. Once you have a good understanding of number bases and can understand that code, it's a simple matter to create a base 26 counter that counts in binary, but converts to base 26 for display.

Is there a simple method of converting an ordinal numeric string to its matching numeric value?

Does anyone know of a method to convert words like "first", "tenth" and "one hundredth" to their numeric equivalent?
Samples:
"first" -> 1,
"second" -> 2,
"tenth" -> 10,
"hundredth" -> 100
Any algorithm will suffice but I'm writing this in C#.
EDIT
It ain't pretty and only works with one word at a time but it suits my purposes. Maybe someone can improve it but I'm out of time.
public static int GetNumberFromOrdinalString(string inputString)
{
string[] ordinalNumberWords = { "", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth" };
string[] ordinalNumberWordsTens = { "", "tenth", "twentieth", "thirtieth", "fortieth", "fiftieth", "sixtieth", "seventieth", "eightieth", "ninetieth" };
string[] ordinalNumberWordsExtended = {"hundredth", "thousandth", "millionth", "billionth" };
if (inputString.IsNullOrEmpty() || inputString.Length < 5 || inputString.Contains(" ")) return 0;
if (ordinalNumberWords.Contains(inputString) || ordinalNumberWordsTens.Contains(inputString))
{
var outputMultiplier = ordinalNumberWords.Contains(inputString) ? 1 : 10;
var arrayToCheck = ordinalNumberWords.Contains(inputString) ? ordinalNumberWords : ordinalNumberWordsTens;
// Use the loop counter to get our output integer.
for (int x = 0; x < arrayToCheck.Count(); x++)
{
if (arrayToCheck[x] == inputString)
{
return x * outputMultiplier;
}
}
}
// Check if the number is one of our extended numbers and return the appropriate value.
if (ordinalNumberWordsExtended.Contains(inputString))
{
return inputString == ordinalNumberWordsExtended[0] ? 100 : inputString == ordinalNumberWordsExtended[1] ? 1000 : inputString == ordinalNumberWordsExtended[2] ? 1000000 : 1000000000;
}
return 0;
}
I've never given this much thought beyond I know the word "and" is supposed to be the transition from whole numbers to decimals. Like
One Hundred Ninety-Nine Dollars and Ten Cents
not
One Hundred and Ninety-Nine Dollars.
Anyways any potential solution would have to parse the input string, raise any exceptions or otherwise return the value.
But first you'd have to know "the rules" This seems to be very arbitrary and based on tradition but this gentleman seems as good a place as any to start:
Ask Dr. Math
I think you might end up having to map strings to values up to the maximum range you expect and then parse the string in order and place values as such. Since there's very little regular naming convention across and within order of magnitude, I don't think there's an elegant or easy way to parse a word to get its numeric value. Luckily, depending on the format, you probably only have to map every order of magnitude. For example, if you only expect numbers 0-100 and they are inputted as "ninety-nine" then you only need to map 0-9, then 10-100 in steps of 10.

Categories