This should be easy but somehow I'm not quite getting it.
My assignment is:<blockquote>
Write a function sentenceCapitalizer that has one parameter of type string. The function returns a copy of the string with the first character of each sentence capitalized. The function should return “Hello. My name is Joe. What is your name?” if the argument to the function is “hello. my name is Joe. what is your name?” Assume a sentence is separated by a period followed by a space."</blockquote>
What I have so far is:
def sentenceCapitalizer (string1: str): words = string1.split(". ") words2=words.capitalize() string2=words2.join() return (string2) print (sentenceCapitalizer("hello. my name is Joe. what is your name?"))
Upon execution I get the error:
Traceback (most recent call last): File "C:\Users\Andrew\Desktop\lab3.py", line 83, in <module> print (sentenceCapitalizer("hello. my name is Joe. what is your name?")) File "C:\Users\Andrew\Desktop\lab3.py", line 79, in sentenceCapitalizer words2=words.capitalize() AttributeError: 'list' object has no attribute 'capitalize'"
What is that telling me and how do I fix this? I tried following instructions found on a page listed as the python software foundation so I thought I'd have this.Answer1:
You are trying to use a string method on the wrong object;
words is list object <em>containing</em> strings. Use the method on each individual element instead:
words2 = [word.capitalize() for word in words]
But this would be applying the <em>wrong</em> transformation; you don't want to capitalise the whole sentence, but <em>just</em> the first letter.
str.capitalize() would lowercase <em>everything else</em>, including the
>>> 'my name is Joe'.capitalize() 'My name is joe'
Limit yourself to the <em>first letter only</em>, and then add back the rest of the string unchanged:
words2 = [word.capitalize() + word[1:] for word in words]
Next, a list object has no
.join() method either; that too is a string method:
string2 = '. '.join(words2)
This'll join the strings in
words2 with the
'. ' (full stop and space) joiner.
You'll probably want to use better variable names here; your strings are sentences, not words, so your code could do better reflecting that.
Together that makes your function:
def sentenceCapitalizer (string1: str): sentences = string1.split(". ") sentences2 = [sentence.capitalize() + sentence[1:] for sentence in sentences] string2 = '. '.join(sentences2) return string2
>>> def sentenceCapitalizer (string1: str): ... sentences = string1.split(". ") ... sentences2 = [sentence.capitalize() + sentence[1:] for sentence in sentences] ... string2 = '. '.join(sentences2) ... return string2 ... >>> print (sentenceCapitalizer("hello. my name is Joe. what is your name?")) Hello. My name is Joe. What is your name?Answer2:
This does the job. Since it extracts all sentences including their trailing whitespace, this also works if you have multiple paragraphs, where there are line breaks between sentences.
import re def sentence_case(text): # Split into sentences. Therefore, find all text that ends # with punctuation followed by white space or end of string. sentences = re.findall('[^.!?]+[.!?](?:\s|\Z)', text) # Capitalize the first letter of each sentence sentences = [x.upper() + x[1:] for x in sentences] # Combine sentences return ''.join(sentences)
Here is a <a href="http://ideone.com/fvTezY" rel="nofollow">working example</a>.Answer3:
To allow arbitrary whitespace after the dot. Or to capitalize the full words (It might make the difference for a Unicode text), you could <a href="https://docs.python.org/3/library/re.html" rel="nofollow">use regular expressions --
#!/usr/bin/env python3 import re def sentenceCapitalizer(text): return re.sub(r"(\.\s+|^)(\w+)", lambda m: m.group(1) + m.group(2).capitalize(), text) s = "hEllo. my name is Joe. what is your name?" print(sentenceCapitalizer(s)) # -> 'Hello. My name is Joe. What is your name?'
Note: pep8 recommends lowercase names for functions e.g.,
capitalize_sentence() instead of
To accept a larger variaty of texts, you could <a href="http://www.nltk.org/book/ch00.html" rel="nofollow">use
# $ pip install nltk from nltk.tokenize import sent_tokenize, word_tokenize def sent_capitalize(sentence): """Capitalize the first word in the *sentence*.""" words = word_tokenize(sentence) if words: words = words.capitalize() return " ".join(words[:-1]) + "".join(words[-1:]) # dot text = "hEllo. my name is Joe. what is your name?" # split the text into a list of sentences sentences = sent_tokenize(text) print(" ".join(map(sent_capitalize, sentences))) # -> Hello. My name is Joe. What is your name?Answer4:
I did not use 'split' but just while loop instead. Here is my code.
my_string = input('Enter a string: ') new_string = '' new_string += my_string.upper() i = 1 while i < len(my_string)-2: new_string += my_string[i] if my_string[i] == '.' or my_string[i] == '?' or my_string[i] == '!': new_string += ' ' new_string += my_string[i+2].upper() i = i+3 else: if i == len(my_string)-3: new_string += my_string[len(my_string)-2:len(my_string)] i = i+1 print(new_string)
Here is how it works:
Enter a string: hello. my name is Joe. what is your name? Hello. My name is Joe. What is your nameAnswer5:
Just because I couldn't find this solution here.
You can use 'sent_tokenize' method from nltk.
import nltk string = "hello. my name is Joe. what is your name?" sentences = nltk.sent_tokenize(string) print (' '.join([s.replace(s,s.capitalize(),1) for s in sentences]) )
And the output
Hello. My name is Joe. What is your name?