Posts: 124
Threads: 39
Joined: Apr 2021
Apr-22-2021, 04:52 PM
(This post was last modified: Apr-22-2021, 04:52 PM by Anldra12.)
Quote:trying to implement a match word to dictionary while return the error no attribure 'uppercase' [/quote ]
from __future__ import print_function
import string
import re
import unittest
# You want to build a word cloud, an infographic where the size of a
# word corresponds to how often it appears in the body of text.
# To do this, you'll need data. Write code that takes a long string and
# builds its word cloud data in a dictionary, where the keys are
# words and the values are the number of times the words occurred.
# Think about capitalized words. For example, look at these sentences:
# 'After beating the eggs, Dana read the next step:'
# 'Add milk and eggs, then add flour and sugar.'
# What do we want to do with "After", "Dana", and "add"? In this
# example, your final dictionary should include one "Add" or "add" with
# a value of 22. Make reasonable (not necessarily perfect) decisions
# about cases like "After" and "Dana".
# Assume the input will only contain words and standard punctuation.
# ignore all punctuation except sentence enders . ! and ?
# lowercase any word that starts a sentence IFF it is also in the
# corpus of words as a lowercase word.
# How?
# split corpus into sentences (strings ending with a . ? or !)
# strip sentences into words
# push all words into a case sensitive, word frequency counting, dict
# scan the dict
# if a cap word is in the dict as cap and downcase then downcase
# return dict
# we do make two passes through the input stream, but if this were a
# real problem, I'd use a lexing and parsing library to implement a
# real world's problem's requirements.
def word_cloud(input):
"""map string of words into a dict of word frequencies"""
sentence_enders = r"\.|!|\?"
sentences = re.split(sentence_enders, input)
freq = {}
for sentence in sentences:
words = re.split(r"[^a-zA-Z0-9-]+", sentence)
for word in words:
count = freq.get(word, 0)
freq[word] = count + 1
def is_cap(word):
ch = word[0:1]
return ch in string.uppercase
for word, count in freq.items():
if is_cap(word) and word.lower() in freq:
count = freq[word]
freq[word.lower()] += count
del freq[word]
return freq
class TestWordCloud(unittest.TestCase):
def test_examples(self):
"""test the given example"""
test = 'After beating the eggs, Dana read the next step:' + \
'Add milk and eggs, then add flour and sugar-free diet coke.'
soln = {
'After': 1,
'Dana': 1,
'add': 2,
'and': 2,
'beating': 1,
'coke': 1,
'diet': 1,
'eggs': 2,
'flour': 1,
'milk': 1,
'next': 1,
'read': 1,
'step': 1,
'sugar-free': 1,
'the': 2,
'then': 1,
}
cloud = word_cloud(test)
self.assertDictEqual(soln, cloud)
def test_more_examples(self):
"test some additional examples"
tests = [
["We came, we saw, we conquered...then we ate Bill's "
"(Mille-Feuille) cake."
"The bill came to five dollars.",
{
'Mille-Feuille': 1,
'The': 1,
'ate': 1,
'bill': 2,
'cake': 1,
'came': 2,
'conquered': 1,
'dollars': 1,
'five': 1,
's': 1,
'saw': 1,
'then': 1,
'to': 1,
'we': 4
}
]
]
for test, soln in tests:
cloud = word_cloud(test)
self.assertDictEqual(soln, cloud)
if __name__ == "__main__":
unittest.main()
suite = unittest.TestLoader().loadTestsFromTestCase(TestWordCloud)
unittest.TextTestRunner(verbosity=2).run(suite) [quote]Return this error
Error: ERROR: test_examples (__main__.TestWordCloud)
test the given example
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 105, in test_examples
cloud = word_cloud(test)
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 72, in word_cloud
if is_cap(word) and word.lower() in freq:
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 69, in is_cap
return ch in string.uppercase
AttributeError: module 'string' has no attribute 'uppercase'
======================================================================
ERROR: test_more_examples (__main__.TestWordCloud)
test some additional examples
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 135, in test_more_examples
cloud = word_cloud(test)
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 72, in word_cloud
if is_cap(word) and word.lower() in freq:
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 69, in is_cap
return ch in string.uppercase
AttributeError: module 'string' has no attribute 'uppercase'
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (errors=2)
Posts: 2,164
Threads: 35
Joined: Sep 2016
Apr-22-2021, 05:06 PM
(This post was last modified: Apr-22-2021, 05:14 PM by Yoriz.)
It's .upper not .uppercase
https://docs.python.org/3/library/stdtyp...#str.upper Wrote:str.upper()
Return a copy of the string in which each character has been mapped through the given translation table. The table must be an object that implements indexing via __getitem__(), typically a mapping or sequence. When indexed by a Unicode ordinal (an integer), the table object can do any of the following: return a Unicode ordinal or a string, to map the character to one or more other characters; return None, to delete the character from the return string; or raise a LookupError exception, to map the character to itself.
You can use str.maketrans() to create a translation map from character-to-character mappings in different formats.
See also the codecs module for a more flexible approach to custom character mappings.
I just noticed it's the string module not an actual string, in that case you probably wanted
https://docs.python.org/3/library/string..._uppercase Wrote:string.ascii_uppercase
The uppercase letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. This value is not locale-dependent and will not change.
Posts: 124
Threads: 39
Joined: Apr 2021
Let me check thanks you for error identify and help
Posts: 124
Threads: 39
Joined: Apr 2021
Apr-23-2021, 07:53 AM
(This post was last modified: Apr-23-2021, 07:54 AM by Anldra12.)
when use this return ch in string.ascii_uppercase instead of return ch in string.uppercase return me another error EE
Error: ======================================================================
ERROR: test_examples (__main__.TestWordCloud)
test the given example
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 105, in test_examples
cloud = word_cloud(test)
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 71, in word_cloud
for word, count in freq.items():
RuntimeError: dictionary changed size during iteration
======================================================================
ERROR: test_more_examples (__main__.TestWordCloud)
test some additional examples
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 135, in test_more_examples
cloud = word_cloud(test)
File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 71, in word_cloud
for word, count in freq.items():
RuntimeError: dictionary changed size during iteration
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (errors=2)
Posts: 583
Threads: 1
Joined: Aug 2019
(Apr-22-2021, 04:52 PM)Anldra12 Wrote: for word, count in freq.items():
if is_cap(word) and word.lower() in freq:
count = freq[word]
freq[word.lower()] += count
del freq[word] You are iterating over the dictionary "freq". But then you delete an item from the dictionary. So Python does not know how to continue with the iteration. It is not allowed to change a dictionary (or list or ...) while iterating over it.
Posts: 124
Threads: 39
Joined: Apr 2021
(Apr-23-2021, 08:15 AM)ibreeden Wrote: (Apr-22-2021, 04:52 PM)Anldra12 Wrote: for word, count in freq.items():
if is_cap(word) and word.lower() in freq:
count = freq[word]
freq[word.lower()] += count
del freq[word] You are iterating over the dictionary "freq". But then you delete an item from the dictionary. So Python does not know how to continue with the iteration. It is not allowed to change a dictionary (or list or ...) while iterating over it.
Posts: 124
Threads: 39
Joined: Apr 2021
@ ibreeden so.... confuse what to do next at this stage
Posts: 583
Threads: 1
Joined: Aug 2019
If I understand your logic well, you are first adding all words to a dictionary. Then you are doing a lot of work to inspect the dictionary and move the words starting with a capital to the same word in lower case and delete the word starting with a capital.
My advice would be: make all keys lower case in the first place. Then the dictionary needs no post-processing.
freq = {}
for sentence in sentences:
words = re.split(r"[^a-zA-Z0-9-]+", sentence)
for word in words:
count = freq.get(word.lower(), 0)
freq[word.lower()] = count + 1
Posts: 124
Threads: 39
Joined: Apr 2021
(Apr-23-2021, 10:49 AM)ibreeden Wrote: If I understand your logic well, you are first adding all words to a dictionary. Then you are doing a lot of work to inspect the dictionary and move the words starting with a capital to the same word in lower case and delete the word starting with a capital.
My advice would be: make all keys lower case in the first place. Then the dictionary needs no post-processing.
freq = {}
for sentence in sentences:
words = re.split(r"[^a-zA-Z0-9-]+", sentence)
for word in words:
count = freq.get(word.lower(), 0)
freq[word.lower()] = count + 1
Posts: 124
Threads: 39
Joined: Apr 2021
Apr-23-2021, 02:26 PM
(This post was last modified: Apr-23-2021, 02:29 PM by Anldra12.)
@ ibreeden well from your side please copy paste the codes and run maybe you will understand while apply different ways got this error again and again
Error: File "D:/Python3.8.0/Python/Lib/WordFinder.py", line 71, in word_cloud
for word, count in freq.items():
RuntimeError: dictionary changed size during iteration
|