Build string by generating random characters step by step

Multi tool use
Multi tool use

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'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:



const args = process.argv.slice(2)

const targetWord = args[0]
let builtWord = ''

function getRandomChar()
return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


function updateWord()
const length = builtWord
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(builtWord)
process.stdout.write(nextChar)
if (targetWord[length] === nextChar)
builtWord += nextChar



const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

async function main()
while (true)
updateWord()
if (builtWord === targetWord)
break

await sleep(1000 / 16)



main()


What are your thoughts on it, anything I can improve or do differently? Thanks 😙!







share|improve this question



























    up vote
    3
    down vote

    favorite












    I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:



    const args = process.argv.slice(2)

    const targetWord = args[0]
    let builtWord = ''

    function getRandomChar()
    return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


    function updateWord()
    const length = builtWord
    const nextChar = getRandomChar()
    process.stdout.write('r')
    process.stdout.write(builtWord)
    process.stdout.write(nextChar)
    if (targetWord[length] === nextChar)
    builtWord += nextChar



    const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

    async function main()
    while (true)
    updateWord()
    if (builtWord === targetWord)
    break

    await sleep(1000 / 16)



    main()


    What are your thoughts on it, anything I can improve or do differently? Thanks 😙!







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:



      const args = process.argv.slice(2)

      const targetWord = args[0]
      let builtWord = ''

      function getRandomChar()
      return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


      function updateWord()
      const length = builtWord
      const nextChar = getRandomChar()
      process.stdout.write('r')
      process.stdout.write(builtWord)
      process.stdout.write(nextChar)
      if (targetWord[length] === nextChar)
      builtWord += nextChar



      const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

      async function main()
      while (true)
      updateWord()
      if (builtWord === targetWord)
      break

      await sleep(1000 / 16)



      main()


      What are your thoughts on it, anything I can improve or do differently? Thanks 😙!







      share|improve this question













      I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:



      const args = process.argv.slice(2)

      const targetWord = args[0]
      let builtWord = ''

      function getRandomChar()
      return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


      function updateWord()
      const length = builtWord
      const nextChar = getRandomChar()
      process.stdout.write('r')
      process.stdout.write(builtWord)
      process.stdout.write(nextChar)
      if (targetWord[length] === nextChar)
      builtWord += nextChar



      const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

      async function main()
      while (true)
      updateWord()
      if (builtWord === targetWord)
      break

      await sleep(1000 / 16)



      main()


      What are your thoughts on it, anything I can improve or do differently? Thanks 😙!









      share|improve this question












      share|improve this question




      share|improve this question








      edited May 1 at 9:41









      Vogel612♦

      20.9k345124




      20.9k345124









      asked May 1 at 9:19









      Jennifer Zhou

      183




      183




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          Extract magic numbers into constants




          • For instance, what do 126 and 32 represent in the following line?



            return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


            It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:



            const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
            const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;


            But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with -32, +32, Math.random() and Math.floor() there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:



            return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));


            Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to getRandomInt indicating that property.



          • await sleep(1000 / 16) also features magic numbers.


          Miscellaneous remarks



          • Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!


          • Extracting only a single property with the object destructuring syntax (const length = builtWord) seems a bit unidiomatic to me as opposed to const length = builtWord.length.
            Apart from that, you are using length only once anyway, so I would drop that variable all together.



          • Try to avoid global variables and interdependencies.




            • For example, builtWord as well as targetWord are shared (and the former even modified!) by main and updateWord. I would suggest making updateWord accepting both as arguments and returning the possibly newly built word:



              function tryUpdateWord(currentBuiltWord, targetWord) 
              // This is a good moment to introduce a sanity check as well
              if (currentBuildWord.length >= targetWord.length)
              throw new Error('<todo>');


              const nextChar = getRandomChar()
              process.stdout.write('r')
              process.stdout.write(currentBuiltWord)
              process.stdout.write(nextChar)
              if (targetWord[currentBuildWord.length] === nextChar)
              return currentBuiltWord + nextChar

              else
              return currentBuiltWord;





            • Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into main():



              async function main() 
              const targetWord = process.args[2]
              let builtWord = ''

              const SLEEP_PER_ITERATION = 1000 / 16;
              while (true)
              builtWord = tryUpdateWord(builtWord, targetWord)
              if (builtWord === targetWord)
              break

              await sleep(SLEEP_PER_ITERATION)









          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%2f193339%2fbuild-string-by-generating-random-characters-step-by-step%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
            2
            down vote



            accepted










            Extract magic numbers into constants




            • For instance, what do 126 and 32 represent in the following line?



              return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


              It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:



              const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
              const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;


              But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with -32, +32, Math.random() and Math.floor() there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:



              return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));


              Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to getRandomInt indicating that property.



            • await sleep(1000 / 16) also features magic numbers.


            Miscellaneous remarks



            • Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!


            • Extracting only a single property with the object destructuring syntax (const length = builtWord) seems a bit unidiomatic to me as opposed to const length = builtWord.length.
              Apart from that, you are using length only once anyway, so I would drop that variable all together.



            • Try to avoid global variables and interdependencies.




              • For example, builtWord as well as targetWord are shared (and the former even modified!) by main and updateWord. I would suggest making updateWord accepting both as arguments and returning the possibly newly built word:



                function tryUpdateWord(currentBuiltWord, targetWord) 
                // This is a good moment to introduce a sanity check as well
                if (currentBuildWord.length >= targetWord.length)
                throw new Error('<todo>');


                const nextChar = getRandomChar()
                process.stdout.write('r')
                process.stdout.write(currentBuiltWord)
                process.stdout.write(nextChar)
                if (targetWord[currentBuildWord.length] === nextChar)
                return currentBuiltWord + nextChar

                else
                return currentBuiltWord;





              • Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into main():



                async function main() 
                const targetWord = process.args[2]
                let builtWord = ''

                const SLEEP_PER_ITERATION = 1000 / 16;
                while (true)
                builtWord = tryUpdateWord(builtWord, targetWord)
                if (builtWord === targetWord)
                break

                await sleep(SLEEP_PER_ITERATION)









            share|improve this answer



























              up vote
              2
              down vote



              accepted










              Extract magic numbers into constants




              • For instance, what do 126 and 32 represent in the following line?



                return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


                It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:



                const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
                const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;


                But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with -32, +32, Math.random() and Math.floor() there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:



                return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));


                Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to getRandomInt indicating that property.



              • await sleep(1000 / 16) also features magic numbers.


              Miscellaneous remarks



              • Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!


              • Extracting only a single property with the object destructuring syntax (const length = builtWord) seems a bit unidiomatic to me as opposed to const length = builtWord.length.
                Apart from that, you are using length only once anyway, so I would drop that variable all together.



              • Try to avoid global variables and interdependencies.




                • For example, builtWord as well as targetWord are shared (and the former even modified!) by main and updateWord. I would suggest making updateWord accepting both as arguments and returning the possibly newly built word:



                  function tryUpdateWord(currentBuiltWord, targetWord) 
                  // This is a good moment to introduce a sanity check as well
                  if (currentBuildWord.length >= targetWord.length)
                  throw new Error('<todo>');


                  const nextChar = getRandomChar()
                  process.stdout.write('r')
                  process.stdout.write(currentBuiltWord)
                  process.stdout.write(nextChar)
                  if (targetWord[currentBuildWord.length] === nextChar)
                  return currentBuiltWord + nextChar

                  else
                  return currentBuiltWord;





                • Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into main():



                  async function main() 
                  const targetWord = process.args[2]
                  let builtWord = ''

                  const SLEEP_PER_ITERATION = 1000 / 16;
                  while (true)
                  builtWord = tryUpdateWord(builtWord, targetWord)
                  if (builtWord === targetWord)
                  break

                  await sleep(SLEEP_PER_ITERATION)









              share|improve this answer

























                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                Extract magic numbers into constants




                • For instance, what do 126 and 32 represent in the following line?



                  return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


                  It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:



                  const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
                  const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;


                  But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with -32, +32, Math.random() and Math.floor() there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:



                  return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));


                  Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to getRandomInt indicating that property.



                • await sleep(1000 / 16) also features magic numbers.


                Miscellaneous remarks



                • Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!


                • Extracting only a single property with the object destructuring syntax (const length = builtWord) seems a bit unidiomatic to me as opposed to const length = builtWord.length.
                  Apart from that, you are using length only once anyway, so I would drop that variable all together.



                • Try to avoid global variables and interdependencies.




                  • For example, builtWord as well as targetWord are shared (and the former even modified!) by main and updateWord. I would suggest making updateWord accepting both as arguments and returning the possibly newly built word:



                    function tryUpdateWord(currentBuiltWord, targetWord) 
                    // This is a good moment to introduce a sanity check as well
                    if (currentBuildWord.length >= targetWord.length)
                    throw new Error('<todo>');


                    const nextChar = getRandomChar()
                    process.stdout.write('r')
                    process.stdout.write(currentBuiltWord)
                    process.stdout.write(nextChar)
                    if (targetWord[currentBuildWord.length] === nextChar)
                    return currentBuiltWord + nextChar

                    else
                    return currentBuiltWord;





                  • Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into main():



                    async function main() 
                    const targetWord = process.args[2]
                    let builtWord = ''

                    const SLEEP_PER_ITERATION = 1000 / 16;
                    while (true)
                    builtWord = tryUpdateWord(builtWord, targetWord)
                    if (builtWord === targetWord)
                    break

                    await sleep(SLEEP_PER_ITERATION)









                share|improve this answer















                Extract magic numbers into constants




                • For instance, what do 126 and 32 represent in the following line?



                  return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)


                  It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:



                  const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
                  const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;


                  But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with -32, +32, Math.random() and Math.floor() there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:



                  return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));


                  Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to getRandomInt indicating that property.



                • await sleep(1000 / 16) also features magic numbers.


                Miscellaneous remarks



                • Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!


                • Extracting only a single property with the object destructuring syntax (const length = builtWord) seems a bit unidiomatic to me as opposed to const length = builtWord.length.
                  Apart from that, you are using length only once anyway, so I would drop that variable all together.



                • Try to avoid global variables and interdependencies.




                  • For example, builtWord as well as targetWord are shared (and the former even modified!) by main and updateWord. I would suggest making updateWord accepting both as arguments and returning the possibly newly built word:



                    function tryUpdateWord(currentBuiltWord, targetWord) 
                    // This is a good moment to introduce a sanity check as well
                    if (currentBuildWord.length >= targetWord.length)
                    throw new Error('<todo>');


                    const nextChar = getRandomChar()
                    process.stdout.write('r')
                    process.stdout.write(currentBuiltWord)
                    process.stdout.write(nextChar)
                    if (targetWord[currentBuildWord.length] === nextChar)
                    return currentBuiltWord + nextChar

                    else
                    return currentBuiltWord;





                  • Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into main():



                    async function main() 
                    const targetWord = process.args[2]
                    let builtWord = ''

                    const SLEEP_PER_ITERATION = 1000 / 16;
                    while (true)
                    builtWord = tryUpdateWord(builtWord, targetWord)
                    if (builtWord === targetWord)
                    break

                    await sleep(SLEEP_PER_ITERATION)










                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited May 1 at 16:06


























                answered May 1 at 16:01









                ComFreek

                608617




                608617






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193339%2fbuild-string-by-generating-random-characters-step-by-step%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    6e35YJufzN rssMy4 ofZL8NXYsVB1ukT9chUAw272VP5p,XwV 6El7pMBIRH,sMsNHEbTJwIizoOT4RwC0
                    hUSK,z91re9B ZDTeJap9CAi

                    Popular posts from this blog

                    Chat program with C++ and SFML

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

                    Python - Quiz Game with Tkinter