Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ea5c103
add banter function
sw5556 Oct 30, 2025
f2d152e
add conversations package skeleton
Alif-4 Oct 30, 2025
e050698
Merge pull request #1 from swe-students-fall2025/funFacts
sen5217 Oct 30, 2025
ab99835
Removed old __init__.py file
sw5556 Oct 30, 2025
db7c204
renamed to banter.py
sw5556 Oct 30, 2025
dcbc975
renamed to test_banter.py
sw5556 Oct 30, 2025
d48d09b
worked on banter.py
sw5556 Oct 30, 2025
9fa09ea
Merge pull request #2 from swe-students-fall2025/susan_branch
sen5217 Oct 30, 2025
4a268ee
add smallTalk function and tests
sen5217 Nov 2, 2025
3c2760b
Merge pull request #3 from swe-students-fall2025/smallTalk
Alif-4 Nov 3, 2025
50642bb
Funfacts feature, add CLI flags, and pyproject.toml
Alif-4 Nov 3, 2025
90f20f1
Merge pull request #4 from swe-students-fall2025/funfacts-v1
sen5217 Nov 3, 2025
17d6a82
Fixed test_smalltalk import, added CLI flags for smalltalk
sen5217 Nov 3, 2025
57a1345
Merge pull request #5 from swe-students-fall2025/smallTalk
yungsemitone Nov 3, 2025
09f733c
added pickup lines function and tests
yungsemitone Nov 3, 2025
8a9872b
Merge pull request #6 from swe-students-fall2025/pick_up_lines
sen5217 Nov 3, 2025
0fcf3b2
added init and main for pickupline function
yungsemitone Nov 3, 2025
62af42d
fixed default issue
yungsemitone Nov 3, 2025
242cf4d
Merge pull request #9 from swe-students-fall2025/init_for_pickupline
sen5217 Nov 3, 2025
ce8a12a
Merge pull request #10 from swe-students-fall2025/susan_branch
yungsemitone Nov 3, 2025
bf82fad
Add compliments function and tests
serena0615 Nov 3, 2025
98d026c
Merge pull request #11 from swe-students-fall2025/serena-compliments
sen5217 Nov 3, 2025
3698fbe
worked on banter.py
sw5556 Nov 4, 2025
c29f14e
created banter.py tests and u
sw5556 Nov 4, 2025
44d8424
Merge pull request #12 from swe-students-fall2025/susan_branch
sen5217 Nov 4, 2025
8eeabf9
Update README.md
sw5556 Nov 4, 2025
14d3c54
fixed main for pickup and added to ReadMe
yungsemitone Nov 4, 2025
7ff7bed
Merge pull request #13 from swe-students-fall2025/fix_main_pickup
sen5217 Nov 4, 2025
7fe09ec
Adding fixes to __main__.py and testing build.yaml badge
sen5217 Nov 4, 2025
f760ddf
updated banter.py
sw5556 Nov 4, 2025
08d8f84
Merge pull request #15 from swe-students-fall2025/susan_branch
sen5217 Nov 4, 2025
6c8d2ec
Merge pipfile-experiment into smallTalk
sen5217 Nov 4, 2025
cfc7eb0
Adding fixes to __main__.py and testing build.yaml badge after test_b…
sen5217 Nov 4, 2025
72d92b3
Update funfact defaulting behavior for CLI
Alif-4 Nov 4, 2025
6e8f9ca
added parsing argument for pickup
yungsemitone Nov 4, 2025
ebc2db0
Merge pull request #16 from swe-students-fall2025/funfacts-v2
sen5217 Nov 4, 2025
169fe40
Merge pull request #17 from swe-students-fall2025/parse_pickup
sen5217 Nov 4, 2025
12a1e97
Add compliment integration and fix CLI parser
serena0615 Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: CI / CD
on:
pull_request:
push:
branches: pipfile-experiment
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 5
strategy:
matrix:
python-version: ["3.9", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Install Python, pipenv and Pipfile packages
uses: kojoru/prepare-pipenv@v1
with:
python-version: ${{ matrix.python-version }}
- name: Turn on 'editable' mode
run: |
pipenv install -e .
- name: Test with pytest
run: |
pipenv install pytest
pipenv --venv
pipenv run python -m pytest
deliver:
needs: [build]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Install Python, pipenv and Pipfile packages
uses: kojoru/prepare-pipenv@v1
- name: Build package
run: |
pipenv install build
pipenv run python -m build .
- name: Publish to PyPI test server
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
2 changes: 1 addition & 1 deletion .github/workflows/event-logger.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: log github events
on:
on:
push:
branches: [main, master, pipfile-experiment]
pull_request:
Expand Down
16 changes: 16 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pytest = "*"
conversations = {file = ".", editable = true}

[dev-packages]
pytest = "*"
build = "*"
twine = "*"

[requires]
python_version = "3.12"
422 changes: 422 additions & 0 deletions Pipfile.lock

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# Python Package Exercise
![CI / CD](https://github.com/swe-students-fall2025/3-python-package-team_mistral/actions/workflows/build.yaml/badge.svg)

[Mahabub Alif](https://github.com/Alif-4)

[Sydney Nadeau](https://github.com/sen5217)

[Susan Wang](https://github.com/sw5556)

[Aden Juda](https://github.com/yungsemitone)

[Serena Wang](https://github.com/serena0615)

An exercise to create a Python package, build it, test it, distribute it, and use it. See [instructions](./instructions.md) for details.
22 changes: 22 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[build-system]
requires = ["setuptools>=68", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "conversations"
version = "0.0.1"
description = "Lighthearted conversation helpers (fun facts, etc.)"
requires-python = ">=3.9"
authors = [{name="Team Mistral"}]

[project.scripts]
conversations = "conversations.__main__:main"

[tool.setuptools.package-dir]
"" = "src"

[tool.setuptools.packages.find]
where = ["src"]

[tool.pytest.ini_options]
pythonpath = ["src"]
8 changes: 8 additions & 0 deletions src/conversations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .funfacts import fun_fact
from .smalltalk import smallTalk
from .pickuplines import pickUpLine
from .banter import banter
from .compliments import compliment

__all__ = ["fun_fact", "smallTalk", "pickUpLine", "banter", "compliment"] # append your function to this list
__version__ = "0.0.1"
74 changes: 74 additions & 0 deletions src/conversations/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from .funfacts import fun_fact
from .smalltalk import smallTalk
from .banter import banter
from .pickuplines import pickUpLine
from .compliments import compliment

import argparse

def main() -> None:
parser = argparse.ArgumentParser(prog="conversations")

# funfacts
parser.add_argument("--fact", action="store_true", help="print a fun fact")
parser.add_argument("--category", default="general",
help="fun fact category (general, science, history, animals)")
parser.add_argument("--rarity", default="common",
help="fun fact rarity (common, rare)")

# smalltalk
parser.add_argument("--smalltalk", action="store_true",
help="print a small talk line")
parser.add_argument("--question", action="store_true",
help="when used with --smalltalk, ask a question; otherwise print a comment")
parser.add_argument("--comment", action="store_true",
help="alias: if set, smalltalk will prefer comments")

# common options
parser.add_argument("--kind", choices=["classic", "poetic", "funny", "nerdy"],
help="style/kind for pickup lines (and other funcs if applicable)")
parser.add_argument("--name", default="", help="optional name")

# banter
parser.add_argument("--intensity", choices=["mild", "medium", "intense"],
help="tone intensity for banter/compliment")
parser.add_argument("--banter", action="store_true", help="print a playful banter/insult")

# pickup lines
parser.add_argument("--pickup", action="store_true", help="print a pickup line")

# compliments
parser.add_argument("--compliment", action="store_true", help="print a compliment")

args = parser.parse_args()

# funfacts
if args.fact:
print(fun_fact(category=args.category, rarity=args.rarity))

# smalltalk
if args.smalltalk:
prefer_question = True if args.question else False
if args.comment:
prefer_question = False
print(smallTalk(prefer_question))

# banter
if args.banter:
intensity = args.intensity if args.intensity else "medium"
name = args.name if args.name else ""
print(banter(intensity, name))

# pickup
if args.pickup:
kind = args.kind if args.kind else "classic"
print(pickUpLine(kind, args.name))

# compliment
if args.compliment:
_map = {"mild": 1, "medium": 2, "intense": 3}
inten = _map.get(args.intensity or "medium", 2)
print(compliment(name=args.name, intensity=inten))

if __name__ == "__main__":
main()
41 changes: 41 additions & 0 deletions src/conversations/banter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import random

# separate banter into 3 categories, "mild", "medium," and "intense"
insults = {
"mild": [
f"if I gave you a penny for your thoughts, I'd get change back.",
f"the closest you'll come to a brainstorm is a light drizzle.",
f"you're like a software update: nobody asked for you.",
f"your secret is safe with me, because I wasn't listening.",
f"you have the personality of a loading screen.",
],
"medium": [
f"I envy everyone who hasn't met you.",
f"you'll go far someday. And I hope you stay there.",
f"you look like something I drew with my left hand.",
f"if ignorance is bliss, you must be ecstatic at all times.",
f"you're the human equivalent of a participation trophy.",
f"you bring joy to every room you exit.",


],
"intense": [
f"you're like a cloud: when you disappear, it's a beautiful day.",
f"you're not stupid, you just have bad luck thinking.",
f"you're the kind of person who would get lost in their own thoughts and never be found.",
f"somewhere out there is a tree working hard to replace the oxygen you waste.",
f"you're like a Monday morning: nobody's happy to see you.",
f"you look like a 'before' picture.",
],
}

def banter(intensity, name=""):
"""
Returns a playful insult.
intensity is required (use mild, medium, or intense), name is optional.
"""
result = random.choice(insults[intensity])

if name:
return f"{name}, {result}"
return result
105 changes: 105 additions & 0 deletions src/conversations/compliments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import random
from typing import Optional, Literal

Intensity = Literal[1, 2, 3]
Style = Literal["classic", "geeky", "poetic"]
Category = Literal["personality", "appearance", "accomplishment", "specific"]

def compliment(
name: str = "",
intensity: Intensity = 1,
style: Style = "classic",
category: Category = "personality",
detail: Optional[str] = None,
) -> str:
intensity = 1 if intensity < 1 else 3 if intensity > 3 else intensity

base = {
"personality": {
1: [
"You're such a thoughtful person.",
"You have a gift for making others feel valued.",
"I appreciate your honesty.",
],
2: [
"Your confidence is inspiring.",
"Your kindness is contagious.",
"You have an amazing sense of humor.",
],
3: [
"Your presence lifts everyone around you.",
"Your integrity and empathy set the standard.",
"Your strength under pressure is remarkable.",
],
},
"appearance": {
1: [
"I love your sense of style.",
"That color looks great on you.",
"You look great today.",
],
2: [
"Your outfit is on point.",
"You always add something unique to your look.",
"Your smile lights up the room.",
],
3: [
"Your look today is stunning.",
"Your style is effortlessly impressive.",
"You have a standout, polished presence.",
],
},
"accomplishment": {
1: [
"I admire your creativity.",
"You're a considerate, dependable team player.",
"You have a real way with words.",
],
2: [
"You're an exceptional problem-solver.",
"Your ideas are fresh and insightful.",
"You structure complex tasks brilliantly.",
],
3: [
"Your work sets a new bar for quality.",
"Your leadership on tough tasks is outstanding.",
"You consistently turn hard problems into clear wins.",
],
},
"specific": {
1: [
"I was really impressed by {detail}.",
"Your thoughtful approach to {detail} stood out.",
],
2: [
"The way you handled {detail} showed real skill.",
"{detail} was a smart, well-judged choice.",
],
3: [
"{detail} was exceptional—truly impressive.",
"Your execution on {detail} was outstanding.",
],
},
}

pool = base.get(category, base["personality"])[intensity]
sentence = random.choice(pool)

if category == "specific":
sentence = sentence.replace("{detail}", detail or "that")

style_tail = {
"classic": "",
"geeky": " It's elegantly optimized.",
"poetic": " Like sunlight through calm water.",
}[style]

if name:
sentence = f"{name}, {sentence}"

banned = ["for someone like you", "than you look", "actually pretty good", "not bad", "surprisingly good"]
if any(b in sentence.lower() for b in banned):
sentence = f"{name+', ' if name else ''}You're doing great."

return (sentence + style_tail).strip()
#TODO
55 changes: 55 additions & 0 deletions src/conversations/funfacts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import random

#data
FACTS = {
"general": {
"common": [
"Bananas are berries, but strawberries aren’t.",
"Octopuses have three hearts.",
],
"rare": [
"Sharks existed before trees.",
"Honey never spoils—it can last for millennia.",
],
},
"science": {
"common": [
"A day on Venus is longer than a year on Venus.",
"Humans share about 60% of their DNA with bananas.",
],
"rare": [
"Water can boil and freeze at the same time (triple point).",
"There are more stars in the universe than grains of sand on Earth.",
],
},
"history": {
"common": [
"Oxford University predates the Aztec Empire.",
"Cleopatra lived closer to us than to the building of the pyramids.",
],
"rare": [
"Ancient Roman concrete can 'self-heal'.",
"The first computer bug was a real moth (1947).",
],
},
"animals": {
"common": [
"A group of flamingos is called a flamboyance.",
"Cows can have best friends.",
],
"rare": [
"Axolotls can regenerate parts of their brain.",
"Some jellyfish can revert to a juvenile state.",
],
},
}


def fun_fact(category: str = "general", rarity: str = "common") -> str:
"""
Return one fun fact.
Falls back to general and common if inputs are unknown.
"""
cat = FACTS.get(category) or FACTS["general"]
pool = cat.get(rarity) or cat["common"]
return random.choice(pool)
Loading
Loading