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;
}
$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.
python recursion combinatorics balanced-delimiters
$endgroup$
|
show 4 more comments
$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.
python recursion combinatorics balanced-delimiters
$endgroup$
$begingroup$
At which line did you originally include thereturn
statement?
$endgroup$
– dfhwze
9 hours ago
$begingroup$
After the linebuild_parentheses.counter += 1
in the base-caseif....
$endgroup$
– EML
9 hours ago
1
$begingroup$
The key difference is you are using anelse:
block here, rendering thereturn
obsolete.
$endgroup$
– dfhwze
9 hours ago
1
$begingroup$
No, but because all remaining code in the function is in theelse
, 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
|
show 4 more comments
$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.
python recursion combinatorics balanced-delimiters
$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
python recursion combinatorics balanced-delimiters
edited 3 hours ago
200_success
133k20165437
133k20165437
asked 9 hours ago
EMLEML
4869
4869
$begingroup$
At which line did you originally include thereturn
statement?
$endgroup$
– dfhwze
9 hours ago
$begingroup$
After the linebuild_parentheses.counter += 1
in the base-caseif....
$endgroup$
– EML
9 hours ago
1
$begingroup$
The key difference is you are using anelse:
block here, rendering thereturn
obsolete.
$endgroup$
– dfhwze
9 hours ago
1
$begingroup$
No, but because all remaining code in the function is in theelse
, 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
|
show 4 more comments
$begingroup$
At which line did you originally include thereturn
statement?
$endgroup$
– dfhwze
9 hours ago
$begingroup$
After the linebuild_parentheses.counter += 1
in the base-caseif....
$endgroup$
– EML
9 hours ago
1
$begingroup$
The key difference is you are using anelse:
block here, rendering thereturn
obsolete.
$endgroup$
– dfhwze
9 hours ago
1
$begingroup$
No, but because all remaining code in the function is in theelse
, 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 return
obsolete.$endgroup$
– dfhwze
9 hours ago
$begingroup$
The key difference is you are using an
else:
block here, rendering the return
obsolete.$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
|
show 4 more comments
3 Answers
3
active
oldest
votes
$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
}
$endgroup$
add a comment |
$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.
$endgroup$
add a comment |
$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).
$endgroup$
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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
}
$endgroup$
add a comment |
$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
}
$endgroup$
add a comment |
$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
}
$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
}
edited 9 hours ago
answered 9 hours ago
dfhwzedfhwze
2,262323
2,262323
add a comment |
add a comment |
$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.
$endgroup$
add a comment |
$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.
$endgroup$
add a comment |
$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.
$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.
answered 9 hours ago
bagbag
456
456
add a comment |
add a comment |
$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).
$endgroup$
add a comment |
$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).
$endgroup$
add a comment |
$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).
$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).
edited 19 mins ago
answered 25 mins ago
QuelklefQuelklef
46129
46129
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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-caseif....
$endgroup$
– EML
9 hours ago
1
$begingroup$
The key difference is you are using an
else:
block here, rendering thereturn
obsolete.$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