Skip to content

Instantly share code, notes, and snippets.

@ThatDevopsGuy
Last active December 15, 2015 18:59
Show Gist options
  • Save ThatDevopsGuy/5308058 to your computer and use it in GitHub Desktop.
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.
#!/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