Added style #14
This commit is contained in:
18
14-tabular/README.md
Normal file
18
14-tabular/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Style #14
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Constraints:
|
||||||
|
|
||||||
|
- The input data of the problem is modeled as entities and relations between them
|
||||||
|
|
||||||
|
- The data is placed in tables, with each row potentially cross-referencing rows in other tables
|
||||||
|
|
||||||
|
- Existence of a relational query engine
|
||||||
|
|
||||||
|
- The problem is solved by issuing queries over the tabular data
|
||||||
|
|
||||||
|
Possible names:
|
||||||
|
|
||||||
|
- Tabular
|
||||||
|
- Flatland
|
||||||
|
- Relational
|
||||||
89
14-tabular/tf-14.py
Normal file
89
14-tabular/tf-14.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import sys, re, string, sqlite3
|
||||||
|
|
||||||
|
#
|
||||||
|
# The relational database of this problem consists of 3 tables:
|
||||||
|
# documents, words, characters
|
||||||
|
#
|
||||||
|
def create_db_schema(connection):
|
||||||
|
c = connection.cursor()
|
||||||
|
c.execute('''CREATE TABLE documents (id INTEGER PRIMARY KEY AUTOINCREMENT, name)''')
|
||||||
|
c.execute('''CREATE TABLE words (id, doc_id, value)''')
|
||||||
|
c.execute('''CREATE TABLE characters (id, word_id, value)''')
|
||||||
|
connection.commit()
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
def load_file_into_database(path_to_file, connection):
|
||||||
|
""" Takes the path to a file and loads the contents into the database """
|
||||||
|
def _read_file(path_to_file):
|
||||||
|
"""
|
||||||
|
Takes a path to a file and returns the entire contents of the
|
||||||
|
file as a string
|
||||||
|
"""
|
||||||
|
f = open(path_to_file)
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _filter_chars_and_normalize(str_data):
|
||||||
|
"""
|
||||||
|
Takes a string and returns a copy with all nonalphanumeric chars
|
||||||
|
replaced by white space, and all characters lower-cased
|
||||||
|
"""
|
||||||
|
pattern = re.compile('[\W_]+')
|
||||||
|
return pattern.sub(' ', str_data).lower()
|
||||||
|
|
||||||
|
def _scan(str_data):
|
||||||
|
""" Takes a string and scans for words, returning a list of words. """
|
||||||
|
return str_data.split()
|
||||||
|
|
||||||
|
def _remove_stop_words(word_list):
|
||||||
|
f = open('../stop_words.txt')
|
||||||
|
stop_words = f.read().split(',')
|
||||||
|
f.close()
|
||||||
|
# add single-letter words
|
||||||
|
stop_words.extend(list(string.ascii_lowercase))
|
||||||
|
return [w for w in word_list if not w in stop_words]
|
||||||
|
|
||||||
|
# The actual work of splitting the input into words
|
||||||
|
words = _remove_stop_words(_scan(_filter_chars_and_normalize(_read_file(path_to_file))))
|
||||||
|
|
||||||
|
# Now let's add data to the database
|
||||||
|
# Add the document itself to the database
|
||||||
|
c = connection.cursor()
|
||||||
|
c.execute("INSERT INTO documents (name) VALUES (?)", (path_to_file,))
|
||||||
|
c.execute("SELECT id from documents WHERE name=?", (path_to_file,))
|
||||||
|
doc_id = c.fetchone()[0]
|
||||||
|
|
||||||
|
# Add the words to the database
|
||||||
|
c.execute("SELECT MAX(id) FROM words")
|
||||||
|
row = c.fetchone()
|
||||||
|
word_id = row[0]
|
||||||
|
if word_id == None:
|
||||||
|
word_id = 0
|
||||||
|
for w in words:
|
||||||
|
c.execute("INSERT INTO words VALUES (?, ?, ?)", (word_id, doc_id, w))
|
||||||
|
# Add the characters to the database
|
||||||
|
char_id = 0
|
||||||
|
for char in w:
|
||||||
|
c.execute("INSERT INTO characters VALUES (?, ?, ?)", (char_id, word_id, char))
|
||||||
|
char_id += 1
|
||||||
|
word_id += 1
|
||||||
|
connection.commit()
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
#
|
||||||
|
# The main function
|
||||||
|
#
|
||||||
|
connection = sqlite3.connect(':memory:')
|
||||||
|
create_db_schema(connection)
|
||||||
|
load_file_into_database(sys.argv[1], connection)
|
||||||
|
|
||||||
|
# Now, let's query
|
||||||
|
c = connection.cursor()
|
||||||
|
c.execute("SELECT value, COUNT(*) as C FROM words GROUP BY value ORDER BY C DESC")
|
||||||
|
for i in range(25):
|
||||||
|
row = c.fetchone()
|
||||||
|
if row != None:
|
||||||
|
print row[0] + ' - ' + str(row[1])
|
||||||
|
|
||||||
|
connection.close()
|
||||||
Reference in New Issue
Block a user