Last active
December 15, 2015 18:59
-
-
Save ThatDevopsGuy/5308058 to your computer and use it in GitHub Desktop.
A 4-Pics-1-Word solver, which highlights adjectives for easier findings on harder puzzles.
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
#!/usr/bin/env python | |
# coding: utf-8 | |
''' | |
=============================================================================== | |
__ __ _ | |
\ \ / /__ _ __ __| |_ __ | |
\ \ /\ / / _ \| '__/ _` | '__| | |
\ V V / (_) | | | (_| | | | |
\_/\_/ \___/|_| \__,_|_| | |
A 4-Pics-1-Word Solver | |
=============================================================================== | |
Script: wordr.py | |
Author: Sebastian Weigand | |
Email: sab@sw-dd.com | |
Current: April, 2013 | |
Copyright: 2011-2013, Sebastian Weigand | |
License: BSD License | |
Description: A 4-Pics-1-Word Solver | |
Version: 1.0 Beta | |
Invocation: ./wordr.py <letters given> <# of letters in answer> | |
Ex: ./wordry.py dvrdwreadrco 4 | |
=============================================================================== | |
''' | |
from os import access, R_OK | |
from sys import stdout, stderr, argv | |
from urllib2 import urlopen, HTTPError | |
from xml.dom.minidom import parseString | |
if len(argv) < 3: | |
print >> stderr, "Need 2 arguments: <letters given> and <# of letters>" | |
exit(1) | |
# ============================================================================= | |
# Check for our rather large adjectives list: | |
# ============================================================================= | |
if not access('adjectives.txt', R_OK): | |
print >> stderr, "You don't seem to have a list of adjectives, let me fetch one." | |
print >> stderr, "(this will only happen once, just don't delete the file)" | |
# Store the number of adjectives we've fetched thus far: | |
counter = 0 | |
# Use stdout methods for an improved CLI experience: | |
stdout.write('Downloading a list of adjectives from Wiktionary...'.ljust(80)) | |
stdout.flush() | |
# Use Mediawiki's API to fetch a list of all English adjectives: | |
baseWikiAPIURL = 'http://en.wiktionary.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:English_adjectives&cmlimit=500&format=xml' | |
try: | |
results = urlopen(baseWikiAPIURL).read() | |
except HTTPError: | |
print >> stderr, "Wiktionary's API doesn't seem to be working right now." | |
print >> stderr, "Let's try this later, as we need this list to work." | |
exit(2) # 1 is for user cancel | |
# We're limited to 500 entries per call, so loop through until we're done: | |
while True: | |
# Parse the XML: | |
dom = parseString(results) | |
# Let's save this file, as it's nice to have for later (note the 'a'): | |
with open('adjectives.txt', 'a') as f: | |
# Fetch the correct element with the correct attributes (see API doc): | |
## Ensure encoding is UTF-8, as we'll get some funky characters: | |
### Make lowercase: | |
adjectives = [elem.getAttribute('title').encode('utf-8').lower() for elem in dom.getElementsByTagName('cm') if elem.getAttribute('ns') == '0'] | |
counter += len(adjectives) | |
f.write('\n'.join(adjectives)) | |
# Overwrite the terminal buffer and keep things nice-and-purty: | |
stdout.write('\b' * 10) | |
stdout.write(str(counter).rjust(10)) | |
stdout.flush() | |
# Check and see if there's more to fetch (it will always be the last | |
# categorymember element): | |
if dom.getElementsByTagName('categorymembers')[0].hasAttribute('cmcontinue'): | |
nextLocation = dom.getElementsByTagName('categorymembers')[0].getAttribute('cmcontinue') | |
results = urlopen(baseWikiAPIURL + '&cmcontinue=' + nextLocation).read() | |
# We're done! | |
else: | |
print '\n\tDownloaded adjective list.' | |
break | |
if not access('/usr/share/dict/words', R_OK): | |
print >> stderr, "You do not appear to have a dictionary installed. If you're on Ubuntu, try: `sudo apt-get install wamerican-insane`" | |
exit(1) | |
# ============================================================================= | |
# Process the fun: | |
# ============================================================================= | |
with open('/usr/share/dict/words') as f: | |
words = f.read().splitlines() | |
with open('adjectives.txt') as f: | |
adjectives = f.read().splitlines() | |
letters = list(argv[1]) | |
length = int(argv[2]) | |
# Do some housekeeping: | |
words = [word.lower() for word in words if len(word) == length and ' ' not in word and '-' not in word] | |
results = [] | |
# Set intersections don't work with duplicated letters, | |
# but there's probably a better way of doing this: | |
for word in words: | |
new_letters = letters[:] | |
good = True | |
for letter in word: | |
if letter in new_letters: | |
new_letters.remove(letter) | |
else: | |
good = False | |
break | |
if good: | |
results.append(word) | |
results = sorted(set(results)) | |
adj_results = sorted(set(adjectives).intersection(results)) | |
# ============================================================================= | |
# Print the results: | |
# ============================================================================= | |
print 'There are %s adjective results:' % len(adj_results) | |
print '-' * 80 | |
print '\n'.join(adj_results) | |
print '' | |
print 'Here are the other %s results:' % len(results) | |
print '-' * 80 | |
print '\n'.join(results) | |
print '' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment