Function that loads a random image using an array of paths to images

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I have created a program that generates a random image from a folder of all the world's flags. First, it generates an image as it loads, then it can keep randomizing the shown image if the user clicks on a button. Currently, I have created a method called "ImageGenerator" and call that method both in Form1() and my button click method (view code: https://pastebin.com/qzWXqP0P).



public partial class Form1 : Form

public void ImageGenerator()


string flagImageSources = new string[196];

StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

for (int i = 0; i < flagImageSources.Length; i++)

string s = flagImageSourceReader.ReadLine();
flagImageSources[i] = s;


Random numberGenerator = new Random();
int imageNumber = numberGenerator.Next(0, 196);

string flagImageSrc = flagImageSources[imageNumber];

flagPictureBox.ImageLocation = @flagImageSrc;


public Form1()

InitializeComponent();

ImageGenerator();


private void submitBtn_Click(object sender, EventArgs e)

ImageGenerator();




To me it feels like the linked code is rather inefficient as it recreates the array flagImageSources (which contains the paths to each flag image) every time a new image is to be generated in the picture box. How can I run the code on lines 6 through 13 only once, and then just run the code on lines 16 through 21 when randomizing images?







share|improve this question



























    up vote
    3
    down vote

    favorite












    I have created a program that generates a random image from a folder of all the world's flags. First, it generates an image as it loads, then it can keep randomizing the shown image if the user clicks on a button. Currently, I have created a method called "ImageGenerator" and call that method both in Form1() and my button click method (view code: https://pastebin.com/qzWXqP0P).



    public partial class Form1 : Form

    public void ImageGenerator()


    string flagImageSources = new string[196];

    StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

    for (int i = 0; i < flagImageSources.Length; i++)

    string s = flagImageSourceReader.ReadLine();
    flagImageSources[i] = s;


    Random numberGenerator = new Random();
    int imageNumber = numberGenerator.Next(0, 196);

    string flagImageSrc = flagImageSources[imageNumber];

    flagPictureBox.ImageLocation = @flagImageSrc;


    public Form1()

    InitializeComponent();

    ImageGenerator();


    private void submitBtn_Click(object sender, EventArgs e)

    ImageGenerator();




    To me it feels like the linked code is rather inefficient as it recreates the array flagImageSources (which contains the paths to each flag image) every time a new image is to be generated in the picture box. How can I run the code on lines 6 through 13 only once, and then just run the code on lines 16 through 21 when randomizing images?







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I have created a program that generates a random image from a folder of all the world's flags. First, it generates an image as it loads, then it can keep randomizing the shown image if the user clicks on a button. Currently, I have created a method called "ImageGenerator" and call that method both in Form1() and my button click method (view code: https://pastebin.com/qzWXqP0P).



      public partial class Form1 : Form

      public void ImageGenerator()


      string flagImageSources = new string[196];

      StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

      for (int i = 0; i < flagImageSources.Length; i++)

      string s = flagImageSourceReader.ReadLine();
      flagImageSources[i] = s;


      Random numberGenerator = new Random();
      int imageNumber = numberGenerator.Next(0, 196);

      string flagImageSrc = flagImageSources[imageNumber];

      flagPictureBox.ImageLocation = @flagImageSrc;


      public Form1()

      InitializeComponent();

      ImageGenerator();


      private void submitBtn_Click(object sender, EventArgs e)

      ImageGenerator();




      To me it feels like the linked code is rather inefficient as it recreates the array flagImageSources (which contains the paths to each flag image) every time a new image is to be generated in the picture box. How can I run the code on lines 6 through 13 only once, and then just run the code on lines 16 through 21 when randomizing images?







      share|improve this question













      I have created a program that generates a random image from a folder of all the world's flags. First, it generates an image as it loads, then it can keep randomizing the shown image if the user clicks on a button. Currently, I have created a method called "ImageGenerator" and call that method both in Form1() and my button click method (view code: https://pastebin.com/qzWXqP0P).



      public partial class Form1 : Form

      public void ImageGenerator()


      string flagImageSources = new string[196];

      StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

      for (int i = 0; i < flagImageSources.Length; i++)

      string s = flagImageSourceReader.ReadLine();
      flagImageSources[i] = s;


      Random numberGenerator = new Random();
      int imageNumber = numberGenerator.Next(0, 196);

      string flagImageSrc = flagImageSources[imageNumber];

      flagPictureBox.ImageLocation = @flagImageSrc;


      public Form1()

      InitializeComponent();

      ImageGenerator();


      private void submitBtn_Click(object sender, EventArgs e)

      ImageGenerator();




      To me it feels like the linked code is rather inefficient as it recreates the array flagImageSources (which contains the paths to each flag image) every time a new image is to be generated in the picture box. How can I run the code on lines 6 through 13 only once, and then just run the code on lines 16 through 21 when randomizing images?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 10 at 18:10









      t3chb0t

      32.1k54195




      32.1k54195









      asked Jan 6 at 7:48









      K. Claesson

      184




      184




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          To answer your immediate question, you need to initialise your flagImageSources once, and store it as a field in the class. That allows you to split the two actions into separate methods - one to get your list of flags, and one to get a random flag.



          public partial class Form1 : Form

          private string flagImageSources;

          private void InitializeImageSources()

          flagImageSources = new string[196];
          StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

          for (int i = 0; i < flagImageSources.Length; i++)

          string s = flagImageSourceReader.ReadLine();
          flagImageSources[i] = s;



          private string GetRandomImageLocation()

          Random numberGenerator = new Random();
          int imageNumber = numberGenerator.Next(0, 196);

          return flagImageSources[imageNumber];




          But I think we have some other concerns here.



          Firstly, you open your file but forget to close it again. C# has a handy way of making sure this doesn't happen - something that gets opened and closed should implement IDisposable (and StreamReader does just that). So you can change your code a little to make use of that, like this:



           using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

          //do stuff with flagImageSourceReader



          Secondly, you're using the magic number of 196 in a couple of places in your code - both to set the initial size of your array, and to set the upper bound of your random number generator. I would suggest that rather than using a fixed-size array, you should use an IList, which is dynamically sized. Then, if North and South Korea should merge, or Scotland or Catalonia or Tibet become independent countries, your code will still work even as you add or remove flags :)



          Here is my final code that solves both of those problems:



          public partial class Form1 : Form

          private IList<string> flagImageSources = new List<string>();

          private int NumberOfFlags => flagImageSources.Count;

          public Form1()

          InitializeComponent();

          InitializeImageSources();
          flagPictureBox.ImageLocation = GetRandomImageLocation();


          private void InitializeImageSources()

          using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

          while (!flagImageSourceReader.EndOfStream)

          flagImageSources.Add(flagImageSourceReader.ReadLine());




          private string GetRandomImageLocation()

          Random numberGenerator = new Random();
          int imageNumber = numberGenerator.Next(0, NumberOfFlags);

          return flagImageSources[imageNumber];


          private void submitBtn_Click(object sender, EventArgs e)

          flagPictureBox.ImageLocation = GetRandomImageLocation();







          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184427%2ffunction-that-loads-a-random-image-using-an-array-of-paths-to-images%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            down vote



            accepted










            To answer your immediate question, you need to initialise your flagImageSources once, and store it as a field in the class. That allows you to split the two actions into separate methods - one to get your list of flags, and one to get a random flag.



            public partial class Form1 : Form

            private string flagImageSources;

            private void InitializeImageSources()

            flagImageSources = new string[196];
            StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

            for (int i = 0; i < flagImageSources.Length; i++)

            string s = flagImageSourceReader.ReadLine();
            flagImageSources[i] = s;



            private string GetRandomImageLocation()

            Random numberGenerator = new Random();
            int imageNumber = numberGenerator.Next(0, 196);

            return flagImageSources[imageNumber];




            But I think we have some other concerns here.



            Firstly, you open your file but forget to close it again. C# has a handy way of making sure this doesn't happen - something that gets opened and closed should implement IDisposable (and StreamReader does just that). So you can change your code a little to make use of that, like this:



             using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

            //do stuff with flagImageSourceReader



            Secondly, you're using the magic number of 196 in a couple of places in your code - both to set the initial size of your array, and to set the upper bound of your random number generator. I would suggest that rather than using a fixed-size array, you should use an IList, which is dynamically sized. Then, if North and South Korea should merge, or Scotland or Catalonia or Tibet become independent countries, your code will still work even as you add or remove flags :)



            Here is my final code that solves both of those problems:



            public partial class Form1 : Form

            private IList<string> flagImageSources = new List<string>();

            private int NumberOfFlags => flagImageSources.Count;

            public Form1()

            InitializeComponent();

            InitializeImageSources();
            flagPictureBox.ImageLocation = GetRandomImageLocation();


            private void InitializeImageSources()

            using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

            while (!flagImageSourceReader.EndOfStream)

            flagImageSources.Add(flagImageSourceReader.ReadLine());




            private string GetRandomImageLocation()

            Random numberGenerator = new Random();
            int imageNumber = numberGenerator.Next(0, NumberOfFlags);

            return flagImageSources[imageNumber];


            private void submitBtn_Click(object sender, EventArgs e)

            flagPictureBox.ImageLocation = GetRandomImageLocation();







            share|improve this answer

























              up vote
              4
              down vote



              accepted










              To answer your immediate question, you need to initialise your flagImageSources once, and store it as a field in the class. That allows you to split the two actions into separate methods - one to get your list of flags, and one to get a random flag.



              public partial class Form1 : Form

              private string flagImageSources;

              private void InitializeImageSources()

              flagImageSources = new string[196];
              StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

              for (int i = 0; i < flagImageSources.Length; i++)

              string s = flagImageSourceReader.ReadLine();
              flagImageSources[i] = s;



              private string GetRandomImageLocation()

              Random numberGenerator = new Random();
              int imageNumber = numberGenerator.Next(0, 196);

              return flagImageSources[imageNumber];




              But I think we have some other concerns here.



              Firstly, you open your file but forget to close it again. C# has a handy way of making sure this doesn't happen - something that gets opened and closed should implement IDisposable (and StreamReader does just that). So you can change your code a little to make use of that, like this:



               using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

              //do stuff with flagImageSourceReader



              Secondly, you're using the magic number of 196 in a couple of places in your code - both to set the initial size of your array, and to set the upper bound of your random number generator. I would suggest that rather than using a fixed-size array, you should use an IList, which is dynamically sized. Then, if North and South Korea should merge, or Scotland or Catalonia or Tibet become independent countries, your code will still work even as you add or remove flags :)



              Here is my final code that solves both of those problems:



              public partial class Form1 : Form

              private IList<string> flagImageSources = new List<string>();

              private int NumberOfFlags => flagImageSources.Count;

              public Form1()

              InitializeComponent();

              InitializeImageSources();
              flagPictureBox.ImageLocation = GetRandomImageLocation();


              private void InitializeImageSources()

              using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

              while (!flagImageSourceReader.EndOfStream)

              flagImageSources.Add(flagImageSourceReader.ReadLine());




              private string GetRandomImageLocation()

              Random numberGenerator = new Random();
              int imageNumber = numberGenerator.Next(0, NumberOfFlags);

              return flagImageSources[imageNumber];


              private void submitBtn_Click(object sender, EventArgs e)

              flagPictureBox.ImageLocation = GetRandomImageLocation();







              share|improve this answer























                up vote
                4
                down vote



                accepted







                up vote
                4
                down vote



                accepted






                To answer your immediate question, you need to initialise your flagImageSources once, and store it as a field in the class. That allows you to split the two actions into separate methods - one to get your list of flags, and one to get a random flag.



                public partial class Form1 : Form

                private string flagImageSources;

                private void InitializeImageSources()

                flagImageSources = new string[196];
                StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

                for (int i = 0; i < flagImageSources.Length; i++)

                string s = flagImageSourceReader.ReadLine();
                flagImageSources[i] = s;



                private string GetRandomImageLocation()

                Random numberGenerator = new Random();
                int imageNumber = numberGenerator.Next(0, 196);

                return flagImageSources[imageNumber];




                But I think we have some other concerns here.



                Firstly, you open your file but forget to close it again. C# has a handy way of making sure this doesn't happen - something that gets opened and closed should implement IDisposable (and StreamReader does just that). So you can change your code a little to make use of that, like this:



                 using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

                //do stuff with flagImageSourceReader



                Secondly, you're using the magic number of 196 in a couple of places in your code - both to set the initial size of your array, and to set the upper bound of your random number generator. I would suggest that rather than using a fixed-size array, you should use an IList, which is dynamically sized. Then, if North and South Korea should merge, or Scotland or Catalonia or Tibet become independent countries, your code will still work even as you add or remove flags :)



                Here is my final code that solves both of those problems:



                public partial class Form1 : Form

                private IList<string> flagImageSources = new List<string>();

                private int NumberOfFlags => flagImageSources.Count;

                public Form1()

                InitializeComponent();

                InitializeImageSources();
                flagPictureBox.ImageLocation = GetRandomImageLocation();


                private void InitializeImageSources()

                using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

                while (!flagImageSourceReader.EndOfStream)

                flagImageSources.Add(flagImageSourceReader.ReadLine());




                private string GetRandomImageLocation()

                Random numberGenerator = new Random();
                int imageNumber = numberGenerator.Next(0, NumberOfFlags);

                return flagImageSources[imageNumber];


                private void submitBtn_Click(object sender, EventArgs e)

                flagPictureBox.ImageLocation = GetRandomImageLocation();







                share|improve this answer













                To answer your immediate question, you need to initialise your flagImageSources once, and store it as a field in the class. That allows you to split the two actions into separate methods - one to get your list of flags, and one to get a random flag.



                public partial class Form1 : Form

                private string flagImageSources;

                private void InitializeImageSources()

                flagImageSources = new string[196];
                StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv");

                for (int i = 0; i < flagImageSources.Length; i++)

                string s = flagImageSourceReader.ReadLine();
                flagImageSources[i] = s;



                private string GetRandomImageLocation()

                Random numberGenerator = new Random();
                int imageNumber = numberGenerator.Next(0, 196);

                return flagImageSources[imageNumber];




                But I think we have some other concerns here.



                Firstly, you open your file but forget to close it again. C# has a handy way of making sure this doesn't happen - something that gets opened and closed should implement IDisposable (and StreamReader does just that). So you can change your code a little to make use of that, like this:



                 using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

                //do stuff with flagImageSourceReader



                Secondly, you're using the magic number of 196 in a couple of places in your code - both to set the initial size of your array, and to set the upper bound of your random number generator. I would suggest that rather than using a fixed-size array, you should use an IList, which is dynamically sized. Then, if North and South Korea should merge, or Scotland or Catalonia or Tibet become independent countries, your code will still work even as you add or remove flags :)



                Here is my final code that solves both of those problems:



                public partial class Form1 : Form

                private IList<string> flagImageSources = new List<string>();

                private int NumberOfFlags => flagImageSources.Count;

                public Form1()

                InitializeComponent();

                InitializeImageSources();
                flagPictureBox.ImageLocation = GetRandomImageLocation();


                private void InitializeImageSources()

                using (StreamReader flagImageSourceReader = File.OpenText("flagImageSourceFile.csv"))

                while (!flagImageSourceReader.EndOfStream)

                flagImageSources.Add(flagImageSourceReader.ReadLine());




                private string GetRandomImageLocation()

                Random numberGenerator = new Random();
                int imageNumber = numberGenerator.Next(0, NumberOfFlags);

                return flagImageSources[imageNumber];


                private void submitBtn_Click(object sender, EventArgs e)

                flagPictureBox.ImageLocation = GetRandomImageLocation();








                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Jan 8 at 17:31









                Steven Eccles

                2116




                2116






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184427%2ffunction-that-loads-a-random-image-using-an-array-of-paths-to-images%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation