Counting lowercase and uppercase letters in a string in Python












2












$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.










share|improve this question











$endgroup$



migrated from stackoverflow.com 3 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
    2 hours ago
















2












$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.










share|improve this question











$endgroup$



migrated from stackoverflow.com 3 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
    2 hours ago














2












2








2





$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.










share|improve this question











$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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 hours ago









200_success

129k15153415




129k15153415










asked 5 hours ago









Madrid_dataladyMadrid_datalady

111




111




migrated from stackoverflow.com 3 hours ago


This question came from our site for professional and enthusiast programmers.









migrated from stackoverflow.com 3 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
    2 hours ago


















  • $begingroup$
    @juanpa.arrivillaga All critiques belong in answers, not comments.
    $endgroup$
    – 200_success
    2 hours ago
















$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
2 hours ago




$begingroup$
@juanpa.arrivillaga All critiques belong in answers, not comments.
$endgroup$
– 200_success
2 hours ago










1 Answer
1






active

oldest

votes


















3












$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.






share|improve this answer








New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$









  • 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
    2 hours ago






  • 1




    $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
    1 hour 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 1s conditionally.
    $endgroup$
    – ShadowRanger
    37 mins ago













Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
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%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









3












$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.






share|improve this answer








New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$









  • 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
    2 hours ago






  • 1




    $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
    1 hour 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 1s conditionally.
    $endgroup$
    – ShadowRanger
    37 mins ago


















3












$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.






share|improve this answer








New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$









  • 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
    2 hours ago






  • 1




    $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
    1 hour 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 1s conditionally.
    $endgroup$
    – ShadowRanger
    37 mins ago
















3












3








3





$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.






share|improve this answer








New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$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.







share|improve this answer








New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this answer



share|improve this answer






New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









answered 3 hours ago









ShadowRangerShadowRanger

1312




1312




New contributor




ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






ShadowRanger is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 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
    2 hours ago






  • 1




    $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
    1 hour 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 1s conditionally.
    $endgroup$
    – ShadowRanger
    37 mins ago
















  • 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
    2 hours ago






  • 1




    $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
    1 hour 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 1s conditionally.
    $endgroup$
    – ShadowRanger
    37 mins 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
2 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
2 hours ago




1




1




$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
1 hour 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
1 hour 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 1s conditionally.
$endgroup$
– ShadowRanger
37 mins 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 1s conditionally.
$endgroup$
– ShadowRanger
37 mins ago




















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


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

But avoid



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

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


Use MathJax to format equations. MathJax reference.


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




draft saved


draft discarded














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





















































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

What other Star Trek series did the main TNG cast show up in?

Berlina muro

Berlina aerponto