Generate a random number or null - c#

I want to generate a random number or null. So lets say i have the option to fill in a number or leave a field blank (null) and now i wna tot generate one of the two. Generating a random number is easy using the Random class but i'm not sure how to let mij function return null occasionally. I hope someone has a good idea in stead of always return null if the number generated is divisable through lets say 3 or another static number. the number that are generated will be used for indexes of arrays and the arrays are reasonably small. Lets say between 2 and 10 items.

User for example a negative one for null. Maybe like this:
Random r = new Random();
int? randomNumber;
randomNumber = r.Next(-1, 3); //put whatever range you want in here from negative to positive
if(randomNumber == -1)
{
randomNumber = null;
}

Following my comment above, I would suggest you generate a first random number between n options (based on how many odds you want the number to be null) and based on that outcome, decide to return null or a random number.
The function since can return a nullable int, must declare the type as nullable using int?.
this is an example using that strategy:
private void caller(){
Random rnd = new Random();
//generate 100 random numbers from a caller
for(int i=0;i<100;i++)
this.getNumber(rnd);
}
private int? getNumber(Random rnd, int oddsOfBeingNull = 2){
int nullOrNumber = rnd.Next(1, oddsOfBeingNull);
//if it's == 1, return null
if(nullOrNumber == 1)
return null;
//else return a random number between 1-100
return rnd.Next(1, 100);
}
}

This is a special edge case. The null scenario you wish to add to the possible results is something you will have to define its probability.
I think it is reasonable and quite easy to pre-define a range for which you will return null to the user.
Define this range based on the desired probability and add a simple range check after querying the random function.
something like this:
private double? Random()
{
var r = new Random();
var result = r.NextDouble();
if (result > 0.9)
return null;
return result;
}

Related

C# Random Seed Value of int.MinValue Unpredictable

So I am currently trying to test a function that uses a random function. In order to test it, I'm passing in a seed value to the C# Random function. (ie. System.Random)
My test cases involve using int.MaxValue and int.MinValue to get boundary testing. The max value of integer produces consistent and expected results. But when I try to use the min value the next keeps producing random results that are not predictable and therefore can't be tested.
I'm curious if this is expected or what the reasoning a seed is not producing predictable results. Am I missing something?
Thanks in advance.
Edit:
Supplying the code for reference. The methods are array extensions that I use in order to shuffle the array into a random order. I'm using the random class in order to get varied results and passing in my seed as an optional parameter to allow testing.
public static void Shuffle<T>(this T[] array, int seedValue = -1)
{
// Create the randomizer that will be needed
Random random = seedValue >= 0 ? new Random(seedValue) : new Random();
// Run the algorithm
for (int i = array.Length - 1; i > 0; i--)
{
// Get a random integer with a maximum of i
int r = random.Next(i);
// Swap the element at r with the element at i
array.Swap(r, i);
}
}
public static void Swap<T>(this T[] array, int indexOne, int indexTwo)
{
// Check if the indices that we were passed are the same index
if (indexOne == indexTwo)
{
return;
}
// Check that the first index is in range
if (indexOne < 0 || indexOne >= array.Length)
{
throw new ArgumentOutOfRangeException("indexOne", "The first index provided is out of the range of the array provided.");
}
// Check that the second index is in range
if (indexTwo < 0 || indexTwo >= array.Length)
{
throw new ArgumentOutOfRangeException("indexTwo", "The second index provided is out of the range of the array provided.");
}
// Swap the items
T temp = array[indexOne];
array[indexOne] = array[indexTwo];
array[indexTwo] = temp;
}
So those are the methods that are being tested. I'm passing the minvalue into the Shuffle function. And upon further investigation for myself, it seems to be occuring with any negative value. It seems to produce inconsistent results. I am currently working in the .NET 2.0. Old version I know, but I'm working inside Unity.
Here's your problem:
Random random = seedValue >= 0 ? new Random(seedValue) : new Random();
If you are passing a seed value less than zero, you are not using it at all,
So naturally, the random seed gets selected from the running computer's clock.
If you check the source code of the Random class, you can find the following line in the constructor:
int subtraction = (Seed == Int32.MinValue) ?
Int32.MaxValue : Math.Abs( Seed );
This check means that if the Seed is equal to Int32.MinValue, the MaxValue is used instead. It also means the results from both should be exactly the same.

C# needing a six digit number beginning with two 0's

I'm making a program where products are searched for by there batch number. I want to the batch number to be a random 6 digit code starting with 00, for example 002142; at the moment it is only making a random 6 digit code.
Here is the code I have tried:
public string getRandomNumber()
{
Random random = new Random(100000);
string randomNumber = random.Next(999999).ToString("D6");
return randomNumber;
}
public string getRandomNumber()
{
Random random = new Random();
string randomNumber = "00"+random.Next(10000).ToString("D4");
return randomNumber;
}
You should not set a fix seed in the Random, because it will allways generate the same random number sequence. For example if you call your function in a loop it will allways return the same number, thus not being random.
Also the parameter in the Next() function is the upper bound exclusive so use 10000 instead 9999 so you can get 9999 as a random number as well.
why is everybody creating 6 digit ? what really is needed is create 4 and concat.
int random = new Random().Next(1000, 9999);
string code = "00" + random.ToString();
EDIT:
Thanks for marking as correct answer but my code is wrong. If you don't pass minimum value to next method, you can get numbers from 1 to 999 which you don't want. I edited my answer. Hope it's not late for anything.
You wrote .Next(999999) so i assume you want random values from 0 to 999999.
First you should write 1000000 because .Next() determines a random number from 0 to exclusive the input value.
Then you should
replace
string randomNumber = random.Next(1000000).ToString("D6");
with
string randomNumber = random.Next(999999).ToString().PadLeft(6, '0');
to fill the missing digits with 0
Another possibility is "000000" format string (six digits, leading zeros are mandatory):
random.Next(10000) - last 4 digits are random
ToString("000000") - 6 digits are returned (at least 2 leading zeros)
Implementation
string randomNumber = random.Next(10000).ToString("000000");
Another issue is that you should not declare random locally:
// Simplest, but not thread safe
private static random = new Random();
...
public static string getRandomNumber()
{
return random.Next(10000).ToString("000000");
}
You were close. What you really want is a random four digit number, padded with two leading zeroes (to six places) . So use Random.Next(10000).ToString("D6") or . ToString("000000")
Note however for numbers less than 1000, you will end up with more than two leading zeroes. To avoid that, you can do Random.Next(1000,10000) where the first number is inclusive, and the second exclusive.
Note also that the way you are initializing the random is incorrect if you are going to be calling this method more than once! Make your Random object a class member (preferably static) and only seed/initialize it once (don't pass 100000 to its constructor) Otherwise if this method is called more than once, it is going to return the same value each time.
Use new Random() . If you are going to seed it the way you do, it must be a static variable (or at least a class member--however for each instance of the class you will end up with the same values being generated)
I would do something like this:
var rnd = new Random(); // the internal seed is good enough
var rndNums = string.Join("", Enumerable.Range(0, 4).Select(x => rnd.Next(10)));
return "00" + rndNums;
Then you can easily change the amount you want, like this:
string GetRandomBatch(int numberOfRandomNumbers)
{
var rnd = new Random(); // the internal seed is good enough
var rndNums = string.Join("", Enumerable.Range(0, numberOfRandomNumbers).Select(x => rnd.Next(0, 9)));
return "00" + rndNums;
}
With interpolated string (C# 6.0) you can do it like this :
Random random = new Random();
string randomNumber = $"00{random.Next(9999)}";
Your ToString("D6") does exactly what it appears that you want, but since you are passing a large upper bound for your random.Next, there will in many scenarios not be anything to pad.
As others have indicated, you may prefix "00", or you could simply set a lower upper bound, since the "D6" will take care of your padding:
string randomNumber = random.Next(9999).ToString("D6");
If you want the number to always be 4 digits and not, say, "000123", you'll need to specify a lower bound as well:
string randomNumber = random.Next(1000, 9999).ToString("D6");
Also note that if you are specifying a hardcoded seed as in your example, you will always get the same random number back.
Something like this will do.
public static void Main()
{
Random rnd = new Random();
string Value = rnd.Next(1, 9999).ToString("D6");
Console.WriteLine(Value);
}
Or with lower possibility of getting the same number would be
public static void Main()
{
Random rnd = new Random(DateTime.Now.Millisecond);
string Value = rnd.Next(1, 9999).ToString("D6");
Console.WriteLine(Value);
}
public string RandomNum()
{
return "00"+ new Random().Next(9999).ToString("D4");
}
you can also give minimum and maximum number to Next() function. Like:
return "00"+ new Random().Next(1,9999).ToString("D4");

C# Random Number Creation

Ok so I know to generate a random number one would create a method such as this:
private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
Now lets say instead of having it take two numbers example:
RandomNumber(4, 25);
I want it to make the max a value that will be determined, example:
RandomNumber(0, Alist.Count);
Is there any way to do this? I tried making AList.Count = another int number and putting that in but to no avail.
Yes, RandomNumber(0, Alist.Count) will work perfectly. However, instead of making a function for that, you should be using one instance of Random:
Random r = new Random();
DoSomething(r.Next(0, Alist.Count));
DoSomething(r.Next(0, Alist.Count));
DoSomething(r.Next(0, Alist.Count));
// etc., whatever you want.
Edit: So you want a random element from a list?
Random r = new Random();
Alist[r.Next(0, Alist.Count)] // There's your random element.
In light of the comments in minitech's answer I thought I'd give my own spin on returning random indexes from a list - feel free to take it or leave it ;).
Personally I'd declare an extension method for O(n) shuffling a list (using a Fisher-Yates shuffle):
public static class ListExtensions
{
public static List<T> Shuffle<T>(this List<T> list, Random random)
{
if (list == null) throw new ArgumentNullException("list");
if (random == null) throw new ArgumentNullException("random");
for (int i = list.Count - 1; i >= 1; i--)
{
int j = random.Next(0, i + 1);
T temp = list[i];
list[i] = list[j];
list[j] = temp;
}
return list; // best made a void method, but for examples I'll return list.
}
}
And then if reordering the original list is acceptable, simply call:
Alist.Shuffle(new Random());
If reordering is not acceptable, and I want a random list of unique indexes I'd use:
List<int> indexes = Enumerable.Range(0, Alist.Count).ToList().Shuffle(new Random());
Or I could create a new list, with the original elements shuffled:
var shuffledList = Alist.ToList().Shuffle(new Random());
It's a pretty versatile extension method, perhaps worth adding to one's arsenal.
No, you would not create a method like that. Consider:
int num1 = RandomNumber(1, 6);
int num2 = RandomNumber(1, 6);
Almost all of the times, the two variables will end up having the same value. If you create Random instances too close in time, they will get the seed from the same clock tick, and end up giving you the same sequence of numbers.
Anyway, you can very well use Alist.Count in a call to a method, but you can't assign a number to it. You would have to add items to the list to change the Count property:
List<int> Alist = new List<int> { 1, 2, 3 };
int index = RandomNumber(0, Alist.Count);
here you go, this should do the trick. this will take your list and sort it in random order:
list = list.OrderBy( itm => Guid.NewGuid() ).ToList();

Create a random int number that differ from previous run of program

I use this code to generate a random number.
Random R = new Random(0);
int Rand = R.Next(7);
but i get the same random number in each run of program.
Remove the 0 from the constructor and you'll get different random numbers.
If you pass a number to the constructor it's used as seed, by always specifying 0 you'll always get the same sequence.
You can specify an int32 which is random, but the easiest is to just not pass any parameter and you get a timebased seed
you have to change the seed of your random number generator object everytime you run your program, as what i've seen from you example, your current seed is 0, so you have to change it to something else if you want to get a different stream of random number... just a thought!
Seed your (pseudo)-random generator using a non-constant value, e.g. current time and date:
Random R = new Random(DateTime.Now.Ticks);
Read more about pseudo-random generators at Wikipedia.
Use time as initial seed of your PRNG.
You need to seed the random generator. You can use as follows:
Random R = new Random(DateTime.Now.Millisecond);
int Rand = R.Next(7);
Random number generators generate a new 'random' value based on the previous number generated. The seed is the initial value for this.
Seeding with the same value (like 0 in your example code) basically tells the random number generator to start with the same number each time. Having the exact same random number generated each time means your code becomes restartable. Example: Simulations use this to restart the simulation with changed parameters, but with the same 'data set'.
Another example:
I want to send myself a motivational message each day. Sometimes the messages are garbled. Being able to rerun the script, producing the same message again and again during a day, makes fixing this simple. In Perl code this means:
# By initialising the random generator with the day number since
# the epoch, we get the same quote during one day.
srand(time()/(24*3600));
my $i = int(rand(#messages));
If you want to produce different numbers each time, you will have to set this seed to something random. The options are many, like time, PID, delay between two keystrokes by the user, some value derived from the ethernet interface, etc. or more likely a combination of the above like time*PID.
Hope this clarifies the idea behind the concept of a random number seed value.
if we want a random number between 1 and 100 the code would look like this:
RandomNumberGenerator.GetRandomInt(1, 100)
The most secure way to generate random number is to use the System.Security.Cryptography.RandomNumberGenerator class.
Here is an example that will generate a number between 1 and 100;
public Number Rand()
{
byte[] Salt = new byte[8];
System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(Salt);
decimal result = 0;
foreach (byte b in Salt)
{
result = result * 255 + b;
}
while (result > 100)
{
result /= 10;
}
return result
}
Complete Code:
public static class RandomHelper
{
static object _myLock = new object();
static Random _random = new Random();
public static int RandomNumber(int min, int max)
{
lock (_myLock)
{
if (min == max)
return min;
if (min > max)
return _random.Next(max, min);
return _random.Next(min, max);
}
}
You need to seed the Random class with something more variable than 0. I normally use DataTime.Now.Ticks or you could use a new Guid's integer value.

C# code only gives expected results on step through?

Ok so I have a dice throw app...
When I step through the code it functions normally and 'results' contains the correct number of throw results and they appear to be random, when I leave the code to run and do exactly the same thing it produces a set of identical numbers.
I'm sure this is a logical error I cannot see but fiddling with it for hours hasnt improved the situation, so any help is much appriciated. :)
class Dice
{
public int[] Roll(int _throws, int _sides, int _count)
{
Random rnd = new Random();
int[] results = new int[_throws];
// for each set of dice to throw pass data to calculate method
for (int i = 0; i < _throws; i++)
{
int thisThrow = Calculate(_sides, _count);
//add each throw to a new index of array... repeat for every throw
results[i] = thisThrow;
}
return results;
}
private int Calculate(int _sides, int _count)
{
Random rnd = new Random();
int[] result = new int[_count];
int total = 0;
//for each dice to throw put data into result
for (int i = 0; i < _count; i++)
{
result[i] = rnd.Next(1, _sides);
}
//count the values in result
for (int x = 0; x < _count; x++)
{
total = total + result[x];
}
//return total of all dice to Roll method
return total;
}
}
First mistake: Never use multiple instances of Random, use a single instance, and pass that along with the other parameters.
When you create "Random rnd = new Random();" it is seeded by the current time. When you debug your code (which takes time) it will be seeded differently each time.
Create 1 instance of Random, and reference that everywhere.
You're creating a random class every time you need to create a number. Doing this will give you the nutty results.
See here: FROM MSDN
This problem can be avoided by creating a single Random object rather than multiple ones.
To improve performance, create one Random object to generate many random numbers over time, instead of repeatedly creating a new Random objects to generate one random number.
E.g. create a private instance of Random...
In addition to what has been mentioned before...
Use Random for things like dice, card games, choosing random images and so forth. If you ever need to create a random number for security sake, use System.Security.Cryptography.RandomNumberGenerator. This simple example shows creating a random integer.
RandomNumberGenerator gen = RandomNumberGenerator.Create();
byte[] myBytes = new byte[4];
gen.GetBytes(myBytes);
int myValue = (BitConverter.ToInt32(myBytes, 0));
DO NOT use this unless you have a security need. The performance is less than that of the Random class. I suppose you could use this to seed Random but that might be overkill.
EDIT: It occurred to me that I had never tested this. A quick performance test showed the following:
1,000,000 random numbers:
RandomNumberGenerator: 2.6 seconds
Random: .015 seconds.
So Random is about 150 times faster.
Give the constructor Random a seed. That's the problem.
http://msdn.microsoft.com/en-us/library/aa329890%28VS.71%29.aspx
Random r = new Random(DateTime.Now.Millisecond);

Categories

Resources