Skip to content

Commit

Permalink
Merge pull request #1 from prosegrinder/init
Browse files Browse the repository at this point in the history
Initial package release.
  • Loading branch information
davidlday authored Mar 18, 2018
2 parents cf18495 + eadb618 commit b07d043
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 2 deletions.
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# http://editorconfig.org

root = true

[*]
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
charset = utf-8

# Docstrings and comments use max_line_length = 79
[*.py]
indent_size = 4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
Expand Down
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Config file for automatic testing at travis-ci.org

language: python

python:
- "pypy3"
- "pypy"
- "3.6"
- "3.5"
- "3.4"
- "2.7"

# Use container-based infrastructure
sudo: false

# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install:
- pip install -U pip
- pip install -U pytest

# command to run tests, e.g. python setup.py test
script:
- python ./setup.py develop
- pytest tests/*

after_script:
- pip install pycodestyle pyflakes
- pyflakes . | tee >(wc -l) # static analysis
- pycodestyle --statistics --count . # static analysis
8 changes: 8 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include MANIFEST.in
include README.rst
include LICENSE
graft pointofview
graft tests
global-exclude .git
global-exclude __pycache__
global-exclude *.py[co] .DS_Store
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

65 changes: 65 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pointofview
===========

.. image:: https://img.shields.io/pypi/v/pointofview.svg
:target: https://pypi.python.org/pypi/pointofview
:alt: Latest PyPI version

.. image:: https://travis-ci.org/prosegrinder/python-pointofview.svg?branch=master
:target: https://travis-ci.org/prosegrinder/python-pointofview
:alt: Latest Travis CI build status

.. image:: https://api.codacy.com/project/badge/Grade/df0afcc70ffc4a86a8777588567820c0
:target: https://www.codacy.com/app/ProseGrinder/python-pointofview?utm_source=github.com&utm_medium=referral&utm_content=prosegrinder/python-pointofview&utm_campaign=Badge_Grade
:alt: Latest Codacy Coverage Report

A Python package for determining a piece of text's point of view (first, second, third, or unknown).

Installation
------------

``pointofview`` is available on PyPI. Simply install it with ``pip``::

$ pip install pointofview

You can also install it from source::

$ git clone https://github.com/prosegrinder/python-pointofview.git
Cloning into 'python-pointofview'...
...

$ cd python-pointofview
$ python setup.py install
...

Usage
-----

``pointofview`` guesses a text's point of view by counting point of view pronouns. The main function ``get_pov()`` will return 'first', 'second', 'third', or null (Python's ``None`` object)::

>>> import pointofview
>>> text = "I'm a piece of text written in first person! What are you?"
>>> pointofview.get_pov(text)
'first'

There are two other helper functions as well.

``get_word_pov()`` returns the point of view of a single word::

>>> pointofview.get_word_pov("I")
'first'
>>> pointofview.get_word_pov("nope")
None

``parse_pov_words`` returns a dict containing all first, second, and third person pov words::

>>> text = """
... When I try to analyze my own cravings, motives, actions and so forth, I surrender to a sort of retrospective imagination which feeds the analytic faculty with boundless alternatives and which causes each visualized route to fork and re-fork without end in the maddeningly complex prospect of my past.
... """
>>> pointofview.parse_pov_words(text)
{'first': ['i', 'i'], 'second': [], 'third': []}

Authors
-------

`pointofview` was written by `David L. Day <[email protected]>`_.
1 change: 1 addition & 0 deletions pointofview/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
63 changes: 63 additions & 0 deletions pointofview/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-

"""pointofview - A Python package for determining a piece of text's point of view (first, second, third, or unknown)."""

import re

import pkg_resources

__version__ = pkg_resources.resource_string(
'pointofview', 'VERSION').decode('utf-8').strip()

POV_WORDS = {
'first':
["i", "i'm", "i'll", "i'd", "i've", "me", "mine", "myself", "we",
"we're", "we'll", "we'd", "we've", "us", "ours", "ourselves"],
'second':
["you", "you're", "you'll", "you'd", "you've",
"your", "yours", "yourself", "yourselves"],
'third':
["he", "he's", "he'll", "he'd", "him", "his", "himself", "she", "she's",
"she'll", "she'd", "her", "hers", "herself", "it", "it's", "it'll",
"it'd", "itself", "they", "they're", "they'll", "they'd", "they've",
"them", "their", "theirs", "themselves"]
}

RE_WORDS = re.compile(r"[^\w’']+")


def _normalize_word(word):
return word.strip().lower().replace("’", "'")


def get_word_pov(word):
for pov in POV_WORDS:
if _normalize_word(word) in POV_WORDS[pov]:
return pov
return None


def parse_pov_words(text):
pov_words = {
'first': [],
'second': [],
'third': [],
}
words = re.split(RE_WORDS, text.strip().lower())
for word in words:
pov = get_word_pov(word)
if pov != None:
pov_words[pov].append(word)
return pov_words


def get_pov(text):
pov_words = parse_pov_words(text)
if len(pov_words['first']) > 0:
return 'first'
elif len(pov_words['second']) > 0:
return 'second'
elif len(pov_words['third']) > 0:
return 'third'
else:
return None
5 changes: 5 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[bdist_wheel]
universal = 1

[metadata]
license_file = LICENSE
48 changes: 48 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-

from os import path

from setuptools import setup

# Version
with open(path.join(path.dirname(__file__), 'pointofview', 'VERSION')) as version_file:
VERSION = version_file.read().strip()
# Long Description
with open(path.join(path.dirname(__file__), 'README.rst')) as readme_file:
LONG_DESCRIPTION = readme_file.read()


setup(
name="pointofview",
version=VERSION,
url="https://github.com/prosegrinder/python-pointofview",

author="David L. Day",
author_email="[email protected]",

description="A Python package for determining a piece of text's point of view (first, second, third, or unknown).",
long_description=LONG_DESCRIPTION,

packages=[
'pointofview'
],
package_dir={'pointofview': 'pointofview'},
package_data={
'': ['LICENSE', '*.rst', 'MANIFEST.in'],
},
include_package_data=True,

classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
'Natural Language :: English',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
)
Empty file added tests/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions tests/test_pointofview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-

import pointofview

POV_FIRST_SINGULAR="""
When I try to analyze my own cravings, motives, actions and so forth, I surrender to a sort of retrospective imagination which feeds the analytic faculty with boundless alternatives and which causes each visualized route to fork and re-fork without end in the maddeningly complex prospect of my past.
"""
# Lolita by Vladimir Nabakov

POV_FIRST_PLURAL="""
Most of us on the boat were accomplished, and were sure we would make good wives. We knew how to cook and sew. We knew how to serve tea and arrange flowers and sit quietly on our flat wide feet for hours, saying absolutely nothing of substance at all.
"""
# The Buddha in the Attic by Julie Otsuka

POV_SECOND="""
You are not the kind of guy who would be at a place like this at this time of the morning. But here you are, and you cannot say that the terrain is entirely unfamiliar, although the details are fuzzy.
"""
# Bright Lights, Big City by Jay Mclnemey

POV_SECOND="""
While standing in his parents kitchen, you tell your boyfriend you’re leaving. You’re not going to college. You’re not buying into the schedules, the credits, or the points. No standardized success for you.
"""

POV_THIRD="""
The family of Dashwood had long been settled in Sussex. Their estate was large, and their residence was at Norland Park, in the centre of their property, where, for many generations, they had lived in so respectable a manner as to engage the general good opinion of their surrounding acquaintance.
"""
# Sense and Sensibility by Jane Austen

POV_NONE="""
Due to pytest‘s detailed assertion introspection, only plain assert statements are used. See Getting Started for more examples.
"""
# https://docs.pytest.org/en/latest/index.html

def test_first():
assert(pointofview.get_pov(POV_FIRST_SINGULAR) == 'first') # nosec
assert(pointofview.get_pov(POV_FIRST_PLURAL) == 'first') # nosec

def test_second():
assert(pointofview.get_pov(POV_SECOND) == 'second') # nosec

def test_third():
assert(pointofview.get_pov(POV_THIRD) == 'third') # nosec

def test_none():
assert(pointofview.get_pov(POV_NONE) == None) # nosec
6 changes: 6 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[tox]
envlist=py27,py34,py35

[testenv]
commands=py.test pointofview
deps=pytest

0 comments on commit b07d043

Please sign in to comment.