Reduce the length of words in a sentence











up vote
2
down vote

favorite












This function's goal is to reduce the length of a sentence to exactly max_length characters by cutting each word in the sentence to a length of minimum 4 characters, if cutting each word to 4 characters isn't enough the the sentence is returned anyway.

All sentences are free of special characters and words are separated by spaces.

Here is the function:



def cut_everything(sentence, max_length):
"""
reduces each word in sentence to a length of 4

:type sentence: string
:param sentence: the sentence to cut
:type max_length: int
:param max_length: the length to which the sentence will be reduced
"""
words = sentence.split()
for index, word in enumerate(words):
word_length = len(word)
if word_length > 4:
to_cut = len(sentence) - max_length
to_keep = word_length - to_cut
if to_keep < 4:
to_keep = 4
words[index] = word[:to_keep]
sentence = ' '.join(words)
if len(sentence) <= max_length:
break

return sentence


My main concern for this review is performance, but any readability comment is appreciated










share|improve this question




























    up vote
    2
    down vote

    favorite












    This function's goal is to reduce the length of a sentence to exactly max_length characters by cutting each word in the sentence to a length of minimum 4 characters, if cutting each word to 4 characters isn't enough the the sentence is returned anyway.

    All sentences are free of special characters and words are separated by spaces.

    Here is the function:



    def cut_everything(sentence, max_length):
    """
    reduces each word in sentence to a length of 4

    :type sentence: string
    :param sentence: the sentence to cut
    :type max_length: int
    :param max_length: the length to which the sentence will be reduced
    """
    words = sentence.split()
    for index, word in enumerate(words):
    word_length = len(word)
    if word_length > 4:
    to_cut = len(sentence) - max_length
    to_keep = word_length - to_cut
    if to_keep < 4:
    to_keep = 4
    words[index] = word[:to_keep]
    sentence = ' '.join(words)
    if len(sentence) <= max_length:
    break

    return sentence


    My main concern for this review is performance, but any readability comment is appreciated










    share|improve this question


























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      This function's goal is to reduce the length of a sentence to exactly max_length characters by cutting each word in the sentence to a length of minimum 4 characters, if cutting each word to 4 characters isn't enough the the sentence is returned anyway.

      All sentences are free of special characters and words are separated by spaces.

      Here is the function:



      def cut_everything(sentence, max_length):
      """
      reduces each word in sentence to a length of 4

      :type sentence: string
      :param sentence: the sentence to cut
      :type max_length: int
      :param max_length: the length to which the sentence will be reduced
      """
      words = sentence.split()
      for index, word in enumerate(words):
      word_length = len(word)
      if word_length > 4:
      to_cut = len(sentence) - max_length
      to_keep = word_length - to_cut
      if to_keep < 4:
      to_keep = 4
      words[index] = word[:to_keep]
      sentence = ' '.join(words)
      if len(sentence) <= max_length:
      break

      return sentence


      My main concern for this review is performance, but any readability comment is appreciated










      share|improve this question















      This function's goal is to reduce the length of a sentence to exactly max_length characters by cutting each word in the sentence to a length of minimum 4 characters, if cutting each word to 4 characters isn't enough the the sentence is returned anyway.

      All sentences are free of special characters and words are separated by spaces.

      Here is the function:



      def cut_everything(sentence, max_length):
      """
      reduces each word in sentence to a length of 4

      :type sentence: string
      :param sentence: the sentence to cut
      :type max_length: int
      :param max_length: the length to which the sentence will be reduced
      """
      words = sentence.split()
      for index, word in enumerate(words):
      word_length = len(word)
      if word_length > 4:
      to_cut = len(sentence) - max_length
      to_keep = word_length - to_cut
      if to_keep < 4:
      to_keep = 4
      words[index] = word[:to_keep]
      sentence = ' '.join(words)
      if len(sentence) <= max_length:
      break

      return sentence


      My main concern for this review is performance, but any readability comment is appreciated







      python strings natural-language-processing






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 30 mins ago









      Anthony Geoghegan

      1278




      1278










      asked 2 hours ago









      Comte_Zero

      10211




      10211






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          Review





          • Magic numbers



            4 is a magic number, it is best to assign these to a variable name, that way it is more clear what this number means



            numbers don't have names, variables do



            MAX_WORD_LENGHT = 4



          • Use built-ins when possible




            to_keep = word_length - to_cut
            if to_keep < 4:
            to_keep = 4



            Can be replaced with the max builtin



             to_keep = max(word_length - to_cut, 4)



          • Add tests



            That way it becomes easy to check after a change if the function still works




          Alternative



          I went a slightly different route,



          Instead of joining after each word, I calculate the chars we need to cut beforehand



          So we can keep a variable that will hold the amount of chars we still need to cut to reach our target



          And only at the return join the words



          import doctest

          MAX_WORD_LENGHT = 4

          def cut_everything(sentence, max_length):
          """
          reduces each word in sentence to a length of 4

          :type sentence: string
          :param sentence: the sentence to cut
          :type max_length: int
          :param max_length: the length to which the sentence will be reduced

          >>> cut_everything('foo bar foooobar', 16)
          'foo bar foooobar'

          >>> cut_everything('foo bar foooobar', 8)
          'foo bar fooo'

          >>> cut_everything('foo bar foooobar baaarfoo', 20)
          'foo bar fooo baaarfo'

          >>> cut_everything('fooooooo baaaaaaar foooobar baaarfoo', 2)
          'fooo baaa fooo baaa'
          """
          words = sentence.split()
          chars_to_cut = len(sentence) - max_length
          for index, word in enumerate(words):
          if chars_to_cut == 0:
          break
          word_length = len(word)
          if word_length > MAX_WORD_LENGHT:
          to_keep = max(word_length - chars_to_cut, MAX_WORD_LENGHT)
          words[index] = word[:to_keep]
          chars_to_cut -= word_length - to_keep
          return ' '.join(words)

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer























          • do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
            – Comte_Zero
            25 mins ago












          • I have used the docstrings to add a test-suite with the doctest module
            – Ludisposed
            23 mins ago












          • Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
            – Ludisposed
            19 mins ago













          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: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          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%2f209813%2freduce-the-length-of-words-in-a-sentence%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          Review





          • Magic numbers



            4 is a magic number, it is best to assign these to a variable name, that way it is more clear what this number means



            numbers don't have names, variables do



            MAX_WORD_LENGHT = 4



          • Use built-ins when possible




            to_keep = word_length - to_cut
            if to_keep < 4:
            to_keep = 4



            Can be replaced with the max builtin



             to_keep = max(word_length - to_cut, 4)



          • Add tests



            That way it becomes easy to check after a change if the function still works




          Alternative



          I went a slightly different route,



          Instead of joining after each word, I calculate the chars we need to cut beforehand



          So we can keep a variable that will hold the amount of chars we still need to cut to reach our target



          And only at the return join the words



          import doctest

          MAX_WORD_LENGHT = 4

          def cut_everything(sentence, max_length):
          """
          reduces each word in sentence to a length of 4

          :type sentence: string
          :param sentence: the sentence to cut
          :type max_length: int
          :param max_length: the length to which the sentence will be reduced

          >>> cut_everything('foo bar foooobar', 16)
          'foo bar foooobar'

          >>> cut_everything('foo bar foooobar', 8)
          'foo bar fooo'

          >>> cut_everything('foo bar foooobar baaarfoo', 20)
          'foo bar fooo baaarfo'

          >>> cut_everything('fooooooo baaaaaaar foooobar baaarfoo', 2)
          'fooo baaa fooo baaa'
          """
          words = sentence.split()
          chars_to_cut = len(sentence) - max_length
          for index, word in enumerate(words):
          if chars_to_cut == 0:
          break
          word_length = len(word)
          if word_length > MAX_WORD_LENGHT:
          to_keep = max(word_length - chars_to_cut, MAX_WORD_LENGHT)
          words[index] = word[:to_keep]
          chars_to_cut -= word_length - to_keep
          return ' '.join(words)

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer























          • do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
            – Comte_Zero
            25 mins ago












          • I have used the docstrings to add a test-suite with the doctest module
            – Ludisposed
            23 mins ago












          • Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
            – Ludisposed
            19 mins ago

















          up vote
          1
          down vote



          accepted










          Review





          • Magic numbers



            4 is a magic number, it is best to assign these to a variable name, that way it is more clear what this number means



            numbers don't have names, variables do



            MAX_WORD_LENGHT = 4



          • Use built-ins when possible




            to_keep = word_length - to_cut
            if to_keep < 4:
            to_keep = 4



            Can be replaced with the max builtin



             to_keep = max(word_length - to_cut, 4)



          • Add tests



            That way it becomes easy to check after a change if the function still works




          Alternative



          I went a slightly different route,



          Instead of joining after each word, I calculate the chars we need to cut beforehand



          So we can keep a variable that will hold the amount of chars we still need to cut to reach our target



          And only at the return join the words



          import doctest

          MAX_WORD_LENGHT = 4

          def cut_everything(sentence, max_length):
          """
          reduces each word in sentence to a length of 4

          :type sentence: string
          :param sentence: the sentence to cut
          :type max_length: int
          :param max_length: the length to which the sentence will be reduced

          >>> cut_everything('foo bar foooobar', 16)
          'foo bar foooobar'

          >>> cut_everything('foo bar foooobar', 8)
          'foo bar fooo'

          >>> cut_everything('foo bar foooobar baaarfoo', 20)
          'foo bar fooo baaarfo'

          >>> cut_everything('fooooooo baaaaaaar foooobar baaarfoo', 2)
          'fooo baaa fooo baaa'
          """
          words = sentence.split()
          chars_to_cut = len(sentence) - max_length
          for index, word in enumerate(words):
          if chars_to_cut == 0:
          break
          word_length = len(word)
          if word_length > MAX_WORD_LENGHT:
          to_keep = max(word_length - chars_to_cut, MAX_WORD_LENGHT)
          words[index] = word[:to_keep]
          chars_to_cut -= word_length - to_keep
          return ' '.join(words)

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer























          • do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
            – Comte_Zero
            25 mins ago












          • I have used the docstrings to add a test-suite with the doctest module
            – Ludisposed
            23 mins ago












          • Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
            – Ludisposed
            19 mins ago















          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          Review





          • Magic numbers



            4 is a magic number, it is best to assign these to a variable name, that way it is more clear what this number means



            numbers don't have names, variables do



            MAX_WORD_LENGHT = 4



          • Use built-ins when possible




            to_keep = word_length - to_cut
            if to_keep < 4:
            to_keep = 4



            Can be replaced with the max builtin



             to_keep = max(word_length - to_cut, 4)



          • Add tests



            That way it becomes easy to check after a change if the function still works




          Alternative



          I went a slightly different route,



          Instead of joining after each word, I calculate the chars we need to cut beforehand



          So we can keep a variable that will hold the amount of chars we still need to cut to reach our target



          And only at the return join the words



          import doctest

          MAX_WORD_LENGHT = 4

          def cut_everything(sentence, max_length):
          """
          reduces each word in sentence to a length of 4

          :type sentence: string
          :param sentence: the sentence to cut
          :type max_length: int
          :param max_length: the length to which the sentence will be reduced

          >>> cut_everything('foo bar foooobar', 16)
          'foo bar foooobar'

          >>> cut_everything('foo bar foooobar', 8)
          'foo bar fooo'

          >>> cut_everything('foo bar foooobar baaarfoo', 20)
          'foo bar fooo baaarfo'

          >>> cut_everything('fooooooo baaaaaaar foooobar baaarfoo', 2)
          'fooo baaa fooo baaa'
          """
          words = sentence.split()
          chars_to_cut = len(sentence) - max_length
          for index, word in enumerate(words):
          if chars_to_cut == 0:
          break
          word_length = len(word)
          if word_length > MAX_WORD_LENGHT:
          to_keep = max(word_length - chars_to_cut, MAX_WORD_LENGHT)
          words[index] = word[:to_keep]
          chars_to_cut -= word_length - to_keep
          return ' '.join(words)

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer














          Review





          • Magic numbers



            4 is a magic number, it is best to assign these to a variable name, that way it is more clear what this number means



            numbers don't have names, variables do



            MAX_WORD_LENGHT = 4



          • Use built-ins when possible




            to_keep = word_length - to_cut
            if to_keep < 4:
            to_keep = 4



            Can be replaced with the max builtin



             to_keep = max(word_length - to_cut, 4)



          • Add tests



            That way it becomes easy to check after a change if the function still works




          Alternative



          I went a slightly different route,



          Instead of joining after each word, I calculate the chars we need to cut beforehand



          So we can keep a variable that will hold the amount of chars we still need to cut to reach our target



          And only at the return join the words



          import doctest

          MAX_WORD_LENGHT = 4

          def cut_everything(sentence, max_length):
          """
          reduces each word in sentence to a length of 4

          :type sentence: string
          :param sentence: the sentence to cut
          :type max_length: int
          :param max_length: the length to which the sentence will be reduced

          >>> cut_everything('foo bar foooobar', 16)
          'foo bar foooobar'

          >>> cut_everything('foo bar foooobar', 8)
          'foo bar fooo'

          >>> cut_everything('foo bar foooobar baaarfoo', 20)
          'foo bar fooo baaarfo'

          >>> cut_everything('fooooooo baaaaaaar foooobar baaarfoo', 2)
          'fooo baaa fooo baaa'
          """
          words = sentence.split()
          chars_to_cut = len(sentence) - max_length
          for index, word in enumerate(words):
          if chars_to_cut == 0:
          break
          word_length = len(word)
          if word_length > MAX_WORD_LENGHT:
          to_keep = max(word_length - chars_to_cut, MAX_WORD_LENGHT)
          words[index] = word[:to_keep]
          chars_to_cut -= word_length - to_keep
          return ' '.join(words)

          if __name__ == '__main__':
          doctest.testmod()






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 27 mins ago

























          answered 33 mins ago









          Ludisposed

          6,96421959




          6,96421959












          • do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
            – Comte_Zero
            25 mins ago












          • I have used the docstrings to add a test-suite with the doctest module
            – Ludisposed
            23 mins ago












          • Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
            – Ludisposed
            19 mins ago




















          • do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
            – Comte_Zero
            25 mins ago












          • I have used the docstrings to add a test-suite with the doctest module
            – Ludisposed
            23 mins ago












          • Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
            – Ludisposed
            19 mins ago


















          do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
          – Comte_Zero
          25 mins ago






          do you think it is useful to put use cases in the docstring or is it just for the answer to be clearer ? Also would using a parameter with a default value be more efficient than a global variable for the "magic number situation" ?
          – Comte_Zero
          25 mins ago














          I have used the docstrings to add a test-suite with the doctest module
          – Ludisposed
          23 mins ago






          I have used the docstrings to add a test-suite with the doctest module
          – Ludisposed
          23 mins ago














          Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
          – Ludisposed
          19 mins ago






          Both could work, but depending on the situation. If the max_word_length can be changed you could add it as a parameter. But if the max_word_length is static ie cannot be changed add it as a constant.
          – Ludisposed
          19 mins ago




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209813%2freduce-the-length-of-words-in-a-sentence%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Quarter-circle Tiles

          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

          Mont Emei