Search code examples
c#bogus

Generate Random Age Height Weight using Bogus


using Bogus we can generate fake and random data easily: https://github.com/bchavez/Bogus Now I need to generate some Person's. They have age, weight, height, so here is my code:

internal class Person
{
    public int Age { get; set; }
    public int Height { get; set; }
    public int Weight { get; set; }

    public static Faker<Person> FakeData { get; } =
        new Faker<Person>()
            .RuleFor(p => p.Age, f => f.Random.Number(8, 90))
            .RuleFor(p => p.Height, f => f.Random.Number(70, 200))
            .RuleFor(p => p.Weight, f => f.Random.Number(15, 200));
}

It will generate fake and random data very well. But there is a problem. I need to make it conditional. For example it will generate a person with age 9 and the height of 180 !!! Or a Person with the height of 70 and the weight of 190. I need to avoid such generationgs.

Any fix way?


Solution

  • To make the limits of the height dependent on the age and the limits of the weight dependent on the height (so, another function for that), you need to refer to the current Person instance - see the (f, x) => { return ...} parts below.

    After reading Generating Test Data with Bogus, I came up with this:

    using Bogus;
    
    namespace SO70976495
    {
        public class Person
        {
            public int Age { get; set; }
            public int Height { get; set; }
            public int Weight { get; set; }
    
            //TODO: Put the rand declaration somewhere more sensible.
            private static Random rand = new Random();
    
            public static Faker<Person> FakeData
            {
                get
                {
                    return new Faker<Person>()
                          .RuleFor(p => p.Age, f => f.Random.Number(8, 90))
                          .RuleFor(p => p.Height, (f, x) =>
                          {
                              return RandHeightForAge(x.Age);
                          })
                          .RuleFor(p => p.Weight, (f, x) =>
                          {
                              return RandWeightForHeight(x.Height);
                          });
                }
            }
    
            private static int RandHeightForAge(int age)
            {
                //TODO: Make a realistic distribution
                return rand.Next(70, (int)(70 + age / 90.0 * 130));
            }
    
            private static int RandWeightForHeight(int height)
            {
                //TODO: Make a realistic distribution
                return 10 * rand.Next((int)Math.Sqrt(height - 15), (int)Math.Sqrt(height + 20));
            }
    
            public override string ToString()
            {
                return $"Person: {Age} yrs, {Height} cm, {Weight} kg";
            }
    
        }
    }
    

    Anything silly in the above code is my fault.