Last active
July 25, 2019 23:11
-
-
Save kevinpostal/db8b2fbc95c828c94f3cd94e34d81d6e to your computer and use it in GitHub Desktop.
Telesign
This file contains hidden or 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
from flask import Flask, request, g, jsonify | |
from flask_restful import Resource, Api | |
from util import parse_json_body | |
import sqlite3 | |
import os | |
# Flask | |
app = Flask(__name__) | |
app.config.update( | |
dict(DATABASE=os.path.join(app.root_path, 'database.db'), DEBUG=True)) | |
api = Api(app) | |
# SQL RELATED | |
def connect_db(): | |
rv = sqlite3.connect(app.config['DATABASE']) | |
rv.row_factory = sqlite3.Row | |
return rv | |
def get_db(): | |
if not hasattr(g, 'sqlite_db'): | |
g.sqlite_db = connect_db() | |
return g.sqlite_db | |
@app.teardown_appcontext | |
def close_db(error): | |
if hasattr(g, 'sqlite_db'): | |
g.sqlite_db.close() | |
# END SQL RELATED | |
# API | |
class ApiResource(Resource): | |
def query_db(self, query, args=(), one=False): | |
cur = get_db().execute(query, args) | |
rv = cur.fetchall() | |
return (rv[0] if rv else None) if one else rv | |
class PalindromeCountView(ApiResource): | |
def get(self): | |
result = self.query_db( | |
"select count(*) from words where is_palindrome is 1", one=True) | |
return jsonify(result[0]) | |
class AnagramsCountView(ApiResource): | |
def get(self): | |
result = self.query_db( | |
'SELECT count(*) FROM words GROUP BY alphagram HAVING count(alphagram) > 1', | |
) | |
return jsonify(len(result)) | |
class AnagramsSingleView(ApiResource): | |
def get(self, word): | |
alphagram = "".join(sorted(list(word))) | |
results = self.query_db('SELECT word FROM words WHERE alphagram = ?', | |
[alphagram]) | |
return jsonify( | |
[item['word'] for item in results if item['word'] != word]) | |
class WordsCountView(ApiResource): | |
def get(self): | |
result = self.query_db("SELECT count(*) FROM words", one=True) | |
return jsonify(result[0]) | |
class WordsDeleteView(ApiResource): | |
def delete(self, word): | |
cur = get_db() | |
cur.execute('DELETE FROM words WHERE word = "%s"' % word) | |
cur.commit() | |
return | |
class WordsView(ApiResource): | |
def __db_insert(self, fields=(), values=()): | |
cur = get_db() | |
query = 'INSERT OR IGNORE INTO words (%s) VALUES (%s)' % ( | |
', '.join(fields), ', '.join(['?'] * len(values))) | |
cur.execute(query, values) | |
cur.commit() | |
return | |
def post(self): | |
post_body = request.get_json() | |
for item in parse_json_body(list_of_words=post_body): | |
self.__db_insert(("word", "alphagram", "is_palindrome"), | |
(item.get("text"), item.get("alphagram"), | |
item.get("is_palindrome"))) | |
def delete(self): | |
cur = get_db() | |
cur.execute("Delete From words") | |
cur.commit() | |
# End API | |
api.add_resource(WordsView, '/words') | |
api.add_resource(WordsCountView, '/words/count') | |
api.add_resource(WordsDeleteView, '/words/<string:word>') | |
api.add_resource(PalindromeCountView, '/palindromes/count') | |
api.add_resource(AnagramsCountView, '/anagrams/count') | |
api.add_resource(AnagramsSingleView, '/anagrams/<string:word>') | |
if __name__ == '__main__': | |
app.run(debug=True) |
This file contains hidden or 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
Telesign Take Home Task | |
======================= | |
Warm up | |
------- | |
Define a function to check if two words are a [palindrome](https://en.wikipedia.org/wiki/Palindrome). | |
Define a function to check if two words are an [anagram](https://en.wikipedia.org/wiki/Anagram). | |
The Task | |
-------- | |
Build a RESTful web service API that allows clients to perform queries against a body of text - such as | |
[Alice in Wonderland](http://www.gutenberg.org/files/11/11-0.txt). TIP: your solution may be tested against an excerpt | |
or the full text. | |
You should design the service to support many HTTP clients. This will be a popular service, therefore performance, | |
availability and scalability are important considerations in your approach and overall design. | |
Your RESTful web service should accept JSON content as the request body. It should also return JSON content as responses where | |
applicable. You should also return appropriate HTTP status codes according to RESTful best practices. | |
IMPORTANT: The body of text can change through the addition and removal of arbitrary words, changes must be persisted. | |
You may use any available libraries, OSS and/or systems to support your service. | |
Please provide documentation that is useful for clients and developers maintaining the solution. This should include | |
design considerations, tradeoffs and justifications. Identify any weaknesses in your implementation and/or future | |
enhancements that could be made. | |
For this exercise, you may ignore punctuation, abbreviation and categorization of real words vs nouns, | |
pronouns, verbs etc. You should also only consider single whole words when evaluating anagrams or palindromes - no | |
sentences. | |
You must support the following RESTful operations: | |
POST /words | |
example POST body: ["cat", "act", "bat", "eye"] | |
accept a JSON array of arbitrary words and add them to the existing data store, if a word already exists it is a no op | |
GET /words/count | |
return a count of total unique words in the data store | |
GET /palindromes/count | |
return a count of total palindromes in the data store | |
GET /anagrams/count | |
return a count of total anagrams in the data store (words with at least one other anagram) | |
GET /anagrams/<word> | |
return an array of words that are anagrams of the word queried | |
DELETE /words/<word> | |
delete the specified word from the data store | |
DELETE /words | |
delete all the words in the data store | |
Solution | |
-------- | |
Please provide a link to a private Github or Bitbucket repository with your solution or provide it in a zip file. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To Run
(in a new terminal/window...)
POST /words
GET /words/count
GET /palindromes/count
GET /anagrams/count
GET /anagrams/
DELETE /words/
DELETE /words
Design considerations
Suggestions
- Perhaps only match up nouns.