Generate parentheses solutionPrint the string equivalents of a phone numberAnother permutatorPassword...

Why are backslashes included in this shell script?

Am I allowed to determine tenets of my contract as a warlock?

What is the source of 'Ma'alin bekodesh'?

What do you call the action of "describing events as they happen" like sports anchors do?

As easy as Three, Two, One... How fast can you go from Five to Four?

Print "N NE E SE S SW W NW"

Someone who is granted access to information but not expected to read it

Are athlete's college degrees discounted by employers and graduate school admissions?

Can I attach a DC blower to intake manifold of my 150CC Yamaha FZS FI engine?

Table with varying step

Why didn't all the iron and heavier elements find their way to the center of the accretion disc in the early solar system?

Idiom for 'person who gets violent when drunk"

How do I properly use a function under a class?

Can I use 220 V outlets on a 15 ampere breaker and wire it up as 110 V?

Am I being scammed by a sugar daddy?

Why would a home insurer offer a discount based on credit score?

Must I use my personal social media account for work?

What are some of the expected properties of metallic glasses and some steps to create them? (semi-ELI5)

What do I need to do, tax-wise, for a sudden windfall?

Changing the PK column of a data extension without completely recreating it

How to remove the empty page that is placed after the ToC, List of figures and List of tables

How to make this Scala method return the same generic as the input?

My mom's return ticket is 3 days after I-94 expires

Is it a good security practice to force employees hide their employer to avoid being targeted?



Generate parentheses solution


Print the string equivalents of a phone numberAnother permutatorPassword Attacker (Google apac test problem)You need to diversify your stringsCheck for balanced parentheses in JavaScriptTwo approaches to print all permutations - returning versus passing through the “result” listFinding pairs of complementary numbersRead list of dictionaries with nested dictionariesMinimum number of parentheses to be removed to make a string of parentheses balancedReturn all valid paren strings with a given lengthPython program to remove invalid parentheses






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







3












$begingroup$


I have coded a solution to build all valid permutations of parentheses.



My code is below.



I have a question on my code based on a comment by my PEP8 checker. It said that there was no need to include the line return anywhere in the code (initially I included one). The solution works but I have never had a case using recursion where I didn't have to use the return line in the base-case.



How come I don't need it here?



The following expression initially had a return statement but I was told this was obsolete.



    if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
return


Python 3.7 code:



"""Module builds all valid permutations of n parentheses
For example: n = 3:
((()))
(()())
(())()
()(())
()()()
Total = 5
"""


def build_parentheses(number_pairs: int,
output="",
number_open=0,
number_closed=0)-> str:
"""The function that builds the parentheses. Output as a string:
number_pairs: number of parentheses pairs user desired
All other parameters are private
"""
if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
else:
if number_open < number_pairs:
output += "("
build_parentheses(number_pairs, output, number_open + 1, number_closed)
output = output[:-1]
if number_closed < number_open and number_open:
output += ")"
build_parentheses(number_pairs, output, number_open, number_closed + 1)


if __name__ == "__main__":
build_parentheses.counter = 0
build_parentheses(5)
print(f"=========n{build_parentheses.counter} solutions")


By comparison, in this post I made, I did use the return statement.










share|improve this question











$endgroup$












  • $begingroup$
    At which line did you originally include the return statement?
    $endgroup$
    – dfhwze
    9 hours ago










  • $begingroup$
    After the line build_parentheses.counter += 1 in the base-case if....
    $endgroup$
    – EML
    9 hours ago






  • 1




    $begingroup$
    The key difference is you are using an else: block here, rendering the returnobsolete.
    $endgroup$
    – dfhwze
    9 hours ago






  • 1




    $begingroup$
    No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
    $endgroup$
    – dfhwze
    9 hours ago








  • 1




    $begingroup$
    Let us continue this discussion in chat.
    $endgroup$
    – dfhwze
    9 hours ago


















3












$begingroup$


I have coded a solution to build all valid permutations of parentheses.



My code is below.



I have a question on my code based on a comment by my PEP8 checker. It said that there was no need to include the line return anywhere in the code (initially I included one). The solution works but I have never had a case using recursion where I didn't have to use the return line in the base-case.



How come I don't need it here?



The following expression initially had a return statement but I was told this was obsolete.



    if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
return


Python 3.7 code:



"""Module builds all valid permutations of n parentheses
For example: n = 3:
((()))
(()())
(())()
()(())
()()()
Total = 5
"""


def build_parentheses(number_pairs: int,
output="",
number_open=0,
number_closed=0)-> str:
"""The function that builds the parentheses. Output as a string:
number_pairs: number of parentheses pairs user desired
All other parameters are private
"""
if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
else:
if number_open < number_pairs:
output += "("
build_parentheses(number_pairs, output, number_open + 1, number_closed)
output = output[:-1]
if number_closed < number_open and number_open:
output += ")"
build_parentheses(number_pairs, output, number_open, number_closed + 1)


if __name__ == "__main__":
build_parentheses.counter = 0
build_parentheses(5)
print(f"=========n{build_parentheses.counter} solutions")


By comparison, in this post I made, I did use the return statement.










share|improve this question











$endgroup$












  • $begingroup$
    At which line did you originally include the return statement?
    $endgroup$
    – dfhwze
    9 hours ago










  • $begingroup$
    After the line build_parentheses.counter += 1 in the base-case if....
    $endgroup$
    – EML
    9 hours ago






  • 1




    $begingroup$
    The key difference is you are using an else: block here, rendering the returnobsolete.
    $endgroup$
    – dfhwze
    9 hours ago






  • 1




    $begingroup$
    No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
    $endgroup$
    – dfhwze
    9 hours ago








  • 1




    $begingroup$
    Let us continue this discussion in chat.
    $endgroup$
    – dfhwze
    9 hours ago














3












3








3





$begingroup$


I have coded a solution to build all valid permutations of parentheses.



My code is below.



I have a question on my code based on a comment by my PEP8 checker. It said that there was no need to include the line return anywhere in the code (initially I included one). The solution works but I have never had a case using recursion where I didn't have to use the return line in the base-case.



How come I don't need it here?



The following expression initially had a return statement but I was told this was obsolete.



    if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
return


Python 3.7 code:



"""Module builds all valid permutations of n parentheses
For example: n = 3:
((()))
(()())
(())()
()(())
()()()
Total = 5
"""


def build_parentheses(number_pairs: int,
output="",
number_open=0,
number_closed=0)-> str:
"""The function that builds the parentheses. Output as a string:
number_pairs: number of parentheses pairs user desired
All other parameters are private
"""
if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
else:
if number_open < number_pairs:
output += "("
build_parentheses(number_pairs, output, number_open + 1, number_closed)
output = output[:-1]
if number_closed < number_open and number_open:
output += ")"
build_parentheses(number_pairs, output, number_open, number_closed + 1)


if __name__ == "__main__":
build_parentheses.counter = 0
build_parentheses(5)
print(f"=========n{build_parentheses.counter} solutions")


By comparison, in this post I made, I did use the return statement.










share|improve this question











$endgroup$




I have coded a solution to build all valid permutations of parentheses.



My code is below.



I have a question on my code based on a comment by my PEP8 checker. It said that there was no need to include the line return anywhere in the code (initially I included one). The solution works but I have never had a case using recursion where I didn't have to use the return line in the base-case.



How come I don't need it here?



The following expression initially had a return statement but I was told this was obsolete.



    if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
return


Python 3.7 code:



"""Module builds all valid permutations of n parentheses
For example: n = 3:
((()))
(()())
(())()
()(())
()()()
Total = 5
"""


def build_parentheses(number_pairs: int,
output="",
number_open=0,
number_closed=0)-> str:
"""The function that builds the parentheses. Output as a string:
number_pairs: number of parentheses pairs user desired
All other parameters are private
"""
if number_open == number_pairs and number_closed == number_pairs:
print(output)
build_parentheses.counter += 1
else:
if number_open < number_pairs:
output += "("
build_parentheses(number_pairs, output, number_open + 1, number_closed)
output = output[:-1]
if number_closed < number_open and number_open:
output += ")"
build_parentheses(number_pairs, output, number_open, number_closed + 1)


if __name__ == "__main__":
build_parentheses.counter = 0
build_parentheses(5)
print(f"=========n{build_parentheses.counter} solutions")


By comparison, in this post I made, I did use the return statement.







python recursion combinatorics balanced-delimiters






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









200_success

133k20165437




133k20165437










asked 9 hours ago









EMLEML

4869




4869












  • $begingroup$
    At which line did you originally include the return statement?
    $endgroup$
    – dfhwze
    9 hours ago










  • $begingroup$
    After the line build_parentheses.counter += 1 in the base-case if....
    $endgroup$
    – EML
    9 hours ago






  • 1




    $begingroup$
    The key difference is you are using an else: block here, rendering the returnobsolete.
    $endgroup$
    – dfhwze
    9 hours ago






  • 1




    $begingroup$
    No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
    $endgroup$
    – dfhwze
    9 hours ago








  • 1




    $begingroup$
    Let us continue this discussion in chat.
    $endgroup$
    – dfhwze
    9 hours ago


















  • $begingroup$
    At which line did you originally include the return statement?
    $endgroup$
    – dfhwze
    9 hours ago










  • $begingroup$
    After the line build_parentheses.counter += 1 in the base-case if....
    $endgroup$
    – EML
    9 hours ago






  • 1




    $begingroup$
    The key difference is you are using an else: block here, rendering the returnobsolete.
    $endgroup$
    – dfhwze
    9 hours ago






  • 1




    $begingroup$
    No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
    $endgroup$
    – dfhwze
    9 hours ago








  • 1




    $begingroup$
    Let us continue this discussion in chat.
    $endgroup$
    – dfhwze
    9 hours ago
















$begingroup$
At which line did you originally include the return statement?
$endgroup$
– dfhwze
9 hours ago




$begingroup$
At which line did you originally include the return statement?
$endgroup$
– dfhwze
9 hours ago












$begingroup$
After the line build_parentheses.counter += 1 in the base-case if....
$endgroup$
– EML
9 hours ago




$begingroup$
After the line build_parentheses.counter += 1 in the base-case if....
$endgroup$
– EML
9 hours ago




1




1




$begingroup$
The key difference is you are using an else: block here, rendering the returnobsolete.
$endgroup$
– dfhwze
9 hours ago




$begingroup$
The key difference is you are using an else: block here, rendering the returnobsolete.
$endgroup$
– dfhwze
9 hours ago




1




1




$begingroup$
No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
$endgroup$
– dfhwze
9 hours ago






$begingroup$
No, but because all remaining code in the function is in the else, there is no more reachable code detected. If you have more questions about the scope of code blocks, take it to chat :)
$endgroup$
– dfhwze
9 hours ago






1




1




$begingroup$
Let us continue this discussion in chat.
$endgroup$
– dfhwze
9 hours ago




$begingroup$
Let us continue this discussion in chat.
$endgroup$
– dfhwze
9 hours ago










3 Answers
3






active

oldest

votes


















3












$begingroup$

As mentioned here I'll provide a short answer to summarize what we discussed. A return statement only impacts code that short-circuits any remaining code that would have been called if omitted.



pseudo code snippets below



The return statement here skips snippet 2.



if (condition) {
// .. snippet 1
return;
}
// snippet 2


The return statement here is unnecessary.



if (condition) {
// .. snippet 1
return;
} else {
// snippet 2
}





share|improve this answer











$endgroup$





















    2












    $begingroup$

    There is no need for a return statement here because when you reach the end of a function, there is an implicit return.



    For example:



    1 def exampleFunction():
    2 if someCondition:
    3 doThis()
    4 else:
    5 doTheOtherThing()
    6


    We could put a return statement after the call to doThis(), but this would make no difference to the execution of the code. When someCondition is True, we enter that code block and then call doThis(). Then, we go to line 6 and implicitly return from the function.



    So after executing line 3, we jump to line 6 and implicitly return, so explicitly returning after line 3 makes no difference.






    share|improve this answer









    $endgroup$





















      0












      $begingroup$

      Effects



      This is my main complaint about your code. build_parentheses prints out its results, but it would be cleaner for it to return them as a list, or yield them.



      .counter



      Using the attribute build_parenthesis.counter like this is technically fine, but it's really strange. I don't feel that ad-hoc attributes are particularly Pythonic, especially for functions. Also, .counter will not be needed if build_parentheses returns a list as suggested.



      Names



      I'd recommend X_count rather than number_X. It's mostly preference, though.



      Public API



      Since the number_open and number_closed parameters are not part of the public API, I'd recommend removing them. Make build_parentheses take only one parameter, number_pairs. It will call, and return the results of, build_parentheses_aux, an auxiliary/helper function, which takes number_pairs as well as several private/internal parameters.



      Chained comparisons



      number_open == number_pairs and number_closed == number_pairs may be written as number_open == number_closed == number_pairs. Generally, Python interprets chained comparisons as if they were combined with and. Two comparisons A and B applied to three variables x, y, and z like x A y B z is the same as writing x A y and y B z.



      Everything else looks good



      Style is generally good, though a space to the left of -> str would be nice; and number_open rather than and number_open != 0 is Pythonic; if __name__ == "__main__" guard is good; snake_case is good; you have a docstring, ...



      Suggested Code



      Here is your code, with all suggestions implemented:



      def build_parentheses(pair_count: int) -> str:
      """The function that builds the parentheses. Output as a string:
      pair_count: number of parentheses pairs user desired
      """
      return build_parentheses_aux(pair_count, 0, 0)

      def build_parentheses_aux(pair_count: int,
      open_count,
      closed_count)-> str:
      """Auxiliary build_parentheses function.
      pair_count: number of parentheses pairs
      open_count: number of open parens so far
      closed_count: number of closed parens so far
      """
      if open_count == closed_count == pair_count:
      return [""]
      else:
      result = []
      if open_count < pair_count:
      for r in build_parentheses_aux(pair_count, open_count + 1, closed_count):
      result.append("(" + r)
      if closed_count < open_count and open_count:
      for r in build_parentheses_aux(pair_count, open_count, closed_count + 1):
      result.append(")" + r)
      return result

      if __name__ == "__main__":
      options = build_parentheses(5)
      print("n".join(options) + f"n=========n{len(options)} solutions")


      If you are familiar with generators, you could also write build_parentheses_aux as a generator, which would look cleaner (but may be less efficient).






      share|improve this answer











      $endgroup$














        Your Answer






        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',
        autoActivateHeartbeat: false,
        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%2f222101%2fgenerate-parentheses-solution%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        3












        $begingroup$

        As mentioned here I'll provide a short answer to summarize what we discussed. A return statement only impacts code that short-circuits any remaining code that would have been called if omitted.



        pseudo code snippets below



        The return statement here skips snippet 2.



        if (condition) {
        // .. snippet 1
        return;
        }
        // snippet 2


        The return statement here is unnecessary.



        if (condition) {
        // .. snippet 1
        return;
        } else {
        // snippet 2
        }





        share|improve this answer











        $endgroup$


















          3












          $begingroup$

          As mentioned here I'll provide a short answer to summarize what we discussed. A return statement only impacts code that short-circuits any remaining code that would have been called if omitted.



          pseudo code snippets below



          The return statement here skips snippet 2.



          if (condition) {
          // .. snippet 1
          return;
          }
          // snippet 2


          The return statement here is unnecessary.



          if (condition) {
          // .. snippet 1
          return;
          } else {
          // snippet 2
          }





          share|improve this answer











          $endgroup$
















            3












            3








            3





            $begingroup$

            As mentioned here I'll provide a short answer to summarize what we discussed. A return statement only impacts code that short-circuits any remaining code that would have been called if omitted.



            pseudo code snippets below



            The return statement here skips snippet 2.



            if (condition) {
            // .. snippet 1
            return;
            }
            // snippet 2


            The return statement here is unnecessary.



            if (condition) {
            // .. snippet 1
            return;
            } else {
            // snippet 2
            }





            share|improve this answer











            $endgroup$



            As mentioned here I'll provide a short answer to summarize what we discussed. A return statement only impacts code that short-circuits any remaining code that would have been called if omitted.



            pseudo code snippets below



            The return statement here skips snippet 2.



            if (condition) {
            // .. snippet 1
            return;
            }
            // snippet 2


            The return statement here is unnecessary.



            if (condition) {
            // .. snippet 1
            return;
            } else {
            // snippet 2
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 9 hours ago

























            answered 9 hours ago









            dfhwzedfhwze

            2,262323




            2,262323

























                2












                $begingroup$

                There is no need for a return statement here because when you reach the end of a function, there is an implicit return.



                For example:



                1 def exampleFunction():
                2 if someCondition:
                3 doThis()
                4 else:
                5 doTheOtherThing()
                6


                We could put a return statement after the call to doThis(), but this would make no difference to the execution of the code. When someCondition is True, we enter that code block and then call doThis(). Then, we go to line 6 and implicitly return from the function.



                So after executing line 3, we jump to line 6 and implicitly return, so explicitly returning after line 3 makes no difference.






                share|improve this answer









                $endgroup$


















                  2












                  $begingroup$

                  There is no need for a return statement here because when you reach the end of a function, there is an implicit return.



                  For example:



                  1 def exampleFunction():
                  2 if someCondition:
                  3 doThis()
                  4 else:
                  5 doTheOtherThing()
                  6


                  We could put a return statement after the call to doThis(), but this would make no difference to the execution of the code. When someCondition is True, we enter that code block and then call doThis(). Then, we go to line 6 and implicitly return from the function.



                  So after executing line 3, we jump to line 6 and implicitly return, so explicitly returning after line 3 makes no difference.






                  share|improve this answer









                  $endgroup$
















                    2












                    2








                    2





                    $begingroup$

                    There is no need for a return statement here because when you reach the end of a function, there is an implicit return.



                    For example:



                    1 def exampleFunction():
                    2 if someCondition:
                    3 doThis()
                    4 else:
                    5 doTheOtherThing()
                    6


                    We could put a return statement after the call to doThis(), but this would make no difference to the execution of the code. When someCondition is True, we enter that code block and then call doThis(). Then, we go to line 6 and implicitly return from the function.



                    So after executing line 3, we jump to line 6 and implicitly return, so explicitly returning after line 3 makes no difference.






                    share|improve this answer









                    $endgroup$



                    There is no need for a return statement here because when you reach the end of a function, there is an implicit return.



                    For example:



                    1 def exampleFunction():
                    2 if someCondition:
                    3 doThis()
                    4 else:
                    5 doTheOtherThing()
                    6


                    We could put a return statement after the call to doThis(), but this would make no difference to the execution of the code. When someCondition is True, we enter that code block and then call doThis(). Then, we go to line 6 and implicitly return from the function.



                    So after executing line 3, we jump to line 6 and implicitly return, so explicitly returning after line 3 makes no difference.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 9 hours ago









                    bagbag

                    456




                    456























                        0












                        $begingroup$

                        Effects



                        This is my main complaint about your code. build_parentheses prints out its results, but it would be cleaner for it to return them as a list, or yield them.



                        .counter



                        Using the attribute build_parenthesis.counter like this is technically fine, but it's really strange. I don't feel that ad-hoc attributes are particularly Pythonic, especially for functions. Also, .counter will not be needed if build_parentheses returns a list as suggested.



                        Names



                        I'd recommend X_count rather than number_X. It's mostly preference, though.



                        Public API



                        Since the number_open and number_closed parameters are not part of the public API, I'd recommend removing them. Make build_parentheses take only one parameter, number_pairs. It will call, and return the results of, build_parentheses_aux, an auxiliary/helper function, which takes number_pairs as well as several private/internal parameters.



                        Chained comparisons



                        number_open == number_pairs and number_closed == number_pairs may be written as number_open == number_closed == number_pairs. Generally, Python interprets chained comparisons as if they were combined with and. Two comparisons A and B applied to three variables x, y, and z like x A y B z is the same as writing x A y and y B z.



                        Everything else looks good



                        Style is generally good, though a space to the left of -> str would be nice; and number_open rather than and number_open != 0 is Pythonic; if __name__ == "__main__" guard is good; snake_case is good; you have a docstring, ...



                        Suggested Code



                        Here is your code, with all suggestions implemented:



                        def build_parentheses(pair_count: int) -> str:
                        """The function that builds the parentheses. Output as a string:
                        pair_count: number of parentheses pairs user desired
                        """
                        return build_parentheses_aux(pair_count, 0, 0)

                        def build_parentheses_aux(pair_count: int,
                        open_count,
                        closed_count)-> str:
                        """Auxiliary build_parentheses function.
                        pair_count: number of parentheses pairs
                        open_count: number of open parens so far
                        closed_count: number of closed parens so far
                        """
                        if open_count == closed_count == pair_count:
                        return [""]
                        else:
                        result = []
                        if open_count < pair_count:
                        for r in build_parentheses_aux(pair_count, open_count + 1, closed_count):
                        result.append("(" + r)
                        if closed_count < open_count and open_count:
                        for r in build_parentheses_aux(pair_count, open_count, closed_count + 1):
                        result.append(")" + r)
                        return result

                        if __name__ == "__main__":
                        options = build_parentheses(5)
                        print("n".join(options) + f"n=========n{len(options)} solutions")


                        If you are familiar with generators, you could also write build_parentheses_aux as a generator, which would look cleaner (but may be less efficient).






                        share|improve this answer











                        $endgroup$


















                          0












                          $begingroup$

                          Effects



                          This is my main complaint about your code. build_parentheses prints out its results, but it would be cleaner for it to return them as a list, or yield them.



                          .counter



                          Using the attribute build_parenthesis.counter like this is technically fine, but it's really strange. I don't feel that ad-hoc attributes are particularly Pythonic, especially for functions. Also, .counter will not be needed if build_parentheses returns a list as suggested.



                          Names



                          I'd recommend X_count rather than number_X. It's mostly preference, though.



                          Public API



                          Since the number_open and number_closed parameters are not part of the public API, I'd recommend removing them. Make build_parentheses take only one parameter, number_pairs. It will call, and return the results of, build_parentheses_aux, an auxiliary/helper function, which takes number_pairs as well as several private/internal parameters.



                          Chained comparisons



                          number_open == number_pairs and number_closed == number_pairs may be written as number_open == number_closed == number_pairs. Generally, Python interprets chained comparisons as if they were combined with and. Two comparisons A and B applied to three variables x, y, and z like x A y B z is the same as writing x A y and y B z.



                          Everything else looks good



                          Style is generally good, though a space to the left of -> str would be nice; and number_open rather than and number_open != 0 is Pythonic; if __name__ == "__main__" guard is good; snake_case is good; you have a docstring, ...



                          Suggested Code



                          Here is your code, with all suggestions implemented:



                          def build_parentheses(pair_count: int) -> str:
                          """The function that builds the parentheses. Output as a string:
                          pair_count: number of parentheses pairs user desired
                          """
                          return build_parentheses_aux(pair_count, 0, 0)

                          def build_parentheses_aux(pair_count: int,
                          open_count,
                          closed_count)-> str:
                          """Auxiliary build_parentheses function.
                          pair_count: number of parentheses pairs
                          open_count: number of open parens so far
                          closed_count: number of closed parens so far
                          """
                          if open_count == closed_count == pair_count:
                          return [""]
                          else:
                          result = []
                          if open_count < pair_count:
                          for r in build_parentheses_aux(pair_count, open_count + 1, closed_count):
                          result.append("(" + r)
                          if closed_count < open_count and open_count:
                          for r in build_parentheses_aux(pair_count, open_count, closed_count + 1):
                          result.append(")" + r)
                          return result

                          if __name__ == "__main__":
                          options = build_parentheses(5)
                          print("n".join(options) + f"n=========n{len(options)} solutions")


                          If you are familiar with generators, you could also write build_parentheses_aux as a generator, which would look cleaner (but may be less efficient).






                          share|improve this answer











                          $endgroup$
















                            0












                            0








                            0





                            $begingroup$

                            Effects



                            This is my main complaint about your code. build_parentheses prints out its results, but it would be cleaner for it to return them as a list, or yield them.



                            .counter



                            Using the attribute build_parenthesis.counter like this is technically fine, but it's really strange. I don't feel that ad-hoc attributes are particularly Pythonic, especially for functions. Also, .counter will not be needed if build_parentheses returns a list as suggested.



                            Names



                            I'd recommend X_count rather than number_X. It's mostly preference, though.



                            Public API



                            Since the number_open and number_closed parameters are not part of the public API, I'd recommend removing them. Make build_parentheses take only one parameter, number_pairs. It will call, and return the results of, build_parentheses_aux, an auxiliary/helper function, which takes number_pairs as well as several private/internal parameters.



                            Chained comparisons



                            number_open == number_pairs and number_closed == number_pairs may be written as number_open == number_closed == number_pairs. Generally, Python interprets chained comparisons as if they were combined with and. Two comparisons A and B applied to three variables x, y, and z like x A y B z is the same as writing x A y and y B z.



                            Everything else looks good



                            Style is generally good, though a space to the left of -> str would be nice; and number_open rather than and number_open != 0 is Pythonic; if __name__ == "__main__" guard is good; snake_case is good; you have a docstring, ...



                            Suggested Code



                            Here is your code, with all suggestions implemented:



                            def build_parentheses(pair_count: int) -> str:
                            """The function that builds the parentheses. Output as a string:
                            pair_count: number of parentheses pairs user desired
                            """
                            return build_parentheses_aux(pair_count, 0, 0)

                            def build_parentheses_aux(pair_count: int,
                            open_count,
                            closed_count)-> str:
                            """Auxiliary build_parentheses function.
                            pair_count: number of parentheses pairs
                            open_count: number of open parens so far
                            closed_count: number of closed parens so far
                            """
                            if open_count == closed_count == pair_count:
                            return [""]
                            else:
                            result = []
                            if open_count < pair_count:
                            for r in build_parentheses_aux(pair_count, open_count + 1, closed_count):
                            result.append("(" + r)
                            if closed_count < open_count and open_count:
                            for r in build_parentheses_aux(pair_count, open_count, closed_count + 1):
                            result.append(")" + r)
                            return result

                            if __name__ == "__main__":
                            options = build_parentheses(5)
                            print("n".join(options) + f"n=========n{len(options)} solutions")


                            If you are familiar with generators, you could also write build_parentheses_aux as a generator, which would look cleaner (but may be less efficient).






                            share|improve this answer











                            $endgroup$



                            Effects



                            This is my main complaint about your code. build_parentheses prints out its results, but it would be cleaner for it to return them as a list, or yield them.



                            .counter



                            Using the attribute build_parenthesis.counter like this is technically fine, but it's really strange. I don't feel that ad-hoc attributes are particularly Pythonic, especially for functions. Also, .counter will not be needed if build_parentheses returns a list as suggested.



                            Names



                            I'd recommend X_count rather than number_X. It's mostly preference, though.



                            Public API



                            Since the number_open and number_closed parameters are not part of the public API, I'd recommend removing them. Make build_parentheses take only one parameter, number_pairs. It will call, and return the results of, build_parentheses_aux, an auxiliary/helper function, which takes number_pairs as well as several private/internal parameters.



                            Chained comparisons



                            number_open == number_pairs and number_closed == number_pairs may be written as number_open == number_closed == number_pairs. Generally, Python interprets chained comparisons as if they were combined with and. Two comparisons A and B applied to three variables x, y, and z like x A y B z is the same as writing x A y and y B z.



                            Everything else looks good



                            Style is generally good, though a space to the left of -> str would be nice; and number_open rather than and number_open != 0 is Pythonic; if __name__ == "__main__" guard is good; snake_case is good; you have a docstring, ...



                            Suggested Code



                            Here is your code, with all suggestions implemented:



                            def build_parentheses(pair_count: int) -> str:
                            """The function that builds the parentheses. Output as a string:
                            pair_count: number of parentheses pairs user desired
                            """
                            return build_parentheses_aux(pair_count, 0, 0)

                            def build_parentheses_aux(pair_count: int,
                            open_count,
                            closed_count)-> str:
                            """Auxiliary build_parentheses function.
                            pair_count: number of parentheses pairs
                            open_count: number of open parens so far
                            closed_count: number of closed parens so far
                            """
                            if open_count == closed_count == pair_count:
                            return [""]
                            else:
                            result = []
                            if open_count < pair_count:
                            for r in build_parentheses_aux(pair_count, open_count + 1, closed_count):
                            result.append("(" + r)
                            if closed_count < open_count and open_count:
                            for r in build_parentheses_aux(pair_count, open_count, closed_count + 1):
                            result.append(")" + r)
                            return result

                            if __name__ == "__main__":
                            options = build_parentheses(5)
                            print("n".join(options) + f"n=========n{len(options)} solutions")


                            If you are familiar with generators, you could also write build_parentheses_aux as a generator, which would look cleaner (but may be less efficient).







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited 19 mins ago

























                            answered 25 mins ago









                            QuelklefQuelklef

                            46129




                            46129






























                                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.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222101%2fgenerate-parentheses-solution%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

                                Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                                Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                                Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...