Sync with latest manuscript

This commit is contained in:
Michael Hartl
2022-11-13 10:43:33 -08:00
parent 256ad44d08
commit 51494ca0ce
70 changed files with 0 additions and 914 deletions
-24
View File
@@ -1,24 +0,0 @@
import os
from flask import Flask, render_template
def create_app(test_config=None):
"""Create and configure the app."""
app = Flask(__name__, instance_relative_config=True)
.
.
.
@app.route("/")
def index():
return render_template("index.html")
@app.route("/about")
def about():
return render_template("about.html")
@app.route("/palindrome")
def palindrome():
return render_template("palindrome.html")
return app
app = create_app()
-37
View File
@@ -1,37 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Learn Enough Python Sample App</title>
<link rel="stylesheet" type="text/css" href="/static/stylesheets/main.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400"
rel="stylesheet">
</head>
<body>
<a href="/" class="header-logo">
<img src="/static/images/logo_b.png" alt="Learn Enough logo">
</a>
<div class="container">
<div class="content">
<h1>Sample Flask App</h1>
<p>
This is the sample Flask app for
<a href="https://www.learnenough.com/python-tutorial"><em>Learn Enough Python
to Be Dangerous</em></a>. Learn more on the <a href="/about">About</a> page.
</p>
<p>
Click the <a href="https://en.wikipedia.org/wiki/Sator_Square">Sator
Square</a> below to run the custom <a href="/palindrome">Palindrome
Detector</a>.
</p>
<a class="sator-square" href="/palindrome">
<img src="/static/images/sator_square.jpg" alt="Sator Square">
</a>
</div>
</div>
</body>
</html>
-10
View File
@@ -1,10 +0,0 @@
% import os
% from flask import Flask
% def create_app(test_config=None):
% """Create and configure the app."""
% app = Flask(__name__, instance_relative_config=True,
% static_url_path="/static")
% .
% .
% .
-20
View File
@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Learn Enough Python Sample App</title>
<link rel="stylesheet" type="text/css" href="/static/stylesheets/main.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400"
rel="stylesheet">
</head>
<body>
<a href="/" class="header-logo">
<img src="/static/images/logo_b.png" alt="Learn Enough logo">
</a>
<div class="container">
<div class="content">
<!-- page-specific content -->
</div>
</div>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
$ pip install -e .
-11
View File
@@ -1,11 +0,0 @@
def test_index(client):
response = client.get("/")
assert response.status_code == 200
def test_about(client):
response = client.get("/about")
assert response.status_code == 200
def test_palindrome(client):
response = client.get("/palindrome")
assert response.status_code == 200
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 3 items
tests/test_site_pages.py ... [100%]
============================== 3 passed in 0.01s ===============================
-20
View File
@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Learn Enough Python Sample App</title>
<link rel="stylesheet" type="text/css" href="/static/stylesheets/main.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400"
rel="stylesheet">
</head>
<body>
<a href="/" class="header-logo">
<img src="/static/images/logo_b.png" alt="Learn Enough logo">
</a>
<div class="container">
<div class="content">
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
-21
View File
@@ -1,21 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Sample Flask App</h1>
<p>
This is the sample Flask app for
<a href="https://www.learnenough.com/python-tutorial"><em>Learn Enough Python
to Be Dangerous</em></a>. Learn more on the <a href="/about">About</a> page.
</p>
<p>
Click the <a href="https://en.wikipedia.org/wiki/Sator_Square">Sator
Square</a> below to run the custom <a href="/palindrome">Palindrome
Detector</a>.
</p>
<a class="sator-square" href="/palindrome">
<img src="/static/images/sator_square.jpg" alt="Sator Square">
</a>
{% endblock %}
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 3 items
tests/test_site_pages.py ... [100%]
============================== 3 passed in 0.01s ===============================
-23
View File
@@ -1,23 +0,0 @@
def test_index(client):
response = client.get("/")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title}</title>"
assert title in response.text
assert "<h1>" in response.text
def test_about(client):
response = client.get("/about")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title}</title>"
assert title in response.text
assert "<h1>" in response.text
def test_palindrome(client):
response = client.get("/palindrome")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title}</title>"
assert title in response.text
assert "<h1>" in response.text
-8
View File
@@ -1,8 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Learn Enough Python Sample App | {{ page_title }}</title>
.
.
.
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 3 items
tests/test_site_pages.py ... [100%]
============================== 3 passed in 0.01s ===============================
-24
View File
@@ -1,24 +0,0 @@
def test_index(client):
response = client.get("/")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title} | Home</title>"
assert title in response.text
assert "<h1>" in response.text
assert "<nav>" in response.text
def test_about(client):
response = client.get("/about")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title} | About</title>"
assert title in response.text
assert "<h1>" in response.text
def test_palindrome(client):
response = client.get("/palindrome")
assert response.status_code == 200
base_title = "Learn Enough Python Sample App"
title = f"<title>{base_title} | Palindrome Detector</title>"
assert title in response.text
assert "<h1>" in response.text
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 3 items
tests/test_site_pages.py ... [100%]
============================== 3 passed in 0.01s ===============================
-24
View File
@@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Learn Enough Python Sample App | {{ page_title }}</title>
<link rel="stylesheet" type="text/css" href="/static/stylesheets/main.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400"
rel="stylesheet">
</head>
<body>
<a href="/" class="header-logo">
<img src="/static/images/logo_b.png" alt="Learn Enough logo">
</a>
<div class="container">
<header class="header">
                              
</header>
<div class="content">
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
-9
View File
@@ -1,9 +0,0 @@
<header class="header">
<nav>
<ul class="header-nav">
<li><a href="/">Home</a></li>
<li><a href="/palindrome">Is It a Palindrome?</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
-14
View File
@@ -1,14 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 3 items
tests/test_site_pages.py F.. [100%]
=================================== FAILURES ===================================
__________________________________ test_index __________________________________
.
.
.
=========================== short test summary info ============================
FAILED tests/test_site_pages.py::test_index - assert '<nav>' in '<!DOCTYPE ht...
========================= 1 failed, 2 passed in 0.03s ==========================
-23
View File
@@ -1,23 +0,0 @@
def test_index(client):
response = client.get("/")
assert response.status_code == 200
assert full_title("Home") in response.text
assert "<h1>" in response.text
assert "<nav>" in response.text
def test_about(client):
response = client.get("/about")
assert response.status_code == 200
assert full_title("About") in response.text
assert "<h1>" in response.text
def test_palindrome(client):
response = client.get("/palindrome")
assert response.status_code == 200
assert full_title("Palindrome Detector") in response.text
assert "<h1>" in response.text
def full_title(variable_title):
"""Return the full title."""
base_title = "Learn Enough Python Sample App"
return f"<title>{base_title} | {variable_title}</title>"
-6
View File
@@ -1,6 +0,0 @@
import os
from flask import Flask, render_template, request
from palindrome.phrase import Phrase
.
.
.
-6
View File
@@ -1,6 +0,0 @@
--extra-index-url https://testpypi.python.org/pypi
click==8.1.3
Flask==2.2.2
.
.
.
-11
View File
@@ -1,11 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Palindrome Detector</h1>
<form id="palindrome_tester" action="/check" method="post">
<textarea name="phrase" rows="10" cols="60"></textarea>
<br>
<button class="form-submit" type="submit">Is it a palindrome?</button>
</form>
{% endblock %}
-30
View File
@@ -1,30 +0,0 @@
import os
from flask import Flask, render_template, request
from palindrome.phrase import Phrase
def create_app(test_config=None):
.
.
.
@app.route("/")
def index():
page_title = "Home"
return render_template("index.html", page_title=page_title)
@app.route("/about")
def about():
page_title = "About"
return render_template("about.html", page_title=page_title)
@app.route("/palindrome")
def palindrome():
page_title = "Palindrome Detector"
return render_template("palindrome.html", page_title=page_title)
@app.route("/check", methods=("POST",))
def check():
return request.form
return app
app = create_app()
-4
View File
@@ -1,4 +0,0 @@
if Phrase(phrase).ispalindrome():
print(f'"{phrase}" is a palindrome!"
else:
print(f'"{phrase}" isn\'t a palindrome."
-5
View File
@@ -1,5 +0,0 @@
{% if Phrase(phrase).ispalindrome() %}
"{{ phrase }}" is a palindrome!
{% else %}
"{{ phrase }}" isn't a palindrome.
{% endif %}
-15
View File
@@ -1,15 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Palindrome Result</h1>
{% if Phrase(phrase).ispalindrome() %}
<div class="result result-success">
<p>"{{ phrase }}" is a palindrome!</p>
</div>
{% else %}
<div class="result result-fail">
<p>"{{ phrase }}" isn't a palindrome.</p>
</div>
{% endif %}
{% endblock %}
-45
View File
@@ -1,45 +0,0 @@
import os
from flask import Flask, render_template, request
from palindrome.phrase import Phrase
def create_app(test_config=None):
"""Create and configure the app."""
app = Flask(__name__, instance_relative_config=True)
if test_config is None:
# Load the instance config, if it exists, when not testing.
app.config.from_pyfile("config.py", silent=True)
else:
# Load the test config if passed in.
app.config.from_mapping(test_config)
# Ensure the instance folder exists.
try:
os.makedirs(app.instance_path)
except OSError:
pass
@app.route("/")
def index():
page_title = "Home"
return render_template("index.html", page_title=page_title)
@app.route("/about")
def about():
page_title = "About"
return render_template("about.html", page_title=page_title)
@app.route("/palindrome")
def palindrome():
page_title = "Palindrome Detector"
return render_template("palindrome.html", page_title=page_title)
@app.route("/check", methods=("POST",))
def check():
return render_template("result.html",
Phrase=Phrase,
phrase=request.form["phrase"])
return app
app = create_app()
-6
View File
@@ -1,6 +0,0 @@
def test_palindrome_page(client):
response = client.get("/palindrome")
assert form_tag() in response.text
def form_tag():
return '<form id="palindrome_tester" action="/check" method="post">'
-8
View File
@@ -1,8 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 6 items
tests/test_palindrome.py ... [ 50%]
tests/test_site_pages.py ... [100%]
============================== 6 passed in 0.03s ===============================
-21
View File
@@ -1,21 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Palindrome Result</h1>
{% if ispalindrome %}
<div class="result result-success">
<p>"{{ phrase }}" is a palindrome!</p>
</div>
{% else %}
<div class="result result-fail">
<p>"{{ phrase }}" isn't a palindrome.</p>
</div>
{% endif %}
<form id="palindrome_tester" action="/check" method="post">
<textarea name="phrase" rows="10" cols="60"></textarea>
<br>
<button class="form-submit" type="submit">Is it a palindrome?</button>
</form>
{% endblock %}
-19
View File
@@ -1,19 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Palindrome Result</h1>
{% if ispalindrome %}
<div class="result result-success">
<p>"{{ phrase }}" is a palindrome!</p>
</div>
{% else %}
<div class="result result-fail">
<p>"{{ phrase }}" isn't a palindrome.</p>
</div>
{% endif %}
<h2>Try another one!</h2>
{% include "palindrome_form.html" %}
{% endblock %}
-8
View File
@@ -1,8 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 6 items
tests/test_palindrome.py ... [ 50%]
tests/test_site_pages.py ... [100%]
============================== 6 passed in 0.03s ===============================
-2
View File
@@ -1,2 +0,0 @@
(venv) $ pip install --upgrade your-package \
> --index-url https://test.pypi.org/simple/
-1
View File
@@ -1 +0,0 @@
web: gunicorn palindrome_detector:app
-7
View File
@@ -1,7 +0,0 @@
(venv) $ deactivate
$ rm -rf venv/
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install -r requirements.txt
(venv) $ flask --app palindrome_detector --debug run
* Running on http://127.0.0.1:5000/
-8
View File
@@ -1,8 +0,0 @@
> for (i = 0; i < 5; i++) {
console.log(i);
}
0
1
2
3
4
-16
View File
@@ -1,16 +0,0 @@
>>> for i in range(len(soliloquy)): # Not Pythonic
... print(soliloquy[i])
...
T
o
b
e
.
.
.
t
i
o
n
:
-5
View File
@@ -1,5 +0,0 @@
class Phrase(str):
"""A class for phrases."""
.
.
.
-2
View File
@@ -1,2 +0,0 @@
def test_initial_example():
assert False
-17
View File
@@ -1,17 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 1 item
tests/palindrome_test.py F [100%]
=================================== FAILURES ===================================
_____________________________ test_non_palindrome ______________________________
def test_non_palindrome():
> assert False
E assert False
tests/palindrome_test.py:4: AssertionError
=========================== short test summary info ============================
FAILED tests/palindrome_test.py::test_non_palindrome - assert False
============================== 1 failed in 0.01s ===============================
-2
View File
@@ -1,2 +0,0 @@
def test_initial_example():
assert True
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 1 item
tests/test_phrase.py . [100%]
============================== 1 passed in 0.00s ===============================
-2
View File
@@ -1,2 +0,0 @@
def test_initial_example():
assert not False
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 1 item
tests/test_phrase.py . [100%]
============================== 1 passed in 0.00s ===============================
-1
View File
@@ -1 +0,0 @@
from palindrome.phrase import Phrase
-1
View File
@@ -1 +0,0 @@
(venv) $ pip install -e .
-7
View File
@@ -1,7 +0,0 @@
from palindrome.phrase import Phrase
def test_non_palindrome():
assert not Phrase("apple").ispalindrome()
def test_literal_palindrome():
assert Phrase("racecar").ispalindrome()
-9
View File
@@ -1,9 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: /Users/mhartl/repos/python_package_tutorial
collected 2 items
tests/test_phrase.py .. [100%]
============================== 2 passed in 0.00s ===============================
-14
View File
@@ -1,14 +0,0 @@
from palindrome.phrase import Phrase
from pytest import skip
def test_non_palindrome():
assert not Phrase("apple").ispalindrome()
def test_literal_palindrome():
assert Phrase("racecar").ispalindrome()
def test_mixed_case_palindrome():
skip()
def test_palindrome_with_punctuation():
skip()
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 4 items
tests/test_phrase.py ..ss [100%]
========================= 2 passed, 2 skipped in 0.00s =========================
-14
View File
@@ -1,14 +0,0 @@
from palindrome.phrase import Phrase
from pytest import skip
def test_non_palindrome():
assert not Phrase("apple").ispalindrome()
def test_literal_palindrome():
assert Phrase("racecar").ispalindrome()
def test_mixed_case_palindrome():
assert Phrase("RaceCar").ispalindrome()
def test_palindrome_with_punctuation():
assert Phrase("Madam, I'm Adam.").ispalindrome()
-17
View File
@@ -1,17 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 4 items
tests/test_phrase.py ...F [100%]
=================================== FAILURES ===================================
_______________________ test_palindrome_with_punctuation _______________________
def test_palindrome_with_punctuation():
> assert Phrase("Madam, I'm Adam.").ispalindrome()
E assert False
tests/test_phrase.py:14: AssertionError
=========================== short test summary info ============================
FAILED tests/test_phrase.py::test_palindrome_with_punctuation - assert False
========================= 1 failed, 3 passed in 0.01s ==========================
-21
View File
@@ -1,21 +0,0 @@
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = content
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.content.lower()
def letters(self):
"""Return the letters in the content."""
pass
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-24
View File
@@ -1,24 +0,0 @@
[metadata]
name = palindrome-<username>
version = 0.0.1
author = Example Author
author_email = author@example.com
description = A small example package
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/pypa/sampleproject
project_urls =
Bug Tracker = https://github.com/pypa/sampleproject/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
package_dir =
= src
packages = find:
python_requires = >=3.6
[options.packages.find]
where = src
-24
View File
@@ -1,24 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 5 items
tests/test_phrase.py ...FF [100%]
=================================== FAILURES ===================================
_______________________ test_palindrome_with_punctuation _______________________
def test_palindrome_with_punctuation():
> assert Phrase("Madam, I'm Adam.").ispalindrome()
E assert False
tests/test_phrase.py:14: AssertionError
_________________________________ test_letters _________________________________
def test_letters():
> assert Phrase("Madam, I'm Adam.").letters() == "MadamImAdam"
E assert None == 'MadamImAdam'
tests/test_phrase.py:17: AssertionError
=========================== short test summary info ============================
FAILED tests/test_phrase.py::test_palindrome_with_punctuation - assert False
FAILED tests/test_phrase.py::test_letters - assert None == 'MadamImAdam'
========================= 2 failed, 3 passed in 0.01s ==========================
-27
View File
@@ -1,27 +0,0 @@
import re
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = content
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.content.lower()
def letters(self):
"""Return the letters in the content."""
the_letters = []
for character in self.content:
if re.search(r"[a-zA-Z]", character):
the_letters.append(character)
return "".join(the_letters)
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-19
View File
@@ -1,19 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: /Users/mhartl/repos/python_package_tutorial
collected 5 items
tests/test_phrase.py ...F. [100%]
=================================== FAILURES ===================================
_______________________ test_palindrome_with_punctuation _______________________
def test_palindrome_with_punctuation():
> assert Phrase("Madam, I'm Adam.").ispalindrome()
E assert False
tests/test_phrase.py:14: AssertionError
=========================== short test summary info ============================
FAILED tests/test_phrase.py::test_palindrome_with_punctuation - assert False
========================= 1 failed, 4 passed in 0.01s ==========================
-27
View File
@@ -1,27 +0,0 @@
import re
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = content
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.letters().lower()
def letters(self):
"""Return the letters in the content."""
the_letters = []
for character in self.content:
if re.search(r"[a-zA-Z]", character):
the_letters.append(character)
return "".join(the_letters)
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 5 items
tests/test_phrase.py ..... [100%]
============================== 5 passed in 0.00s ===============================
-23
View File
@@ -1,23 +0,0 @@
import re
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = content
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.letters().lower()
def letters(self):
"""Return the letters in the content."""
return "".join([c for c in self.content if re.search(r"[a-zA-Z]", c)])
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 5 items
tests/test_phrase.py ..... [100%]
============================== 5 passed in 0.01s ===============================
-23
View File
@@ -1,23 +0,0 @@
import re
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = content
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.letters().lower()
def letters(self):
"""Return the letters in the content."""
return "".join(re.findall(r"[a-zA-Z]", self.content))
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-7
View File
@@ -1,7 +0,0 @@
(venv) $ pytest
============================= test session starts ==============================
collected 5 items
tests/test_phrase.py ..... [100%]
============================== 5 passed in 0.01s ===============================
-23
View File
@@ -1,23 +0,0 @@
from palindrome.phrase import Phrase
from pytest import skip
def test_non_palindrome():
assert not Phrase("apple").ispalindrome()
def test_literal_palindrome():
assert Phrase("racecar").ispalindrome()
def test_mixed_case_palindrome():
assert Phrase("RaceCar").ispalindrome()
def test_palindrome_with_punctuation():
assert Phrase("Madam, I'm Adam.").ispalindrome()
def test_letters_and_digits():
assert Phrase("Madam, I'm Adam.").letters_and_digits() == "MadamImAdam"
def test_integer_non_palindrome():
FILL_IN Phrase(12345).ispalindrome()
def test_integer_palindrome():
FILL_IN Phrase(12321).ispalindrome()
-23
View File
@@ -1,23 +0,0 @@
import re
class Phrase:
"""A class to represent phrases."""
def __init__(self, content):
self.content = str(content)
def ispalindrome(self):
"""Return True for a palindrome, False otherwise."""
return self.processed_content() == reverse(self.processed_content())
def processed_content(self):
"""Return content for palindrome testing."""
return self.letters_and_digits().lower()
def letters_and_digits(self):
"""Return the letters and digits in the content."""
return "".join(re.findall(r"[a-zA-Z\d]", self.content))
def reverse(string):
"""Reverse a string."""
return "".join(reversed(string))
-2
View File
@@ -1,2 +0,0 @@
(venv) $ pip install --upgrade your-package \
> --index-url https://test.pypi.org/simple/
-6
View File
@@ -1,6 +0,0 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"
-5
View File
@@ -1,5 +0,0 @@
$ deactivate # just in case a virtual env is already active
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install --upgrade pip
(venv) $ pip install pytest==7.1.3
-16
View File
@@ -1,16 +0,0 @@
venv/
*.pyc
__pycache__/
instance/
.pytest_cache/
.coverage
htmlcov/
dist/
build/
*.egg-info/
.DS_Store
-3
View File
@@ -1,3 +0,0 @@
$ git init
$ git add -A
$ git commit -m "Initialize repository"