Last active
April 22, 2022 06:33
-
-
Save mouse-reeve/20dfaea738814531ef21cade725e9af0 to your computer and use it in GitHub Desktop.
Fizzbuzz via answers.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' we're solving fizzbuzz with a little help from the web ''' | |
from html.parser import HTMLParser | |
from urllib.request import Request, urlopen | |
import re | |
import time | |
base_url = 'https://www.answers.com/Q/' | |
tag_name = 'div' | |
class_name = 'answer-body' | |
delimiter = '_' | |
class SearchParser(HTMLParser): | |
''' Parses search results from the web ''' | |
def __init__(self): | |
HTMLParser.__init__(self) | |
# track if the data we're encountering is part of an answer. we have | |
# to do this because there can be nested tags inside the answer tag | |
self.in_answer = False | |
# keep track of nested tags | |
self.tag_stack = [] | |
# a list of all the answers found | |
self.answers = [] | |
# words that indicate whether the answer is yes or no | |
self.positive_signs = [ | |
'yes', | |
'exactly', | |
'is divisible', | |
] | |
self.negative_signs = [ | |
'no', | |
'not', | |
'decimal', | |
] | |
def handle_starttag(self, tag, attrs): | |
''' identify the tag that we expect to contain the answer ''' | |
if tag == tag_name: | |
for attr in attrs: | |
if attr[0] == 'class' and class_name in attr[1]: | |
self.in_answer = True | |
self.answers.append('') | |
break | |
if self.in_answer: | |
self.tag_stack.append(tag) | |
def handle_endtag(self, tag): | |
''' behavior on encountering a close tag ''' | |
self.tag_stack = self.tag_stack[:-1] | |
# if the stack is empty, we're done with that answer | |
if self.in_answer and self.tag_stack == []: | |
self.in_answer = False | |
def handle_data(self, data): | |
''' extract the answer, if we're in an answer tag ''' | |
if self.in_answer: | |
self.answers[-1] += data | |
def conclude_yes_no(self): | |
''' looks through all the answer to conclude either true or false ''' | |
results = 0 | |
for answer in self.answers: | |
answer = answer.lower().strip() | |
results += self.score_answer(answer) | |
return results > 0 | |
def score_answer(self, answer): | |
''' evaluates an answer to determine if it's a yes or a no ''' | |
score = 0 | |
positive_signs = re.findall( | |
r'\b%s\b' % r'\b|\b'.join(self.positive_signs), | |
answer, | |
) | |
score += len(positive_signs) | |
negative_signs = re.findall( | |
r'\b%s\b' % r'\b|\b'.join(self.negative_signs), | |
answer | |
) | |
score -= len(negative_signs) | |
return score | |
def query_search_engine(numerator, denominator): | |
''' ask a search engine if these numbers are divisible ''' | |
question = 'is %d divisible by %d' % (numerator, denominator) | |
question = question.replace(' ', delimiter) | |
url = '%s%s' % (base_url, question) | |
request = Request(url) | |
request.add_header( | |
'User-Agent', | |
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) ' \ | |
'Gecko/20100101 Firefox/72.0') | |
response = urlopen(request) | |
# politeness -- wait a few seconds before the next query | |
time.sleep(3) | |
if url != response.url: | |
return False | |
text = response.read().decode('unicode-escape') | |
parser = SearchParser() | |
parser.feed(text) | |
return parser.conclude_yes_no() | |
if __name__ == '__main__': | |
divisors = [(3, 'fizz'), (5, 'buzz')] | |
for i in range(1, 101): | |
output = '' | |
for d in divisors: | |
if query_search_engine(i, d[0]): | |
output += d[1] | |
output = output or i | |
print(output) | |
# cool |
Salient and timely.
Waiitt a minute.... ._.
https://www.answers.com/Q/is_17_divisible_by_3
answers.com wouldn't lead us astray.
Wow. My world has changed
"There are four lights!" -Jean-Luc Picard
Star Trek The Next Generation, Season 10 Episodes 10 and 11: Chain of Command
https://en.wikipedia.org/wiki/Chain_of_Command_(Star_Trek:_The_Next_Generation)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This solution blows my mind.