1

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?

Inside Man
  • 4,194
  • 12
  • 59
  • 119
  • 1
    It looks like you need to make the limits of the height dependent on the age (so, a function for that) and the limits of the weight dependent on the height (so, another function for that). – Andrew Morton Feb 03 '22 at 18:45
  • @AndrewMorton how can I send the result of Age into another method while it is not generated yet? – Inside Man Feb 04 '22 at 05:37
  • Pick a random BMI and work backwards? Work out a random height as an adult, then scale based on growth between age 2-16? – Jeremy Lakeman Feb 04 '22 at 12:19

1 Answers1

2

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.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84