Marking projects as done when all tasks' progress are 100%

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
4
down vote

favorite












We have project.task model, where each task has many lines and each line has progress field indicating how much work has been done and how much still remaining (from 0 to 100 percent). The task cannot be done until all lines' progress is 100%.



@api.onchange('task_line_ids','task_line_rider_ids')
def progress_on_change(self):
for record in self:
if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
all_done = True
for line in record.task_line_ids or record.task_line_rider_ids:
if line.progress != 100:
all_done = False
break
if all_done == True:
record.state = 'done'
else:
record.state = 'open'


However, SonarQube reported a code smell:
SonarQube



How can the complexity be reduced?







share|improve this question



























    up vote
    4
    down vote

    favorite












    We have project.task model, where each task has many lines and each line has progress field indicating how much work has been done and how much still remaining (from 0 to 100 percent). The task cannot be done until all lines' progress is 100%.



    @api.onchange('task_line_ids','task_line_rider_ids')
    def progress_on_change(self):
    for record in self:
    if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
    all_done = True
    for line in record.task_line_ids or record.task_line_rider_ids:
    if line.progress != 100:
    all_done = False
    break
    if all_done == True:
    record.state = 'done'
    else:
    record.state = 'open'


    However, SonarQube reported a code smell:
    SonarQube



    How can the complexity be reduced?







    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      We have project.task model, where each task has many lines and each line has progress field indicating how much work has been done and how much still remaining (from 0 to 100 percent). The task cannot be done until all lines' progress is 100%.



      @api.onchange('task_line_ids','task_line_rider_ids')
      def progress_on_change(self):
      for record in self:
      if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
      all_done = True
      for line in record.task_line_ids or record.task_line_rider_ids:
      if line.progress != 100:
      all_done = False
      break
      if all_done == True:
      record.state = 'done'
      else:
      record.state = 'open'


      However, SonarQube reported a code smell:
      SonarQube



      How can the complexity be reduced?







      share|improve this question













      We have project.task model, where each task has many lines and each line has progress field indicating how much work has been done and how much still remaining (from 0 to 100 percent). The task cannot be done until all lines' progress is 100%.



      @api.onchange('task_line_ids','task_line_rider_ids')
      def progress_on_change(self):
      for record in self:
      if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
      all_done = True
      for line in record.task_line_ids or record.task_line_rider_ids:
      if line.progress != 100:
      all_done = False
      break
      if all_done == True:
      record.state = 'done'
      else:
      record.state = 'open'


      However, SonarQube reported a code smell:
      SonarQube



      How can the complexity be reduced?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 18 at 14:31









      200_success

      123k14142399




      123k14142399









      asked Apr 17 at 15:49









      Tessnim

      336




      336




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          There appears to be a bug in your code. The line:



          if len(record.task_line_ids) != 0 and record.state in ('open', 'done')


          Is followed by the line:



          for line in record.task_line_ids or record.task_line_rider_ids


          Since bool(record.task_line_ids) will always be True by the virtue of the list not being empty (as previously checked). This second line is equivalent to



          for line in record.task_line_ids


          This does not seem to be the intention of the code. Assuming you want to check all lines in either record.task_line_ids and record.task_line_rider_ids you may want to use the following code:



          all_lines = record.task_line_ids + record.task_line_rider_ids
          all_done = all(line.progress == 100 for line in all_lines)


          Combined with the other answer's suggestion, this should result in a pretty clean function.






          share|improve this answer




























            up vote
            7
            down vote













            16 and 15 are pretty artificial values, you should aim for a better code quality rather than a higher/smaller metric in particular.



            Let's see what can be improved...



            • Your boolean comparison if all_done == True: could (and should) be written in a more concise way: if all_done:.


            • Python has an optional else on for loops which can be understood as "this loop exited the usual way, not via a break". This removes the need for the all_done variable altogether:



              if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
              for line in record.task_line_ids or record.task_line_rider_ids:
              if line.progress != 100:
              record.state = 'open'
              break
              else:
              record.state = 'done'



            • You could use the all or any builtin to rewrite this without the for... else logic:



              if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
              if all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids):
              record.state = 'done'
              else:
              record.state = 'open'



            • You could re-introduce the temporary variable and use ternary operator:



              if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
              all_done = all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids)
              record.state = 'done' if all_done else 'open'






            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%2f192304%2fmarking-projects-as-done-when-all-tasks-progress-are-100%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              2
              down vote



              accepted










              There appears to be a bug in your code. The line:



              if len(record.task_line_ids) != 0 and record.state in ('open', 'done')


              Is followed by the line:



              for line in record.task_line_ids or record.task_line_rider_ids


              Since bool(record.task_line_ids) will always be True by the virtue of the list not being empty (as previously checked). This second line is equivalent to



              for line in record.task_line_ids


              This does not seem to be the intention of the code. Assuming you want to check all lines in either record.task_line_ids and record.task_line_rider_ids you may want to use the following code:



              all_lines = record.task_line_ids + record.task_line_rider_ids
              all_done = all(line.progress == 100 for line in all_lines)


              Combined with the other answer's suggestion, this should result in a pretty clean function.






              share|improve this answer

























                up vote
                2
                down vote



                accepted










                There appears to be a bug in your code. The line:



                if len(record.task_line_ids) != 0 and record.state in ('open', 'done')


                Is followed by the line:



                for line in record.task_line_ids or record.task_line_rider_ids


                Since bool(record.task_line_ids) will always be True by the virtue of the list not being empty (as previously checked). This second line is equivalent to



                for line in record.task_line_ids


                This does not seem to be the intention of the code. Assuming you want to check all lines in either record.task_line_ids and record.task_line_rider_ids you may want to use the following code:



                all_lines = record.task_line_ids + record.task_line_rider_ids
                all_done = all(line.progress == 100 for line in all_lines)


                Combined with the other answer's suggestion, this should result in a pretty clean function.






                share|improve this answer























                  up vote
                  2
                  down vote



                  accepted







                  up vote
                  2
                  down vote



                  accepted






                  There appears to be a bug in your code. The line:



                  if len(record.task_line_ids) != 0 and record.state in ('open', 'done')


                  Is followed by the line:



                  for line in record.task_line_ids or record.task_line_rider_ids


                  Since bool(record.task_line_ids) will always be True by the virtue of the list not being empty (as previously checked). This second line is equivalent to



                  for line in record.task_line_ids


                  This does not seem to be the intention of the code. Assuming you want to check all lines in either record.task_line_ids and record.task_line_rider_ids you may want to use the following code:



                  all_lines = record.task_line_ids + record.task_line_rider_ids
                  all_done = all(line.progress == 100 for line in all_lines)


                  Combined with the other answer's suggestion, this should result in a pretty clean function.






                  share|improve this answer













                  There appears to be a bug in your code. The line:



                  if len(record.task_line_ids) != 0 and record.state in ('open', 'done')


                  Is followed by the line:



                  for line in record.task_line_ids or record.task_line_rider_ids


                  Since bool(record.task_line_ids) will always be True by the virtue of the list not being empty (as previously checked). This second line is equivalent to



                  for line in record.task_line_ids


                  This does not seem to be the intention of the code. Assuming you want to check all lines in either record.task_line_ids and record.task_line_rider_ids you may want to use the following code:



                  all_lines = record.task_line_ids + record.task_line_rider_ids
                  all_done = all(line.progress == 100 for line in all_lines)


                  Combined with the other answer's suggestion, this should result in a pretty clean function.







                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Apr 18 at 20:03









                  Jared Goguen

                  777212




                  777212






















                      up vote
                      7
                      down vote













                      16 and 15 are pretty artificial values, you should aim for a better code quality rather than a higher/smaller metric in particular.



                      Let's see what can be improved...



                      • Your boolean comparison if all_done == True: could (and should) be written in a more concise way: if all_done:.


                      • Python has an optional else on for loops which can be understood as "this loop exited the usual way, not via a break". This removes the need for the all_done variable altogether:



                        if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                        for line in record.task_line_ids or record.task_line_rider_ids:
                        if line.progress != 100:
                        record.state = 'open'
                        break
                        else:
                        record.state = 'done'



                      • You could use the all or any builtin to rewrite this without the for... else logic:



                        if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                        if all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids):
                        record.state = 'done'
                        else:
                        record.state = 'open'



                      • You could re-introduce the temporary variable and use ternary operator:



                        if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                        all_done = all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids)
                        record.state = 'done' if all_done else 'open'






                      share|improve this answer



























                        up vote
                        7
                        down vote













                        16 and 15 are pretty artificial values, you should aim for a better code quality rather than a higher/smaller metric in particular.



                        Let's see what can be improved...



                        • Your boolean comparison if all_done == True: could (and should) be written in a more concise way: if all_done:.


                        • Python has an optional else on for loops which can be understood as "this loop exited the usual way, not via a break". This removes the need for the all_done variable altogether:



                          if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                          for line in record.task_line_ids or record.task_line_rider_ids:
                          if line.progress != 100:
                          record.state = 'open'
                          break
                          else:
                          record.state = 'done'



                        • You could use the all or any builtin to rewrite this without the for... else logic:



                          if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                          if all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids):
                          record.state = 'done'
                          else:
                          record.state = 'open'



                        • You could re-introduce the temporary variable and use ternary operator:



                          if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                          all_done = all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids)
                          record.state = 'done' if all_done else 'open'






                        share|improve this answer

























                          up vote
                          7
                          down vote










                          up vote
                          7
                          down vote









                          16 and 15 are pretty artificial values, you should aim for a better code quality rather than a higher/smaller metric in particular.



                          Let's see what can be improved...



                          • Your boolean comparison if all_done == True: could (and should) be written in a more concise way: if all_done:.


                          • Python has an optional else on for loops which can be understood as "this loop exited the usual way, not via a break". This removes the need for the all_done variable altogether:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            for line in record.task_line_ids or record.task_line_rider_ids:
                            if line.progress != 100:
                            record.state = 'open'
                            break
                            else:
                            record.state = 'done'



                          • You could use the all or any builtin to rewrite this without the for... else logic:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            if all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids):
                            record.state = 'done'
                            else:
                            record.state = 'open'



                          • You could re-introduce the temporary variable and use ternary operator:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            all_done = all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids)
                            record.state = 'done' if all_done else 'open'






                          share|improve this answer















                          16 and 15 are pretty artificial values, you should aim for a better code quality rather than a higher/smaller metric in particular.



                          Let's see what can be improved...



                          • Your boolean comparison if all_done == True: could (and should) be written in a more concise way: if all_done:.


                          • Python has an optional else on for loops which can be understood as "this loop exited the usual way, not via a break". This removes the need for the all_done variable altogether:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            for line in record.task_line_ids or record.task_line_rider_ids:
                            if line.progress != 100:
                            record.state = 'open'
                            break
                            else:
                            record.state = 'done'



                          • You could use the all or any builtin to rewrite this without the for... else logic:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            if all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids):
                            record.state = 'done'
                            else:
                            record.state = 'open'



                          • You could re-introduce the temporary variable and use ternary operator:



                            if len(record.task_line_ids) != 0 and record.state in ('open', 'done'):
                            all_done = all(line.progress == 100 for line in record.task_line_ids or record.task_line_rider_ids)
                            record.state = 'done' if all_done else 'open'







                          share|improve this answer















                          share|improve this answer



                          share|improve this answer








                          edited Apr 18 at 13:24


























                          answered Apr 17 at 16:06









                          Josay

                          23.8k13580




                          23.8k13580






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192304%2fmarking-projects-as-done-when-all-tasks-progress-are-100%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