Spaces:
Runtime error
Runtime error
iamspruce
commited on
Commit
·
71192d1
1
Parent(s):
f24a55f
updated fastapi
Browse files- .dockerignore +25 -0
- Dockerfile +8 -23
- app/core/app.py +31 -0
- app/core/config.py +9 -0
- app/core/logging.py +8 -0
- app/core/middleware.py +21 -0
- app/core/prompts.py +30 -0
- app/core/security.py +8 -22
- app/data/en/ablist.yml +697 -0
- app/data/en/condescending.yml +50 -0
- app/data/en/gender.yml +1808 -0
- app/data/en/lgbtq.yml +206 -0
- app/data/en/misc.yml +19 -0
- app/data/en/press.yml +20 -0
- app/data/en/race.yml +370 -0
- app/data/en/slogans.yml +9 -0
- app/data/en/suicide.yml +51 -0
- app/main.py +4 -47
- app/models.py +0 -108
- app/prompts.py +0 -121
- app/routers/conciseness.py +0 -42
- app/routers/grammar.py +52 -53
- app/routers/inclusive_language.py +8 -39
- app/routers/paraphrase.py +9 -36
- app/routers/punctuation.py +0 -67
- app/routers/readability.py +24 -46
- app/routers/rewrite.py +18 -0
- app/routers/sentence_correctness.py +0 -62
- app/routers/summarize.py +0 -39
- app/routers/tone.py +8 -53
- app/routers/translate.py +12 -38
- app/routers/vocabulary.py +0 -42
- app/routers/voice.py +8 -69
- app/schemas/base.py +13 -0
- app/services/__init__.py +0 -0
- app/services/base.py +42 -0
- app/services/conciseness_suggestion.py +30 -0
- app/services/gpt4_rewrite.py +44 -0
- app/services/grammar.py +32 -0
- app/services/inclusive_language.py +98 -0
- app/services/paraphrase.py +39 -0
- app/services/tone_classification.py +36 -0
- app/services/translation.py +40 -0
- app/services/vocabulary_enhancement.py +30 -0
- app/services/voice_detection.py +33 -0
- app/test/test_rewrite.py +15 -0
- app/test_main.py +0 -39
- app/utils/shared.py +4 -0
- requirements.txt +1 -1
- run.py +15 -0
.dockerignore
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Python specific files and directories
|
2 |
+
*.pyc
|
3 |
+
*.pyo
|
4 |
+
__pycache__/
|
5 |
+
.pytest_cache/
|
6 |
+
.mypy_cache/
|
7 |
+
.venv/
|
8 |
+
venv/
|
9 |
+
env/
|
10 |
+
|
11 |
+
# Editor/IDE specific files
|
12 |
+
.vscode/
|
13 |
+
.idea/
|
14 |
+
*.sublime-project
|
15 |
+
*.sublime-workspace
|
16 |
+
|
17 |
+
# Common build/distribution files
|
18 |
+
dist/
|
19 |
+
build/
|
20 |
+
*.egg-info/
|
21 |
+
.DS_Store
|
22 |
+
|
23 |
+
# Git specific files
|
24 |
+
.git/
|
25 |
+
.gitignore
|
Dockerfile
CHANGED
@@ -1,43 +1,28 @@
|
|
1 |
FROM python:3.10-slim
|
2 |
|
3 |
-
# Set working directory inside the container
|
4 |
WORKDIR /app
|
5 |
|
6 |
# Install system dependencies
|
7 |
-
|
8 |
-
|
9 |
-
RUN apt-get update && apt-get install -y git default-jre && rm -rf /var/lib/apt/lists/*
|
10 |
|
11 |
-
# Install Python dependencies from requirements.txt
|
12 |
-
# Ensure requirements.txt is copied before installing to leverage Docker cache
|
13 |
COPY requirements.txt .
|
14 |
RUN pip install --no-cache-dir -r requirements.txt
|
15 |
|
16 |
-
|
17 |
-
# This is crucial for resolving the "[E050] Can't find model 'en_core_web_sm'" error
|
18 |
RUN python -m spacy download en_core_web_sm
|
19 |
|
20 |
-
|
21 |
-
# This directory will also be used by language-tool-python for its main downloads.
|
22 |
ENV HF_HOME=/cache
|
23 |
RUN mkdir -p /cache && chmod -R 777 /cache
|
24 |
|
25 |
-
# ... other Dockerfile content ...
|
26 |
-
ENV GRAMMAFREE_API_KEY="admin"
|
27 |
|
28 |
-
# Explicitly create and set permissions for /.cache
|
29 |
-
# This is to address PermissionError: [Errno 13] Permission denied: '/.cache'
|
30 |
-
# which language-tool-python might be trying to write to.
|
31 |
RUN mkdir -p /.cache && chmod -R 777 /.cache
|
32 |
|
33 |
-
# Set environment variable for language-tool-python download directory
|
34 |
-
# This redirects LanguageTool's primary downloads to the shared /cache directory.
|
35 |
-
ENV LANGUAGE_TOOL_DOWNLOAD_DIR=/cache
|
36 |
|
37 |
-
# Copy the entire application code into the container
|
38 |
-
# This copies your 'app' directory, including main.py, routers, models, etc.
|
39 |
COPY app ./app
|
40 |
|
41 |
-
#
|
42 |
-
|
43 |
-
|
|
|
|
1 |
FROM python:3.10-slim
|
2 |
|
|
|
3 |
WORKDIR /app
|
4 |
|
5 |
# Install system dependencies
|
6 |
+
RUN apt-get update && apt-get install -y git && \
|
7 |
+
rm -rf /var/lib/apt/lists/*
|
|
|
8 |
|
|
|
|
|
9 |
COPY requirements.txt .
|
10 |
RUN pip install --no-cache-dir -r requirements.txt
|
11 |
|
12 |
+
|
|
|
13 |
RUN python -m spacy download en_core_web_sm
|
14 |
|
15 |
+
|
|
|
16 |
ENV HF_HOME=/cache
|
17 |
RUN mkdir -p /cache && chmod -R 777 /cache
|
18 |
|
|
|
|
|
19 |
|
|
|
|
|
|
|
20 |
RUN mkdir -p /.cache && chmod -R 777 /.cache
|
21 |
|
|
|
|
|
|
|
22 |
|
|
|
|
|
23 |
COPY app ./app
|
24 |
|
25 |
+
# Expose the port your FastAPI application will run on
|
26 |
+
EXPOSE 7860
|
27 |
+
|
28 |
+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
|
app/core/app.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from fastapi.middleware.gzip import GZipMiddleware
|
3 |
+
from app.routers import (
|
4 |
+
grammar,
|
5 |
+
tone,
|
6 |
+
voice,
|
7 |
+
inclusive_language,
|
8 |
+
readability,
|
9 |
+
paraphrase,
|
10 |
+
translate,
|
11 |
+
rewrite,
|
12 |
+
)
|
13 |
+
|
14 |
+
def create_app() -> FastAPI:
|
15 |
+
app = FastAPI()
|
16 |
+
app.add_middleware(GZipMiddleware, minimum_size=500)
|
17 |
+
|
18 |
+
app.include_router(grammar.router)
|
19 |
+
app.include_router(tone.router)
|
20 |
+
app.include_router(voice.router)
|
21 |
+
app.include_router(inclusive_language.router)
|
22 |
+
app.include_router(readability.router)
|
23 |
+
app.include_router(paraphrase.router)
|
24 |
+
app.include_router(translate.router)
|
25 |
+
app.include_router(rewrite.router)
|
26 |
+
|
27 |
+
@app.get("/")
|
28 |
+
def root():
|
29 |
+
return {"message": "Welcome to Grammafree API"}
|
30 |
+
|
31 |
+
return app
|
app/core/config.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic_settings import BaseSettings
|
2 |
+
|
3 |
+
class Settings(BaseSettings):
|
4 |
+
inclusive_rules_dir: str = "app/data/en"
|
5 |
+
openai_model: str = "gpt-4o"
|
6 |
+
openai_temperature: float = 0.7
|
7 |
+
openai_max_tokens: int = 512
|
8 |
+
|
9 |
+
settings = Settings()
|
app/core/logging.py
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# core/logging.py
|
2 |
+
import logging
|
3 |
+
|
4 |
+
def configure_logging():
|
5 |
+
logging.basicConfig(
|
6 |
+
level=logging.INFO,
|
7 |
+
format="%(asctime)s - %(levelname)s - %(message)s"
|
8 |
+
)
|
app/core/middleware.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, Request
|
2 |
+
from fastapi.responses import JSONResponse
|
3 |
+
from slowapi import Limiter
|
4 |
+
from slowapi.util import get_remote_address
|
5 |
+
from slowapi.errors import RateLimitExceeded
|
6 |
+
import logging
|
7 |
+
|
8 |
+
limiter = Limiter(key_func=get_remote_address)
|
9 |
+
|
10 |
+
def setup_middlewares(app: FastAPI):
|
11 |
+
@app.exception_handler(Exception)
|
12 |
+
async def unhandled_exception_handler(request: Request, exc: Exception):
|
13 |
+
logging.exception("Unhandled exception")
|
14 |
+
return JSONResponse(status_code=500, content={"detail": "Internal server error"})
|
15 |
+
|
16 |
+
@app.exception_handler(RateLimitExceeded)
|
17 |
+
async def rate_limit_exceeded_handler(request: Request, exc: RateLimitExceeded):
|
18 |
+
return JSONResponse(status_code=429, content={"detail": "Rate limit exceeded"})
|
19 |
+
|
20 |
+
limiter.init_app(app)
|
21 |
+
app.state.limiter = limiter
|
app/core/prompts.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def tone_prompt(text: str, tone: str) -> str:
|
2 |
+
return f"Change the tone of this sentence to {tone}: {text.strip()}"
|
3 |
+
|
4 |
+
def summarize_prompt(text: str) -> str:
|
5 |
+
return f"Summarize the following text:\n{text.strip()}"
|
6 |
+
|
7 |
+
def clarity_prompt(text: str) -> str:
|
8 |
+
return f"Improve the clarity of the following sentence:\n{text.strip()}"
|
9 |
+
|
10 |
+
def conciseness_prompt(text: str) -> str:
|
11 |
+
return f"Make the following sentence more concise:\n{text.strip()}"
|
12 |
+
|
13 |
+
def rewrite_prompt(text: str, instruction: str) -> str:
|
14 |
+
return f"{instruction.strip()}\n{text.strip()}"
|
15 |
+
|
16 |
+
def vocabulary_prompt(text: str) -> str:
|
17 |
+
return (
|
18 |
+
"You are an expert vocabulary enhancer. Rewrite the following text "
|
19 |
+
"by replacing common and simple words with more sophisticated, "
|
20 |
+
"precise, and contextually appropriate synonyms. Do not change "
|
21 |
+
"the original meaning. Maintain the tone.\n" + text.strip()
|
22 |
+
)
|
23 |
+
|
24 |
+
def concise_prompt(text: str) -> str:
|
25 |
+
return (
|
26 |
+
"You are an expert editor specializing in conciseness. "
|
27 |
+
"Rewrite the following text to be more concise and to the point, "
|
28 |
+
"removing any verbose phrases, redundant words, or unnecessary clauses. "
|
29 |
+
"Maintain the original meaning and professional tone.\n" + text.strip()
|
30 |
+
)
|
app/core/security.py
CHANGED
@@ -1,25 +1,11 @@
|
|
1 |
-
from fastapi import Header, HTTPException
|
2 |
import os
|
|
|
3 |
|
4 |
-
|
5 |
-
# In a production environment, this should be a more robust and securely managed key.
|
6 |
-
# Load API_KEY from an environment variable for security.
|
7 |
-
# Fallback to a default for local development if not set, but warn about it.
|
8 |
-
API_KEY = os.getenv("GRAMMAFREE_API_KEY", "12345") # Use a strong default for production!
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
Args:
|
18 |
-
x_api_key (str): The API key expected in the 'X-API-Key' header.
|
19 |
-
|
20 |
-
Raises:
|
21 |
-
HTTPException: If the provided API key does not match the expected API_KEY.
|
22 |
-
"""
|
23 |
-
if x_api_key != API_KEY:
|
24 |
-
# Raise an HTTPException with 401 Unauthorized status if the key is invalid.
|
25 |
-
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
|
|
|
1 |
import os
|
2 |
+
from fastapi import Header, HTTPException, status, Depends
|
3 |
|
4 |
+
API_KEY = os.getenv("GRAMMAFREE_API_KEY", "12345")
|
|
|
|
|
|
|
|
|
5 |
|
6 |
+
def verify_api_key(x_api_key: str = Header(...)) -> None:
|
7 |
+
if not x_api_key or x_api_key != API_KEY:
|
8 |
+
raise HTTPException(
|
9 |
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
10 |
+
detail="Invalid or missing API key"
|
11 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/data/en/ablist.yml
ADDED
@@ -0,0 +1,697 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
note: Refer to the person, rather than the disability, first.
|
3 |
+
considerate: person with learning disabilities
|
4 |
+
inconsiderate: learning disabled
|
5 |
+
- type: basic
|
6 |
+
note: Refer to the person, rather than the disability, first.
|
7 |
+
considerate:
|
8 |
+
- turned off
|
9 |
+
- has a disability
|
10 |
+
- person with a disability
|
11 |
+
- people with disabilities
|
12 |
+
inconsiderate:
|
13 |
+
- disabled
|
14 |
+
- invalid
|
15 |
+
- type: basic
|
16 |
+
source: https://ncdj.org/style-guide/
|
17 |
+
note: Assumes/implies that a person with a disability is deficient or inferior to others. When possible, specify the functional ability or its restriction.
|
18 |
+
considerate:
|
19 |
+
- has a disability
|
20 |
+
- person with a disability
|
21 |
+
- people with disabilities
|
22 |
+
inconsiderate:
|
23 |
+
- birth defect
|
24 |
+
- type: basic
|
25 |
+
source: https://ncdj.org/style-guide/
|
26 |
+
note: Assumes that a person with a disability has a reduced quality of life.
|
27 |
+
considerate:
|
28 |
+
- has a disability
|
29 |
+
- person with a disability
|
30 |
+
- people with disabilities
|
31 |
+
inconsiderate:
|
32 |
+
- suffers from disabilities
|
33 |
+
- suffering from disabilities
|
34 |
+
- suffering from a disability
|
35 |
+
- afflicted with disabilities
|
36 |
+
- afflicted with a disability
|
37 |
+
- type: basic
|
38 |
+
source: https://ncdj.org/style-guide/
|
39 |
+
note: Refer to the person, rather than the disability, first.
|
40 |
+
considerate:
|
41 |
+
- people with intellectual disabilities
|
42 |
+
inconsiderate:
|
43 |
+
- intellectually disabled people
|
44 |
+
- type: basic
|
45 |
+
source: https://ncdj.org/style-guide/
|
46 |
+
note: Assumes that a person with an intellectual disability has a reduced quality of life.
|
47 |
+
considerate:
|
48 |
+
- person with an intellectual disability
|
49 |
+
inconsiderate:
|
50 |
+
- intellectually disabled
|
51 |
+
- has intellectual issues
|
52 |
+
- suffers from intellectual disabilities
|
53 |
+
- suffering from intellectual disabilities
|
54 |
+
- suffering from an intellectual disability
|
55 |
+
- afflicted with intellectual disabilities
|
56 |
+
- afflicted with a intellectual disability
|
57 |
+
- type: basic
|
58 |
+
source: https://ncdj.org/style-guide/
|
59 |
+
note: Describe the behavior or illness without derogatory words.
|
60 |
+
considerate:
|
61 |
+
- rude
|
62 |
+
- malicious
|
63 |
+
- mean
|
64 |
+
- disgusting
|
65 |
+
- incredible
|
66 |
+
- vile
|
67 |
+
- person with symptoms of mental illness
|
68 |
+
- person with mental illness
|
69 |
+
- person with symptoms of a mental disorder
|
70 |
+
- person with a mental disorder
|
71 |
+
inconsiderate:
|
72 |
+
- batshit
|
73 |
+
- psycho
|
74 |
+
- crazy
|
75 |
+
- delirious
|
76 |
+
- insane
|
77 |
+
- insanity
|
78 |
+
- loony
|
79 |
+
- lunacy
|
80 |
+
- lunatic
|
81 |
+
- mentally ill
|
82 |
+
- psychopathology
|
83 |
+
- mental defective
|
84 |
+
- moron
|
85 |
+
- moronic
|
86 |
+
- nuts
|
87 |
+
- mental case
|
88 |
+
- mental
|
89 |
+
- type: basic
|
90 |
+
note: Describe the behavior or illness without derogatory words.
|
91 |
+
considerate:
|
92 |
+
- incredibly
|
93 |
+
inconsiderate:
|
94 |
+
- insanely
|
95 |
+
- type: basic
|
96 |
+
note: When describing a mathematical or programmatic value, using the word “sane” needlessly invokes the topic of mental health. Consider using a domain-specific or neutral term instead.
|
97 |
+
considerate:
|
98 |
+
- correct
|
99 |
+
- adequate
|
100 |
+
- sufficient
|
101 |
+
- consistent
|
102 |
+
- valid
|
103 |
+
- coherent
|
104 |
+
- sensible
|
105 |
+
- reasonable
|
106 |
+
inconsiderate: sane
|
107 |
+
- type: basic
|
108 |
+
note: When describing a mathematical or programmatic value, using the phrase “sanity check” needlessly invokes the topic of mental health. Consider using simply “check”, or a domain-specific or neutral term, instead.
|
109 |
+
considerate:
|
110 |
+
- check
|
111 |
+
- assertion
|
112 |
+
- validation
|
113 |
+
- smoke test
|
114 |
+
inconsiderate: sanity check
|
115 |
+
- type: basic
|
116 |
+
source: https://ncdj.org/style-guide/
|
117 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
118 |
+
considerate:
|
119 |
+
- fluctuating
|
120 |
+
- person with bipolar disorder
|
121 |
+
inconsiderate:
|
122 |
+
- bipolar
|
123 |
+
- type: basic
|
124 |
+
source: https://ncdj.org/style-guide/
|
125 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
126 |
+
considerate:
|
127 |
+
- person with schizophrenia
|
128 |
+
inconsiderate:
|
129 |
+
- schizophrenic
|
130 |
+
- schizo
|
131 |
+
- type: basic
|
132 |
+
source: https://ncdj.org/style-guide/
|
133 |
+
note: Assumes a person with schizophrenia experiences a reduced quality of life.
|
134 |
+
considerate:
|
135 |
+
- person with schizophrenia
|
136 |
+
inconsiderate:
|
137 |
+
- suffers from schizophrenia
|
138 |
+
- suffering from schizophrenia
|
139 |
+
- afflicted with schizophrenia
|
140 |
+
- manic
|
141 |
+
- type: basic
|
142 |
+
source: https://ncdj.org/style-guide/
|
143 |
+
considerate: accessible parking
|
144 |
+
inconsiderate: handicapped parking
|
145 |
+
- type: basic
|
146 |
+
source: https://ncdj.org/style-guide/
|
147 |
+
note: Refer to the person, rather than the disability, first.
|
148 |
+
considerate:
|
149 |
+
- person with a handicap
|
150 |
+
- accessible
|
151 |
+
inconsiderate: handicapped
|
152 |
+
- type: basic
|
153 |
+
source: https://ncdj.org/style-guide/
|
154 |
+
note: Refer to the person, rather than the condition, first.
|
155 |
+
considerate: person with an amputation
|
156 |
+
inconsiderate: amputee
|
157 |
+
- type: basic
|
158 |
+
note: Refer to the specific disability.
|
159 |
+
considerate: person with a limp
|
160 |
+
inconsiderate:
|
161 |
+
- cripple
|
162 |
+
- crippled
|
163 |
+
- gimp
|
164 |
+
- type: basic
|
165 |
+
considerate: person with Down Syndrome
|
166 |
+
inconsiderate: mongoloid
|
167 |
+
- type: basic
|
168 |
+
note: Refer to the person, rather than the condition, first.
|
169 |
+
considerate: individual who has had a stroke
|
170 |
+
inconsiderate:
|
171 |
+
- stroke victim
|
172 |
+
- suffering from a stroke
|
173 |
+
- victim of a stroke
|
174 |
+
- type: basic
|
175 |
+
considerate: person who has multiple sclerosis
|
176 |
+
inconsiderate:
|
177 |
+
- suffers from multiple sclerosis
|
178 |
+
- suffering from multiple sclerosis
|
179 |
+
- victim of multiple sclerosis
|
180 |
+
- multiple sclerosis victim
|
181 |
+
- afflicted with multiple sclerosis
|
182 |
+
- type: basic
|
183 |
+
source: https://ncdj.org/style-guide
|
184 |
+
note: Refer to a person's condition as a state, not as an affliction.
|
185 |
+
considerate: person who has muscular dystrophy
|
186 |
+
inconsiderate:
|
187 |
+
- suffers from muscular dystrophy
|
188 |
+
- afflicted with muscular dystrophy
|
189 |
+
- suffers from MD
|
190 |
+
- afflicted with MD
|
191 |
+
- type: basic
|
192 |
+
considerate: with family support needs
|
193 |
+
inconsiderate: family burden
|
194 |
+
- type: basic
|
195 |
+
considerate:
|
196 |
+
- psychiatric hospital
|
197 |
+
- mental health hospital
|
198 |
+
inconsiderate:
|
199 |
+
- asylum
|
200 |
+
- type: basic
|
201 |
+
considerate:
|
202 |
+
- chaos
|
203 |
+
- hectic
|
204 |
+
- pandemonium
|
205 |
+
inconsiderate:
|
206 |
+
- bedlam
|
207 |
+
- madhouse
|
208 |
+
- loony bin
|
209 |
+
- type: basic
|
210 |
+
source: https://media.specialolympics.org/soi/files/press-kit/2014_FactSheet_Final.pdf
|
211 |
+
considerate:
|
212 |
+
- Down Syndrome
|
213 |
+
inconsiderate:
|
214 |
+
- downs syndrome
|
215 |
+
- type: basic
|
216 |
+
considerate:
|
217 |
+
- silly
|
218 |
+
- dullard
|
219 |
+
- person with Down Syndrome
|
220 |
+
- person with developmental disabilities
|
221 |
+
- delay
|
222 |
+
- hold back
|
223 |
+
inconsiderate:
|
224 |
+
- retard
|
225 |
+
- retarded
|
226 |
+
- short bus
|
227 |
+
- type: basic
|
228 |
+
considerate:
|
229 |
+
- sillies
|
230 |
+
- dullards
|
231 |
+
- people with developmental disabilities
|
232 |
+
- people with Down’s Syndrome
|
233 |
+
- delays
|
234 |
+
- holds back
|
235 |
+
inconsiderate: retards
|
236 |
+
- type: basic
|
237 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
238 |
+
considerate:
|
239 |
+
- person with a psychotic condition
|
240 |
+
- person with psychosis
|
241 |
+
inconsiderate:
|
242 |
+
- psychotic
|
243 |
+
- suffers from psychosis
|
244 |
+
- suffering from psychosis
|
245 |
+
- afflicted with psychosis
|
246 |
+
- victim of psychosis
|
247 |
+
- type: basic
|
248 |
+
source: https://ncdj.org/style-guide/
|
249 |
+
considerate:
|
250 |
+
- boring
|
251 |
+
- dull
|
252 |
+
inconsiderate: lame
|
253 |
+
- type: basic
|
254 |
+
considerate:
|
255 |
+
- person with AIDS
|
256 |
+
inconsiderate:
|
257 |
+
- suffering from aids
|
258 |
+
- suffer from aids
|
259 |
+
- suffers from aids
|
260 |
+
- afflicted with aids
|
261 |
+
- victim of aids
|
262 |
+
- aids victim
|
263 |
+
- type: basic
|
264 |
+
considerate:
|
265 |
+
- uses a wheelchair
|
266 |
+
inconsiderate:
|
267 |
+
- confined to a wheelchair
|
268 |
+
- bound to a wheelchair
|
269 |
+
- restricted to a wheelchair
|
270 |
+
- wheelchair bound
|
271 |
+
- type: basic
|
272 |
+
source: https://media.specialolympics.org/soi/files/press-kit/2014_FactSheet_Final.pdf
|
273 |
+
note: When possible, use the exact discipline of sport.
|
274 |
+
considerate:
|
275 |
+
- athletes
|
276 |
+
- Special Olympics athletes
|
277 |
+
inconsiderate:
|
278 |
+
- special olympians
|
279 |
+
- special olympic athletes
|
280 |
+
- type: basic
|
281 |
+
source: https://ncdj.org/style-guide/
|
282 |
+
note: Can imply that people with disabilities lack the ability to use their bodies well. Sometimes `typical` can be used.
|
283 |
+
considerate:
|
284 |
+
- non-disabled
|
285 |
+
inconsiderate:
|
286 |
+
- ablebodied
|
287 |
+
- type: basic
|
288 |
+
source: https://ncdj.org/style-guide/
|
289 |
+
note: Addiction is a neurobiological disease.
|
290 |
+
considerate:
|
291 |
+
- person with a drug addiction
|
292 |
+
- person recovering from a drug addiction
|
293 |
+
inconsiderate:
|
294 |
+
- addict
|
295 |
+
- junkie
|
296 |
+
- type: basic
|
297 |
+
source: https://ncdj.org/style-guide/
|
298 |
+
note: Addiction is a neurobiological disease.
|
299 |
+
considerate:
|
300 |
+
- people with a drug addiction
|
301 |
+
- people recovering from a drug addiction
|
302 |
+
inconsiderate:
|
303 |
+
- addicts
|
304 |
+
- junkies
|
305 |
+
- type: basic
|
306 |
+
source: https://ncdj.org/style-guide/
|
307 |
+
note: Alcoholism is a neurobiological disease.
|
308 |
+
considerate:
|
309 |
+
- someone with an alcohol problem
|
310 |
+
inconsiderate:
|
311 |
+
- alcoholic
|
312 |
+
- alcohol abuser
|
313 |
+
- type: basic
|
314 |
+
source: https://ncdj.org/style-guide/
|
315 |
+
considerate:
|
316 |
+
- deaf
|
317 |
+
inconsiderate:
|
318 |
+
- deaf and dumb
|
319 |
+
- deafmute
|
320 |
+
- type: basic
|
321 |
+
source: https://ncdj.org/style-guide/
|
322 |
+
considerate:
|
323 |
+
- person with dementia
|
324 |
+
inconsiderate:
|
325 |
+
- demented
|
326 |
+
- senile
|
327 |
+
- type: basic
|
328 |
+
source: https://ncdj.org/style-guide/
|
329 |
+
considerate:
|
330 |
+
- sad
|
331 |
+
- blue
|
332 |
+
- bummed out
|
333 |
+
- person with seasonal affective disorder
|
334 |
+
- person with psychotic depression
|
335 |
+
- person with postpartum depression
|
336 |
+
inconsiderate:
|
337 |
+
- depressed
|
338 |
+
- type: basic
|
339 |
+
source:
|
340 |
+
- https://ncdj.org/style-guide/
|
341 |
+
- https://www.lpaonline.org/faq-#Midget
|
342 |
+
considerate:
|
343 |
+
- person with dwarfism
|
344 |
+
- little person
|
345 |
+
- little people
|
346 |
+
- LP
|
347 |
+
- person of short stature
|
348 |
+
inconsiderate:
|
349 |
+
- vertically challenged
|
350 |
+
- midget
|
351 |
+
- small person
|
352 |
+
- dwarf
|
353 |
+
- type: basic
|
354 |
+
source: https://ncdj.org/style-guide/
|
355 |
+
considerate:
|
356 |
+
- person with dyslexia
|
357 |
+
inconsiderate:
|
358 |
+
- dyslexic
|
359 |
+
- type: basic
|
360 |
+
source: https://ncdj.org/style-guide/
|
361 |
+
considerate:
|
362 |
+
- person with epilepsy
|
363 |
+
inconsiderate:
|
364 |
+
- epileptic
|
365 |
+
- type: basic
|
366 |
+
source: https://ncdj.org/style-guide/
|
367 |
+
note: When possible, ask the person what they prefer.
|
368 |
+
considerate:
|
369 |
+
- hard of hearing
|
370 |
+
- partially deaf
|
371 |
+
- partial hearing loss
|
372 |
+
- deaf
|
373 |
+
inconsiderate:
|
374 |
+
- hearing impaired
|
375 |
+
- hearing impairment
|
376 |
+
- type: basic
|
377 |
+
source: https://ncdj.org/style-guide/
|
378 |
+
considerate:
|
379 |
+
- polio
|
380 |
+
- person who had polio
|
381 |
+
inconsiderate:
|
382 |
+
- infantile paralysis
|
383 |
+
- suffers from polio
|
384 |
+
- suffering from polio
|
385 |
+
- suffering from a polio
|
386 |
+
- afflicted with polio
|
387 |
+
- afflicted with a polio
|
388 |
+
- victim of polio
|
389 |
+
- type: basic
|
390 |
+
source: https://ncdj.org/style-guide/
|
391 |
+
considerate:
|
392 |
+
- sustain an injury
|
393 |
+
- receive an injury
|
394 |
+
inconsiderate:
|
395 |
+
- suffer from an injury
|
396 |
+
- suffers from an injury
|
397 |
+
- suffering from an injury
|
398 |
+
- afflicted with an injury
|
399 |
+
- victim of an injury
|
400 |
+
- type: basic
|
401 |
+
source: https://ncdj.org/style-guide/
|
402 |
+
considerate:
|
403 |
+
- sustain injuries
|
404 |
+
- receive injuries
|
405 |
+
inconsiderate:
|
406 |
+
- suffer from injuries
|
407 |
+
- suffers from injuries
|
408 |
+
- suffering from injuries
|
409 |
+
- afflicted with injuries
|
410 |
+
- victim of injuries
|
411 |
+
- type: basic
|
412 |
+
source: https://ncdj.org/style-guide/
|
413 |
+
considerate:
|
414 |
+
- person with paraplegia
|
415 |
+
inconsiderate:
|
416 |
+
- paraplegic
|
417 |
+
- type: basic
|
418 |
+
source: https://ncdj.org/style-guide/
|
419 |
+
considerate:
|
420 |
+
- person with quadriplegia
|
421 |
+
inconsiderate:
|
422 |
+
- quadriplegic
|
423 |
+
- type: basic
|
424 |
+
source: https://ncdj.org/style-guide/
|
425 |
+
considerate:
|
426 |
+
- person with cerebral palsy
|
427 |
+
- twitch
|
428 |
+
- flinch
|
429 |
+
- hectic
|
430 |
+
inconsiderate:
|
431 |
+
- spaz
|
432 |
+
- type: basic
|
433 |
+
source: https://ncdj.org/style-guide/
|
434 |
+
considerate:
|
435 |
+
- person with cerebral palsy
|
436 |
+
- twitch
|
437 |
+
- flinch
|
438 |
+
inconsiderate:
|
439 |
+
- spastic
|
440 |
+
- type: basic
|
441 |
+
source: https://ncdj.org/style-guide/
|
442 |
+
considerate:
|
443 |
+
- stuttering
|
444 |
+
- disfluency of speech
|
445 |
+
inconsiderate:
|
446 |
+
- stammering
|
447 |
+
- type: basic
|
448 |
+
source: https://ncdj.org/style-guide/
|
449 |
+
considerate:
|
450 |
+
- person who stutters
|
451 |
+
inconsiderate:
|
452 |
+
- stutterer
|
453 |
+
- type: basic
|
454 |
+
source: https://ncdj.org/style-guide/
|
455 |
+
considerate:
|
456 |
+
- Tourette syndrome
|
457 |
+
inconsiderate:
|
458 |
+
- tourettes syndrome
|
459 |
+
- tourettes disorder
|
460 |
+
- type: basic
|
461 |
+
source: https://ncdj.org/style-guide/
|
462 |
+
considerate:
|
463 |
+
- treatment center
|
464 |
+
inconsiderate:
|
465 |
+
- rehab center
|
466 |
+
- detox center
|
467 |
+
- type: basic
|
468 |
+
source: https://ncdj.org/style-guide/
|
469 |
+
considerate:
|
470 |
+
- treatment
|
471 |
+
inconsiderate:
|
472 |
+
- rehab
|
473 |
+
- detox
|
474 |
+
- type: basic
|
475 |
+
source: https://ncdj.org/style-guide/
|
476 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
477 |
+
considerate:
|
478 |
+
- person with a personality disorder
|
479 |
+
- person with psychopathic personality
|
480 |
+
inconsiderate:
|
481 |
+
- sociopath
|
482 |
+
- type: basic
|
483 |
+
source: https://ncdj.org/style-guide/
|
484 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
485 |
+
considerate:
|
486 |
+
- people with psychopathic personalities
|
487 |
+
- people with a personality disorder
|
488 |
+
inconsiderate:
|
489 |
+
- sociopaths
|
490 |
+
- type: basic
|
491 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
492 |
+
note: Dumb here is used in 2 different contexts , the inability to talk or as a curse word.
|
493 |
+
considerate:
|
494 |
+
- foolish
|
495 |
+
- ludicrous
|
496 |
+
- speechless
|
497 |
+
- silent
|
498 |
+
inconsiderate:
|
499 |
+
- dumb
|
500 |
+
- type: basic
|
501 |
+
source: https://web.archive.org/web/20181025174508/http://www.mmonjejr.com:80/2014/02/deconstructing-stupid.html
|
502 |
+
considerate:
|
503 |
+
- foolish
|
504 |
+
- ludicrous
|
505 |
+
- unintelligent
|
506 |
+
inconsiderate:
|
507 |
+
- simpleton
|
508 |
+
- stupid
|
509 |
+
- wacko
|
510 |
+
- whacko
|
511 |
+
- low iq
|
512 |
+
- type: basic
|
513 |
+
considerate:
|
514 |
+
- fit of terror
|
515 |
+
- scare
|
516 |
+
inconsiderate:
|
517 |
+
- panic attack
|
518 |
+
- type: basic
|
519 |
+
considerate:
|
520 |
+
- thin
|
521 |
+
- slim
|
522 |
+
inconsiderate:
|
523 |
+
- anorexic
|
524 |
+
- bony
|
525 |
+
- type: basic
|
526 |
+
source: https://english.stackexchange.com/questions/247550/
|
527 |
+
note: Only use terms describing mental illness when referring to a professionally diagnosed medical condition.
|
528 |
+
considerate:
|
529 |
+
- has an anxiety disorder
|
530 |
+
- obsessive
|
531 |
+
- pedantic
|
532 |
+
- niggly
|
533 |
+
- picky
|
534 |
+
inconsiderate:
|
535 |
+
- neurotic
|
536 |
+
- ocd
|
537 |
+
- o.c.d
|
538 |
+
- o.c.d.
|
539 |
+
- type: basic
|
540 |
+
considerate:
|
541 |
+
- restlessness
|
542 |
+
- sleeplessness
|
543 |
+
inconsiderate:
|
544 |
+
- insomnia
|
545 |
+
- type: basic
|
546 |
+
considerate:
|
547 |
+
- person who has insomnia
|
548 |
+
inconsiderate:
|
549 |
+
- insomniac
|
550 |
+
- type: basic
|
551 |
+
considerate:
|
552 |
+
- people who have insomnia
|
553 |
+
inconsiderate:
|
554 |
+
- insomniacs
|
555 |
+
- type: basic
|
556 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
557 |
+
considerate:
|
558 |
+
- empty
|
559 |
+
- sterile
|
560 |
+
- infertile
|
561 |
+
inconsiderate:
|
562 |
+
- barren
|
563 |
+
- type: basic
|
564 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
565 |
+
considerate:
|
566 |
+
- careless
|
567 |
+
- heartless
|
568 |
+
- indifferent
|
569 |
+
- insensitive
|
570 |
+
inconsiderate:
|
571 |
+
- blind to
|
572 |
+
- blind eye to
|
573 |
+
- blinded by
|
574 |
+
- deaf to
|
575 |
+
- deaf ear to
|
576 |
+
- deafened by
|
577 |
+
- type: basic
|
578 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
579 |
+
considerate:
|
580 |
+
- creep
|
581 |
+
- fool
|
582 |
+
inconsiderate:
|
583 |
+
- cretin
|
584 |
+
- type: basic
|
585 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
586 |
+
considerate:
|
587 |
+
- absurd
|
588 |
+
- foolish
|
589 |
+
inconsiderate:
|
590 |
+
- daft
|
591 |
+
- type: basic
|
592 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
593 |
+
considerate:
|
594 |
+
- foolish
|
595 |
+
- ludicrous
|
596 |
+
- silly
|
597 |
+
inconsiderate:
|
598 |
+
- feebleminded
|
599 |
+
- feeble minded
|
600 |
+
- idiot
|
601 |
+
- imbecile
|
602 |
+
- type: basic
|
603 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
604 |
+
note: Sometimes it's cleft lip or palate, not both. Specify when possible.
|
605 |
+
considerate:
|
606 |
+
- person with a cleft-lip and palate
|
607 |
+
inconsiderate:
|
608 |
+
- harelipped
|
609 |
+
- cleftlipped
|
610 |
+
- type: basic
|
611 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
612 |
+
considerate:
|
613 |
+
- cleft-lip and palate
|
614 |
+
inconsiderate:
|
615 |
+
- harelip
|
616 |
+
- hare lip
|
617 |
+
- type: basic
|
618 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
619 |
+
considerate:
|
620 |
+
- fanatic
|
621 |
+
- zealot
|
622 |
+
- enthusiast
|
623 |
+
inconsiderate:
|
624 |
+
- maniac
|
625 |
+
- type: basic
|
626 |
+
considerate:
|
627 |
+
- person with prominent teeth
|
628 |
+
- prominent teeth
|
629 |
+
inconsiderate:
|
630 |
+
- bucktoothed
|
631 |
+
- buckteeth
|
632 |
+
- type: basic
|
633 |
+
source:
|
634 |
+
- http://cdrnys.org/blog/disability-dialogue/the-disability-dialogue-4-disability-euphemisms-that-need-to-bite-the-dust/
|
635 |
+
- https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
636 |
+
note: Euphemisms for disabilities can be infantilizing.
|
637 |
+
considerate:
|
638 |
+
- has a disability
|
639 |
+
- person with a disability
|
640 |
+
- people with disabilities
|
641 |
+
inconsiderate:
|
642 |
+
- challenged
|
643 |
+
- diffability
|
644 |
+
- differently abled
|
645 |
+
- handicapable
|
646 |
+
- special
|
647 |
+
- special needs
|
648 |
+
- specially abled
|
649 |
+
- type: basic
|
650 |
+
source: https://www.autistichoya.com/p/ableist-words-and-terms-to-avoid.html
|
651 |
+
considerate:
|
652 |
+
- disagreeable
|
653 |
+
- uneducated
|
654 |
+
- ignorant
|
655 |
+
- naive
|
656 |
+
- inconsiderate
|
657 |
+
inconsiderate:
|
658 |
+
- fucktard
|
659 |
+
- libtard
|
660 |
+
- contard
|
661 |
+
- type: basic
|
662 |
+
considerate:
|
663 |
+
- disorganized
|
664 |
+
- distracted
|
665 |
+
- energetic
|
666 |
+
- hyperactive
|
667 |
+
- impetuous
|
668 |
+
- impulsive
|
669 |
+
- inattentive
|
670 |
+
- restless
|
671 |
+
- unfocused
|
672 |
+
inconsiderate:
|
673 |
+
# Upper case to only match `ADD`, not `add`.
|
674 |
+
- ADD
|
675 |
+
- adhd
|
676 |
+
- a.d.d.
|
677 |
+
- a.d.h.d.
|
678 |
+
- type: basic
|
679 |
+
note: Dummy can refer to the inability to talk or be used as a derogatory word meaning stupid. In computer programming it is used where a value or behavior is unimportant. There are better alternatives for other use cases also.
|
680 |
+
considerate:
|
681 |
+
- test double
|
682 |
+
- placeholder
|
683 |
+
- fake
|
684 |
+
- stub
|
685 |
+
inconsiderate:
|
686 |
+
- dummyvariable
|
687 |
+
- dummyvalue
|
688 |
+
- dummyobject
|
689 |
+
- dummy
|
690 |
+
- type: basic
|
691 |
+
note: Binge might be insensitive towards folks with eating or drinking disorders
|
692 |
+
source: https://github.com/retextjs/retext-equality/issues/110
|
693 |
+
considerate:
|
694 |
+
- enthusiastic
|
695 |
+
- spree
|
696 |
+
inconsiderate:
|
697 |
+
- binge
|
app/data/en/condescending.yml
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# List of words to avoid, specifically in education writing.
|
2 |
+
# From: https://css-tricks.com/words-avoid-educational-writing/
|
3 |
+
# The terms `however` and `so` are not included as they’re only an offense if at
|
4 |
+
# the start of a sentence according to CSS Tricks.
|
5 |
+
# If you want messages for those, use `retext-intensify`.
|
6 |
+
- type: basic
|
7 |
+
inconsiderate:
|
8 |
+
- obvious
|
9 |
+
- obviously
|
10 |
+
note: Not everything is as obvious as you might think. And if it isn’t obvious to the reader, it can hurt.
|
11 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
12 |
+
- type: basic
|
13 |
+
inconsiderate: just
|
14 |
+
note: Not everything is as easy as you might think. And if it isn’t easy for the reader, it can hurt.
|
15 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
16 |
+
- type: basic
|
17 |
+
inconsiderate: basically
|
18 |
+
note: It’s probably not that basic. If you’re going to explain a confusing previous sentence with a clearer next sentence, why not drop the former and only use the latter?
|
19 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
20 |
+
- type: basic
|
21 |
+
inconsiderate:
|
22 |
+
- simple
|
23 |
+
- simply
|
24 |
+
note: It’s probably not that simple. Even if it is, you probably don’t need to specifically say it.
|
25 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
26 |
+
- type: basic
|
27 |
+
inconsiderate:
|
28 |
+
- easy
|
29 |
+
- easily
|
30 |
+
note: It’s probably not that easy. Even if it is, you probably don’t need to specifically say it.
|
31 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
32 |
+
- type: basic
|
33 |
+
inconsiderate: of course
|
34 |
+
note: If it’s self-evident then maybe you don’t need to describe it. If it isn’t, don’t say it.
|
35 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
36 |
+
- type: basic
|
37 |
+
inconsiderate: clearly
|
38 |
+
note: If it’s self-evident then maybe you don’t need to describe it. If it isn’t, don’t say it.
|
39 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
40 |
+
- type: basic
|
41 |
+
inconsiderate: everyone knows
|
42 |
+
note: If it’s self-evident then maybe you don’t need to describe it. If it isn’t, don’t say it.
|
43 |
+
source: https://css-tricks.com/words-avoid-educational-writing/
|
44 |
+
- type: basic
|
45 |
+
inconsiderate:
|
46 |
+
- straight forward
|
47 |
+
- straightforward
|
48 |
+
- straight forwardly
|
49 |
+
- straightforwardly
|
50 |
+
note: It’s probably not that straight forward. Even if it is, you probably don’t need to specifically say it.
|
app/data/en/gender.yml
ADDED
@@ -0,0 +1,1808 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: or
|
2 |
+
condition: when referring to a person
|
3 |
+
considerate:
|
4 |
+
- their
|
5 |
+
- theirs
|
6 |
+
- them
|
7 |
+
inconsiderate:
|
8 |
+
her: female
|
9 |
+
hers: female
|
10 |
+
him: male
|
11 |
+
his: male
|
12 |
+
- type: or
|
13 |
+
apostrophe: true
|
14 |
+
considerate:
|
15 |
+
- they
|
16 |
+
- it
|
17 |
+
inconsiderate:
|
18 |
+
she: female
|
19 |
+
he: male
|
20 |
+
she'd: female
|
21 |
+
he'd: male
|
22 |
+
she'll: female
|
23 |
+
he'll: male
|
24 |
+
she's: female
|
25 |
+
he's: male
|
26 |
+
- type: or
|
27 |
+
considerate:
|
28 |
+
- themselves
|
29 |
+
- theirself
|
30 |
+
- self
|
31 |
+
inconsiderate:
|
32 |
+
herself: female
|
33 |
+
himself: male
|
34 |
+
- type: or
|
35 |
+
condition: when referring to a person
|
36 |
+
considerate:
|
37 |
+
- kid
|
38 |
+
- child
|
39 |
+
- youth
|
40 |
+
inconsiderate:
|
41 |
+
girl: female
|
42 |
+
boy: male
|
43 |
+
- type: or
|
44 |
+
considerate:
|
45 |
+
- people
|
46 |
+
- persons
|
47 |
+
- folks
|
48 |
+
inconsiderate:
|
49 |
+
women: female
|
50 |
+
girls: female
|
51 |
+
gals: female
|
52 |
+
ladies: female
|
53 |
+
man: male
|
54 |
+
boys: male
|
55 |
+
men: male
|
56 |
+
guys: male
|
57 |
+
dudes: male
|
58 |
+
gents: male
|
59 |
+
gentlemen: male
|
60 |
+
- type: or
|
61 |
+
considerate:
|
62 |
+
- person
|
63 |
+
- friend
|
64 |
+
- pal
|
65 |
+
- folk
|
66 |
+
- individual
|
67 |
+
inconsiderate:
|
68 |
+
woman: female
|
69 |
+
gal: female
|
70 |
+
lady: female
|
71 |
+
babe: female
|
72 |
+
bimbo: female
|
73 |
+
chick: female
|
74 |
+
guy: male
|
75 |
+
lad: male
|
76 |
+
fellow: male
|
77 |
+
dude: male
|
78 |
+
bro: male
|
79 |
+
gentleman: male
|
80 |
+
- type: or
|
81 |
+
considerate:
|
82 |
+
- native land
|
83 |
+
- homeland
|
84 |
+
inconsiderate:
|
85 |
+
motherland: female
|
86 |
+
fatherland: male
|
87 |
+
- type: or
|
88 |
+
considerate:
|
89 |
+
- native tongue
|
90 |
+
- native language
|
91 |
+
inconsiderate:
|
92 |
+
mother tongue: female
|
93 |
+
father tongue: male
|
94 |
+
- type: or
|
95 |
+
considerate:
|
96 |
+
- first-year students
|
97 |
+
- freshers
|
98 |
+
inconsiderate:
|
99 |
+
freshwomen: female
|
100 |
+
freshmen: male
|
101 |
+
- type: or
|
102 |
+
considerate:
|
103 |
+
- garbage collector
|
104 |
+
- waste collector
|
105 |
+
- trash collector
|
106 |
+
inconsiderate:
|
107 |
+
garbagewoman: female
|
108 |
+
garbageman: male
|
109 |
+
- type: or
|
110 |
+
considerate:
|
111 |
+
- garbage collectors
|
112 |
+
- waste collectors
|
113 |
+
- trash collectors
|
114 |
+
inconsiderate:
|
115 |
+
garbagewomen: female
|
116 |
+
garbagemen: male
|
117 |
+
- type: or
|
118 |
+
considerate:
|
119 |
+
- chair
|
120 |
+
- head
|
121 |
+
- chairperson
|
122 |
+
- coordinator
|
123 |
+
- committee head
|
124 |
+
- moderator
|
125 |
+
- presiding officer
|
126 |
+
inconsiderate:
|
127 |
+
chairwoman: female
|
128 |
+
chairman: male
|
129 |
+
- type: or
|
130 |
+
considerate:
|
131 |
+
- committee member
|
132 |
+
inconsiderate:
|
133 |
+
committee woman: female
|
134 |
+
committee man: male
|
135 |
+
- type: or
|
136 |
+
considerate:
|
137 |
+
- cowhand
|
138 |
+
inconsiderate:
|
139 |
+
cowgirl: female
|
140 |
+
cowboy: male
|
141 |
+
- type: or
|
142 |
+
considerate:
|
143 |
+
- cowhands
|
144 |
+
inconsiderate:
|
145 |
+
cowgirls: female
|
146 |
+
cowboys: male
|
147 |
+
- type: or
|
148 |
+
considerate:
|
149 |
+
- cattle rancher
|
150 |
+
inconsiderate:
|
151 |
+
cattlewoman: female
|
152 |
+
cattleman: male
|
153 |
+
- type: or
|
154 |
+
considerate:
|
155 |
+
- cattle ranchers
|
156 |
+
inconsiderate:
|
157 |
+
cattlewomen: female
|
158 |
+
cattlemen: male
|
159 |
+
- type: or
|
160 |
+
considerate:
|
161 |
+
- chairs
|
162 |
+
- chairpersons
|
163 |
+
- coordinators
|
164 |
+
inconsiderate:
|
165 |
+
chairwomen: female
|
166 |
+
chairmen: male
|
167 |
+
- type: or
|
168 |
+
considerate:
|
169 |
+
- mail carrier
|
170 |
+
- letter carrier
|
171 |
+
- postal worker
|
172 |
+
inconsiderate:
|
173 |
+
postwoman: female
|
174 |
+
mailwoman: female
|
175 |
+
postman: male
|
176 |
+
mailman: male
|
177 |
+
- type: or
|
178 |
+
considerate:
|
179 |
+
- mail carriers
|
180 |
+
- letter carriers
|
181 |
+
- postal workers
|
182 |
+
inconsiderate:
|
183 |
+
postwomen: female
|
184 |
+
mailwomen: female
|
185 |
+
postmen: male
|
186 |
+
mailmen: male
|
187 |
+
- type: or
|
188 |
+
considerate:
|
189 |
+
- officer
|
190 |
+
- police officer
|
191 |
+
inconsiderate:
|
192 |
+
policewoman: female
|
193 |
+
policeman: male
|
194 |
+
chick cop: female
|
195 |
+
- type: or
|
196 |
+
considerate:
|
197 |
+
- officers
|
198 |
+
- police officers
|
199 |
+
inconsiderate:
|
200 |
+
policewomen: female
|
201 |
+
policemen: male
|
202 |
+
- type: or
|
203 |
+
considerate:
|
204 |
+
- flight attendant
|
205 |
+
inconsiderate:
|
206 |
+
stewardess: female
|
207 |
+
steward: male
|
208 |
+
- type: or
|
209 |
+
considerate:
|
210 |
+
- flight attendants
|
211 |
+
inconsiderate:
|
212 |
+
stewardesses: female
|
213 |
+
stewards: male
|
214 |
+
- type: or
|
215 |
+
considerate:
|
216 |
+
- member of congress
|
217 |
+
- congress person
|
218 |
+
- legislator
|
219 |
+
- representative
|
220 |
+
inconsiderate:
|
221 |
+
congresswoman: female
|
222 |
+
congressman: male
|
223 |
+
- type: or
|
224 |
+
considerate:
|
225 |
+
- members of congress
|
226 |
+
- congress persons
|
227 |
+
- legislators
|
228 |
+
- representatives
|
229 |
+
inconsiderate:
|
230 |
+
congresswomen: female
|
231 |
+
congressmen: male
|
232 |
+
- type: or
|
233 |
+
considerate:
|
234 |
+
- fire fighter
|
235 |
+
- fire officer
|
236 |
+
inconsiderate:
|
237 |
+
firewoman: female
|
238 |
+
fireman: male
|
239 |
+
- type: or
|
240 |
+
considerate:
|
241 |
+
- fire fighters
|
242 |
+
inconsiderate:
|
243 |
+
firewomen: female
|
244 |
+
firemen: male
|
245 |
+
- type: or
|
246 |
+
considerate:
|
247 |
+
- fisher
|
248 |
+
- crew member
|
249 |
+
- fisherfolk
|
250 |
+
- angler
|
251 |
+
inconsiderate:
|
252 |
+
fisherwoman: female
|
253 |
+
fisherman: male
|
254 |
+
- type: or
|
255 |
+
considerate:
|
256 |
+
- fishers
|
257 |
+
inconsiderate:
|
258 |
+
fisherwomen: female
|
259 |
+
fishermen: male
|
260 |
+
- type: or
|
261 |
+
considerate:
|
262 |
+
- kinship
|
263 |
+
- community
|
264 |
+
inconsiderate:
|
265 |
+
sisterhood: female
|
266 |
+
brotherhood: male
|
267 |
+
- type: or
|
268 |
+
considerate:
|
269 |
+
- common person
|
270 |
+
- average person
|
271 |
+
inconsiderate:
|
272 |
+
common girl: female
|
273 |
+
common man: male
|
274 |
+
- type: or
|
275 |
+
considerate:
|
276 |
+
- business executive
|
277 |
+
- entrepreneur
|
278 |
+
- business person
|
279 |
+
- professional
|
280 |
+
inconsiderate:
|
281 |
+
businesswoman: female
|
282 |
+
salarywoman: female
|
283 |
+
businessman: male
|
284 |
+
salaryman: male
|
285 |
+
- type: or
|
286 |
+
considerate:
|
287 |
+
- business executives
|
288 |
+
- entrepreneurs
|
289 |
+
inconsiderate:
|
290 |
+
businesswomen: female
|
291 |
+
salarywomen: female
|
292 |
+
career girl: female
|
293 |
+
career woman: female
|
294 |
+
businessmen: male
|
295 |
+
salarymen: male
|
296 |
+
- type: or
|
297 |
+
considerate:
|
298 |
+
- cleaner
|
299 |
+
inconsiderate:
|
300 |
+
cleaning lady: female
|
301 |
+
cleaning girl: female
|
302 |
+
cleaning woman: female
|
303 |
+
janitress: female
|
304 |
+
cleaning man: male
|
305 |
+
cleaning boy: male
|
306 |
+
janitor: male
|
307 |
+
- type: or
|
308 |
+
considerate:
|
309 |
+
- cleaners
|
310 |
+
- housekeeping
|
311 |
+
inconsiderate:
|
312 |
+
cleaning ladies: female
|
313 |
+
cleaning girls: female
|
314 |
+
janitresses: female
|
315 |
+
cleaning men: male
|
316 |
+
janitors: male
|
317 |
+
- type: or
|
318 |
+
considerate:
|
319 |
+
- courier
|
320 |
+
- messenger
|
321 |
+
inconsiderate:
|
322 |
+
delivery girl: female
|
323 |
+
delivery boy: male
|
324 |
+
- type: or
|
325 |
+
considerate:
|
326 |
+
- supervisor
|
327 |
+
- shift boss
|
328 |
+
inconsiderate:
|
329 |
+
forewoman: female
|
330 |
+
foreman: male
|
331 |
+
- type: or
|
332 |
+
considerate:
|
333 |
+
- lead
|
334 |
+
- front
|
335 |
+
- figurehead
|
336 |
+
inconsiderate:
|
337 |
+
'frontwoman, front woman': female
|
338 |
+
'frontman, front man': male
|
339 |
+
- type: or
|
340 |
+
considerate:
|
341 |
+
- figureheads
|
342 |
+
inconsiderate:
|
343 |
+
'front women, frontwomen': female
|
344 |
+
'front men, frontmen': male
|
345 |
+
- type: or
|
346 |
+
considerate:
|
347 |
+
- supervisors
|
348 |
+
- shift bosses
|
349 |
+
inconsiderate:
|
350 |
+
forewomen: female
|
351 |
+
foremen: male
|
352 |
+
- type: or
|
353 |
+
considerate:
|
354 |
+
- insurance agent
|
355 |
+
inconsiderate:
|
356 |
+
insurance woman: female
|
357 |
+
insurance man: male
|
358 |
+
- type: or
|
359 |
+
considerate:
|
360 |
+
- insurance agents
|
361 |
+
inconsiderate:
|
362 |
+
insurance women: female
|
363 |
+
insurance men: male
|
364 |
+
- type: or
|
365 |
+
considerate:
|
366 |
+
- proprietor
|
367 |
+
- building manager
|
368 |
+
inconsiderate:
|
369 |
+
landlady: female
|
370 |
+
landlord: male
|
371 |
+
- type: or
|
372 |
+
considerate:
|
373 |
+
- proprietors
|
374 |
+
- building managers
|
375 |
+
inconsiderate:
|
376 |
+
landladies: female
|
377 |
+
landlords: male
|
378 |
+
- type: or
|
379 |
+
considerate:
|
380 |
+
- graduate
|
381 |
+
inconsiderate:
|
382 |
+
alumna: female
|
383 |
+
alumnus: male
|
384 |
+
- type: or
|
385 |
+
considerate:
|
386 |
+
- graduates
|
387 |
+
inconsiderate:
|
388 |
+
alumnae: female
|
389 |
+
alumni: male
|
390 |
+
- type: or
|
391 |
+
considerate:
|
392 |
+
- anchor
|
393 |
+
- journalist
|
394 |
+
inconsiderate:
|
395 |
+
newswoman: female
|
396 |
+
newspaperwoman: female
|
397 |
+
anchorwoman: female
|
398 |
+
newsman: male
|
399 |
+
newspaperman: male
|
400 |
+
anchorman: male
|
401 |
+
- type: or
|
402 |
+
considerate:
|
403 |
+
- anchors
|
404 |
+
- journalists
|
405 |
+
inconsiderate:
|
406 |
+
newswomen: female
|
407 |
+
newspaperwomen: female
|
408 |
+
anchorwomen: female
|
409 |
+
newsmen: male
|
410 |
+
newspapermen: male
|
411 |
+
anchormen: male
|
412 |
+
- type: or
|
413 |
+
considerate:
|
414 |
+
- repairer
|
415 |
+
- technician
|
416 |
+
inconsiderate:
|
417 |
+
repairwoman: female
|
418 |
+
repairman: male
|
419 |
+
- type: or
|
420 |
+
considerate:
|
421 |
+
- technicians
|
422 |
+
inconsiderate:
|
423 |
+
repairwomen: female
|
424 |
+
repairmen: male
|
425 |
+
- type: or
|
426 |
+
considerate:
|
427 |
+
- salesperson
|
428 |
+
- sales clerk
|
429 |
+
- sales rep
|
430 |
+
- sales agent
|
431 |
+
- sales attendant
|
432 |
+
- seller
|
433 |
+
- shop assistant
|
434 |
+
inconsiderate:
|
435 |
+
saleswoman: female
|
436 |
+
sales woman: female
|
437 |
+
saleslady: female
|
438 |
+
salesman: male
|
439 |
+
sales man: male
|
440 |
+
- type: or
|
441 |
+
considerate:
|
442 |
+
- sales clerks
|
443 |
+
- sales reps
|
444 |
+
- sales agents
|
445 |
+
- sellers
|
446 |
+
inconsiderate:
|
447 |
+
saleswomen: female
|
448 |
+
sales women: female
|
449 |
+
salesladies: female
|
450 |
+
salesmen: male
|
451 |
+
sales men: male
|
452 |
+
- type: or
|
453 |
+
considerate:
|
454 |
+
- soldier
|
455 |
+
- service representative
|
456 |
+
inconsiderate:
|
457 |
+
servicewoman: female
|
458 |
+
serviceman: male
|
459 |
+
- type: or
|
460 |
+
considerate:
|
461 |
+
- soldiers
|
462 |
+
- service representatives
|
463 |
+
inconsiderate:
|
464 |
+
servicewomen: female
|
465 |
+
servicemen: male
|
466 |
+
- type: or
|
467 |
+
considerate:
|
468 |
+
- server
|
469 |
+
inconsiderate:
|
470 |
+
waitress: female
|
471 |
+
waiter: male
|
472 |
+
- type: or
|
473 |
+
considerate:
|
474 |
+
- servers
|
475 |
+
inconsiderate:
|
476 |
+
waitresses: female
|
477 |
+
waiters: male
|
478 |
+
- type: or
|
479 |
+
considerate:
|
480 |
+
- worker
|
481 |
+
- wage earner
|
482 |
+
- taxpayer
|
483 |
+
inconsiderate:
|
484 |
+
workwoman: female
|
485 |
+
working woman: female
|
486 |
+
workman: male
|
487 |
+
working man: male
|
488 |
+
- type: or
|
489 |
+
considerate:
|
490 |
+
- workers
|
491 |
+
inconsiderate:
|
492 |
+
workwomen: female
|
493 |
+
workmen: male
|
494 |
+
- type: or
|
495 |
+
considerate:
|
496 |
+
- performer
|
497 |
+
- star
|
498 |
+
- artist
|
499 |
+
- entertainer
|
500 |
+
inconsiderate:
|
501 |
+
actress: female
|
502 |
+
actor: male
|
503 |
+
- type: or
|
504 |
+
considerate:
|
505 |
+
- performers
|
506 |
+
- stars
|
507 |
+
- artists
|
508 |
+
- entertainers
|
509 |
+
inconsiderate:
|
510 |
+
actresses: female
|
511 |
+
actors: male
|
512 |
+
- type: or
|
513 |
+
considerate:
|
514 |
+
- pilot
|
515 |
+
- aviator
|
516 |
+
- airstaff
|
517 |
+
inconsiderate:
|
518 |
+
aircrewwoman: female
|
519 |
+
aircrew woman: female
|
520 |
+
aircrewman: male
|
521 |
+
airman: male
|
522 |
+
- type: or
|
523 |
+
considerate:
|
524 |
+
- pilots
|
525 |
+
- aviators
|
526 |
+
- airstaff
|
527 |
+
inconsiderate:
|
528 |
+
aircrewwomen: female
|
529 |
+
aircrew women: female
|
530 |
+
aircrewmen: male
|
531 |
+
airmen: male
|
532 |
+
- type: or
|
533 |
+
considerate:
|
534 |
+
- cabinet member
|
535 |
+
inconsiderate:
|
536 |
+
alderwoman: female
|
537 |
+
alderman: male
|
538 |
+
- type: or
|
539 |
+
considerate:
|
540 |
+
- cabinet
|
541 |
+
- cabinet members
|
542 |
+
- alderperson
|
543 |
+
inconsiderate:
|
544 |
+
alderwomen: female
|
545 |
+
aldermen: male
|
546 |
+
- type: or
|
547 |
+
considerate:
|
548 |
+
- assembly person
|
549 |
+
- assembly worker
|
550 |
+
inconsiderate:
|
551 |
+
assemblywoman: female
|
552 |
+
assemblyman: male
|
553 |
+
- type: or
|
554 |
+
considerate:
|
555 |
+
- relative
|
556 |
+
inconsiderate:
|
557 |
+
kinswoman: female
|
558 |
+
aunt: female
|
559 |
+
kinsman: male
|
560 |
+
uncle: male
|
561 |
+
- type: or
|
562 |
+
considerate:
|
563 |
+
- relatives
|
564 |
+
inconsiderate:
|
565 |
+
kinswomen: female
|
566 |
+
aunts: female
|
567 |
+
kinsmen: male
|
568 |
+
uncles: male
|
569 |
+
- type: or
|
570 |
+
considerate:
|
571 |
+
- boogeymonster
|
572 |
+
inconsiderate:
|
573 |
+
boogeywoman: female
|
574 |
+
boogeyman: male
|
575 |
+
- type: or
|
576 |
+
considerate:
|
577 |
+
- boogeymonster
|
578 |
+
inconsiderate:
|
579 |
+
boogiewoman: female
|
580 |
+
boogieman: male
|
581 |
+
- type: or
|
582 |
+
considerate:
|
583 |
+
- bogeymonster
|
584 |
+
inconsiderate:
|
585 |
+
bogeywoman: female
|
586 |
+
bogeyman: male
|
587 |
+
- type: or
|
588 |
+
considerate:
|
589 |
+
- bogeymonster
|
590 |
+
inconsiderate:
|
591 |
+
bogiewoman: female
|
592 |
+
bogieman: male
|
593 |
+
- type: or
|
594 |
+
considerate:
|
595 |
+
- boogeymonsters
|
596 |
+
inconsiderate:
|
597 |
+
boogiewomen: female
|
598 |
+
boogiemen: male
|
599 |
+
- type: or
|
600 |
+
considerate:
|
601 |
+
- bogeymonsters
|
602 |
+
inconsiderate:
|
603 |
+
bogiewomen: female
|
604 |
+
bogiemen: male
|
605 |
+
- type: or
|
606 |
+
considerate:
|
607 |
+
- bonder
|
608 |
+
inconsiderate:
|
609 |
+
bondswoman: female
|
610 |
+
bondsman: male
|
611 |
+
- type: or
|
612 |
+
considerate:
|
613 |
+
- bonders
|
614 |
+
inconsiderate:
|
615 |
+
bondswomen: female
|
616 |
+
bondsmen: male
|
617 |
+
- type: or
|
618 |
+
source: https://www.bustle.com/articles/108321-6-reasons-to-refer-to-your-significant-other-as-your-partner
|
619 |
+
considerate:
|
620 |
+
- partner
|
621 |
+
- significant other
|
622 |
+
- spouse
|
623 |
+
inconsiderate:
|
624 |
+
wife: female
|
625 |
+
husband: male
|
626 |
+
- type: or
|
627 |
+
source: https://www.bustle.com/articles/108321-6-reasons-to-refer-to-your-significant-other-as-your-partner
|
628 |
+
considerate:
|
629 |
+
- partners
|
630 |
+
- significant others
|
631 |
+
- spouses
|
632 |
+
inconsiderate:
|
633 |
+
wives: female
|
634 |
+
husbands: male
|
635 |
+
- type: or
|
636 |
+
source: https://www.bustle.com/articles/108321-6-reasons-to-refer-to-your-significant-other-as-your-partner
|
637 |
+
considerate:
|
638 |
+
- partner
|
639 |
+
- friend
|
640 |
+
- significant other
|
641 |
+
inconsiderate:
|
642 |
+
girlfriend: female
|
643 |
+
boyfriend: male
|
644 |
+
- type: or
|
645 |
+
source: https://www.bustle.com/articles/108321-6-reasons-to-refer-to-your-significant-other-as-your-partner
|
646 |
+
considerate:
|
647 |
+
- partners
|
648 |
+
- friends
|
649 |
+
- significant others
|
650 |
+
inconsiderate:
|
651 |
+
girlfriends: female
|
652 |
+
boyfriends: male
|
653 |
+
- type: or
|
654 |
+
considerate:
|
655 |
+
- childhood
|
656 |
+
inconsiderate:
|
657 |
+
girlhood: female
|
658 |
+
boyhood: male
|
659 |
+
- type: or
|
660 |
+
considerate:
|
661 |
+
- childish
|
662 |
+
inconsiderate:
|
663 |
+
girly: female
|
664 |
+
girlish: female
|
665 |
+
boyish: male
|
666 |
+
- type: or
|
667 |
+
considerate:
|
668 |
+
- journeyperson
|
669 |
+
inconsiderate:
|
670 |
+
journeywoman: female
|
671 |
+
journeyman: male
|
672 |
+
- type: or
|
673 |
+
considerate:
|
674 |
+
- journeypersons
|
675 |
+
inconsiderate:
|
676 |
+
journeywomen: female
|
677 |
+
journeymen: male
|
678 |
+
- type: or
|
679 |
+
considerate:
|
680 |
+
- godparent
|
681 |
+
- elder
|
682 |
+
- patron
|
683 |
+
inconsiderate:
|
684 |
+
godmother: female
|
685 |
+
patroness: female
|
686 |
+
godfather: male
|
687 |
+
- type: or
|
688 |
+
considerate:
|
689 |
+
- grandchild
|
690 |
+
inconsiderate:
|
691 |
+
granddaughter: female
|
692 |
+
grandson: male
|
693 |
+
- type: or
|
694 |
+
considerate:
|
695 |
+
- grandchildren
|
696 |
+
inconsiderate:
|
697 |
+
granddaughters: female
|
698 |
+
grandsons: male
|
699 |
+
- type: or
|
700 |
+
considerate:
|
701 |
+
- ancestor
|
702 |
+
inconsiderate:
|
703 |
+
foremother: female
|
704 |
+
forefather: male
|
705 |
+
- type: or
|
706 |
+
considerate:
|
707 |
+
- ancestors
|
708 |
+
inconsiderate:
|
709 |
+
foremothers: female
|
710 |
+
forefathers: male
|
711 |
+
- type: or
|
712 |
+
considerate:
|
713 |
+
- grandparent
|
714 |
+
- ancestor
|
715 |
+
inconsiderate:
|
716 |
+
granny: female
|
717 |
+
grandma: female
|
718 |
+
grandmother: female
|
719 |
+
grandpappy: male
|
720 |
+
granddaddy: male
|
721 |
+
gramps: male
|
722 |
+
grandpa: male
|
723 |
+
grandfather: male
|
724 |
+
- type: or
|
725 |
+
considerate:
|
726 |
+
- grandparents
|
727 |
+
- ancestors
|
728 |
+
inconsiderate:
|
729 |
+
grandmothers: female
|
730 |
+
grandfathers: male
|
731 |
+
- type: or
|
732 |
+
considerate:
|
733 |
+
- spouse
|
734 |
+
- newlywed
|
735 |
+
inconsiderate:
|
736 |
+
bride: female
|
737 |
+
groom: male
|
738 |
+
- type: or
|
739 |
+
considerate:
|
740 |
+
- sibling
|
741 |
+
inconsiderate:
|
742 |
+
sister: female
|
743 |
+
brother: male
|
744 |
+
- type: or
|
745 |
+
considerate:
|
746 |
+
- siblings
|
747 |
+
inconsiderate:
|
748 |
+
sisters: female
|
749 |
+
brothers: male
|
750 |
+
- type: or
|
751 |
+
considerate:
|
752 |
+
- camera operator
|
753 |
+
- camera person
|
754 |
+
inconsiderate:
|
755 |
+
camerawoman: female
|
756 |
+
cameraman: male
|
757 |
+
- type: or
|
758 |
+
considerate:
|
759 |
+
- camera operators
|
760 |
+
inconsiderate:
|
761 |
+
camerawomen: female
|
762 |
+
cameramen: male
|
763 |
+
- type: or
|
764 |
+
considerate:
|
765 |
+
- troglodyte
|
766 |
+
- hominidae
|
767 |
+
inconsiderate:
|
768 |
+
cavewoman: female
|
769 |
+
caveman: male
|
770 |
+
- type: or
|
771 |
+
considerate:
|
772 |
+
- troglodytae
|
773 |
+
- troglodyti
|
774 |
+
- troglodytes
|
775 |
+
- hominids
|
776 |
+
inconsiderate:
|
777 |
+
cavewomen: female
|
778 |
+
cavemen: male
|
779 |
+
- type: or
|
780 |
+
considerate:
|
781 |
+
- clergyperson
|
782 |
+
- clergy
|
783 |
+
- cleric
|
784 |
+
inconsiderate:
|
785 |
+
clergywoman: female
|
786 |
+
clergyman: male
|
787 |
+
- type: or
|
788 |
+
considerate:
|
789 |
+
- clergies
|
790 |
+
- clerics
|
791 |
+
inconsiderate:
|
792 |
+
clergywomen: female
|
793 |
+
clergymen: male
|
794 |
+
- type: or
|
795 |
+
considerate:
|
796 |
+
- council member
|
797 |
+
inconsiderate:
|
798 |
+
councilwoman: female
|
799 |
+
councilman: male
|
800 |
+
- type: or
|
801 |
+
considerate:
|
802 |
+
- council members
|
803 |
+
inconsiderate:
|
804 |
+
councilwomen: female
|
805 |
+
councilmen: male
|
806 |
+
- type: or
|
807 |
+
considerate:
|
808 |
+
- country person
|
809 |
+
inconsiderate:
|
810 |
+
countrywoman: female
|
811 |
+
countryman: male
|
812 |
+
- type: or
|
813 |
+
considerate:
|
814 |
+
- country folk
|
815 |
+
inconsiderate:
|
816 |
+
countrywomen: female
|
817 |
+
countrymen: male
|
818 |
+
- type: or
|
819 |
+
considerate:
|
820 |
+
- artisan
|
821 |
+
- craftsperson
|
822 |
+
- skilled worker
|
823 |
+
inconsiderate:
|
824 |
+
handywoman: female
|
825 |
+
craftswoman: female
|
826 |
+
handyman: male
|
827 |
+
craftsman: male
|
828 |
+
- type: or
|
829 |
+
considerate:
|
830 |
+
- presenter
|
831 |
+
- entertainer
|
832 |
+
- emcee
|
833 |
+
inconsiderate:
|
834 |
+
hostess: female
|
835 |
+
host: male
|
836 |
+
- type: or
|
837 |
+
considerate:
|
838 |
+
- presenters
|
839 |
+
- entertainers
|
840 |
+
- emcees
|
841 |
+
inconsiderate:
|
842 |
+
hostesses: female
|
843 |
+
hosts: male
|
844 |
+
- type: or
|
845 |
+
considerate:
|
846 |
+
- artisans
|
847 |
+
- craftspersons
|
848 |
+
- skilled workers
|
849 |
+
inconsiderate:
|
850 |
+
handywomen: female
|
851 |
+
craftswomen: female
|
852 |
+
handymen: male
|
853 |
+
craftsmen: male
|
854 |
+
- type: or
|
855 |
+
considerate:
|
856 |
+
- guillotine
|
857 |
+
inconsiderate:
|
858 |
+
hangwoman: female
|
859 |
+
hangman: male
|
860 |
+
- type: or
|
861 |
+
considerate:
|
862 |
+
- guillotines
|
863 |
+
inconsiderate:
|
864 |
+
hangwomen: female
|
865 |
+
hangmen: male
|
866 |
+
- type: or
|
867 |
+
considerate:
|
868 |
+
- sidekick
|
869 |
+
inconsiderate:
|
870 |
+
henchwoman: female
|
871 |
+
henchman: male
|
872 |
+
- type: or
|
873 |
+
considerate:
|
874 |
+
- sidekicks
|
875 |
+
inconsiderate:
|
876 |
+
henchwomen: female
|
877 |
+
henchmen: male
|
878 |
+
- type: or
|
879 |
+
considerate:
|
880 |
+
- role-model
|
881 |
+
- mentor
|
882 |
+
inconsiderate:
|
883 |
+
heroine: female
|
884 |
+
hero: male
|
885 |
+
- type: or
|
886 |
+
considerate:
|
887 |
+
- role-models
|
888 |
+
- mentor
|
889 |
+
inconsiderate:
|
890 |
+
heroines: female
|
891 |
+
heroes: male
|
892 |
+
- type: or
|
893 |
+
considerate:
|
894 |
+
- parental
|
895 |
+
- warm
|
896 |
+
- intimate
|
897 |
+
inconsiderate:
|
898 |
+
maternal: female
|
899 |
+
paternal: male
|
900 |
+
fraternal: male
|
901 |
+
- type: or
|
902 |
+
considerate:
|
903 |
+
- parental
|
904 |
+
inconsiderate:
|
905 |
+
maternity: female
|
906 |
+
paternity: male
|
907 |
+
- type: or
|
908 |
+
considerate:
|
909 |
+
- parents
|
910 |
+
inconsiderate:
|
911 |
+
mamas: female
|
912 |
+
mothers: female
|
913 |
+
moms: female
|
914 |
+
mums: female
|
915 |
+
mommas: female
|
916 |
+
mommies: female
|
917 |
+
papas: male
|
918 |
+
fathers: male
|
919 |
+
dads: male
|
920 |
+
daddies: male
|
921 |
+
- type: or
|
922 |
+
considerate:
|
923 |
+
- parent
|
924 |
+
inconsiderate:
|
925 |
+
mama: female
|
926 |
+
mother: female
|
927 |
+
mom: female
|
928 |
+
mum: female
|
929 |
+
momma: female
|
930 |
+
mommy: female
|
931 |
+
papa: male
|
932 |
+
father: male
|
933 |
+
dad: male
|
934 |
+
pop: male
|
935 |
+
daddy: male
|
936 |
+
- type: or
|
937 |
+
considerate:
|
938 |
+
- child
|
939 |
+
inconsiderate:
|
940 |
+
daughter: female
|
941 |
+
son: male
|
942 |
+
- type: or
|
943 |
+
considerate:
|
944 |
+
- children
|
945 |
+
inconsiderate:
|
946 |
+
daughters: female
|
947 |
+
sons: male
|
948 |
+
- type: or
|
949 |
+
considerate:
|
950 |
+
- concierge
|
951 |
+
inconsiderate:
|
952 |
+
doorwoman: female
|
953 |
+
doorman: male
|
954 |
+
- type: or
|
955 |
+
considerate:
|
956 |
+
- concierges
|
957 |
+
inconsiderate:
|
958 |
+
doorwomen: female
|
959 |
+
doormen: male
|
960 |
+
- type: or
|
961 |
+
considerate:
|
962 |
+
- humanly
|
963 |
+
- mature
|
964 |
+
inconsiderate:
|
965 |
+
feminin: female
|
966 |
+
dudely: male
|
967 |
+
manly: male
|
968 |
+
- type: or
|
969 |
+
considerate:
|
970 |
+
- humans
|
971 |
+
inconsiderate:
|
972 |
+
females: female
|
973 |
+
males: male
|
974 |
+
- type: or
|
975 |
+
considerate:
|
976 |
+
- ruler
|
977 |
+
inconsiderate:
|
978 |
+
empress: female
|
979 |
+
queen: female
|
980 |
+
emperor: male
|
981 |
+
king: male
|
982 |
+
- type: or
|
983 |
+
considerate:
|
984 |
+
- rulers
|
985 |
+
inconsiderate:
|
986 |
+
empresses: female
|
987 |
+
queens: female
|
988 |
+
emperors: male
|
989 |
+
kings: male
|
990 |
+
- type: or
|
991 |
+
considerate:
|
992 |
+
- jumbo
|
993 |
+
- gigantic
|
994 |
+
inconsiderate:
|
995 |
+
queensize: female
|
996 |
+
kingsize: male
|
997 |
+
- type: or
|
998 |
+
considerate:
|
999 |
+
- power behind the throne
|
1000 |
+
inconsiderate:
|
1001 |
+
queenmaker: female
|
1002 |
+
kingmaker: male
|
1003 |
+
- type: or
|
1004 |
+
considerate:
|
1005 |
+
- civilian
|
1006 |
+
inconsiderate:
|
1007 |
+
laywoman: female
|
1008 |
+
layman: male
|
1009 |
+
- type: or
|
1010 |
+
considerate:
|
1011 |
+
- civilians
|
1012 |
+
inconsiderate:
|
1013 |
+
laywomen: female
|
1014 |
+
laymen: male
|
1015 |
+
- type: or
|
1016 |
+
considerate:
|
1017 |
+
- official
|
1018 |
+
- owner
|
1019 |
+
- expert
|
1020 |
+
- superior
|
1021 |
+
- chief
|
1022 |
+
- ruler
|
1023 |
+
inconsiderate:
|
1024 |
+
dame: female
|
1025 |
+
lord: male
|
1026 |
+
- type: or
|
1027 |
+
considerate:
|
1028 |
+
- officials
|
1029 |
+
- chiefs
|
1030 |
+
- rulers
|
1031 |
+
inconsiderate:
|
1032 |
+
dames: female
|
1033 |
+
lords: male
|
1034 |
+
- type: or
|
1035 |
+
considerate:
|
1036 |
+
- adulthood
|
1037 |
+
- personhood
|
1038 |
+
- maturity
|
1039 |
+
inconsiderate:
|
1040 |
+
womanhood: female
|
1041 |
+
masculinity: male
|
1042 |
+
manhood: male
|
1043 |
+
- type: or
|
1044 |
+
considerate:
|
1045 |
+
- humanity
|
1046 |
+
inconsiderate:
|
1047 |
+
femininity: female
|
1048 |
+
manliness: male
|
1049 |
+
- type: or
|
1050 |
+
considerate:
|
1051 |
+
- shooter
|
1052 |
+
inconsiderate:
|
1053 |
+
markswoman: female
|
1054 |
+
marksman: male
|
1055 |
+
- type: or
|
1056 |
+
considerate:
|
1057 |
+
- shooters
|
1058 |
+
inconsiderate:
|
1059 |
+
markswomen: female
|
1060 |
+
marksmen: male
|
1061 |
+
- type: or
|
1062 |
+
considerate:
|
1063 |
+
- intermediary
|
1064 |
+
- go-between
|
1065 |
+
inconsiderate:
|
1066 |
+
middlewoman: female
|
1067 |
+
middleman: male
|
1068 |
+
- type: or
|
1069 |
+
considerate:
|
1070 |
+
- intermediaries
|
1071 |
+
- go-betweens
|
1072 |
+
inconsiderate:
|
1073 |
+
middlewomen: female
|
1074 |
+
middlemen: male
|
1075 |
+
- type: or
|
1076 |
+
considerate:
|
1077 |
+
- milk person
|
1078 |
+
inconsiderate:
|
1079 |
+
milkwoman: female
|
1080 |
+
milkman: male
|
1081 |
+
- type: or
|
1082 |
+
considerate:
|
1083 |
+
- milk people
|
1084 |
+
inconsiderate:
|
1085 |
+
milkwomen: female
|
1086 |
+
milkmen: male
|
1087 |
+
- type: or
|
1088 |
+
considerate:
|
1089 |
+
- nibling
|
1090 |
+
- sibling’s child
|
1091 |
+
inconsiderate:
|
1092 |
+
niece: female
|
1093 |
+
nephew: male
|
1094 |
+
- type: or
|
1095 |
+
considerate:
|
1096 |
+
- niblings
|
1097 |
+
- sibling’s children
|
1098 |
+
inconsiderate:
|
1099 |
+
nieces: female
|
1100 |
+
nephews: male
|
1101 |
+
- type: or
|
1102 |
+
considerate:
|
1103 |
+
- noble
|
1104 |
+
inconsiderate:
|
1105 |
+
noblewoman: female
|
1106 |
+
nobleman: male
|
1107 |
+
- type: or
|
1108 |
+
considerate:
|
1109 |
+
- nobles
|
1110 |
+
inconsiderate:
|
1111 |
+
noblewomen: female
|
1112 |
+
noblemen: male
|
1113 |
+
- type: or
|
1114 |
+
considerate:
|
1115 |
+
- notary
|
1116 |
+
- consumer advocate
|
1117 |
+
- trouble shooter
|
1118 |
+
- omsbudperson
|
1119 |
+
- mediator
|
1120 |
+
inconsiderate:
|
1121 |
+
ombudswoman: female
|
1122 |
+
ombudsman: male
|
1123 |
+
- type: or
|
1124 |
+
considerate:
|
1125 |
+
- notaries
|
1126 |
+
- omsbudpersons
|
1127 |
+
- omsbudpeople
|
1128 |
+
- mediators
|
1129 |
+
inconsiderate:
|
1130 |
+
ombudswomen: female
|
1131 |
+
ombudsmen: male
|
1132 |
+
- type: or
|
1133 |
+
considerate:
|
1134 |
+
- heir
|
1135 |
+
inconsiderate:
|
1136 |
+
princess: female
|
1137 |
+
prince: male
|
1138 |
+
- type: or
|
1139 |
+
considerate:
|
1140 |
+
- heirs
|
1141 |
+
inconsiderate:
|
1142 |
+
princesses: female
|
1143 |
+
princes: male
|
1144 |
+
- type: or
|
1145 |
+
considerate:
|
1146 |
+
- fairy
|
1147 |
+
inconsiderate:
|
1148 |
+
sandwoman: female
|
1149 |
+
sandman: male
|
1150 |
+
- type: or
|
1151 |
+
considerate:
|
1152 |
+
- fairies
|
1153 |
+
inconsiderate:
|
1154 |
+
sandwomen: female
|
1155 |
+
sandmen: male
|
1156 |
+
- type: or
|
1157 |
+
considerate:
|
1158 |
+
- promoter
|
1159 |
+
inconsiderate:
|
1160 |
+
showwoman: female
|
1161 |
+
showman: male
|
1162 |
+
- type: or
|
1163 |
+
considerate:
|
1164 |
+
- promoters
|
1165 |
+
inconsiderate:
|
1166 |
+
showwomen: female
|
1167 |
+
show women: female
|
1168 |
+
showmen: male
|
1169 |
+
- type: or
|
1170 |
+
considerate:
|
1171 |
+
- astronaut
|
1172 |
+
inconsiderate:
|
1173 |
+
spacewoman: female
|
1174 |
+
spaceman: male
|
1175 |
+
- type: or
|
1176 |
+
considerate:
|
1177 |
+
- astronauts
|
1178 |
+
inconsiderate:
|
1179 |
+
spacewomen: female
|
1180 |
+
spacemen: male
|
1181 |
+
- type: or
|
1182 |
+
considerate:
|
1183 |
+
- speaker
|
1184 |
+
- spokesperson
|
1185 |
+
- representative
|
1186 |
+
inconsiderate:
|
1187 |
+
spokeswoman: female
|
1188 |
+
spokesman: male
|
1189 |
+
- type: or
|
1190 |
+
considerate:
|
1191 |
+
- speakers
|
1192 |
+
- spokespersons
|
1193 |
+
inconsiderate:
|
1194 |
+
spokeswomen: female
|
1195 |
+
spokesmen: male
|
1196 |
+
- type: or
|
1197 |
+
considerate:
|
1198 |
+
- athlete
|
1199 |
+
- sports person
|
1200 |
+
inconsiderate:
|
1201 |
+
sportswoman: female
|
1202 |
+
sportsman: male
|
1203 |
+
- type: or
|
1204 |
+
considerate:
|
1205 |
+
- athletes
|
1206 |
+
- sports persons
|
1207 |
+
inconsiderate:
|
1208 |
+
sportswomen: female
|
1209 |
+
sportsmen: male
|
1210 |
+
- type: or
|
1211 |
+
considerate:
|
1212 |
+
- senator
|
1213 |
+
inconsiderate:
|
1214 |
+
stateswoman: female
|
1215 |
+
statesman: male
|
1216 |
+
- type: or
|
1217 |
+
considerate:
|
1218 |
+
- step-sibling
|
1219 |
+
inconsiderate:
|
1220 |
+
stepsister: female
|
1221 |
+
stepbrother: male
|
1222 |
+
- type: or
|
1223 |
+
considerate:
|
1224 |
+
- step-siblings
|
1225 |
+
inconsiderate:
|
1226 |
+
stepsisters: female
|
1227 |
+
stepbrothers: male
|
1228 |
+
- type: or
|
1229 |
+
considerate:
|
1230 |
+
- step-parent
|
1231 |
+
inconsiderate:
|
1232 |
+
stepmom: female
|
1233 |
+
stepmother: female
|
1234 |
+
stepdad: male
|
1235 |
+
stepfather: male
|
1236 |
+
- type: or
|
1237 |
+
considerate:
|
1238 |
+
- step-parents
|
1239 |
+
inconsiderate:
|
1240 |
+
stepmothers: female
|
1241 |
+
stepfathers: male
|
1242 |
+
- type: or
|
1243 |
+
considerate:
|
1244 |
+
- titan
|
1245 |
+
inconsiderate:
|
1246 |
+
superwoman: female
|
1247 |
+
superman: male
|
1248 |
+
- type: or
|
1249 |
+
considerate:
|
1250 |
+
- titans
|
1251 |
+
inconsiderate:
|
1252 |
+
superwomen: female
|
1253 |
+
supermen: male
|
1254 |
+
- type: or
|
1255 |
+
considerate:
|
1256 |
+
- inhumane
|
1257 |
+
inconsiderate:
|
1258 |
+
unwomanly: female
|
1259 |
+
unwomenly: female
|
1260 |
+
unmanly: male
|
1261 |
+
unmenly: male
|
1262 |
+
- type: or
|
1263 |
+
considerate:
|
1264 |
+
- watcher
|
1265 |
+
inconsiderate:
|
1266 |
+
watchwoman: female
|
1267 |
+
watchman: male
|
1268 |
+
- type: or
|
1269 |
+
considerate:
|
1270 |
+
- watchers
|
1271 |
+
inconsiderate:
|
1272 |
+
watchwomen: female
|
1273 |
+
watchmen: male
|
1274 |
+
- type: or
|
1275 |
+
considerate:
|
1276 |
+
- weather forecaster
|
1277 |
+
- meteorologist
|
1278 |
+
inconsiderate:
|
1279 |
+
weatherwoman: female
|
1280 |
+
weatherman: male
|
1281 |
+
- type: or
|
1282 |
+
considerate:
|
1283 |
+
- weather forecasters
|
1284 |
+
- meteorologists
|
1285 |
+
inconsiderate:
|
1286 |
+
weatherwomen: female
|
1287 |
+
weathermen: male
|
1288 |
+
- type: or
|
1289 |
+
considerate:
|
1290 |
+
- bereaved
|
1291 |
+
inconsiderate:
|
1292 |
+
widow: female
|
1293 |
+
widows: female
|
1294 |
+
widower: male
|
1295 |
+
widowers: male
|
1296 |
+
- type: or
|
1297 |
+
considerate:
|
1298 |
+
- own person
|
1299 |
+
inconsiderate:
|
1300 |
+
own woman: female
|
1301 |
+
own man: male
|
1302 |
+
- type: basic
|
1303 |
+
considerate:
|
1304 |
+
- french
|
1305 |
+
- the french
|
1306 |
+
inconsiderate:
|
1307 |
+
frenchmen: male
|
1308 |
+
- type: basic
|
1309 |
+
considerate:
|
1310 |
+
- courteous
|
1311 |
+
- cultured
|
1312 |
+
inconsiderate:
|
1313 |
+
ladylike: female
|
1314 |
+
- type: basic
|
1315 |
+
considerate:
|
1316 |
+
- resolutely
|
1317 |
+
- bravely
|
1318 |
+
inconsiderate:
|
1319 |
+
like a man: male
|
1320 |
+
- type: basic
|
1321 |
+
considerate:
|
1322 |
+
- birth name
|
1323 |
+
inconsiderate:
|
1324 |
+
maiden name: female
|
1325 |
+
- type: basic
|
1326 |
+
considerate:
|
1327 |
+
- first voyage
|
1328 |
+
inconsiderate:
|
1329 |
+
maiden voyage: female
|
1330 |
+
- type: basic
|
1331 |
+
considerate:
|
1332 |
+
- first flight
|
1333 |
+
inconsiderate:
|
1334 |
+
maiden flight: female
|
1335 |
+
- type: basic
|
1336 |
+
considerate:
|
1337 |
+
- strong enough
|
1338 |
+
inconsiderate:
|
1339 |
+
man enough: male
|
1340 |
+
- type: basic
|
1341 |
+
considerate:
|
1342 |
+
- upstaging
|
1343 |
+
- competitiveness
|
1344 |
+
inconsiderate:
|
1345 |
+
oneupmanship: male
|
1346 |
+
- type: basic
|
1347 |
+
considerate:
|
1348 |
+
- ms.
|
1349 |
+
inconsiderate:
|
1350 |
+
miss.: female
|
1351 |
+
mrs.: female
|
1352 |
+
- type: basic
|
1353 |
+
considerate:
|
1354 |
+
- manufactured
|
1355 |
+
- artificial
|
1356 |
+
- synthetic
|
1357 |
+
- machine-made
|
1358 |
+
- constructed
|
1359 |
+
inconsiderate:
|
1360 |
+
manmade: male
|
1361 |
+
- type: basic
|
1362 |
+
considerate:
|
1363 |
+
- dynamo
|
1364 |
+
inconsiderate:
|
1365 |
+
man of action: male
|
1366 |
+
- type: basic
|
1367 |
+
considerate:
|
1368 |
+
- scholar
|
1369 |
+
- writer
|
1370 |
+
- literary figure
|
1371 |
+
inconsiderate:
|
1372 |
+
man of letters: male
|
1373 |
+
- type: basic
|
1374 |
+
considerate:
|
1375 |
+
- sophisticate
|
1376 |
+
inconsiderate:
|
1377 |
+
man of the world: male
|
1378 |
+
- type: basic
|
1379 |
+
considerate:
|
1380 |
+
- camaraderie
|
1381 |
+
- community
|
1382 |
+
- organization
|
1383 |
+
inconsiderate:
|
1384 |
+
fellowship: male
|
1385 |
+
- type: basic
|
1386 |
+
considerate:
|
1387 |
+
- first-year student
|
1388 |
+
- fresher
|
1389 |
+
inconsiderate:
|
1390 |
+
freshman: male
|
1391 |
+
freshwoman: male
|
1392 |
+
- type: basic
|
1393 |
+
considerate:
|
1394 |
+
- quality construction
|
1395 |
+
- expertise
|
1396 |
+
inconsiderate:
|
1397 |
+
workmanship: male
|
1398 |
+
- type: basic
|
1399 |
+
considerate:
|
1400 |
+
- homemaker
|
1401 |
+
- homeworker
|
1402 |
+
inconsiderate:
|
1403 |
+
housewife: female
|
1404 |
+
- type: basic
|
1405 |
+
considerate:
|
1406 |
+
- homemakers
|
1407 |
+
- homeworkers
|
1408 |
+
inconsiderate:
|
1409 |
+
housewives: female
|
1410 |
+
- type: basic
|
1411 |
+
considerate:
|
1412 |
+
- loving
|
1413 |
+
- warm
|
1414 |
+
- nurturing
|
1415 |
+
inconsiderate:
|
1416 |
+
motherly: female
|
1417 |
+
- type: basic
|
1418 |
+
considerate:
|
1419 |
+
- human resources
|
1420 |
+
- workforce
|
1421 |
+
- personnel
|
1422 |
+
- staff
|
1423 |
+
- labor
|
1424 |
+
- personnel
|
1425 |
+
- labor force
|
1426 |
+
- staffing
|
1427 |
+
- combat personnel
|
1428 |
+
inconsiderate:
|
1429 |
+
manpower: male
|
1430 |
+
- type: basic
|
1431 |
+
considerate:
|
1432 |
+
- emcee
|
1433 |
+
- moderator
|
1434 |
+
- convenor
|
1435 |
+
inconsiderate:
|
1436 |
+
master of ceremonies: male
|
1437 |
+
- type: basic
|
1438 |
+
considerate:
|
1439 |
+
- skilled
|
1440 |
+
- authoritative
|
1441 |
+
- commanding
|
1442 |
+
inconsiderate:
|
1443 |
+
masterful: male
|
1444 |
+
- type: basic
|
1445 |
+
considerate:
|
1446 |
+
- genius
|
1447 |
+
- creator
|
1448 |
+
- instigator
|
1449 |
+
- oversee
|
1450 |
+
- launch
|
1451 |
+
- originate
|
1452 |
+
inconsiderate:
|
1453 |
+
mastermind: male
|
1454 |
+
- type: basic
|
1455 |
+
considerate:
|
1456 |
+
- work of genius
|
1457 |
+
- chef d’oeuvre
|
1458 |
+
inconsiderate:
|
1459 |
+
masterpiece: male
|
1460 |
+
- type: basic
|
1461 |
+
considerate:
|
1462 |
+
- vision
|
1463 |
+
- comprehensive plan
|
1464 |
+
inconsiderate:
|
1465 |
+
masterplan: male
|
1466 |
+
- type: basic
|
1467 |
+
considerate:
|
1468 |
+
- trump card
|
1469 |
+
- stroke of genius
|
1470 |
+
inconsiderate:
|
1471 |
+
masterstroke: male
|
1472 |
+
- type: basic
|
1473 |
+
considerate:
|
1474 |
+
- fanatic
|
1475 |
+
- zealot
|
1476 |
+
- enthusiast
|
1477 |
+
inconsiderate:
|
1478 |
+
madman: male
|
1479 |
+
mad man: male
|
1480 |
+
- type: basic
|
1481 |
+
considerate:
|
1482 |
+
- fanatics
|
1483 |
+
- zealots
|
1484 |
+
- enthusiasts
|
1485 |
+
inconsiderate:
|
1486 |
+
madmen: male
|
1487 |
+
mad men: male
|
1488 |
+
- type: basic
|
1489 |
+
considerate:
|
1490 |
+
- humankind
|
1491 |
+
inconsiderate:
|
1492 |
+
mankind: male
|
1493 |
+
- type: basic
|
1494 |
+
considerate:
|
1495 |
+
- staff hour
|
1496 |
+
- hour of work
|
1497 |
+
inconsiderate:
|
1498 |
+
manhour: male
|
1499 |
+
man hour: male
|
1500 |
+
- type: basic
|
1501 |
+
considerate:
|
1502 |
+
- staff hours
|
1503 |
+
- hours of work
|
1504 |
+
- hours of labor
|
1505 |
+
- hours
|
1506 |
+
inconsiderate:
|
1507 |
+
manhours: male
|
1508 |
+
man hours: male
|
1509 |
+
- type: basic
|
1510 |
+
note: Using gender neutral language means users will help to break up gender stereotypes.
|
1511 |
+
considerate:
|
1512 |
+
- staffed
|
1513 |
+
- crewed
|
1514 |
+
- piloted
|
1515 |
+
inconsiderate:
|
1516 |
+
- manned
|
1517 |
+
- type: basic
|
1518 |
+
note: Using gender neutral language means users will help to break up gender stereotypes.
|
1519 |
+
considerate:
|
1520 |
+
- robotic
|
1521 |
+
- automated
|
1522 |
+
inconsiderate:
|
1523 |
+
- unmanned
|
1524 |
+
- type: basic
|
1525 |
+
considerate:
|
1526 |
+
- whining
|
1527 |
+
- complaining
|
1528 |
+
- crying
|
1529 |
+
inconsiderate:
|
1530 |
+
- bitching
|
1531 |
+
- moaning
|
1532 |
+
- type: basic
|
1533 |
+
considerate:
|
1534 |
+
- whine
|
1535 |
+
- complain
|
1536 |
+
- cry
|
1537 |
+
inconsiderate:
|
1538 |
+
- bitch
|
1539 |
+
- moan
|
1540 |
+
- type: basic
|
1541 |
+
considerate:
|
1542 |
+
- tank top
|
1543 |
+
- sleeveless undershirt
|
1544 |
+
inconsiderate:
|
1545 |
+
- wife beater
|
1546 |
+
- wifebeater
|
1547 |
+
- type: basic
|
1548 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1549 |
+
considerate:
|
1550 |
+
- ancient civilization
|
1551 |
+
- ancient people
|
1552 |
+
inconsiderate: ancient man
|
1553 |
+
- type: basic
|
1554 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1555 |
+
considerate:
|
1556 |
+
- author
|
1557 |
+
- writer
|
1558 |
+
inconsiderate: authoress
|
1559 |
+
- type: basic
|
1560 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1561 |
+
considerate:
|
1562 |
+
- average consumer
|
1563 |
+
- average household
|
1564 |
+
- average homemaker
|
1565 |
+
inconsiderate: average housewife
|
1566 |
+
- type: basic
|
1567 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1568 |
+
considerate: average person
|
1569 |
+
inconsiderate: average man
|
1570 |
+
- type: basic
|
1571 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1572 |
+
considerate:
|
1573 |
+
- average wage earner
|
1574 |
+
- average taxpayer
|
1575 |
+
inconsiderate: average working man
|
1576 |
+
- type: basic
|
1577 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1578 |
+
considerate: aviator
|
1579 |
+
inconsiderate: aviatrix
|
1580 |
+
- type: basic
|
1581 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1582 |
+
considerate: the human family
|
1583 |
+
inconsiderate: brotherhood of man
|
1584 |
+
- type: basic
|
1585 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1586 |
+
considerate: model
|
1587 |
+
inconsiderate: calendar girl
|
1588 |
+
- type: basic
|
1589 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1590 |
+
considerate:
|
1591 |
+
- escort
|
1592 |
+
- prostitute
|
1593 |
+
- sex worker
|
1594 |
+
inconsiderate: call girl
|
1595 |
+
- type: basic
|
1596 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1597 |
+
considerate:
|
1598 |
+
- cleric
|
1599 |
+
- practicing Christian
|
1600 |
+
- pillar of the Church
|
1601 |
+
inconsiderate: churchman
|
1602 |
+
- type: basic
|
1603 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1604 |
+
considerate:
|
1605 |
+
- english coordinator
|
1606 |
+
- senior teacher of english
|
1607 |
+
inconsiderate: english master
|
1608 |
+
- type: basic
|
1609 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1610 |
+
considerate: the english
|
1611 |
+
inconsiderate: englishmen
|
1612 |
+
- type: basic
|
1613 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1614 |
+
considerate: executor
|
1615 |
+
inconsiderate: executrix
|
1616 |
+
- type: basic
|
1617 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1618 |
+
considerate: founder of
|
1619 |
+
inconsiderate: father of *
|
1620 |
+
- type: basic
|
1621 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1622 |
+
considerate:
|
1623 |
+
- the founders
|
1624 |
+
- founding leaders
|
1625 |
+
- forebears
|
1626 |
+
inconsiderate: founding father
|
1627 |
+
- type: basic
|
1628 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1629 |
+
considerate:
|
1630 |
+
- house worker
|
1631 |
+
- domestic help
|
1632 |
+
inconsiderate: housemaid
|
1633 |
+
- type: basic
|
1634 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1635 |
+
considerate:
|
1636 |
+
- industrial civilization
|
1637 |
+
- industrial people
|
1638 |
+
inconsiderate: industrial man
|
1639 |
+
- type: basic
|
1640 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1641 |
+
considerate: doctor
|
1642 |
+
inconsiderate: lady doctor
|
1643 |
+
- type: basic
|
1644 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1645 |
+
considerate: lead
|
1646 |
+
inconsiderate: leading lady
|
1647 |
+
- type: basic
|
1648 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1649 |
+
considerate: virgin
|
1650 |
+
inconsiderate: maiden
|
1651 |
+
- type: basic
|
1652 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1653 |
+
considerate: first race
|
1654 |
+
inconsiderate: maiden race
|
1655 |
+
- type: basic
|
1656 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1657 |
+
considerate: first speech
|
1658 |
+
inconsiderate: maiden speech
|
1659 |
+
- type: basic
|
1660 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1661 |
+
considerate: staff a desk
|
1662 |
+
inconsiderate: man a desk
|
1663 |
+
- type: basic
|
1664 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1665 |
+
considerate:
|
1666 |
+
- ordinary citizen
|
1667 |
+
- typical person
|
1668 |
+
- average person
|
1669 |
+
inconsiderate: man in the street
|
1670 |
+
- type: basic
|
1671 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1672 |
+
considerate:
|
1673 |
+
- farmer
|
1674 |
+
- rural worker
|
1675 |
+
- grazier
|
1676 |
+
- landowner
|
1677 |
+
- rural community
|
1678 |
+
- country people
|
1679 |
+
- country folk
|
1680 |
+
inconsiderate: man of the land
|
1681 |
+
- type: basic
|
1682 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1683 |
+
considerate: a faithful dog
|
1684 |
+
inconsiderate: mans best friend
|
1685 |
+
- type: basic
|
1686 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1687 |
+
considerate: staff the booth
|
1688 |
+
inconsiderate: man the booth
|
1689 |
+
- type: basic
|
1690 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1691 |
+
considerate: answer the phones
|
1692 |
+
inconsiderate: man the phones
|
1693 |
+
- type: basic
|
1694 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1695 |
+
considerate:
|
1696 |
+
- a demanding task
|
1697 |
+
- a big job
|
1698 |
+
inconsiderate:
|
1699 |
+
- mansized task
|
1700 |
+
- man sized task
|
1701 |
+
- type: basic
|
1702 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1703 |
+
considerate:
|
1704 |
+
- pass key
|
1705 |
+
- original
|
1706 |
+
inconsiderate:
|
1707 |
+
- master key
|
1708 |
+
- master copy
|
1709 |
+
- type: basic
|
1710 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1711 |
+
considerate:
|
1712 |
+
- grand scheme
|
1713 |
+
- guiding principles
|
1714 |
+
inconsiderate: master plan
|
1715 |
+
- type: basic
|
1716 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1717 |
+
considerate: become skilled
|
1718 |
+
inconsiderate: master the art
|
1719 |
+
- type: basic
|
1720 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1721 |
+
considerate: scientists
|
1722 |
+
inconsiderate: men of science
|
1723 |
+
- type: basic
|
1724 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1725 |
+
considerate: birthing nurse
|
1726 |
+
inconsiderate: midwife
|
1727 |
+
- type: basic
|
1728 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1729 |
+
considerate:
|
1730 |
+
- modern civilization
|
1731 |
+
- modern people
|
1732 |
+
inconsiderate: modern man
|
1733 |
+
- type: basic
|
1734 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1735 |
+
considerate:
|
1736 |
+
- unoccupied territory
|
1737 |
+
- wasteland
|
1738 |
+
- deathtrap
|
1739 |
+
inconsiderate: no mans land
|
1740 |
+
- type: basic
|
1741 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1742 |
+
considerate: administrative staff
|
1743 |
+
inconsiderate: office girls
|
1744 |
+
- type: basic
|
1745 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1746 |
+
considerate: poet
|
1747 |
+
inconsiderate: poetess
|
1748 |
+
- type: basic
|
1749 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1750 |
+
considerate: railway worker
|
1751 |
+
inconsiderate: railwayman
|
1752 |
+
- type: basic
|
1753 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1754 |
+
considerate:
|
1755 |
+
- fair
|
1756 |
+
- sporting
|
1757 |
+
inconsiderate: sportsmanlike
|
1758 |
+
- type: basic
|
1759 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1760 |
+
considerate:
|
1761 |
+
- fairness
|
1762 |
+
- good humor
|
1763 |
+
- sense of fair play
|
1764 |
+
inconsiderate: sportsmanship
|
1765 |
+
- type: basic
|
1766 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1767 |
+
considerate: diplomatic
|
1768 |
+
inconsiderate:
|
1769 |
+
- statesmanlike
|
1770 |
+
- statesman like
|
1771 |
+
- type: basic
|
1772 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1773 |
+
considerate:
|
1774 |
+
- cattle worker
|
1775 |
+
- farmhand
|
1776 |
+
- drover
|
1777 |
+
inconsiderate: stockman
|
1778 |
+
- type: basic
|
1779 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1780 |
+
considerate: service entrance
|
1781 |
+
inconsiderate: tradesmans entrance
|
1782 |
+
- type: basic
|
1783 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1784 |
+
considerate:
|
1785 |
+
- tax commissioner
|
1786 |
+
- tax office
|
1787 |
+
- tax collector
|
1788 |
+
inconsiderate: tax man
|
1789 |
+
- type: basic
|
1790 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1791 |
+
considerate: usher
|
1792 |
+
inconsiderate: usherette
|
1793 |
+
- type: basic
|
1794 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1795 |
+
considerate: lawyer
|
1796 |
+
inconsiderate: woman lawyer
|
1797 |
+
- type: basic
|
1798 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1799 |
+
considerate: painter
|
1800 |
+
inconsiderate: woman painter
|
1801 |
+
- type: basic
|
1802 |
+
source: https://radyananda.wordpress.com/2009/06/06/nonsexist-alternative-language-handbook-for-conscious-writers/
|
1803 |
+
considerate:
|
1804 |
+
- wage or salary earning woman
|
1805 |
+
- two-income family
|
1806 |
+
inconsiderate:
|
1807 |
+
- working mother
|
1808 |
+
- working wife
|
app/data/en/lgbtq.yml
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
source: https://www.glaad.org/reference/offensive
|
3 |
+
note: This term has a clinical history and is used to imply LGBTQ+ people are diseased or psychologically/emotionally disordered
|
4 |
+
considerate:
|
5 |
+
- gay
|
6 |
+
- gay man
|
7 |
+
- lesbian
|
8 |
+
- gay person/people
|
9 |
+
inconsiderate:
|
10 |
+
- homosexual
|
11 |
+
- type: basic
|
12 |
+
source: https://www.glaad.org/reference/offensive
|
13 |
+
note: Avoid labeling something as LGBTQ+ unless you would call the same thing “straight”
|
14 |
+
considerate:
|
15 |
+
- relationship
|
16 |
+
inconsiderate:
|
17 |
+
- homosexual relations
|
18 |
+
- homosexual relationship
|
19 |
+
- type: basic
|
20 |
+
source: https://www.glaad.org/reference/offensive
|
21 |
+
note: Avoid labeling something as LGBTQ+ unless you would call the same thing “straight”
|
22 |
+
considerate:
|
23 |
+
- couple
|
24 |
+
inconsiderate:
|
25 |
+
- homosexual couple
|
26 |
+
- type: basic
|
27 |
+
source: https://www.glaad.org/reference/offensive
|
28 |
+
note: Implies that being LGBTQ+ is a choice
|
29 |
+
considerate:
|
30 |
+
- sexual orientation
|
31 |
+
- orientation
|
32 |
+
inconsiderate:
|
33 |
+
- sexual preference
|
34 |
+
- type: basic
|
35 |
+
source: https://www.glaad.org/reference/offensive
|
36 |
+
note: Implies that being LGBTQ+ is a choice
|
37 |
+
considerate:
|
38 |
+
- gay lives
|
39 |
+
- gay/lesbian lives
|
40 |
+
inconsiderate:
|
41 |
+
- gay lifestyle
|
42 |
+
- homosexual lifestyle
|
43 |
+
- type: basic
|
44 |
+
source: https://www.glaad.org/reference/offensive
|
45 |
+
note: Used by anti-LGBTQ+ extremists to create a climate of fear around LGBTQ+ issues
|
46 |
+
considerate:
|
47 |
+
- gay issues
|
48 |
+
inconsiderate:
|
49 |
+
- gay agenda
|
50 |
+
- homosexual agenda
|
51 |
+
- type: basic
|
52 |
+
source: https://www.glaad.org/reference/style
|
53 |
+
note: LGBTQ+ rights are human rights
|
54 |
+
considerate:
|
55 |
+
- equal rights
|
56 |
+
- civil rights for gay people
|
57 |
+
inconsiderate:
|
58 |
+
- special rights
|
59 |
+
- gay rights
|
60 |
+
- type: basic
|
61 |
+
source: https://www.glaad.org/reference/offensive
|
62 |
+
note: Derogatory terms for LGBTQ+ people are offensive
|
63 |
+
considerate:
|
64 |
+
- gay
|
65 |
+
inconsiderate:
|
66 |
+
- fag
|
67 |
+
- faggot
|
68 |
+
- dyke
|
69 |
+
- homo
|
70 |
+
- sodomite
|
71 |
+
- type: basic
|
72 |
+
source: https://www.glaad.org/reference/style
|
73 |
+
note: Avoid using slang shorthand
|
74 |
+
considerate:
|
75 |
+
- bisexual
|
76 |
+
inconsiderate:
|
77 |
+
- bi
|
78 |
+
- type: basic
|
79 |
+
source: https://www.glaad.org/reference/style
|
80 |
+
note: Homosexual has a clinical history and is used to imply LGBTQ+ people are diseased or psychologically/emotionally disordered
|
81 |
+
considerate:
|
82 |
+
- gay marriage
|
83 |
+
- same-sex marriage
|
84 |
+
inconsiderate:
|
85 |
+
- homosexual marriage
|
86 |
+
- type: basic
|
87 |
+
source: https://www.glaad.org/reference/style
|
88 |
+
note: Derogatory terms for LGBTQ+ people are offensive
|
89 |
+
considerate:
|
90 |
+
- transgender
|
91 |
+
inconsiderate:
|
92 |
+
- tranny
|
93 |
+
- type: basic
|
94 |
+
source: https://www.glaad.org/reference/transgender
|
95 |
+
note: Avoid using outdated / offensive terms
|
96 |
+
considerate:
|
97 |
+
- cross-dresser
|
98 |
+
inconsiderate:
|
99 |
+
- transvestite
|
100 |
+
- type: basic
|
101 |
+
source: https://www.glaad.org/reference/transgender
|
102 |
+
note: Avoid overemphasizing surgery when discussing transgender people or the process of transition - it’s not a necessary component
|
103 |
+
considerate:
|
104 |
+
- transition
|
105 |
+
- gender confirmation surgery
|
106 |
+
inconsiderate:
|
107 |
+
- sexchange
|
108 |
+
- sex change
|
109 |
+
- type: basic
|
110 |
+
source: https://www.glaad.org/reference/transgender
|
111 |
+
note: Shift focus away from the assigned sex and towards the identified gender
|
112 |
+
considerate:
|
113 |
+
- sex reassignment surgery
|
114 |
+
- gender confirmation surgery
|
115 |
+
inconsiderate:
|
116 |
+
- sex change operation
|
117 |
+
- type: basic
|
118 |
+
source: https://www.glaad.org/reference/transgender
|
119 |
+
note: Transgender should be used as an adjective, not as a noun
|
120 |
+
considerate:
|
121 |
+
- transgender people
|
122 |
+
inconsiderate:
|
123 |
+
- transgenders
|
124 |
+
- type: basic
|
125 |
+
source: https://www.glaad.org/reference/transgender
|
126 |
+
note: Transgender is already an adjective
|
127 |
+
considerate:
|
128 |
+
- transgender
|
129 |
+
inconsiderate:
|
130 |
+
- transgendered
|
131 |
+
- type: basic
|
132 |
+
source: https://www.glaad.org/reference/transgender
|
133 |
+
note: This is a term used by anti-transgender activists to dehumanize transgender people and reduce who they are to a condition
|
134 |
+
considerate:
|
135 |
+
- being transgender
|
136 |
+
- the movement for transgender equality
|
137 |
+
inconsiderate:
|
138 |
+
- transgenderism
|
139 |
+
- type: basic
|
140 |
+
note: Assigned birth gender is complicated; gender identity is more than what your parents decided you were at birth
|
141 |
+
considerate:
|
142 |
+
- assigned male at birth
|
143 |
+
- designated male at birth
|
144 |
+
inconsiderate:
|
145 |
+
- biologically male
|
146 |
+
- born a man
|
147 |
+
- genetically male
|
148 |
+
- type: basic
|
149 |
+
note: Assigned birth gender is complicated; gender identity is more than what your parents decided you were at birth
|
150 |
+
considerate:
|
151 |
+
- assigned female at birth
|
152 |
+
- designated female at birth
|
153 |
+
inconsiderate:
|
154 |
+
- biologically female
|
155 |
+
- born a woman
|
156 |
+
- genetically female
|
157 |
+
- type: basic
|
158 |
+
source: https://www.glaad.org/reference/transgender
|
159 |
+
note: A term created and used by far-right extremists to oppose nondiscrimination laws that protect transgender people
|
160 |
+
considerate:
|
161 |
+
- non-discrimination law
|
162 |
+
- non-discrimination ordinance
|
163 |
+
inconsiderate:
|
164 |
+
- bathroom bill
|
165 |
+
- type: basic
|
166 |
+
source: http://www.isna.org/node/979
|
167 |
+
note: These terms are stigmatizing to patients and their families because intersex status is more complicated than the mere presence or absence of certain gonadal tissues
|
168 |
+
considerate:
|
169 |
+
- intersex
|
170 |
+
inconsiderate:
|
171 |
+
- hermaphroditic
|
172 |
+
- pseudohermaphroditic
|
173 |
+
- pseudo hermaphroditic
|
174 |
+
- type: basic
|
175 |
+
source: http://www.isna.org/node/979
|
176 |
+
note: These terms are stigmatizing to patients and their families because intersex status is more complicated than the mere presence or absence of certain gonadal tissues
|
177 |
+
considerate:
|
178 |
+
- person who is intersex
|
179 |
+
- person
|
180 |
+
- intersex person
|
181 |
+
inconsiderate:
|
182 |
+
- hermaphrodite
|
183 |
+
- pseudohermaphrodite
|
184 |
+
- pseudo hermaphrodite
|
185 |
+
- type: basic
|
186 |
+
source: https://www.reddit.com/r/asktransgender/comments/23wbq1/is_the_term_shemale_seen_as_offensive/
|
187 |
+
note: This word dehumanizes transgender people
|
188 |
+
considerate:
|
189 |
+
- transgender person
|
190 |
+
- person
|
191 |
+
inconsiderate:
|
192 |
+
- shemale
|
193 |
+
- she male
|
194 |
+
- heshe
|
195 |
+
- shehe
|
196 |
+
- type: basic
|
197 |
+
source: https://www.selfdefined.app/definitions/pronouns/
|
198 |
+
note: Preferred pronoun sounds like it is optional to use someone's correct pronoun
|
199 |
+
considerate:
|
200 |
+
- pronoun
|
201 |
+
- pronouns
|
202 |
+
inconsiderate:
|
203 |
+
- preferred pronoun
|
204 |
+
- preferred pronouns
|
205 |
+
- gender pronoun
|
206 |
+
- gender pronouns
|
app/data/en/misc.yml
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
note: Avoid using terms that implies colonialism/genocide against Indigenous peoples
|
3 |
+
considerate:
|
4 |
+
- keep an eye on things
|
5 |
+
- keep shop
|
6 |
+
- provide coverage
|
7 |
+
- cover things
|
8 |
+
- take charge
|
9 |
+
inconsiderate:
|
10 |
+
- man the fort
|
11 |
+
- type: basic
|
12 |
+
note: Avoid using terms that relate to gun violence.
|
13 |
+
considerate:
|
14 |
+
- go for it
|
15 |
+
- take a chance
|
16 |
+
- make a move
|
17 |
+
- take action
|
18 |
+
inconsiderate:
|
19 |
+
- pull the trigger
|
app/data/en/press.yml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
source: https://www.usnews.com/news/newsgram/articles/2013/04/04/the-associated-press-revises-islamist-another-politically-charged-term
|
3 |
+
considerate:
|
4 |
+
- muslim
|
5 |
+
- person of Islamic faith
|
6 |
+
- fanatic
|
7 |
+
- zealot
|
8 |
+
- follower of islam
|
9 |
+
- follower of the islamic faith
|
10 |
+
inconsiderate:
|
11 |
+
- islamist
|
12 |
+
- type: basic
|
13 |
+
source: https://www.usnews.com/news/newsgram/articles/2013/04/04/the-associated-press-revises-islamist-another-politically-charged-term
|
14 |
+
considerate:
|
15 |
+
- muslims
|
16 |
+
- people of Islamic faith
|
17 |
+
- fanatics
|
18 |
+
- zealots
|
19 |
+
inconsiderate:
|
20 |
+
- islamists
|
app/data/en/race.yml
ADDED
@@ -0,0 +1,370 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
note: Avoid using the term `master`; these suggestions are for the computer term, but there are better alternatives for other cases too
|
3 |
+
considerate:
|
4 |
+
- primary
|
5 |
+
- lead
|
6 |
+
- hub
|
7 |
+
- reference
|
8 |
+
inconsiderate:
|
9 |
+
- master
|
10 |
+
- type: basic
|
11 |
+
note: Avoid using the term `master`; these suggestions are for the computer term, but there are better alternatives for other cases too
|
12 |
+
considerate:
|
13 |
+
- primaries
|
14 |
+
- hubs
|
15 |
+
- references
|
16 |
+
inconsiderate:
|
17 |
+
- masters
|
18 |
+
- type: basic
|
19 |
+
note: Avoid using the term `slave`; these suggestions are for the computer term, but there are better alternatives for other cases too
|
20 |
+
considerate:
|
21 |
+
- secondary
|
22 |
+
- worker
|
23 |
+
- replica
|
24 |
+
- node
|
25 |
+
inconsiderate:
|
26 |
+
- slave
|
27 |
+
- type: basic
|
28 |
+
note: Avoid using the term `slave`; these suggestions are for the computer term, but there are better alternatives for other cases too
|
29 |
+
considerate:
|
30 |
+
- secondaries
|
31 |
+
- workers
|
32 |
+
- replicas
|
33 |
+
- nodes
|
34 |
+
inconsiderate:
|
35 |
+
- slaves
|
36 |
+
- type: basic
|
37 |
+
considerate:
|
38 |
+
- unethical hacker
|
39 |
+
- malicious actor
|
40 |
+
inconsiderate:
|
41 |
+
- blackhat
|
42 |
+
- type: basic
|
43 |
+
considerate:
|
44 |
+
- ethical hacker
|
45 |
+
- security researcher
|
46 |
+
inconsiderate:
|
47 |
+
- whitehat
|
48 |
+
- type: basic
|
49 |
+
considerate:
|
50 |
+
- Inuit
|
51 |
+
inconsiderate:
|
52 |
+
- eskimo
|
53 |
+
- type: basic
|
54 |
+
considerate:
|
55 |
+
- Inuits
|
56 |
+
inconsiderate:
|
57 |
+
- eskimos
|
58 |
+
- type: basic
|
59 |
+
considerate:
|
60 |
+
- Asian person
|
61 |
+
inconsiderate:
|
62 |
+
- oriental
|
63 |
+
- type: basic
|
64 |
+
considerate:
|
65 |
+
- Asian people
|
66 |
+
inconsiderate:
|
67 |
+
- orientals
|
68 |
+
- type: basic
|
69 |
+
considerate:
|
70 |
+
- person of color
|
71 |
+
- people of color
|
72 |
+
inconsiderate:
|
73 |
+
- nonwhite
|
74 |
+
- non white
|
75 |
+
- type: basic
|
76 |
+
considerate:
|
77 |
+
- projects
|
78 |
+
- urban
|
79 |
+
inconsiderate:
|
80 |
+
- ghetto
|
81 |
+
- type: basic
|
82 |
+
considerate:
|
83 |
+
- Native American
|
84 |
+
inconsiderate:
|
85 |
+
- red indian
|
86 |
+
- pocahontas
|
87 |
+
- redskin
|
88 |
+
- type: basic
|
89 |
+
considerate:
|
90 |
+
- Native American People
|
91 |
+
inconsiderate:
|
92 |
+
- red indians
|
93 |
+
- redskins
|
94 |
+
- type: basic
|
95 |
+
inconsiderate:
|
96 |
+
- animal spirit
|
97 |
+
- dream catcher
|
98 |
+
- spirit animal
|
99 |
+
- totem
|
100 |
+
note: Avoid using terms that oversimplify the complex and varied beliefs of indigenous religions.
|
101 |
+
source:
|
102 |
+
- https://www.worldreligionnews.com/opinion/spirit-animal-not-joke-oppression
|
103 |
+
- https://www.spiralnature.com/spirituality/spirit-animal-cultural-appropriation
|
104 |
+
considerate:
|
105 |
+
- favorite
|
106 |
+
- inspiration
|
107 |
+
- personal interest
|
108 |
+
- personality type
|
109 |
+
- type: basic
|
110 |
+
inconsiderate:
|
111 |
+
- long time no hear
|
112 |
+
- long time no see
|
113 |
+
note: Avoid using phrases that implicitly mock people with limited knowledge of the English language.
|
114 |
+
source: https://www.npr.org/sections/codeswitch/2014/03/09/288300303/who-first-said-long-time-no-see-and-in-which-language
|
115 |
+
considerate:
|
116 |
+
- I haven’t seen you in a long time
|
117 |
+
- it’s been a long time
|
118 |
+
- type: basic
|
119 |
+
inconsiderate:
|
120 |
+
- Indian country
|
121 |
+
note: Avoid using phrases referring to the genocidal United States “Indian Removal” laws.
|
122 |
+
source:
|
123 |
+
- https://newsmaven.io/indiancountrytoday/archive/off-the-reservation-a-teachable-moment-nW1d7U0JRkOszhtg8N1V1A/
|
124 |
+
considerate:
|
125 |
+
- enemy territory
|
126 |
+
- type: basic
|
127 |
+
inconsiderate:
|
128 |
+
- jump the reservation
|
129 |
+
- off reserve
|
130 |
+
- off the reservation
|
131 |
+
note: Avoid using phrases referring to the genocidal United States “Indian Removal” laws.
|
132 |
+
source:
|
133 |
+
- http://blog.nativepartnership.org/off-the-reservation/
|
134 |
+
- https://www.wsj.com/articles/off-the-reservation-is-a-phrase-with-a-dark-past-1462552837
|
135 |
+
- https://www.npr.org/sections/codeswitch/2014/06/29/326690947/should-saying-someone-is-off-the-reservation-be-off-limits
|
136 |
+
- https://nowtoronto.com/news/native-references-and-terms-that-are-offensive-to-indigenous-people/
|
137 |
+
considerate:
|
138 |
+
- disobey
|
139 |
+
- endure
|
140 |
+
- object to
|
141 |
+
- oppose
|
142 |
+
- resist
|
143 |
+
- type: basic
|
144 |
+
inconsiderate:
|
145 |
+
- circle the wagons
|
146 |
+
- on the warpath
|
147 |
+
note: Avoid using phrases referring to colonial stereotypes regarding Native Americans.
|
148 |
+
source:
|
149 |
+
- https://idioms.thefreedictionary.com/circle+the+wagons
|
150 |
+
- https://idioms.thefreedictionary.com/go+on+the+warpath
|
151 |
+
considerate:
|
152 |
+
- defend
|
153 |
+
- type: basic
|
154 |
+
inconsiderate:
|
155 |
+
- too many chiefs
|
156 |
+
note: Avoid using phrases referring to colonial stereotypes regarding Native Americans.
|
157 |
+
source:
|
158 |
+
- https://idioms.thefreedictionary.com/too+many+chiefs+and+not+enough+Indians
|
159 |
+
considerate:
|
160 |
+
- too many chefs in the kitchen
|
161 |
+
- too many cooks spoil the broth
|
162 |
+
- type: basic
|
163 |
+
inconsiderate:
|
164 |
+
- natives are restless
|
165 |
+
- natives are becoming restless
|
166 |
+
- natives are getting restless
|
167 |
+
- natives are growing restless
|
168 |
+
note: Avoid using phrases referring to colonial stereotypes regarding indigenous peoples.
|
169 |
+
source:
|
170 |
+
- https://tvtropes.org/pmwiki/pmwiki.php/Main/TheNativesAreRestless
|
171 |
+
considerate:
|
172 |
+
- dissatisfied
|
173 |
+
- frustrated
|
174 |
+
- type: basic
|
175 |
+
inconsiderate:
|
176 |
+
- pow wow
|
177 |
+
- powwow
|
178 |
+
note: Avoid casually using this term, which refers to traditional indigenous celebration ceremonies that were banned by genocidal laws in the United States and Canada — Native people died fighting for this right.
|
179 |
+
source:
|
180 |
+
- https://twitter.com/chadloder/status/1203507070772793345
|
181 |
+
- http://nativeappropriations.com/2012/09/paul-frank-offends-every-native-person-on-the-planet-with-fashion-night-out-dream-catchin-pow-wow.html
|
182 |
+
- https://www.britannica.com/topic/powwow
|
183 |
+
- https://nowtoronto.com/news/native-references-and-terms-that-are-offensive-to-indigenous-people/
|
184 |
+
considerate:
|
185 |
+
- conference
|
186 |
+
- gathering
|
187 |
+
- meeting
|
188 |
+
- type: basic
|
189 |
+
note: Avoid using phrases referring to colonial stereotypes regarding Native Americans.
|
190 |
+
considerate:
|
191 |
+
- go back on one’s offer
|
192 |
+
inconsiderate:
|
193 |
+
- indian give
|
194 |
+
- indian giver
|
195 |
+
- type: basic
|
196 |
+
considerate:
|
197 |
+
- Filipinos
|
198 |
+
- Filipino people
|
199 |
+
inconsiderate:
|
200 |
+
- pinoys
|
201 |
+
- pinays
|
202 |
+
- type: basic
|
203 |
+
considerate:
|
204 |
+
- Arabs
|
205 |
+
- Middle Eastern People
|
206 |
+
inconsiderate:
|
207 |
+
- towel heads
|
208 |
+
- type: basic
|
209 |
+
note: Whenever possible, try to be gender inclusive.
|
210 |
+
considerate:
|
211 |
+
- Latinx
|
212 |
+
inconsiderate:
|
213 |
+
- latino
|
214 |
+
- latina
|
215 |
+
- type: basic
|
216 |
+
considerate:
|
217 |
+
- Japanese person
|
218 |
+
- Japanese people
|
219 |
+
inconsiderate:
|
220 |
+
- japs
|
221 |
+
- type: basic
|
222 |
+
considerate:
|
223 |
+
- Jewish person
|
224 |
+
inconsiderate:
|
225 |
+
- shlomo
|
226 |
+
- shyster
|
227 |
+
- hymie
|
228 |
+
- type: basic
|
229 |
+
considerate:
|
230 |
+
- a person who is not Jewish
|
231 |
+
- not Jewish
|
232 |
+
inconsiderate:
|
233 |
+
- goyim
|
234 |
+
- goyum
|
235 |
+
- goy
|
236 |
+
- type: basic
|
237 |
+
considerate:
|
238 |
+
- a Black person
|
239 |
+
inconsiderate:
|
240 |
+
- spade
|
241 |
+
- type: basic
|
242 |
+
source: en.wikipedia.org/wiki/Romani_people#cite_ref-80
|
243 |
+
note: Gypsy is insensitive, use Roma or Romani. They’re not Egyptian as the name suggests.
|
244 |
+
considerate:
|
245 |
+
- Nomad
|
246 |
+
- Traveler
|
247 |
+
- Roma
|
248 |
+
- Romani
|
249 |
+
inconsiderate:
|
250 |
+
- gyppo
|
251 |
+
- gypsy
|
252 |
+
- Gipsy
|
253 |
+
- gyp
|
254 |
+
- type: basic
|
255 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
256 |
+
considerate:
|
257 |
+
- blocklist
|
258 |
+
- wronglist
|
259 |
+
- banlist
|
260 |
+
- deny list
|
261 |
+
inconsiderate:
|
262 |
+
- blacklist
|
263 |
+
- black list
|
264 |
+
- type: basic
|
265 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
266 |
+
considerate:
|
267 |
+
- blocklisted
|
268 |
+
- wronglisted
|
269 |
+
- banlisted
|
270 |
+
- deny-listed
|
271 |
+
inconsiderate:
|
272 |
+
- blacklisted
|
273 |
+
- type: basic
|
274 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
275 |
+
considerate:
|
276 |
+
- blocklisting
|
277 |
+
- wronglisting
|
278 |
+
- banlisting
|
279 |
+
- deny-listing
|
280 |
+
inconsiderate:
|
281 |
+
- blacklisting
|
282 |
+
- type: basic
|
283 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
284 |
+
considerate:
|
285 |
+
- passlist
|
286 |
+
- alrightlist
|
287 |
+
- safelist
|
288 |
+
- allow list
|
289 |
+
inconsiderate:
|
290 |
+
- whitelist
|
291 |
+
- white list
|
292 |
+
- type: basic
|
293 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
294 |
+
considerate:
|
295 |
+
- passlisted
|
296 |
+
- alrightlisted
|
297 |
+
- safelisted
|
298 |
+
- allow-listed
|
299 |
+
inconsiderate:
|
300 |
+
- whitelisted
|
301 |
+
- type: basic
|
302 |
+
note: Replace racially-charged language with more accurate and inclusive words
|
303 |
+
considerate:
|
304 |
+
- passlisting
|
305 |
+
- alrightlisting
|
306 |
+
- safelisting
|
307 |
+
- allow-listing
|
308 |
+
inconsiderate:
|
309 |
+
- whitelisting
|
310 |
+
- type: basic
|
311 |
+
note: Avoid using terms that imply a group has not changed over time and that they are inferior
|
312 |
+
considerate:
|
313 |
+
- simple
|
314 |
+
- indigenous
|
315 |
+
- hunter-gatherer
|
316 |
+
inconsiderate:
|
317 |
+
- primitive
|
318 |
+
- savage
|
319 |
+
- stone age
|
320 |
+
- type: basic
|
321 |
+
note: Avoid using terms that make some groups sound inferior
|
322 |
+
considerate:
|
323 |
+
- society
|
324 |
+
- community
|
325 |
+
inconsiderate:
|
326 |
+
- tribe
|
327 |
+
- type: basic
|
328 |
+
note: Avoid using terms that make some groups sound inferior. Replace “sophisticated” with a neutral term such as “complex”
|
329 |
+
considerate:
|
330 |
+
- complex culture
|
331 |
+
inconsiderate:
|
332 |
+
- sophisticated culture
|
333 |
+
- type: basic
|
334 |
+
note: Avoid using terms that make some groups sound inferior. Replace “sophisticated” with a neutral term such as “complex”
|
335 |
+
considerate:
|
336 |
+
- complex technology
|
337 |
+
inconsiderate:
|
338 |
+
- sophisticated technology
|
339 |
+
- type: basic
|
340 |
+
note: Avoid using `bugreport`, as the word `bugre` is a slur in Brazilian Portuguese
|
341 |
+
considerate:
|
342 |
+
- bug report
|
343 |
+
- snapshot
|
344 |
+
inconsiderate:
|
345 |
+
- bugreport
|
346 |
+
- type: basic
|
347 |
+
source: https://en.wikipedia.org/wiki/Grandfather_clause#Origin
|
348 |
+
note: Avoid using phrases referring to racist United States “Jim Crow” laws.
|
349 |
+
considerate:
|
350 |
+
- legacy policy
|
351 |
+
- legacy clause
|
352 |
+
- deprecation policy
|
353 |
+
inconsiderate:
|
354 |
+
- grandfather clause
|
355 |
+
- grandfather policy
|
356 |
+
- type: basic
|
357 |
+
source: https://en.wikipedia.org/wiki/Grandfather_clause#Origin
|
358 |
+
note: Avoid using phrases referring to racist United States “Jim Crow” laws.
|
359 |
+
considerate:
|
360 |
+
- deprecate
|
361 |
+
inconsiderate:
|
362 |
+
- grandfathering
|
363 |
+
- type: basic
|
364 |
+
source: https://en.wikipedia.org/wiki/Grandfather_clause#Origin
|
365 |
+
note: Avoid using phrases referring to racist United States “Jim Crow” laws.
|
366 |
+
considerate:
|
367 |
+
- deprecated
|
368 |
+
- legacy
|
369 |
+
inconsiderate:
|
370 |
+
- grandfathered
|
app/data/en/slogans.yml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
considerate:
|
3 |
+
- improve
|
4 |
+
inconsiderate:
|
5 |
+
- make * great again
|
6 |
+
- make * * great again
|
7 |
+
- make * * * great again
|
8 |
+
- make * * * * great again
|
9 |
+
- make * * * * * great again
|
app/data/en/suicide.yml
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- type: basic
|
2 |
+
source: https://www.afsp.org/news-events/for-the-media/reporting-on-suicide, https://www.speakingofsuicide.com/2013/04/13/language/
|
3 |
+
considerate:
|
4 |
+
- died by suicide
|
5 |
+
inconsiderate:
|
6 |
+
- committed suicide
|
7 |
+
- completed suicide
|
8 |
+
- type: basic
|
9 |
+
source: https://www.afsp.org/news-events/for-the-media/reporting-on-suicide, https://www.speakingofsuicide.com/2013/04/13/language/
|
10 |
+
note: Committing suicide is not successful/unsuccessful, that sends the wrong message
|
11 |
+
considerate:
|
12 |
+
- die by suicide
|
13 |
+
inconsiderate:
|
14 |
+
- commit suicide
|
15 |
+
- complete suicide
|
16 |
+
- successful suicide
|
17 |
+
- type: basic
|
18 |
+
source: https://www.afsp.org/news-events/for-the-media/reporting-on-suicide
|
19 |
+
note: Using sensational words can cause copycat suicides or contagion
|
20 |
+
considerate:
|
21 |
+
- rise in suicides
|
22 |
+
inconsiderate:
|
23 |
+
- suicide epidemic
|
24 |
+
- epidemic of suicides
|
25 |
+
- suicide pact
|
26 |
+
- type: basic
|
27 |
+
source: https://www.speakingofsuicide.com/2013/04/13/language, https://www.afsp.org/news-events/for-the-media/reporting-on-suicide
|
28 |
+
note: Attempted suicide should not be depicted as a failure
|
29 |
+
considerate:
|
30 |
+
- suicide attempt
|
31 |
+
- attempted suicide
|
32 |
+
inconsiderate:
|
33 |
+
- failed suicide
|
34 |
+
- failed attempt
|
35 |
+
- suicide failure
|
36 |
+
- type: basic
|
37 |
+
source: https://www.afsp.org/news-events/for-the-media/reporting-on-suicide
|
38 |
+
considerate:
|
39 |
+
- a note from the deceased
|
40 |
+
inconsiderate:
|
41 |
+
- suicide note
|
42 |
+
- type: basic
|
43 |
+
note: When describing the behavior of computer software, using the word “hanged” needlessly invokes the topic of death by self-harm or lynching. Consider using the word “froze” or the phrase “stopped responding to events” or “became unresponsive” instead.
|
44 |
+
considerate:
|
45 |
+
- the app froze
|
46 |
+
- the app stopped responding
|
47 |
+
- the app stopped responding to events
|
48 |
+
- the app became unresponsive
|
49 |
+
inconsiderate:
|
50 |
+
- hang
|
51 |
+
- hanged
|
app/main.py
CHANGED
@@ -1,48 +1,5 @@
|
|
1 |
-
from
|
2 |
-
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
logger = logging.getLogger(__name__)
|
7 |
-
|
8 |
-
# Import all individual routers for different functionalities
|
9 |
-
from app.routers import (
|
10 |
-
grammar,
|
11 |
-
punctuation,
|
12 |
-
sentence_correctness,
|
13 |
-
tone,
|
14 |
-
voice,
|
15 |
-
inclusive_language,
|
16 |
-
vocabulary,
|
17 |
-
conciseness,
|
18 |
-
readability,
|
19 |
-
paraphrase,
|
20 |
-
translate,
|
21 |
-
summarize
|
22 |
-
)
|
23 |
-
|
24 |
-
# Initialize the FastAPI application
|
25 |
-
app = FastAPI()
|
26 |
-
|
27 |
-
@app.get("/")
|
28 |
-
def root():
|
29 |
-
"""
|
30 |
-
Root endpoint for the API.
|
31 |
-
Returns a welcome message.
|
32 |
-
"""
|
33 |
-
logger.info("Root endpoint accessed.")
|
34 |
-
return {"message": "Welcome to Grammafree API"}
|
35 |
-
|
36 |
-
# Include all the individual routers for modular API structure.
|
37 |
-
app.include_router(grammar.router) # Grammar correction and diffs
|
38 |
-
app.include_router(punctuation.router) # Punctuation fixes
|
39 |
-
app.include_router(sentence_correctness.router) # Sentence correctness feedback
|
40 |
-
app.include_router(tone.router) # Tone detection and suggestions
|
41 |
-
app.include_router(voice.router) # Active/Passive voice detection
|
42 |
-
app.include_router(inclusive_language.router) # Inclusive language rewriting
|
43 |
-
app.include_router(vocabulary.router) # Vocabulary enhancement
|
44 |
-
app.include_router(conciseness.router) # Conciseness suggestions
|
45 |
-
app.include_router(readability.router) # Readability scores
|
46 |
-
app.include_router(paraphrase.router) # Existing paraphrasing functionality
|
47 |
-
app.include_router(translate.router) # Existing translation functionality
|
48 |
-
app.include_router(summarize.router) # Existing summarization functionality
|
|
|
1 |
+
from app.core.app import create_app
|
2 |
+
from app.core.logging import configure_logging
|
3 |
|
4 |
+
configure_logging()
|
5 |
+
app = create_app()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/models.py
DELETED
@@ -1,108 +0,0 @@
|
|
1 |
-
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, pipeline
|
2 |
-
import torch
|
3 |
-
|
4 |
-
# Set the device for model inference (CPU is used by default)
|
5 |
-
# You can change to "cuda" if a compatible GPU is available for faster processing.
|
6 |
-
device = torch.device("cpu")
|
7 |
-
|
8 |
-
# --- Grammar model ---
|
9 |
-
# Changed to deepashri/t5-small-grammar-correction, a publicly available model
|
10 |
-
# for grammatical error correction. This model is fine-tuned from T5-small.
|
11 |
-
grammar_tokenizer = AutoTokenizer.from_pretrained("AventIQ-AI/t5-small-grammar-correction")
|
12 |
-
grammar_model = AutoModelForSeq2SeqLM.from_pretrained("AventIQ-AI/t5-small-grammar-correction").to(device)
|
13 |
-
|
14 |
-
# --- FLAN-T5 for all prompts ---
|
15 |
-
# Uses google/flan-t5-small for various text generation tasks based on prompts,
|
16 |
-
# such as paraphrasing, summarizing, and generating tone suggestions.
|
17 |
-
flan_tokenizer = AutoTokenizer.from_pretrained("google/flan-t5-small")
|
18 |
-
flan_model = AutoModelForSeq2SeqLM.from_pretrained("google/flan-t5-small").to(device)
|
19 |
-
|
20 |
-
# --- Translation model ---
|
21 |
-
# Uses Helsinki-NLP/opus-mt-en-ROMANCE for English to Romance language translation.
|
22 |
-
trans_tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-ROMANCE")
|
23 |
-
trans_model = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-en-ROMANCE").to(device)
|
24 |
-
|
25 |
-
# --- Tone classification model ---
|
26 |
-
# Uses j-hartmann/emotion-english-distilroberta-base for detecting emotions/tones
|
27 |
-
# within text. This provides a more nuanced analysis than simple positive/negative.
|
28 |
-
# 'top_k=1' ensures that only the most confident label is returned.
|
29 |
-
tone_classifier = pipeline("sentiment-analysis", model="j-hartmann/emotion-english-distilroberta-base", top_k=1)
|
30 |
-
|
31 |
-
def run_grammar_correction(text: str) -> str:
|
32 |
-
"""
|
33 |
-
Corrects the grammar of the input text using the pre-trained T5 grammar model.
|
34 |
-
|
35 |
-
Args:
|
36 |
-
text (str): The input text to be grammatically corrected.
|
37 |
-
|
38 |
-
Returns:
|
39 |
-
str: The corrected text.
|
40 |
-
"""
|
41 |
-
# Prepare the input for the grammar model by prefixing with "grammar: " as per
|
42 |
-
# the 'deepashri/t5-small-grammar-correction' model's expected input format.
|
43 |
-
# Some grammar correction models expect a specific prefix like "grammar: " or "fix: ".
|
44 |
-
inputs = grammar_tokenizer(f"grammar: {text}", return_tensors="pt").to(device)
|
45 |
-
# Generate the corrected output
|
46 |
-
outputs = grammar_model.generate(**inputs)
|
47 |
-
# Decode the generated tokens back into a readable string, skipping special tokens
|
48 |
-
return grammar_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
49 |
-
|
50 |
-
def run_flan_prompt(prompt: str) -> str:
|
51 |
-
"""
|
52 |
-
Runs a given prompt through the FLAN-T5 model to generate a response.
|
53 |
-
Includes advanced generation parameters for better output quality.
|
54 |
-
|
55 |
-
Args:
|
56 |
-
prompt (str): The prompt string to be processed by FLAN-T5.
|
57 |
-
|
58 |
-
Returns:
|
59 |
-
str: The generated text response from FLAN-T5.
|
60 |
-
"""
|
61 |
-
# Prepare the input for the FLAN-T5 model
|
62 |
-
inputs = flan_tokenizer(prompt, return_tensors="pt").to(device)
|
63 |
-
|
64 |
-
# Generate the output with improved parameters:
|
65 |
-
outputs = flan_model.generate(
|
66 |
-
**inputs,
|
67 |
-
max_new_tokens=100,
|
68 |
-
num_beams=5,
|
69 |
-
do_sample=True,
|
70 |
-
top_k=50,
|
71 |
-
top_p=0.95,
|
72 |
-
temperature=0.7
|
73 |
-
)
|
74 |
-
# Decode the generated tokens back into a readable string
|
75 |
-
return flan_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
76 |
-
|
77 |
-
def run_translation(text: str, target_lang: str) -> str:
|
78 |
-
"""
|
79 |
-
Translates the input text to the target language using the Helsinki-NLP translation model.
|
80 |
-
|
81 |
-
Args:
|
82 |
-
text (str): The input text to be translated.
|
83 |
-
target_lang (str): The target language code (e.g., "fr" for French, "es" for Spanish).
|
84 |
-
|
85 |
-
Returns:
|
86 |
-
str: The translated text.
|
87 |
-
"""
|
88 |
-
# Prepare the input for the translation model by specifying the target language
|
89 |
-
inputs = trans_tokenizer(f">>{target_lang}<< {text}", return_tensors="pt").to(device)
|
90 |
-
# Generate the translated output
|
91 |
-
outputs = trans_model.generate(**inputs)
|
92 |
-
# Decode the generated tokens back into a readable string
|
93 |
-
return trans_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
94 |
-
|
95 |
-
def classify_tone(text: str) -> str:
|
96 |
-
"""
|
97 |
-
Classifies the emotional tone of the input text using the pre-trained emotion classifier.
|
98 |
-
|
99 |
-
Args:
|
100 |
-
text (str): The input text for tone classification.
|
101 |
-
|
102 |
-
Returns:
|
103 |
-
str: The detected emotional label (e.g., 'neutral', 'joy', 'sadness', 'anger', 'fear', 'disgust', 'surprise').
|
104 |
-
"""
|
105 |
-
# The tone_classifier returns a list of dictionaries, where each dictionary
|
106 |
-
# contains 'label' and 'score'. We extract the 'label' from the first (and only) result.
|
107 |
-
result = tone_classifier(text)[0][0]
|
108 |
-
return result['label']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/prompts.py
DELETED
@@ -1,121 +0,0 @@
|
|
1 |
-
def tone_prompt(text: str, tone: str) -> str:
|
2 |
-
"""
|
3 |
-
Generates a prompt to rewrite text in a specified tone.
|
4 |
-
|
5 |
-
Args:
|
6 |
-
text (str): The original text.
|
7 |
-
tone (str): The desired tone (e.g., "formal", "informal", "confident").
|
8 |
-
|
9 |
-
Returns:
|
10 |
-
str: The generated prompt.
|
11 |
-
"""
|
12 |
-
return f"Rewrite the following text in a {tone} tone: {text}"
|
13 |
-
|
14 |
-
def clarity_prompt(text: str) -> str:
|
15 |
-
"""
|
16 |
-
Generates a prompt to make text clearer.
|
17 |
-
|
18 |
-
Args:
|
19 |
-
text (str): The original text.
|
20 |
-
|
21 |
-
Returns:
|
22 |
-
str: The generated prompt.
|
23 |
-
"""
|
24 |
-
return f"Make this clearer: {text}"
|
25 |
-
|
26 |
-
def fluency_prompt(text: str) -> str:
|
27 |
-
"""
|
28 |
-
Generates a prompt to improve the fluency of a sentence.
|
29 |
-
|
30 |
-
Args:
|
31 |
-
text (str): The original sentence.
|
32 |
-
|
33 |
-
Returns:
|
34 |
-
str: The generated prompt.
|
35 |
-
"""
|
36 |
-
return f"Improve the fluency of this sentence: {text}"
|
37 |
-
|
38 |
-
def paraphrase_prompt(text: str) -> str:
|
39 |
-
"""
|
40 |
-
Generates a prompt to paraphrase text.
|
41 |
-
|
42 |
-
Args:
|
43 |
-
text (str): The original text.
|
44 |
-
|
45 |
-
Returns:
|
46 |
-
str: The generated prompt.
|
47 |
-
"""
|
48 |
-
return f"Paraphrase: {text}"
|
49 |
-
|
50 |
-
def summarize_prompt(text: str) -> str:
|
51 |
-
"""
|
52 |
-
Generates a prompt to summarize text.
|
53 |
-
|
54 |
-
Args:
|
55 |
-
text (str): The original text.
|
56 |
-
|
57 |
-
Returns:
|
58 |
-
str: The generated prompt.
|
59 |
-
"""
|
60 |
-
return f"Summarize: {text}"
|
61 |
-
|
62 |
-
def pronoun_friendly_prompt(text: str) -> str:
|
63 |
-
"""
|
64 |
-
Generates a prompt to rewrite text using inclusive, respectful language,
|
65 |
-
avoiding gender-specific pronouns.
|
66 |
-
|
67 |
-
Args:
|
68 |
-
text (str): The original text.
|
69 |
-
|
70 |
-
Returns:
|
71 |
-
str: The generated prompt.
|
72 |
-
"""
|
73 |
-
return f"Rewrite the following text using inclusive, respectful language avoiding gender-specific pronouns: {text}"
|
74 |
-
|
75 |
-
def active_voice_prompt(text: str) -> str:
|
76 |
-
"""
|
77 |
-
Generates a prompt to detect passive/active voice and suggest an active voice version if passive.
|
78 |
-
|
79 |
-
Args:
|
80 |
-
text (str): The original text.
|
81 |
-
|
82 |
-
Returns:
|
83 |
-
str: The generated prompt.
|
84 |
-
"""
|
85 |
-
return f"Detect if this is passive or active voice. If passive, suggest an active voice version: {text}"
|
86 |
-
|
87 |
-
def tone_analysis_prompt(text: str) -> str:
|
88 |
-
"""
|
89 |
-
Generates a prompt to analyze the tone of text and suggest improvements.
|
90 |
-
|
91 |
-
Args:
|
92 |
-
text (str): The original text.
|
93 |
-
|
94 |
-
Returns:
|
95 |
-
str: The generated prompt.
|
96 |
-
"""
|
97 |
-
return f"Analyze the tone of the following text and suggest improvements if needed: {text}"
|
98 |
-
|
99 |
-
def vocabulary_prompt(text: str) -> str:
|
100 |
-
"""
|
101 |
-
Generates a prompt to suggest vocabulary improvements for the given text.
|
102 |
-
|
103 |
-
Args:
|
104 |
-
text (str): The original text.
|
105 |
-
|
106 |
-
Returns:
|
107 |
-
str: The generated prompt.
|
108 |
-
"""
|
109 |
-
return f"For the following text, identify any weak or overused words and suggest stronger, more precise synonyms or alternative phrasing. Provide suggestions as a list of 'original word/phrase -> suggested word/phrase': {text}"
|
110 |
-
|
111 |
-
def conciseness_prompt(text: str) -> str:
|
112 |
-
"""
|
113 |
-
Generates a prompt to make the given text more concise.
|
114 |
-
|
115 |
-
Args:
|
116 |
-
text (str): The original text.
|
117 |
-
|
118 |
-
Returns:
|
119 |
-
str: The generated prompt.
|
120 |
-
"""
|
121 |
-
return f"Rewrite the following text to be more concise, removing any unnecessary words or phrases while retaining the original meaning: {text}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/conciseness.py
DELETED
@@ -1,42 +0,0 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status # Import HTTPException and status
|
2 |
-
from pydantic import BaseModel
|
3 |
-
from app import models, prompts
|
4 |
-
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
-
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
-
|
9 |
-
router = APIRouter()
|
10 |
-
|
11 |
-
class ConcisenessInput(BaseModel):
|
12 |
-
"""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /conciseness_check endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/conciseness_check", dependencies=[Depends(verify_api_key)])
|
19 |
-
def conciseness_check(payload: ConcisenessInput):
|
20 |
-
"""
|
21 |
-
Provides suggestions for making text more concise.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (ConcisenessInput): The request body containing the text to be analyzed.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing the concise version of the text.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
concise_text = models.run_flan_prompt(prompts.conciseness_prompt(text))
|
33 |
-
|
34 |
-
return {
|
35 |
-
"concise_version": concise_text
|
36 |
-
}
|
37 |
-
except Exception as e:
|
38 |
-
logger.error(f"Error in conciseness_check: {e}", exc_info=True)
|
39 |
-
raise HTTPException(
|
40 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
41 |
-
detail=f"An error occurred during conciseness checking: {e}"
|
42 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/grammar.py
CHANGED
@@ -1,61 +1,60 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
import difflib
|
6 |
-
import logging
|
7 |
|
|
|
|
|
8 |
logger = logging.getLogger(__name__)
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
dict: A dictionary containing the corrected text and a list of changes.
|
29 |
-
"""
|
30 |
-
original_text = payload.text
|
31 |
-
|
32 |
-
try:
|
33 |
-
corrected_text = models.run_grammar_correction(original_text)
|
34 |
-
|
35 |
-
grammar_changes = []
|
36 |
-
s = difflib.SequenceMatcher(None, original_text.split(), corrected_text.split())
|
37 |
-
|
38 |
-
for opcode, i1, i2, j1, j2 in s.get_opcodes():
|
39 |
-
if opcode == 'replace':
|
40 |
-
original_part = ' '.join(original_text.split()[i1:i2])
|
41 |
-
corrected_part = ' '.join(corrected_text.split()[j1:j2])
|
42 |
-
grammar_changes.append(f"'{original_part}' \u2192 '{corrected_part}'")
|
43 |
-
elif opcode == 'delete':
|
44 |
-
deleted_part = ' '.join(original_text.split()[i1:i2])
|
45 |
-
grammar_changes.append(f"'{deleted_part}' removed")
|
46 |
-
elif opcode == 'insert':
|
47 |
-
inserted_part = ' '.join(corrected_text.split()[j1:j2])
|
48 |
-
grammar_changes.append(f"'{inserted_part}' added")
|
49 |
-
|
50 |
-
return {
|
51 |
-
"grammar": {
|
52 |
-
"corrected": corrected_text,
|
53 |
-
"changes": grammar_changes
|
54 |
-
}
|
55 |
}
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
raise HTTPException(
|
59 |
-
status_code=status.
|
60 |
-
detail=
|
61 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
+
from app.services.grammar import GrammarCorrector
|
4 |
from app.core.security import verify_api_key
|
5 |
import difflib
|
6 |
+
import logging
|
7 |
|
8 |
+
router = APIRouter(prefix="/grammar", tags=["Grammar"])
|
9 |
+
corrector = GrammarCorrector()
|
10 |
logger = logging.getLogger(__name__)
|
11 |
|
12 |
+
def get_diff_issues(original: str, corrected: str):
|
13 |
+
matcher = difflib.SequenceMatcher(None, original, corrected)
|
14 |
+
issues = []
|
15 |
+
|
16 |
+
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
|
17 |
+
if tag == 'equal':
|
18 |
+
continue
|
19 |
+
|
20 |
+
issue = {
|
21 |
+
"offset": i1,
|
22 |
+
"length": i2 - i1,
|
23 |
+
"original": original[i1:i2],
|
24 |
+
"suggestion": corrected[j1:j2],
|
25 |
+
"context_before": original[max(0, i1 - 15):i1],
|
26 |
+
"context_after": original[i2:i2 + 15],
|
27 |
+
"message": "Grammar correction",
|
28 |
+
"line": original[:i1].count("\n") + 1,
|
29 |
+
"column": i1 - original[:i1].rfind("\n") if "\n" in original[:i1] else i1 + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
+
issues.append(issue)
|
32 |
+
|
33 |
+
return issues
|
34 |
+
|
35 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
36 |
+
def correct_grammar(payload: TextOnlyRequest):
|
37 |
+
text = payload.text.strip()
|
38 |
+
|
39 |
+
if not text:
|
40 |
raise HTTPException(
|
41 |
+
status_code=status.HTTP_400_BAD_REQUEST,
|
42 |
+
detail="Input text cannot be empty."
|
43 |
)
|
44 |
+
|
45 |
+
corrected = corrector.correct(text)
|
46 |
+
|
47 |
+
if corrected.startswith("Input text is empty."):
|
48 |
+
raise HTTPException(status_code=400, detail="Input text cannot be empty.")
|
49 |
+
elif corrected.startswith("An error occurred during grammar correction."):
|
50 |
+
raise HTTPException(status_code=500, detail=corrected)
|
51 |
+
|
52 |
+
issues = get_diff_issues(text, corrected)
|
53 |
+
|
54 |
+
return {
|
55 |
+
"grammar": {
|
56 |
+
"original_text": text,
|
57 |
+
"corrected_text_suggestion": corrected,
|
58 |
+
"issues": issues
|
59 |
+
}
|
60 |
+
}
|
app/routers/inclusive_language.py
CHANGED
@@ -1,42 +1,11 @@
|
|
1 |
-
from fastapi import APIRouter, Depends
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
|
7 |
-
|
|
|
8 |
|
9 |
-
router =
|
10 |
-
|
11 |
-
|
12 |
-
"""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /inclusive_language endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/inclusive_language", dependencies=[Depends(verify_api_key)])
|
19 |
-
def inclusive_language_check(payload: InclusiveLanguageInput):
|
20 |
-
"""
|
21 |
-
Provides suggestions for rewriting text using inclusive language.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (InclusiveLanguageInput): The request body containing the text to be analyzed.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing the rewritten text with inclusive language.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
inclusive_text = models.run_flan_prompt(prompts.pronoun_friendly_prompt(text))
|
33 |
-
|
34 |
-
return {
|
35 |
-
"inclusive_pronouns": inclusive_text
|
36 |
-
}
|
37 |
-
except Exception as e:
|
38 |
-
logger.error(f"Error in inclusive_language_check: {e}", exc_info=True)
|
39 |
-
raise HTTPException(
|
40 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
41 |
-
detail=f"An error occurred during inclusive language check: {e}"
|
42 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
+
from app.services.inclusive_language import InclusiveLanguageChecker
|
4 |
from app.core.security import verify_api_key
|
|
|
5 |
|
6 |
+
router = APIRouter(prefix="/inclusive-language", tags=["Inclusive Language"])
|
7 |
+
checker = InclusiveLanguageChecker()
|
8 |
|
9 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
10 |
+
def check_inclusive_language(payload: TextOnlyRequest):
|
11 |
+
return {"suggestions": checker.check(payload.text)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/paraphrase.py
CHANGED
@@ -1,39 +1,12 @@
|
|
1 |
-
from fastapi import APIRouter, Depends
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
|
7 |
-
|
|
|
8 |
|
9 |
-
router =
|
10 |
-
|
11 |
-
|
12 |
-
""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /paraphrase endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/paraphrase", dependencies=[Depends(verify_api_key)])
|
19 |
-
def paraphrase(payload: ParaphraseInput): # Renamed input to payload for consistency
|
20 |
-
"""
|
21 |
-
Paraphrases the provided text.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (ParaphraseInput): The request body containing the text to be paraphrased.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing the paraphrased text.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
paraphrased_text = models.run_flan_prompt(prompts.paraphrase_prompt(text))
|
33 |
-
return {"result": paraphrased_text}
|
34 |
-
except Exception as e:
|
35 |
-
logger.error(f"Error in paraphrase: {e}", exc_info=True)
|
36 |
-
raise HTTPException(
|
37 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
38 |
-
detail=f"An error occurred during paraphrasing: {e}"
|
39 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
+
from app.services.paraphrase import Paraphraser
|
4 |
from app.core.security import verify_api_key
|
|
|
5 |
|
6 |
+
router = APIRouter(prefix="/paraphrase", tags=["Paraphrase"])
|
7 |
+
paraphraser = Paraphraser()
|
8 |
|
9 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
10 |
+
def paraphrase_text(payload: TextOnlyRequest):
|
11 |
+
result = paraphraser.paraphrase(payload.text)
|
12 |
+
return {"result": result}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/punctuation.py
DELETED
@@ -1,67 +0,0 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status # Import HTTPException and status
|
2 |
-
from pydantic import BaseModel
|
3 |
-
from app.core.security import verify_api_key
|
4 |
-
import language_tool_python
|
5 |
-
import logging # Import logging
|
6 |
-
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
-
|
9 |
-
router = APIRouter()
|
10 |
-
|
11 |
-
# Initialize LanguageTool. This will be the same instance as used for punctuation.
|
12 |
-
# Ensure Java is installed in your environment.
|
13 |
-
try:
|
14 |
-
tool = language_tool_python.LanguageTool('en-US')
|
15 |
-
except Exception as e:
|
16 |
-
logger.error(f"Failed to initialize LanguageTool: {e}", exc_info=True)
|
17 |
-
# If LanguageTool cannot be initialized, raise an error or handle gracefully
|
18 |
-
# For an MVP, we might let the app start but fail on requests that use it.
|
19 |
-
# A more robust solution might mark the endpoint as unavailable.
|
20 |
-
tool = None # Set to None if initialization fails
|
21 |
-
|
22 |
-
class PunctuationInput(BaseModel):
|
23 |
-
"""
|
24 |
-
Pydantic BaseModel for validating the input request body for the /punctuation_check endpoint.
|
25 |
-
It expects a single field: 'text' (string).
|
26 |
-
"""
|
27 |
-
text: str
|
28 |
-
|
29 |
-
@router.post("/punctuation_check", dependencies=[Depends(verify_api_key)])
|
30 |
-
def punctuation_check(payload: PunctuationInput):
|
31 |
-
"""
|
32 |
-
Checks the provided text for punctuation errors.
|
33 |
-
|
34 |
-
Args:
|
35 |
-
payload (PunctuationInput): The request body containing the text to be analyzed.
|
36 |
-
|
37 |
-
Returns:
|
38 |
-
dict: A dictionary containing a list of punctuation issues.
|
39 |
-
"""
|
40 |
-
if tool is None:
|
41 |
-
raise HTTPException(
|
42 |
-
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
43 |
-
detail="Punctuation check service is not available (LanguageTool failed to initialize)."
|
44 |
-
)
|
45 |
-
|
46 |
-
text = payload.text
|
47 |
-
|
48 |
-
try:
|
49 |
-
matches = tool.check(text)
|
50 |
-
|
51 |
-
punctuation_issues = []
|
52 |
-
for m in matches:
|
53 |
-
if 'PUNCTUATION' in m.ruleId.upper():
|
54 |
-
punctuation_issues.append(m.message)
|
55 |
-
|
56 |
-
return {
|
57 |
-
"punctuation": {
|
58 |
-
"issues": punctuation_issues,
|
59 |
-
"suggestions": [] # Suggestions might be handled by overall grammar correction
|
60 |
-
}
|
61 |
-
}
|
62 |
-
except Exception as e:
|
63 |
-
logger.error(f"Error in punctuation_check: {e}", exc_info=True)
|
64 |
-
raise HTTPException(
|
65 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
66 |
-
detail=f"An error occurred during punctuation checking: {e}"
|
67 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/readability.py
CHANGED
@@ -1,55 +1,33 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
-
from
|
3 |
from app.core.security import verify_api_key
|
4 |
-
|
5 |
-
import
|
|
|
|
|
6 |
|
|
|
7 |
logger = logging.getLogger(__name__)
|
8 |
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/readability_score", dependencies=[Depends(verify_api_key)])
|
19 |
-
def readability_score(payload: ReadabilityInput):
|
20 |
-
"""
|
21 |
-
Calculates various readability scores for the provided text.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (ReadabilityInput): The request body containing the text to be analyzed.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing various readability scores.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
try:
|
32 |
-
|
33 |
-
|
34 |
-
flesch_kincaid_grade = textstat.flesch_kincaid_grade(text)
|
35 |
-
gunning_fog = textstat.gunning_fog(text)
|
36 |
-
smog_index = textstat.smog_index(text)
|
37 |
-
coleman_liau_index = textstat.coleman_liau_index(text)
|
38 |
-
automated_readability_index = textstat.automated_readability_index(text)
|
39 |
-
|
40 |
-
return {
|
41 |
-
"readability_scores": {
|
42 |
-
"flesch_reading_ease": flesch_reading_ease,
|
43 |
-
"flesch_kincaid_grade": flesch_kincaid_grade,
|
44 |
-
"gunning_fog_index": gunning_fog,
|
45 |
-
"smog_index": smog_index,
|
46 |
-
"coleman_liau_index": coleman_liau_index,
|
47 |
-
"automated_readability_index": automated_readability_index
|
48 |
-
}
|
49 |
-
}
|
50 |
except Exception as e:
|
51 |
-
logger.error(f"
|
52 |
raise HTTPException(
|
53 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
54 |
-
detail=
|
55 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
from app.core.security import verify_api_key
|
4 |
+
from app.utils.shared import executor
|
5 |
+
import asyncio
|
6 |
+
import logging
|
7 |
+
import textstat
|
8 |
|
9 |
+
router = APIRouter(prefix="/readability", tags=["Readability"])
|
10 |
logger = logging.getLogger(__name__)
|
11 |
|
12 |
+
def compute_readability(text: str) -> dict:
|
13 |
+
return {
|
14 |
+
"flesch_reading_ease": textstat.flesch_reading_ease(text),
|
15 |
+
"flesch_kincaid_grade": textstat.flesch_kincaid_grade(text),
|
16 |
+
"gunning_fog_index": textstat.gunning_fog(text),
|
17 |
+
"smog_index": textstat.smog_index(text),
|
18 |
+
"coleman_liau_index": textstat.coleman_liau_index(text),
|
19 |
+
"automated_readability_index": textstat.automated_readability_index(text),
|
20 |
+
}
|
21 |
|
22 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
23 |
+
async def readability_score(payload: TextOnlyRequest):
|
24 |
+
loop = asyncio.get_event_loop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
try:
|
26 |
+
scores = await loop.run_in_executor(executor, compute_readability, payload.text.strip())
|
27 |
+
return {"readability_scores": scores}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
except Exception as e:
|
29 |
+
logger.error(f"Readability score error: {e}", exc_info=True)
|
30 |
raise HTTPException(
|
31 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
32 |
+
detail="An error occurred while computing readability scores."
|
33 |
+
)
|
app/routers/rewrite.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# routers/rewrite.py
|
2 |
+
|
3 |
+
from fastapi import APIRouter, Depends
|
4 |
+
from app.schemas.base import RewriteRequest
|
5 |
+
from app.services.gpt4_rewrite import GPT4Rewriter
|
6 |
+
from app.core.security import verify_api_key
|
7 |
+
|
8 |
+
router = APIRouter(prefix="/rewrite", tags=["Rewrite"])
|
9 |
+
rewriter = GPT4Rewriter()
|
10 |
+
|
11 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
12 |
+
def rewrite_with_instruction(payload: RewriteRequest):
|
13 |
+
result = rewriter.rewrite(
|
14 |
+
text=payload.text,
|
15 |
+
instruction=payload.instruction,
|
16 |
+
user_api_key=payload.user_api_key
|
17 |
+
)
|
18 |
+
return {"result": result}
|
app/routers/sentence_correctness.py
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status # Import HTTPException and status
|
2 |
-
from pydantic import BaseModel
|
3 |
-
from app.core.security import verify_api_key
|
4 |
-
import language_tool_python
|
5 |
-
import logging # Import logging
|
6 |
-
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
-
|
9 |
-
router = APIRouter()
|
10 |
-
|
11 |
-
# Initialize LanguageTool. This will be the same instance as used for punctuation.
|
12 |
-
# Ensure Java is installed in your environment.
|
13 |
-
try:
|
14 |
-
tool = language_tool_python.LanguageTool('en-US')
|
15 |
-
except Exception as e:
|
16 |
-
logger.error(f"Failed to initialize LanguageTool for sentence correctness: {e}", exc_info=True)
|
17 |
-
tool = None
|
18 |
-
|
19 |
-
class SentenceCorrectnessInput(BaseModel):
|
20 |
-
"""
|
21 |
-
Pydantic BaseModel for validating the input request body for the /sentence_correctness endpoint.
|
22 |
-
It expects a single field: 'text' (string).
|
23 |
-
"""
|
24 |
-
text: str
|
25 |
-
|
26 |
-
@router.post("/sentence_correctness", dependencies=[Depends(verify_api_key)])
|
27 |
-
def sentence_correctness_check(payload: SentenceCorrectnessInput):
|
28 |
-
"""
|
29 |
-
Provides feedback on sentence-level correctness (e.g., fragments, subject-verb agreement).
|
30 |
-
|
31 |
-
Args:
|
32 |
-
payload (SentenceCorrectnessInput): The request body containing the text to be analyzed.
|
33 |
-
|
34 |
-
Returns:
|
35 |
-
dict: A dictionary containing a list of sentence correctness feedback.
|
36 |
-
"""
|
37 |
-
if tool is None:
|
38 |
-
raise HTTPException(
|
39 |
-
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
40 |
-
detail="Sentence correctness service is not available (LanguageTool failed to initialize)."
|
41 |
-
)
|
42 |
-
|
43 |
-
text = payload.text
|
44 |
-
|
45 |
-
try:
|
46 |
-
matches = tool.check(text)
|
47 |
-
|
48 |
-
sentence_correctness_feedback = []
|
49 |
-
for m in matches:
|
50 |
-
# Exclude punctuation issues, as they are handled in a separate endpoint
|
51 |
-
if 'PUNCTUATION' not in m.ruleId.upper():
|
52 |
-
sentence_correctness_feedback.append(m.message)
|
53 |
-
|
54 |
-
return {
|
55 |
-
"sentence_correctness": sentence_correctness_feedback
|
56 |
-
}
|
57 |
-
except Exception as e:
|
58 |
-
logger.error(f"Error in sentence_correctness_check: {e}", exc_info=True)
|
59 |
-
raise HTTPException(
|
60 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
61 |
-
detail=f"An error occurred during sentence correctness checking: {e}"
|
62 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/summarize.py
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status # Import HTTPException and status
|
2 |
-
from pydantic import BaseModel
|
3 |
-
from app import models, prompts
|
4 |
-
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
-
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
-
|
9 |
-
router = APIRouter()
|
10 |
-
|
11 |
-
class SummarizeInput(BaseModel): # Renamed Input to SummarizeInput for clarity
|
12 |
-
"""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /summarize endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/summarize", dependencies=[Depends(verify_api_key)])
|
19 |
-
def summarize(payload: SummarizeInput): # Renamed input to payload for consistency
|
20 |
-
"""
|
21 |
-
Summarizes the provided text.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (SummarizeInput): The request body containing the text to be summarized.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing the summarized text.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
summarized_text = models.run_flan_prompt(prompts.summarize_prompt(text))
|
33 |
-
return {"result": summarized_text}
|
34 |
-
except Exception as e:
|
35 |
-
logger.error(f"Error in summarize: {e}", exc_info=True)
|
36 |
-
raise HTTPException(
|
37 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
38 |
-
detail=f"An error occurred during summarization: {e}"
|
39 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/tone.py
CHANGED
@@ -1,56 +1,11 @@
|
|
1 |
-
from fastapi import APIRouter, Depends
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
|
7 |
-
|
|
|
8 |
|
9 |
-
router =
|
10 |
-
|
11 |
-
|
12 |
-
"""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /tone_analysis endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/tone_analysis", dependencies=[Depends(verify_api_key)])
|
19 |
-
def tone_analysis(payload: ToneInput):
|
20 |
-
"""
|
21 |
-
Analyzes the tone of the provided text and suggests improvements.
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (ToneInput): The request body containing the text to be analyzed.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing the detected tone and a suggestion.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
detected_tone = models.classify_tone(text)
|
33 |
-
|
34 |
-
tone_suggestion_text = ""
|
35 |
-
# Provide a simple tone suggestion based on the detected tone.
|
36 |
-
# This logic can be expanded for more sophisticated suggestions based on context or user goals.
|
37 |
-
if detected_tone in ["neutral", "joy", "sadness", "anger", "fear", "disgust", "surprise"]:
|
38 |
-
if detected_tone in ["neutral", "joy"]:
|
39 |
-
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "formal"))
|
40 |
-
else: # For emotions like anger, sadness, fear, etc., suggest a more neutral/calm tone
|
41 |
-
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "neutral and calm"))
|
42 |
-
else:
|
43 |
-
tone_suggestion_text = f"The detected tone '{detected_tone}' seems appropriate for general communication."
|
44 |
-
|
45 |
-
return {
|
46 |
-
"tone_analysis": {
|
47 |
-
"detected": detected_tone,
|
48 |
-
"suggestion": tone_suggestion_text
|
49 |
-
}
|
50 |
-
}
|
51 |
-
except Exception as e:
|
52 |
-
logger.error(f"Error in tone_analysis: {e}", exc_info=True)
|
53 |
-
raise HTTPException(
|
54 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
55 |
-
detail=f"An error occurred during tone analysis: {e}"
|
56 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
+
from app.services.tone_classification import ToneClassifier
|
4 |
from app.core.security import verify_api_key
|
|
|
5 |
|
6 |
+
router = APIRouter(prefix="/tone", tags=["Tone"])
|
7 |
+
classifier = ToneClassifier()
|
8 |
|
9 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
10 |
+
def classify_tone(payload: TextOnlyRequest):
|
11 |
+
return {"result": classifier.classify(payload.text)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/translate.py
CHANGED
@@ -1,41 +1,15 @@
|
|
1 |
-
from fastapi import APIRouter, Depends
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
|
7 |
-
|
|
|
8 |
|
9 |
-
router =
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
""
|
16 |
-
text: str
|
17 |
-
target_lang: str
|
18 |
-
|
19 |
-
@router.post("/translate", dependencies=[Depends(verify_api_key)])
|
20 |
-
def translate(payload: TranslateInput): # Renamed input to payload for consistency
|
21 |
-
"""
|
22 |
-
Translates the provided text to a target language.
|
23 |
-
|
24 |
-
Args:
|
25 |
-
payload (TranslateInput): The request body containing the text and target language.
|
26 |
-
|
27 |
-
Returns:
|
28 |
-
dict: A dictionary containing the translated text.
|
29 |
-
"""
|
30 |
-
text = payload.text
|
31 |
-
target_lang = payload.target_lang
|
32 |
-
|
33 |
-
try:
|
34 |
-
translated_text = models.run_translation(text, target_lang)
|
35 |
-
return {"result": translated_text}
|
36 |
-
except Exception as e:
|
37 |
-
logger.error(f"Error in translate: {e}", exc_info=True)
|
38 |
-
raise HTTPException(
|
39 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
40 |
-
detail=f"An error occurred during translation: {e}"
|
41 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends
|
2 |
+
from app.schemas.base import TranslateRequest
|
3 |
+
from app.services.translation import Translator
|
4 |
from app.core.security import verify_api_key
|
|
|
5 |
|
6 |
+
router = APIRouter(prefix="/translate", tags=["Translate"])
|
7 |
+
translator = Translator()
|
8 |
|
9 |
+
@router.post("/to", dependencies=[Depends(verify_api_key)])
|
10 |
+
def translate_text(payload: TranslateRequest):
|
11 |
+
result = translator.translate(
|
12 |
+
text=payload.text,
|
13 |
+
target_lang=payload.target_lang
|
14 |
+
)
|
15 |
+
return {"result": result}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/vocabulary.py
DELETED
@@ -1,42 +0,0 @@
|
|
1 |
-
from fastapi import APIRouter, Depends, HTTPException, status # Import HTTPException and status
|
2 |
-
from pydantic import BaseModel
|
3 |
-
from app import models, prompts
|
4 |
-
from app.core.security import verify_api_key
|
5 |
-
import logging # Import logging
|
6 |
-
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
-
|
9 |
-
router = APIRouter()
|
10 |
-
|
11 |
-
class VocabularyInput(BaseModel):
|
12 |
-
"""
|
13 |
-
Pydantic BaseModel for validating the input request body for the /vocabulary_suggestions endpoint.
|
14 |
-
It expects a single field: 'text' (string).
|
15 |
-
"""
|
16 |
-
text: str
|
17 |
-
|
18 |
-
@router.post("/vocabulary_suggestions", dependencies=[Depends(verify_api_key)])
|
19 |
-
def vocabulary_suggestions(payload: VocabularyInput):
|
20 |
-
"""
|
21 |
-
Provides suggestions for vocabulary improvement (e.g., stronger synonyms).
|
22 |
-
|
23 |
-
Args:
|
24 |
-
payload (VocabularyInput): The request body containing the text to be analyzed.
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
dict: A dictionary containing vocabulary suggestions.
|
28 |
-
"""
|
29 |
-
text = payload.text
|
30 |
-
|
31 |
-
try:
|
32 |
-
suggestions_raw = models.run_flan_prompt(prompts.vocabulary_prompt(text))
|
33 |
-
|
34 |
-
return {
|
35 |
-
"vocabulary_suggestions": suggestions_raw
|
36 |
-
}
|
37 |
-
except Exception as e:
|
38 |
-
logger.error(f"Error in vocabulary_suggestions: {e}", exc_info=True)
|
39 |
-
raise HTTPException(
|
40 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
41 |
-
detail=f"An error occurred during vocabulary suggestion: {e}"
|
42 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/routers/voice.py
CHANGED
@@ -1,72 +1,11 @@
|
|
1 |
-
from fastapi import APIRouter, Depends
|
2 |
-
from
|
3 |
-
from app import
|
4 |
from app.core.security import verify_api_key
|
5 |
-
import spacy
|
6 |
-
import logging # Import logging
|
7 |
|
8 |
-
|
|
|
9 |
|
10 |
-
router =
|
11 |
-
|
12 |
-
|
13 |
-
try:
|
14 |
-
nlp = spacy.load("en_core_web_sm")
|
15 |
-
except OSError as e:
|
16 |
-
logger.error(f"SpaCy model 'en_core_web_sm' not found. Please run: python -m spacy download en_core_web_sm. Error: {e}", exc_info=True)
|
17 |
-
nlp = None # Set to None if initialization fails
|
18 |
-
# Re-raising here to prevent server startup if critical dependency is missing
|
19 |
-
raise RuntimeError("SpaCy model 'en_core_web_sm' not loaded. Please install it.")
|
20 |
-
|
21 |
-
|
22 |
-
class VoiceInput(BaseModel):
|
23 |
-
"""
|
24 |
-
Pydantic BaseModel for validating the input request body for the /voice_analysis endpoint.
|
25 |
-
It expects a single field: 'text' (string).
|
26 |
-
"""
|
27 |
-
text: str
|
28 |
-
|
29 |
-
@router.post("/voice_analysis", dependencies=[Depends(verify_api_key)])
|
30 |
-
def voice_analysis(payload: VoiceInput):
|
31 |
-
"""
|
32 |
-
Detects active/passive voice and suggests improvements.
|
33 |
-
|
34 |
-
Args:
|
35 |
-
payload (VoiceInput): The request body containing the text to be analyzed.
|
36 |
-
|
37 |
-
Returns:
|
38 |
-
dict: A dictionary containing the detected voice and a suggestion.
|
39 |
-
"""
|
40 |
-
if nlp is None:
|
41 |
-
raise HTTPException(
|
42 |
-
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
43 |
-
detail="Voice analysis service is not available (SpaCy model failed to load)."
|
44 |
-
)
|
45 |
-
|
46 |
-
text = payload.text
|
47 |
-
|
48 |
-
try:
|
49 |
-
doc = nlp(text)
|
50 |
-
|
51 |
-
voice_detected = "active"
|
52 |
-
voice_suggestion = "None \u2014 active voice is fine here."
|
53 |
-
|
54 |
-
for token in doc:
|
55 |
-
if token.dep_ == "auxpass":
|
56 |
-
voice_detected = "passive"
|
57 |
-
better_voice_prompt = prompts.active_voice_prompt(text)
|
58 |
-
voice_suggestion = models.run_flan_prompt(better_voice_prompt)
|
59 |
-
break
|
60 |
-
|
61 |
-
return {
|
62 |
-
"voice": {
|
63 |
-
"detected": voice_detected,
|
64 |
-
"suggestion": voice_suggestion
|
65 |
-
}
|
66 |
-
}
|
67 |
-
except Exception as e:
|
68 |
-
logger.error(f"Error in voice_analysis: {e}", exc_info=True)
|
69 |
-
raise HTTPException(
|
70 |
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
71 |
-
detail=f"An error occurred during voice analysis: {e}"
|
72 |
-
)
|
|
|
1 |
+
from fastapi import APIRouter, Depends
|
2 |
+
from app.schemas.base import TextOnlyRequest
|
3 |
+
from app.services.voice_detection import VoiceDetector
|
4 |
from app.core.security import verify_api_key
|
|
|
|
|
5 |
|
6 |
+
router = APIRouter(prefix="/voice", tags=["Voice"])
|
7 |
+
detector = VoiceDetector()
|
8 |
|
9 |
+
@router.post("/", dependencies=[Depends(verify_api_key)])
|
10 |
+
def detect_voice(payload: TextOnlyRequest):
|
11 |
+
return {"result": detector.classify(payload.text)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/schemas/base.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel, Field
|
2 |
+
|
3 |
+
class TextOnlyRequest(BaseModel):
|
4 |
+
text: str = Field(..., example="Your input text here")
|
5 |
+
|
6 |
+
class RewriteRequest(BaseModel):
|
7 |
+
text: str = Field(..., example="Your input text here")
|
8 |
+
instruction: str = Field(..., example="Rewrite this more concisely")
|
9 |
+
user_api_key: str = Field(..., example="sk-...")
|
10 |
+
|
11 |
+
class TranslateRequest(BaseModel):
|
12 |
+
text: str = Field(..., example="Translate this")
|
13 |
+
target_lang: str = Field(..., example="fr")
|
app/services/__init__.py
ADDED
File without changes
|
app/services/base.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
from threading import Lock
|
3 |
+
import logging
|
4 |
+
import time
|
5 |
+
logger = logging.getLogger(__name__)
|
6 |
+
|
7 |
+
|
8 |
+
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
9 |
+
logging.getLogger(__name__).info(f"Using device: {DEVICE}")
|
10 |
+
|
11 |
+
_models = {}
|
12 |
+
_models_lock = Lock()
|
13 |
+
|
14 |
+
|
15 |
+
def get_cached_model(model_name: str, load_fn):
|
16 |
+
with _models_lock:
|
17 |
+
if model_name not in _models:
|
18 |
+
logging.info(f"Loading model: {model_name}")
|
19 |
+
_models[model_name] = load_fn()
|
20 |
+
return _models[model_name]
|
21 |
+
|
22 |
+
|
23 |
+
def load_with_timer(name, fn):
|
24 |
+
# TODO: Add timing later if needed
|
25 |
+
return fn()
|
26 |
+
|
27 |
+
def timed_model_load(label: str, load_fn):
|
28 |
+
start = time.time()
|
29 |
+
model = load_fn()
|
30 |
+
logger.info(f"{label} loaded in {time.time() - start:.2f}s")
|
31 |
+
return model
|
32 |
+
|
33 |
+
# Lazy spaCy loading
|
34 |
+
_nlp = None
|
35 |
+
|
36 |
+
def get_spacy():
|
37 |
+
global _nlp
|
38 |
+
if _nlp is None:
|
39 |
+
import spacy
|
40 |
+
_nlp = spacy.load("en_core_web_sm")
|
41 |
+
return _nlp
|
42 |
+
|
app/services/conciseness_suggestion.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from app.services.gpt4_rewrite import GPT4Rewriter
|
3 |
+
from app.core.prompts import concise_prompt
|
4 |
+
|
5 |
+
logger = logging.getLogger(__name__)
|
6 |
+
gpt4_rewriter = GPT4Rewriter()
|
7 |
+
|
8 |
+
class ConcisenessSuggester:
|
9 |
+
def suggest(self, text: str, user_api_key: str) -> str:
|
10 |
+
text = text.strip()
|
11 |
+
if not text:
|
12 |
+
logger.warning("Conciseness suggestion requested for empty input.")
|
13 |
+
return "Input text is empty."
|
14 |
+
|
15 |
+
if not user_api_key:
|
16 |
+
logger.error("Conciseness suggestion failed: Missing user_api_key.")
|
17 |
+
return "Missing OpenAI API key."
|
18 |
+
|
19 |
+
instruction = concise_prompt(text)
|
20 |
+
concise_text = gpt4_rewriter.rewrite(text, user_api_key, instruction)
|
21 |
+
|
22 |
+
if concise_text.startswith("An OpenAI API error occurred:") or \
|
23 |
+
concise_text.startswith("An unexpected error occurred:") or \
|
24 |
+
concise_text.startswith("Missing OpenAI API key.") or \
|
25 |
+
concise_text.startswith("Input text is empty."):
|
26 |
+
logger.error(f"GPT-4 conciseness suggestion failed for text: '{text[:50]}...' - {concise_text}")
|
27 |
+
return concise_text
|
28 |
+
|
29 |
+
logger.info(f"Conciseness suggestion completed for text length: {len(text)}")
|
30 |
+
return concise_text
|
app/services/gpt4_rewrite.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import openai
|
2 |
+
import logging
|
3 |
+
from tenacity import retry, stop_after_attempt, wait_exponential
|
4 |
+
from app.core.config import settings
|
5 |
+
|
6 |
+
logger = logging.getLogger(__name__)
|
7 |
+
|
8 |
+
class GPT4Rewriter:
|
9 |
+
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
|
10 |
+
def rewrite(self, text: str, user_api_key: str, instruction: str) -> str:
|
11 |
+
if not user_api_key:
|
12 |
+
logger.error("GPT-4 rewrite requested without an OpenAI API key.")
|
13 |
+
return "Missing OpenAI API key."
|
14 |
+
|
15 |
+
text = text.strip()
|
16 |
+
instruction = instruction.strip()
|
17 |
+
|
18 |
+
if not text:
|
19 |
+
logger.warning("GPT-4 rewrite requested for empty input.")
|
20 |
+
return "Input text is empty."
|
21 |
+
if not instruction:
|
22 |
+
logger.error("GPT-4 rewrite requested without a specific instruction.")
|
23 |
+
return "Missing rewrite instruction. Please provide a clear instruction for the rewrite."
|
24 |
+
|
25 |
+
messages = [
|
26 |
+
{"role": "system", "content": instruction},
|
27 |
+
{"role": "user", "content": text},
|
28 |
+
]
|
29 |
+
|
30 |
+
try:
|
31 |
+
client = openai.OpenAI(api_key=user_api_key)
|
32 |
+
response = client.chat.completions.create(
|
33 |
+
model=settings.openai_model,
|
34 |
+
messages=messages,
|
35 |
+
temperature=settings.openai_temperature,
|
36 |
+
max_tokens=settings.openai_max_tokens
|
37 |
+
)
|
38 |
+
return response.choices[0].message.content.strip()
|
39 |
+
except openai.APIError as e:
|
40 |
+
logger.error(f"OpenAI API error during GPT-4 rewrite: {e}")
|
41 |
+
return f"An OpenAI API error occurred: {e}"
|
42 |
+
except Exception as e:
|
43 |
+
logger.error(f"Unexpected error during GPT-4 rewrite: {e}")
|
44 |
+
return "An unexpected error occurred during GPT-4 rewrite."
|
app/services/grammar.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
2 |
+
import torch
|
3 |
+
from .base import get_cached_model, DEVICE, load_with_timer
|
4 |
+
import logging
|
5 |
+
|
6 |
+
class GrammarCorrector:
|
7 |
+
def __init__(self):
|
8 |
+
self.tokenizer, self.model = self._load_model()
|
9 |
+
|
10 |
+
def _load_model(self):
|
11 |
+
def load_fn():
|
12 |
+
tokenizer = load_with_timer("grammar_tokenizer", lambda: AutoTokenizer.from_pretrained("visheratin/t5-efficient-mini-grammar-correction"))
|
13 |
+
model = load_with_timer("grammar_model", lambda: AutoModelForSeq2SeqLM.from_pretrained("visheratin/t5-efficient-mini-grammar-correction"))
|
14 |
+
model = model.to(DEVICE).eval()
|
15 |
+
return tokenizer, model
|
16 |
+
|
17 |
+
return get_cached_model("grammar", load_fn)
|
18 |
+
|
19 |
+
def correct(self, text: str) -> str:
|
20 |
+
text = text.strip()
|
21 |
+
if not text:
|
22 |
+
logging.warning("Grammar correction requested for empty input.")
|
23 |
+
return "Input text is empty."
|
24 |
+
|
25 |
+
try:
|
26 |
+
with torch.no_grad():
|
27 |
+
inputs = self.tokenizer([text], return_tensors="pt", truncation=True, padding=True).to(DEVICE)
|
28 |
+
outputs = self.model.generate(**inputs, max_length=256, num_beams=4, early_stopping=True)
|
29 |
+
return self.tokenizer.decode(outputs[0], skip_special_tokens=True)
|
30 |
+
except Exception as e:
|
31 |
+
logging.error(f"Error during grammar correction: {e}")
|
32 |
+
return "An error occurred during grammar correction."
|
app/services/inclusive_language.py
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import yaml
|
2 |
+
from pathlib import Path
|
3 |
+
from spacy.matcher import PhraseMatcher
|
4 |
+
from typing import List, Dict
|
5 |
+
from .base import get_spacy
|
6 |
+
from app.core.config import settings
|
7 |
+
import logging
|
8 |
+
|
9 |
+
class InclusiveLanguageChecker:
|
10 |
+
def __init__(self, rules_directory=settings.inclusive_rules_dir):
|
11 |
+
self.matcher = PhraseMatcher(get_spacy().vocab, attr="LOWER")
|
12 |
+
self.rules = self._load_inclusive_rules(rules_directory)
|
13 |
+
self._init_matcher()
|
14 |
+
|
15 |
+
def _load_inclusive_rules(self, directory: str) -> Dict[str, Dict]:
|
16 |
+
rules = {}
|
17 |
+
for path in Path(directory).glob("*.yml"):
|
18 |
+
try:
|
19 |
+
with open(path, encoding="utf-8") as f:
|
20 |
+
rule_list = yaml.safe_load(f)
|
21 |
+
if not isinstance(rule_list, list):
|
22 |
+
logging.warning(f"Skipping malformed rule file: {path}")
|
23 |
+
continue
|
24 |
+
for rule in rule_list:
|
25 |
+
note = rule.get("note", "")
|
26 |
+
source = rule.get("source", "")
|
27 |
+
considerate = rule.get("considerate", [])
|
28 |
+
inconsiderate = rule.get("inconsiderate", [])
|
29 |
+
|
30 |
+
if isinstance(considerate, str):
|
31 |
+
considerate = [considerate]
|
32 |
+
if isinstance(inconsiderate, str):
|
33 |
+
inconsiderate = [inconsiderate]
|
34 |
+
|
35 |
+
for phrase in inconsiderate:
|
36 |
+
key = phrase.lower()
|
37 |
+
rules[key] = {
|
38 |
+
"note": note,
|
39 |
+
"considerate": considerate,
|
40 |
+
"source": source,
|
41 |
+
"type": rule.get("type", "basic")
|
42 |
+
}
|
43 |
+
except Exception as e:
|
44 |
+
logging.error(f"Error loading inclusive language rule from {path}: {e}")
|
45 |
+
return rules
|
46 |
+
|
47 |
+
def _init_matcher(self):
|
48 |
+
for phrase in self.rules:
|
49 |
+
self.matcher.add(phrase, [get_spacy().make_doc(phrase)])
|
50 |
+
logging.info(f"Loaded {len(self.rules)} inclusive language rules.")
|
51 |
+
|
52 |
+
def check(self, text: str) -> List[Dict]:
|
53 |
+
text = text.strip()
|
54 |
+
if not text:
|
55 |
+
logging.warning("Inclusive language check requested for empty input.")
|
56 |
+
return []
|
57 |
+
|
58 |
+
nlp = get_spacy()
|
59 |
+
doc = nlp(text)
|
60 |
+
matches = self.matcher(doc)
|
61 |
+
results = []
|
62 |
+
matched_spans = set()
|
63 |
+
|
64 |
+
# 1. PhraseMatcher (exact) matches
|
65 |
+
for match_id, start, end in matches:
|
66 |
+
phrase_str = nlp.vocab.strings[match_id]
|
67 |
+
matched_spans.add((start, end))
|
68 |
+
rule = self.rules.get(phrase_str.lower())
|
69 |
+
if rule:
|
70 |
+
results.append({
|
71 |
+
"term": doc[start:end].text,
|
72 |
+
"type": rule["type"],
|
73 |
+
"note": rule["note"],
|
74 |
+
"suggestions": rule["considerate"],
|
75 |
+
"context": doc[start:end].sent.text,
|
76 |
+
"start": doc[start].idx,
|
77 |
+
"end": doc[end - 1].idx + len(doc[end - 1]),
|
78 |
+
"source": rule.get("source", "")
|
79 |
+
})
|
80 |
+
|
81 |
+
# 2. Lemma-based fallback (for plural/inflected forms)
|
82 |
+
for token in doc:
|
83 |
+
lemma = token.lemma_.lower()
|
84 |
+
span_key = (token.i, token.i + 1)
|
85 |
+
if lemma in self.rules and span_key not in matched_spans:
|
86 |
+
rule = self.rules[lemma]
|
87 |
+
results.append({
|
88 |
+
"term": token.text,
|
89 |
+
"type": rule["type"],
|
90 |
+
"note": rule["note"],
|
91 |
+
"suggestions": rule["considerate"],
|
92 |
+
"context": token.sent.text,
|
93 |
+
"start": token.idx,
|
94 |
+
"end": token.idx + len(token),
|
95 |
+
"source": rule.get("source", "")
|
96 |
+
})
|
97 |
+
|
98 |
+
return results
|
app/services/paraphrase.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
2 |
+
import torch
|
3 |
+
from .base import get_cached_model, DEVICE, timed_model_load
|
4 |
+
import logging
|
5 |
+
|
6 |
+
class Paraphraser:
|
7 |
+
def __init__(self):
|
8 |
+
self.tokenizer, self.model = self._load_model()
|
9 |
+
|
10 |
+
def _load_model(self):
|
11 |
+
def load_fn():
|
12 |
+
tokenizer = timed_model_load("paraphrase_tokenizer", lambda: AutoTokenizer.from_pretrained("humarin/chatgpt_paraphraser_on_T5_base"))
|
13 |
+
model = timed_model_load("paraphrase_model", lambda: AutoModelForSeq2SeqLM.from_pretrained("humarin/chatgpt_paraphraser_on_T5_base"))
|
14 |
+
model = model.to(DEVICE).eval()
|
15 |
+
return tokenizer, model
|
16 |
+
return get_cached_model("paraphrase", load_fn)
|
17 |
+
|
18 |
+
def paraphrase(self, text: str) -> str:
|
19 |
+
text = text.strip()
|
20 |
+
if not text:
|
21 |
+
logging.warning("Paraphrasing requested for empty input.")
|
22 |
+
return "Input text is empty."
|
23 |
+
|
24 |
+
prompt = f"paraphrase: {text} </s>"
|
25 |
+
try:
|
26 |
+
with torch.no_grad():
|
27 |
+
inputs = self.tokenizer([prompt], return_tensors="pt", padding=True, truncation=True).to(DEVICE)
|
28 |
+
outputs = self.model.generate(
|
29 |
+
**inputs,
|
30 |
+
max_length=256,
|
31 |
+
num_beams=5,
|
32 |
+
num_return_sequences=1,
|
33 |
+
early_stopping=True
|
34 |
+
)
|
35 |
+
return self.tokenizer.decode(outputs[0], skip_special_tokens=True, clean_up_tokenization_spaces=True)
|
36 |
+
except Exception as e:
|
37 |
+
logging.error(f"Error during paraphrasing: {e}")
|
38 |
+
return f"An error occurred during paraphrasing: {e}"
|
39 |
+
|
app/services/tone_classification.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import pipeline
|
2 |
+
import torch
|
3 |
+
from .base import get_cached_model, DEVICE
|
4 |
+
import logging
|
5 |
+
|
6 |
+
class ToneClassifier:
|
7 |
+
def __init__(self):
|
8 |
+
self.classifier = self._load_model()
|
9 |
+
|
10 |
+
def _load_model(self):
|
11 |
+
def load_fn():
|
12 |
+
return pipeline(
|
13 |
+
"sentiment-analysis",
|
14 |
+
model="j-hartmann/emotion-english-distilroberta-base",
|
15 |
+
top_k=1,
|
16 |
+
device=0 if torch.cuda.is_available() else -1
|
17 |
+
)
|
18 |
+
return get_cached_model("tone", load_fn)
|
19 |
+
|
20 |
+
def classify(self, text: str) -> str:
|
21 |
+
text = text.strip()
|
22 |
+
if not text:
|
23 |
+
logging.warning("Tone classification requested for empty input.")
|
24 |
+
return "Input text is empty."
|
25 |
+
|
26 |
+
try:
|
27 |
+
result = self.classifier(text)
|
28 |
+
if isinstance(result, list):
|
29 |
+
if isinstance(result[0], list):
|
30 |
+
result = result[0]
|
31 |
+
if result:
|
32 |
+
return result[0]['label']
|
33 |
+
return "Unknown"
|
34 |
+
except Exception as e:
|
35 |
+
logging.error(f"Error during tone classification: {e}")
|
36 |
+
return "An error occurred during tone classification."
|
app/services/translation.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
2 |
+
import torch
|
3 |
+
import logging
|
4 |
+
from .base import get_cached_model, DEVICE, timed_model_load
|
5 |
+
from app.core.config import settings
|
6 |
+
|
7 |
+
class Translator:
|
8 |
+
def __init__(self):
|
9 |
+
self.tokenizer, self.model = self._load_model()
|
10 |
+
|
11 |
+
def _load_model(self):
|
12 |
+
def load_fn():
|
13 |
+
tokenizer = timed_model_load("translate_tokenizer", lambda: AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-ROMANCE"))
|
14 |
+
model = timed_model_load("translate_model", lambda: AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-en-ROMANCE"))
|
15 |
+
model = model.to(DEVICE).eval()
|
16 |
+
return tokenizer, model
|
17 |
+
return get_cached_model("translate", load_fn)
|
18 |
+
|
19 |
+
def translate(self, text: str, target_lang: str) -> str:
|
20 |
+
text = text.strip()
|
21 |
+
target_lang = target_lang.strip()
|
22 |
+
|
23 |
+
if not text:
|
24 |
+
logging.warning("Translation requested for empty input.")
|
25 |
+
return "Input text is empty."
|
26 |
+
if not target_lang:
|
27 |
+
logging.warning("Translation requested without a target language.")
|
28 |
+
return "Target language is empty."
|
29 |
+
if target_lang not in settings.supported_translation_languages:
|
30 |
+
return f"Unsupported target language: {target_lang}"
|
31 |
+
|
32 |
+
prompt = f">>{target_lang}<< {text}"
|
33 |
+
try:
|
34 |
+
with torch.no_grad():
|
35 |
+
inputs = self.tokenizer([prompt], return_tensors="pt", truncation=True, padding=True).to(DEVICE)
|
36 |
+
outputs = self.model.generate(**inputs, max_length=256, num_beams=1, early_stopping=True)
|
37 |
+
return self.tokenizer.decode(outputs[0], skip_special_tokens=True, clean_up_tokenization_spaces=True)
|
38 |
+
except Exception as e:
|
39 |
+
logging.error(f"Error during translation: {e}")
|
40 |
+
return f"An error occurred during translation: {e}"
|
app/services/vocabulary_enhancement.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from app.services.gpt4_rewrite import GPT4Rewriter
|
3 |
+
from app.core.prompts import vocabulary_prompt
|
4 |
+
|
5 |
+
logger = logging.getLogger(__name__)
|
6 |
+
gpt4_rewriter = GPT4Rewriter()
|
7 |
+
|
8 |
+
class VocabularyEnhancer:
|
9 |
+
def enhance(self, text: str, user_api_key: str) -> str:
|
10 |
+
text = text.strip()
|
11 |
+
if not text:
|
12 |
+
logger.warning("Vocabulary enhancement requested for empty input.")
|
13 |
+
return "Input text is empty."
|
14 |
+
|
15 |
+
if not user_api_key:
|
16 |
+
logger.error("Vocabulary enhancement failed: Missing user_api_key.")
|
17 |
+
return "Missing OpenAI API key."
|
18 |
+
|
19 |
+
instruction = vocabulary_prompt(text)
|
20 |
+
enhanced_text = gpt4_rewriter.rewrite(text, user_api_key, instruction)
|
21 |
+
|
22 |
+
if enhanced_text.startswith("An OpenAI API error occurred:") or \
|
23 |
+
enhanced_text.startswith("An unexpected error occurred:") or \
|
24 |
+
enhanced_text.startswith("Missing OpenAI API key.") or \
|
25 |
+
enhanced_text.startswith("Input text is empty."):
|
26 |
+
logger.error(f"GPT-4 vocabulary enhancement failed for text: '{text[:50]}...' - {enhanced_text}")
|
27 |
+
return enhanced_text
|
28 |
+
|
29 |
+
logger.info(f"Vocabulary enhancement completed for text length: {len(text)}")
|
30 |
+
return enhanced_text
|
app/services/voice_detection.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from .base import get_spacy
|
3 |
+
|
4 |
+
class VoiceDetector:
|
5 |
+
def __init__(self):
|
6 |
+
self.nlp = get_spacy()
|
7 |
+
|
8 |
+
def classify(self, text: str) -> str:
|
9 |
+
text = text.strip()
|
10 |
+
if not text:
|
11 |
+
logging.warning("Voice detection requested for empty input.")
|
12 |
+
return "Input text is empty."
|
13 |
+
|
14 |
+
try:
|
15 |
+
doc = self.nlp(text)
|
16 |
+
passive_sentences = 0
|
17 |
+
total_sentences = 0
|
18 |
+
|
19 |
+
for sent in doc.sents:
|
20 |
+
total_sentences += 1
|
21 |
+
for token in sent:
|
22 |
+
if token.dep_ == "nsubjpass":
|
23 |
+
passive_sentences += 1
|
24 |
+
break
|
25 |
+
|
26 |
+
if total_sentences == 0:
|
27 |
+
return "Unknown"
|
28 |
+
|
29 |
+
ratio = passive_sentences / total_sentences
|
30 |
+
return "Passive" if ratio > 0.5 else "Active"
|
31 |
+
except Exception as e:
|
32 |
+
logging.error(f"Error during voice detection: {e}")
|
33 |
+
return "An error occurred during voice detection."
|
app/test/test_rewrite.py
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pytest
|
2 |
+
from fastapi.testclient import TestClient
|
3 |
+
from main import create_app
|
4 |
+
|
5 |
+
client = TestClient(create_app())
|
6 |
+
|
7 |
+
def test_rewrite_success():
|
8 |
+
payload = {
|
9 |
+
"text": "This is a very long and unnecessarily wordy sentence that could be simpler.",
|
10 |
+
"instruction": "Make this more concise"
|
11 |
+
}
|
12 |
+
headers = {"x-api-key": "your-secret-key"}
|
13 |
+
response = client.post("/rewrite/", json=payload, headers=headers)
|
14 |
+
assert response.status_code == 200
|
15 |
+
assert "result" in response.json()
|
app/test_main.py
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
from fastapi.testclient import TestClient
|
2 |
-
from app.main import app
|
3 |
-
|
4 |
-
client = TestClient(app)
|
5 |
-
|
6 |
-
def test_grammar():
|
7 |
-
response = client.post("/rewrite", json={"text": "She go to school yesterday.", "mode": "grammar"})
|
8 |
-
assert response.status_code == 200
|
9 |
-
assert "result" in response.json()
|
10 |
-
|
11 |
-
def test_paraphrase():
|
12 |
-
response = client.post("/rewrite", json={"text": "I love programming.", "mode": "paraphrase"})
|
13 |
-
assert response.status_code == 200
|
14 |
-
assert "result" in response.json()
|
15 |
-
|
16 |
-
def test_clarity():
|
17 |
-
response = client.post("/rewrite", json={"text": "This sentence is a bit confusing.", "mode": "clarity"})
|
18 |
-
assert response.status_code == 200
|
19 |
-
assert "result" in response.json()
|
20 |
-
|
21 |
-
def test_fluency():
|
22 |
-
response = client.post("/rewrite", json={"text": "He no went there before.", "mode": "fluency"})
|
23 |
-
assert response.status_code == 200
|
24 |
-
assert "result" in response.json()
|
25 |
-
|
26 |
-
def test_tone():
|
27 |
-
response = client.post("/rewrite", json={"text": "Leave me alone.", "mode": "tone", "tone": "friendly"})
|
28 |
-
assert response.status_code == 200
|
29 |
-
assert "result" in response.json()
|
30 |
-
|
31 |
-
def test_translation():
|
32 |
-
response = client.post("/rewrite", json={"text": "How are you?", "mode": "translate", "target_lang": "fr"})
|
33 |
-
assert response.status_code == 200
|
34 |
-
assert "result" in response.json()
|
35 |
-
|
36 |
-
def test_pronoun():
|
37 |
-
response = client.post("/rewrite", json={"text": "Each user must provide his email.", "mode": "pronoun"})
|
38 |
-
assert response.status_code == 200
|
39 |
-
assert "result" in response.json()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/utils/shared.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from concurrent.futures import ThreadPoolExecutor
|
2 |
+
|
3 |
+
# Shared executor for all CPU-bound tasks
|
4 |
+
executor = ThreadPoolExecutor(max_workers=4)
|
requirements.txt
CHANGED
@@ -6,6 +6,6 @@ sentencepiece
|
|
6 |
pyspellchecker
|
7 |
spacy
|
8 |
nltk
|
9 |
-
language-tool-python
|
10 |
scikit-learn
|
11 |
textstat
|
|
|
|
6 |
pyspellchecker
|
7 |
spacy
|
8 |
nltk
|
|
|
9 |
scikit-learn
|
10 |
textstat
|
11 |
+
numpy>=1.21
|
run.py
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# run.py (no change needed for path handling if app.main:app is used)
|
2 |
+
import uvicorn
|
3 |
+
import os
|
4 |
+
import sys
|
5 |
+
# from pathlib import Path # No longer strictly necessary to add project_root to sys.path explicitly here
|
6 |
+
# sys.path.insert(0, str(project_root)) # Can likely remove this line if your only problem was 'models' import
|
7 |
+
|
8 |
+
host = "0.0.0.0"
|
9 |
+
port = 7860
|
10 |
+
app_module = "app.main:app" # This refers to the 'app' package correctly
|
11 |
+
|
12 |
+
if __name__ == "__main__":
|
13 |
+
print(f"Starting Uvicorn server for {app_module} at http://{host}:{port}")
|
14 |
+
# ... rest of your print statements and uvicorn.run call
|
15 |
+
uvicorn.run(app_module, host=host, port=port, reload=True)
|