From 9fa5a3a965c433448b78ae50cee60141af9a610e Mon Sep 17 00:00:00 2001 From: Gus Class Date: Mon, 19 Dec 2016 16:12:09 -0800 Subject: [PATCH 1/7] Adds snippets and tests for documentation tutorial. --- language/tutorial/README.rst.in | 20 +++++ language/tutorial/requirements.txt | 1 + .../tutorial/reviews/bladerunner-mixed.txt | 19 +++++ language/tutorial/reviews/bladerunner-neg.txt | 3 + .../tutorial/reviews/bladerunner-neutral.txt | 2 + language/tutorial/reviews/bladerunner-pos.txt | 10 +++ language/tutorial/tutorial.py | 73 +++++++++++++++++++ language/tutorial/tutorial_test.py | 49 +++++++++++++ 8 files changed, 177 insertions(+) create mode 100644 language/tutorial/README.rst.in create mode 100644 language/tutorial/requirements.txt create mode 100644 language/tutorial/reviews/bladerunner-mixed.txt create mode 100644 language/tutorial/reviews/bladerunner-neg.txt create mode 100644 language/tutorial/reviews/bladerunner-neutral.txt create mode 100644 language/tutorial/reviews/bladerunner-pos.txt create mode 100644 language/tutorial/tutorial.py create mode 100644 language/tutorial/tutorial_test.py diff --git a/language/tutorial/README.rst.in b/language/tutorial/README.rst.in new file mode 100644 index 00000000000..aea593b277f --- /dev/null +++ b/language/tutorial/README.rst.in @@ -0,0 +1,20 @@ +# This file is used to generate README.rst + +product: + name: Google Cloud Natural Language Tutorial + short_name: Cloud Natural Language Tutorial + url: https://cloud.google.com/natural-language/docs/ + description: > + The `Google Cloud Natural Language API`_ provides natural language + understanding technologies to developers, including sentiment analysis, + entity recognition, and syntax analysis. This API is part of the larger + Cloud Machine Learning API. + +setup: +- auth +- install_deps + +samples: +- name: Language tutorial + file: tutorial.py + show_help: true diff --git a/language/tutorial/requirements.txt b/language/tutorial/requirements.txt new file mode 100644 index 00000000000..2cd2a1334ea --- /dev/null +++ b/language/tutorial/requirements.txt @@ -0,0 +1 @@ +google-api-python-client==1.5.5 diff --git a/language/tutorial/reviews/bladerunner-mixed.txt b/language/tutorial/reviews/bladerunner-mixed.txt new file mode 100644 index 00000000000..3b520b65a8a --- /dev/null +++ b/language/tutorial/reviews/bladerunner-mixed.txt @@ -0,0 +1,19 @@ +I really wanted to love 'Bladerunner' but ultimately I couldn't get +myself to appreciate it fully. However, you may like it if you're into +science fiction, especially if you're interested in the philosophical +exploration of what it means to be human or machine. Some of the gizmos +like the flying cars and the Vouight-Kampff machine (which seemed very +steampunk), were quite cool. + +I did find the plot pretty slow and but the dialogue and action sequences +were good. Unlike most science fiction films, this one was mostly quiet, and +not all that much happened, except during the last 15 minutes. I didn't +understand why a unicorn was in the movie. The visual effects were fantastic, +however, and the musical score and overall mood was quite interesting. +A futurist Los Angeles that was both highly polished and also falling apart +reminded me of 'Outland.' Certainly, the style of the film made up for +many of its pedantic plot holes. + +If you want your sci-fi to be lasers and spaceships, 'Bladerunner' may +disappoint you. But if you want it to make you think, this movie may +be worth the money. \ No newline at end of file diff --git a/language/tutorial/reviews/bladerunner-neg.txt b/language/tutorial/reviews/bladerunner-neg.txt new file mode 100644 index 00000000000..dbef76271d1 --- /dev/null +++ b/language/tutorial/reviews/bladerunner-neg.txt @@ -0,0 +1,3 @@ +What was Hollywood thinking with this movie! I hated, +hated, hated it. BORING! I went afterwards and demanded my money back. +They refused. \ No newline at end of file diff --git a/language/tutorial/reviews/bladerunner-neutral.txt b/language/tutorial/reviews/bladerunner-neutral.txt new file mode 100644 index 00000000000..60556e604be --- /dev/null +++ b/language/tutorial/reviews/bladerunner-neutral.txt @@ -0,0 +1,2 @@ +I neither liked nor disliked this movie. Parts were interesting, but +overall I was left wanting more. The acting was pretty good. \ No newline at end of file diff --git a/language/tutorial/reviews/bladerunner-pos.txt b/language/tutorial/reviews/bladerunner-pos.txt new file mode 100644 index 00000000000..a7faf81570b --- /dev/null +++ b/language/tutorial/reviews/bladerunner-pos.txt @@ -0,0 +1,10 @@ +`Bladerunner` is often touted as one of the best science fiction films ever +made. Indeed, it satisfies many of the requisites for good sci-fi: a future +world with flying cars and humanoid robots attempting to rebel against their +creators. But more than anything, `Bladerunner` is a fantastic exploration +of the nature of what it means to be human. If we create robots which can +think, will they become human? And if they do, what makes us unique? Indeed, +how can we be sure we're not human in any case? `Bladerunner` explored +these issues before such movies as `The Matrix,' and did so intelligently. +The visual effects and score by Vangelis set the mood. See this movie +in a dark theatre to appreciate it fully. Highly recommended! \ No newline at end of file diff --git a/language/tutorial/tutorial.py b/language/tutorial/tutorial.py new file mode 100644 index 00000000000..6e40c515671 --- /dev/null +++ b/language/tutorial/tutorial.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +# Copyright 2016 Google, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import argparse + + +from googleapiclient import discovery + + +from oauth2client.client import GoogleCredentials + + +def authenticate(): + '''Authenticates the client library using default application + credentials.''' + credentials = GoogleCredentials.get_application_default() + service = discovery.build('language', 'v1', credentials=credentials) + return service + + +def getResponse(filename): + '''Run sentiment analysis on text within a passed filename.''' + service = authenticate() + with open(filename, 'r') as review_file: + service_request = service.documents().analyzeSentiment( + body={ + 'document': { + 'type': 'PLAIN_TEXT', + 'content': review_file.read(), + } + } + ) + response = service_request.execute() + return response + + +def printResponseContents(response): + '''Prints document sentiment, magnitude, and sentence score.''' + score = response['documentSentiment']['score'] + magnitude = response['documentSentiment']['magnitude'] + for i, sentence in enumerate(response['sentences']): + sentence_sentiment = sentence['sentiment']['score'] + print('Sentence {} has a sentiment score of {}'.format(i, + sentence_sentiment)) + print('Overall Sentiment: score of {} with magnitude of {}'.format( + score, magnitude)) + + +def main(filename): + '''Run sentiment analysis on the file contents given a filename.''' + printResponseContents(getResponse(filename)) + return 0 + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + 'movie_review_filename', + help='The filename of the movie review you\'d like to analyze.') + args = parser.parse_args() + main(args.movie_review_filename) diff --git a/language/tutorial/tutorial_test.py b/language/tutorial/tutorial_test.py new file mode 100644 index 00000000000..d7fe798f589 --- /dev/null +++ b/language/tutorial/tutorial_test.py @@ -0,0 +1,49 @@ +# Copyright 2016, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tutorial + + +def test_neutral(): + result = tutorial.getResponse('reviews/bladerunner-neutral.txt') + assert result['language'] == 'en' + assert (result['documentSentiment']['score'] > -1 and + result['documentSentiment']['score'] < 1) + assert (result['documentSentiment']['score'] < 1 and + result['documentSentiment']['score'] > -1) + assert (result['documentSentiment']['magnitude'] > 0 and + result['documentSentiment']['magnitude'] < 2.0) + + +def test_pos(): + result = tutorial.getResponse('reviews/bladerunner-pos.txt') + assert result['language'] == 'en' + assert result['documentSentiment']['score'] > 0.0 + assert result['documentSentiment']['magnitude'] > 2.0 + + +def test_neg(): + result = tutorial.getResponse('reviews/bladerunner-neg.txt') + assert result['language'] == 'en' + assert result['documentSentiment']['score'] < 0.0 + assert result['documentSentiment']['magnitude'] > 1.0 + + +def test_mixed(): + result = tutorial.getResponse('reviews/bladerunner-mixed.txt') + assert result['language'] == 'en' + assert (result['documentSentiment']['score'] > -1 + and result['documentSentiment']['score'] < 1) + assert (result['documentSentiment']['score'] < 1 + and result['documentSentiment']['score'] > -1) + assert result['documentSentiment']['magnitude'] > 4.0 From db5574e848133c38284fbb3c6b2161059c09ea6b Mon Sep 17 00:00:00 2001 From: Gus Class Date: Tue, 20 Dec 2016 09:38:41 -0800 Subject: [PATCH 2/7] Updates snippets to have region tags --- language/tutorial/tutorial.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/language/tutorial/tutorial.py b/language/tutorial/tutorial.py index 6e40c515671..706d530e4d5 100644 --- a/language/tutorial/tutorial.py +++ b/language/tutorial/tutorial.py @@ -13,26 +13,28 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# [START full_tutorial_script] +# [START import_libraries] import argparse - - from googleapiclient import discovery - - from oauth2client.client import GoogleCredentials +# [END import_libraries] def authenticate(): '''Authenticates the client library using default application credentials.''' + # [START authenticating_to_the_api] credentials = GoogleCredentials.get_application_default() service = discovery.build('language', 'v1', credentials=credentials) + # [END authenticating_to_the_api] return service def getResponse(filename): - '''Run sentiment analysis on text within a passed filename.''' + '''Runs sentiment analysis on text within the specified file.''' service = authenticate() + # [START constructing_the_request] with open(filename, 'r') as review_file: service_request = service.documents().analyzeSentiment( body={ @@ -43,11 +45,13 @@ def getResponse(filename): } ) response = service_request.execute() + # [END constructing_the_request] return response def printResponseContents(response): '''Prints document sentiment, magnitude, and sentence score.''' + # [START parsing_the_response] score = response['documentSentiment']['score'] magnitude = response['documentSentiment']['magnitude'] for i, sentence in enumerate(response['sentences']): @@ -56,8 +60,10 @@ def printResponseContents(response): sentence_sentiment)) print('Overall Sentiment: score of {} with magnitude of {}'.format( score, magnitude)) + # [END parsing_the_response] +# [START running_your_application] def main(filename): '''Run sentiment analysis on the file contents given a filename.''' printResponseContents(getResponse(filename)) @@ -71,3 +77,5 @@ def main(filename): help='The filename of the movie review you\'d like to analyze.') args = parser.parse_args() main(args.movie_review_filename) +# [END running_your_application] +# [END full_tutorial_script] From 17e15f89bdbf3945f0f7f8a150643d41b20bc4d0 Mon Sep 17 00:00:00 2001 From: Gus Class Date: Tue, 20 Dec 2016 09:44:11 -0800 Subject: [PATCH 3/7] fix for lint, newline after import --- language/tutorial/tutorial.py | 1 + 1 file changed, 1 insertion(+) diff --git a/language/tutorial/tutorial.py b/language/tutorial/tutorial.py index 706d530e4d5..2501e7360af 100644 --- a/language/tutorial/tutorial.py +++ b/language/tutorial/tutorial.py @@ -16,6 +16,7 @@ # [START full_tutorial_script] # [START import_libraries] import argparse + from googleapiclient import discovery from oauth2client.client import GoogleCredentials # [END import_libraries] From 24d441d9931d1b848b01aece83bcc03b79223a9d Mon Sep 17 00:00:00 2001 From: Gus Class Date: Tue, 20 Dec 2016 10:13:37 -0800 Subject: [PATCH 4/7] Addresses review feedback --- language/tutorial/tutorial.py | 24 +++++++++--------------- language/tutorial/tutorial_test.py | 21 +++++++-------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/language/tutorial/tutorial.py b/language/tutorial/tutorial.py index 2501e7360af..7683cef08ae 100644 --- a/language/tutorial/tutorial.py +++ b/language/tutorial/tutorial.py @@ -18,23 +18,17 @@ import argparse from googleapiclient import discovery + from oauth2client.client import GoogleCredentials # [END import_libraries] -def authenticate(): - '''Authenticates the client library using default application - credentials.''' +def get_response(filename): + """Runs sentiment analysis on text within the specified file.""" # [START authenticating_to_the_api] credentials = GoogleCredentials.get_application_default() service = discovery.build('language', 'v1', credentials=credentials) # [END authenticating_to_the_api] - return service - - -def getResponse(filename): - '''Runs sentiment analysis on text within the specified file.''' - service = authenticate() # [START constructing_the_request] with open(filename, 'r') as review_file: service_request = service.documents().analyzeSentiment( @@ -50,14 +44,14 @@ def getResponse(filename): return response -def printResponseContents(response): - '''Prints document sentiment, magnitude, and sentence score.''' +def print_response_contents(response): + """Prints document sentiment, magnitude, and sentence score.""" # [START parsing_the_response] score = response['documentSentiment']['score'] magnitude = response['documentSentiment']['magnitude'] - for i, sentence in enumerate(response['sentences']): + for n, sentence in enumerate(response['sentences']): sentence_sentiment = sentence['sentiment']['score'] - print('Sentence {} has a sentiment score of {}'.format(i, + print('Sentence {} has a sentiment score of {}'.format(n, sentence_sentiment)) print('Overall Sentiment: score of {} with magnitude of {}'.format( score, magnitude)) @@ -66,8 +60,8 @@ def printResponseContents(response): # [START running_your_application] def main(filename): - '''Run sentiment analysis on the file contents given a filename.''' - printResponseContents(getResponse(filename)) + """Run sentiment analysis on the file contents given a filename.""" + print_response_contents(get_response(filename)) return 0 diff --git a/language/tutorial/tutorial_test.py b/language/tutorial/tutorial_test.py index d7fe798f589..03366ee9b84 100644 --- a/language/tutorial/tutorial_test.py +++ b/language/tutorial/tutorial_test.py @@ -15,35 +15,28 @@ def test_neutral(): - result = tutorial.getResponse('reviews/bladerunner-neutral.txt') + result = tutorial.get_response('reviews/bladerunner-neutral.txt') assert result['language'] == 'en' - assert (result['documentSentiment']['score'] > -1 and - result['documentSentiment']['score'] < 1) - assert (result['documentSentiment']['score'] < 1 and - result['documentSentiment']['score'] > -1) - assert (result['documentSentiment']['magnitude'] > 0 and - result['documentSentiment']['magnitude'] < 2.0) + assert (-1 < result['documentSentiment']['score'] < 1) + assert (0 < result['documentSentiment']['magnitude'] < 2.0) def test_pos(): - result = tutorial.getResponse('reviews/bladerunner-pos.txt') + result = tutorial.get_response('reviews/bladerunner-pos.txt') assert result['language'] == 'en' assert result['documentSentiment']['score'] > 0.0 assert result['documentSentiment']['magnitude'] > 2.0 def test_neg(): - result = tutorial.getResponse('reviews/bladerunner-neg.txt') + result = tutorial.get_response('reviews/bladerunner-neg.txt') assert result['language'] == 'en' assert result['documentSentiment']['score'] < 0.0 assert result['documentSentiment']['magnitude'] > 1.0 def test_mixed(): - result = tutorial.getResponse('reviews/bladerunner-mixed.txt') + result = tutorial.get_response('reviews/bladerunner-mixed.txt') assert result['language'] == 'en' - assert (result['documentSentiment']['score'] > -1 - and result['documentSentiment']['score'] < 1) - assert (result['documentSentiment']['score'] < 1 - and result['documentSentiment']['score'] > -1) + assert (-1 < result['documentSentiment']['score'] < 1) assert result['documentSentiment']['magnitude'] > 4.0 From ef469242f0a3f840f01b62f03198d17ed1478aff Mon Sep 17 00:00:00 2001 From: Gus Class Date: Tue, 20 Dec 2016 13:38:41 -0800 Subject: [PATCH 5/7] Flattens tutorial code as suggested in review and updates tests accordingly --- language/tutorial/tutorial.py | 43 ++++++++---------- language/tutorial/tutorial_test.py | 70 +++++++++++++++++++----------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/language/tutorial/tutorial.py b/language/tutorial/tutorial.py index 7683cef08ae..b2ac2421a5b 100644 --- a/language/tutorial/tutorial.py +++ b/language/tutorial/tutorial.py @@ -16,61 +16,56 @@ # [START full_tutorial_script] # [START import_libraries] import argparse +import io from googleapiclient import discovery - from oauth2client.client import GoogleCredentials # [END import_libraries] -def get_response(filename): - """Runs sentiment analysis on text within the specified file.""" +def print_sentiment(filename): + """Prints sentiment analysis on a given file contents.""" # [START authenticating_to_the_api] credentials = GoogleCredentials.get_application_default() service = discovery.build('language', 'v1', credentials=credentials) # [END authenticating_to_the_api] + # [START constructing_the_request] - with open(filename, 'r') as review_file: - service_request = service.documents().analyzeSentiment( - body={ - 'document': { - 'type': 'PLAIN_TEXT', - 'content': review_file.read(), - } - } - ) - response = service_request.execute() - # [END constructing_the_request] - return response + with io.open(filename, 'r') as review_file: + review_file_contents = review_file.read() + service_request = service.documents().analyzeSentiment( + body={ + 'document': { + 'type': 'PLAIN_TEXT', + 'content': review_file_contents, + } + } + ) + response = service_request.execute() + # [END constructing_the_request] -def print_response_contents(response): - """Prints document sentiment, magnitude, and sentence score.""" # [START parsing_the_response] score = response['documentSentiment']['score'] magnitude = response['documentSentiment']['magnitude'] + for n, sentence in enumerate(response['sentences']): sentence_sentiment = sentence['sentiment']['score'] print('Sentence {} has a sentiment score of {}'.format(n, sentence_sentiment)) + print('Overall Sentiment: score of {} with magnitude of {}'.format( score, magnitude)) # [END parsing_the_response] # [START running_your_application] -def main(filename): - """Run sentiment analysis on the file contents given a filename.""" - print_response_contents(get_response(filename)) - return 0 - - if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument( 'movie_review_filename', help='The filename of the movie review you\'d like to analyze.') args = parser.parse_args() - main(args.movie_review_filename) + print_sentiment(args.movie_review_filename) # [END running_your_application] # [END full_tutorial_script] diff --git a/language/tutorial/tutorial_test.py b/language/tutorial/tutorial_test.py index 03366ee9b84..4ced50f414b 100644 --- a/language/tutorial/tutorial_test.py +++ b/language/tutorial/tutorial_test.py @@ -11,32 +11,50 @@ # See the License for the specific language governing permissions and # limitations under the License. -import tutorial - - -def test_neutral(): - result = tutorial.get_response('reviews/bladerunner-neutral.txt') - assert result['language'] == 'en' - assert (-1 < result['documentSentiment']['score'] < 1) - assert (0 < result['documentSentiment']['magnitude'] < 2.0) - +import re -def test_pos(): - result = tutorial.get_response('reviews/bladerunner-pos.txt') - assert result['language'] == 'en' - assert result['documentSentiment']['score'] > 0.0 - assert result['documentSentiment']['magnitude'] > 2.0 - - -def test_neg(): - result = tutorial.get_response('reviews/bladerunner-neg.txt') - assert result['language'] == 'en' - assert result['documentSentiment']['score'] < 0.0 - assert result['documentSentiment']['magnitude'] > 1.0 +import tutorial -def test_mixed(): - result = tutorial.get_response('reviews/bladerunner-mixed.txt') - assert result['language'] == 'en' - assert (-1 < result['documentSentiment']['score'] < 1) - assert result['documentSentiment']['magnitude'] > 4.0 +def test_neutral(capsys): + tutorial.print_sentiment('reviews/bladerunner-neutral.txt') + out, err = capsys.readouterr() + regex = re.compile('Sentence \d has a sentiment score of \d', re.I) + assert regex.search(out) is not None + regex = re.compile('Overall Sentiment: score of -?[0-2]\.?[0-9]? with ' + 'magnitude of [0-1]\.?[0-9]?', re.I) + assert regex.search(out) is not None + assert err == '' + + +def test_pos(capsys): + tutorial.print_sentiment('reviews/bladerunner-pos.txt') + out, err = capsys.readouterr() + regex = re.compile('Sentence \d has a sentiment score of \d', re.I) + assert regex.search(out) is not None + regex = re.compile('Overall Sentiment: score of [0-9]\.?[0-9]? with ' + 'magnitude of [0-9]\.?[0-9]?', re.I) + assert regex.search(out) is not None + assert err == '' + + +def test_neg(capsys): + tutorial.print_sentiment('reviews/bladerunner-neg.txt') + out, err = capsys.readouterr() + regex = re.compile('Sentence \d has a sentiment score of \d', re.I) + assert regex.search(out) is not None + regex = re.compile('Overall Sentiment: score of -[0-9]\.?[0-9]? with ' + 'magnitude of [2-7]\.?[0-9]?', re.I) + assert regex.search(out) is not None + assert err == '' + + +def test_mixed(capsys): + tutorial.print_sentiment('reviews/bladerunner-mixed.txt') + out, err = capsys.readouterr() + regex = re.compile('Sentence \d has a sentiment score of \d', re.I) + assert regex.search(out) is not None + regex = re.compile('Overall Sentiment: score of -?[0-9]\.?[0-9]? with ' + 'magnitude of [3-6]\.?[0-9]?', re.I) + assert regex.search(out) is not None + assert err == '' From a9ad263eb9348498524b81bd2002553cf86640ce Mon Sep 17 00:00:00 2001 From: Gus Class Date: Tue, 20 Dec 2016 13:41:35 -0800 Subject: [PATCH 6/7] Removes leading newline for consistency with tutorial.py --- language/tutorial/tutorial_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/language/tutorial/tutorial_test.py b/language/tutorial/tutorial_test.py index 4ced50f414b..dc7db573180 100644 --- a/language/tutorial/tutorial_test.py +++ b/language/tutorial/tutorial_test.py @@ -10,7 +10,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - import re import tutorial From 67a7a9cfd79e6cc118b488b3f40576d45feea108 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Tue, 20 Dec 2016 14:24:34 -0800 Subject: [PATCH 7/7] Tweak asserts --- language/tutorial/tutorial_test.py | 48 +++++++++++++----------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/language/tutorial/tutorial_test.py b/language/tutorial/tutorial_test.py index dc7db573180..065076fb4cc 100644 --- a/language/tutorial/tutorial_test.py +++ b/language/tutorial/tutorial_test.py @@ -17,43 +17,35 @@ def test_neutral(capsys): tutorial.print_sentiment('reviews/bladerunner-neutral.txt') - out, err = capsys.readouterr() - regex = re.compile('Sentence \d has a sentiment score of \d', re.I) - assert regex.search(out) is not None - regex = re.compile('Overall Sentiment: score of -?[0-2]\.?[0-9]? with ' - 'magnitude of [0-1]\.?[0-9]?', re.I) - assert regex.search(out) is not None - assert err == '' + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -?[0-2]\.?[0-9]? with ' + r'magnitude of [0-1]\.?[0-9]?', out, re.I) def test_pos(capsys): tutorial.print_sentiment('reviews/bladerunner-pos.txt') - out, err = capsys.readouterr() - regex = re.compile('Sentence \d has a sentiment score of \d', re.I) - assert regex.search(out) is not None - regex = re.compile('Overall Sentiment: score of [0-9]\.?[0-9]? with ' - 'magnitude of [0-9]\.?[0-9]?', re.I) - assert regex.search(out) is not None - assert err == '' + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of [0-9]\.?[0-9]? with ' + r'magnitude of [0-9]\.?[0-9]?', out, re.I) def test_neg(capsys): tutorial.print_sentiment('reviews/bladerunner-neg.txt') - out, err = capsys.readouterr() - regex = re.compile('Sentence \d has a sentiment score of \d', re.I) - assert regex.search(out) is not None - regex = re.compile('Overall Sentiment: score of -[0-9]\.?[0-9]? with ' - 'magnitude of [2-7]\.?[0-9]?', re.I) - assert regex.search(out) is not None - assert err == '' + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -[0-9]\.?[0-9]? with ' + r'magnitude of [2-7]\.?[0-9]?', out, re.I) def test_mixed(capsys): tutorial.print_sentiment('reviews/bladerunner-mixed.txt') - out, err = capsys.readouterr() - regex = re.compile('Sentence \d has a sentiment score of \d', re.I) - assert regex.search(out) is not None - regex = re.compile('Overall Sentiment: score of -?[0-9]\.?[0-9]? with ' - 'magnitude of [3-6]\.?[0-9]?', re.I) - assert regex.search(out) is not None - assert err == '' + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -?[0-9]\.?[0-9]? with ' + r'magnitude of [3-6]\.?[0-9]?', out, re.I)