Counting lowercase and uppercase letters in a string in Python
$begingroup$
I am writing a program to count the number of uppercase and lowercase letters in a string. I came up with something that works, but as I am still a beginner I have a feeling writing the code this way is probably considered "clumsy."
Here is what I have:
stri = input("Give me a phrase:")
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
print("The number of uppercase letters in your phrase is:", stri_up)
print("The number of lowercase letters in your phrase is:", stri_lo)
Output:
Give me a phrase: tHe Sun is sHininG
The number of uppercase letters in your phrase is: 4
The number of lowercase letters in your phrase is: 11
I would like to learn how to write neat, beautiful code so I am wondering if there is a more efficient and elegant way to code this.
python beginner python-3.x strings
$endgroup$
migrated from stackoverflow.com 6 hours ago
This question came from our site for professional and enthusiast programmers.
add a comment |
$begingroup$
I am writing a program to count the number of uppercase and lowercase letters in a string. I came up with something that works, but as I am still a beginner I have a feeling writing the code this way is probably considered "clumsy."
Here is what I have:
stri = input("Give me a phrase:")
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
print("The number of uppercase letters in your phrase is:", stri_up)
print("The number of lowercase letters in your phrase is:", stri_lo)
Output:
Give me a phrase: tHe Sun is sHininG
The number of uppercase letters in your phrase is: 4
The number of lowercase letters in your phrase is: 11
I would like to learn how to write neat, beautiful code so I am wondering if there is a more efficient and elegant way to code this.
python beginner python-3.x strings
$endgroup$
migrated from stackoverflow.com 6 hours ago
This question came from our site for professional and enthusiast programmers.
$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago
add a comment |
$begingroup$
I am writing a program to count the number of uppercase and lowercase letters in a string. I came up with something that works, but as I am still a beginner I have a feeling writing the code this way is probably considered "clumsy."
Here is what I have:
stri = input("Give me a phrase:")
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
print("The number of uppercase letters in your phrase is:", stri_up)
print("The number of lowercase letters in your phrase is:", stri_lo)
Output:
Give me a phrase: tHe Sun is sHininG
The number of uppercase letters in your phrase is: 4
The number of lowercase letters in your phrase is: 11
I would like to learn how to write neat, beautiful code so I am wondering if there is a more efficient and elegant way to code this.
python beginner python-3.x strings
$endgroup$
I am writing a program to count the number of uppercase and lowercase letters in a string. I came up with something that works, but as I am still a beginner I have a feeling writing the code this way is probably considered "clumsy."
Here is what I have:
stri = input("Give me a phrase:")
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
print("The number of uppercase letters in your phrase is:", stri_up)
print("The number of lowercase letters in your phrase is:", stri_lo)
Output:
Give me a phrase: tHe Sun is sHininG
The number of uppercase letters in your phrase is: 4
The number of lowercase letters in your phrase is: 11
I would like to learn how to write neat, beautiful code so I am wondering if there is a more efficient and elegant way to code this.
python beginner python-3.x strings
python beginner python-3.x strings
edited 4 hours ago
200_success
129k15153415
129k15153415
asked 7 hours ago
Madrid_dataladyMadrid_datalady
211
211
migrated from stackoverflow.com 6 hours ago
This question came from our site for professional and enthusiast programmers.
migrated from stackoverflow.com 6 hours ago
This question came from our site for professional and enthusiast programmers.
$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago
add a comment |
$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago
$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago
$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago
add a comment |
1 Answer
1
active
oldest
votes
$begingroup$
Your code is mostly fine. I'd suggest more meaningful names for variables, e.g. i
is typically a name for integer/index variables; since you're iterating over letters/characters, you might choose c
, char
, let
, or letter
. For stri
, you might just name it phrase
(that's what you asked for from the user after all). You get the idea. Make the names self-documenting.
Arguably you could make it look "prettier" by performing a single pass per test, replacing:
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
with:
stri_up = sum(1 for let in stri if let.isupper())
stri_lo = sum(1 for let in stri if let.islower())
That's in theory less efficient, since it has to traverse stri
twice, while your original code only does it once, but in practice it's likely faster; on the CPython reference interpreter, sum
is highly optimized for this case and avoids constructing a bunch of intermediate int
objects while summing.
New contributor
$endgroup$
2
$begingroup$
You can just dosum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.
$endgroup$
– 200_success
4 hours ago
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; thesum
fast path only fires forint
(PyLong_Object
at C layer) exactly (noint
subclasses accepted, includingbool
); yieldingbool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; usingbool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.
$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark wherestri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded1
s conditionally.
$endgroup$
– ShadowRanger
2 hours ago
add a comment |
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',
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%2f213005%2fcounting-lowercase-and-uppercase-letters-in-a-string-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Your code is mostly fine. I'd suggest more meaningful names for variables, e.g. i
is typically a name for integer/index variables; since you're iterating over letters/characters, you might choose c
, char
, let
, or letter
. For stri
, you might just name it phrase
(that's what you asked for from the user after all). You get the idea. Make the names self-documenting.
Arguably you could make it look "prettier" by performing a single pass per test, replacing:
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
with:
stri_up = sum(1 for let in stri if let.isupper())
stri_lo = sum(1 for let in stri if let.islower())
That's in theory less efficient, since it has to traverse stri
twice, while your original code only does it once, but in practice it's likely faster; on the CPython reference interpreter, sum
is highly optimized for this case and avoids constructing a bunch of intermediate int
objects while summing.
New contributor
$endgroup$
2
$begingroup$
You can just dosum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.
$endgroup$
– 200_success
4 hours ago
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; thesum
fast path only fires forint
(PyLong_Object
at C layer) exactly (noint
subclasses accepted, includingbool
); yieldingbool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; usingbool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.
$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark wherestri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded1
s conditionally.
$endgroup$
– ShadowRanger
2 hours ago
add a comment |
$begingroup$
Your code is mostly fine. I'd suggest more meaningful names for variables, e.g. i
is typically a name for integer/index variables; since you're iterating over letters/characters, you might choose c
, char
, let
, or letter
. For stri
, you might just name it phrase
(that's what you asked for from the user after all). You get the idea. Make the names self-documenting.
Arguably you could make it look "prettier" by performing a single pass per test, replacing:
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
with:
stri_up = sum(1 for let in stri if let.isupper())
stri_lo = sum(1 for let in stri if let.islower())
That's in theory less efficient, since it has to traverse stri
twice, while your original code only does it once, but in practice it's likely faster; on the CPython reference interpreter, sum
is highly optimized for this case and avoids constructing a bunch of intermediate int
objects while summing.
New contributor
$endgroup$
2
$begingroup$
You can just dosum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.
$endgroup$
– 200_success
4 hours ago
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; thesum
fast path only fires forint
(PyLong_Object
at C layer) exactly (noint
subclasses accepted, includingbool
); yieldingbool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; usingbool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.
$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark wherestri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded1
s conditionally.
$endgroup$
– ShadowRanger
2 hours ago
add a comment |
$begingroup$
Your code is mostly fine. I'd suggest more meaningful names for variables, e.g. i
is typically a name for integer/index variables; since you're iterating over letters/characters, you might choose c
, char
, let
, or letter
. For stri
, you might just name it phrase
(that's what you asked for from the user after all). You get the idea. Make the names self-documenting.
Arguably you could make it look "prettier" by performing a single pass per test, replacing:
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
with:
stri_up = sum(1 for let in stri if let.isupper())
stri_lo = sum(1 for let in stri if let.islower())
That's in theory less efficient, since it has to traverse stri
twice, while your original code only does it once, but in practice it's likely faster; on the CPython reference interpreter, sum
is highly optimized for this case and avoids constructing a bunch of intermediate int
objects while summing.
New contributor
$endgroup$
Your code is mostly fine. I'd suggest more meaningful names for variables, e.g. i
is typically a name for integer/index variables; since you're iterating over letters/characters, you might choose c
, char
, let
, or letter
. For stri
, you might just name it phrase
(that's what you asked for from the user after all). You get the idea. Make the names self-documenting.
Arguably you could make it look "prettier" by performing a single pass per test, replacing:
stri_up = 0
stri_lo = 0
for i in stri:
if i.isupper():
stri_up += 1
if i.islower():
stri_lo += 1
with:
stri_up = sum(1 for let in stri if let.isupper())
stri_lo = sum(1 for let in stri if let.islower())
That's in theory less efficient, since it has to traverse stri
twice, while your original code only does it once, but in practice it's likely faster; on the CPython reference interpreter, sum
is highly optimized for this case and avoids constructing a bunch of intermediate int
objects while summing.
New contributor
New contributor
answered 6 hours ago
ShadowRangerShadowRanger
1512
1512
New contributor
New contributor
2
$begingroup$
You can just dosum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.
$endgroup$
– 200_success
4 hours ago
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; thesum
fast path only fires forint
(PyLong_Object
at C layer) exactly (noint
subclasses accepted, includingbool
); yieldingbool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; usingbool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.
$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark wherestri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded1
s conditionally.
$endgroup$
– ShadowRanger
2 hours ago
add a comment |
2
$begingroup$
You can just dosum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.
$endgroup$
– 200_success
4 hours ago
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; thesum
fast path only fires forint
(PyLong_Object
at C layer) exactly (noint
subclasses accepted, includingbool
); yieldingbool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; usingbool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.
$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark wherestri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded1
s conditionally.
$endgroup$
– ShadowRanger
2 hours ago
2
2
$begingroup$
You can just do
sum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.$endgroup$
– 200_success
4 hours ago
$begingroup$
You can just do
sum(c.isupper() for c in phrase)
, because boolean will be treated as 0 or 1 when summing.$endgroup$
– 200_success
4 hours ago
2
2
$begingroup$
@200_success: True, but I'm using dirty knowledge here; the
sum
fast path only fires for int
(PyLong_Object
at C layer) exactly (no int
subclasses accepted, including bool
); yielding bool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; using bool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
@200_success: True, but I'm using dirty knowledge here; the
sum
fast path only fires for int
(PyLong_Object
at C layer) exactly (no int
subclasses accepted, including bool
); yielding bool
blocks that optimization (and involves a lot more yields from the genexpr that can be avoided). Plus, I consider it more obvious to actually sum integers conditionally; using bool
for numeric value is perfectly legal, just a little more magical than necessary, given the minimal benefit.$endgroup$
– ShadowRanger
3 hours ago
$begingroup$
Just for comparison, a microbenchmark where
stri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded 1
s conditionally.$endgroup$
– ShadowRanger
2 hours ago
$begingroup$
Just for comparison, a microbenchmark where
stri
/phrase
is just one of each ASCII character (''.join(map(chr, range(128)))
), takes 15.3 µs to complete on my computer using your code, vs. 10.5 µs for summing hardcoded 1
s conditionally.$endgroup$
– ShadowRanger
2 hours ago
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%2f213005%2fcounting-lowercase-and-uppercase-letters-in-a-string-in-python%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$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
4 hours ago