1. Architecture Overview
30 Days Of Python is a structured Python programming curriculum organized as a Git repository of daily lessons. Each day is a self-contained directory with a markdown tutorial and companion Python scripts. The repository also includes a functional Flask web application (python_for_web/) that serves as both a teaching example and a deployable artifact, plus reusable Python packages (mypackage/, 20_Day_Python_package_manager/) demonstrating package creation concepts.
The project is a monorepo combining educational content (markdown), executable code examples (Python scripts), sample data files (CSV/JSON/TXT), and a web application — all organized around a 30-day progression.
Component Inventory
| Component | Path | Role |
|---|---|---|
| Day lessons (English) | 01_Day_Introduction/ through 30_Day_Conclusions/ |
Core curriculum — markdown tutorials + Python example scripts |
| Flask web app | python_for_web/ |
Functional web application for Day 26 |
| Custom module example | mymodule.py (root), 12_Day_Modules/mymodule.py |
Module import teaching example |
| Custom package example | mypackage/ |
Package creation teaching example |
| Package manager example | 20_Day_Python_package_manager/ |
Alternative package demo |
| Sample datasets | data/, files/ |
CSV, JSON, TXT files for exercises |
| Web scraping output | 22_Day_Web_scraping/scrapped_data.json |
Scraped data sample |
| Chinese translation | Chinese/ |
Days 2–30 markdown |
| Korean translation | Korean/ |
Partial (Days 2–5, 7–8, 10) |
| German translation | German/ |
Days 2–30 markdown |
| Spanish translation | Spanish/ |
Days 1–30 with code files |
| Persian translation | Persain/ |
Days 2–30 markdown |
| Portuguese translation | Portuguese/ |
Day 2 only |
| Ukrainian translation | Ukrainian/ |
README only |
| Legacy files | old_files/ |
Superseded multi-day README files |
| NumPy images | numpy_files/ |
Images for NumPy lesson |
| Test file images | test_files/ |
Test output images |
| Instructional images | images/ |
Screenshots, diagrams for lessons |
Technology Stack
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.6+ | Primary language taught |
| Flask | 1.1.1 | Web framework (Day 26 example app) |
| Jinja2 | 2.10.3 | Templating for Flask |
| Werkzeug | 0.16.0 | WSGI utilities for Flask |
| Click | 7.0 | CLI interface (Flask dependency) |
| Markdown | — | Lesson content format |
Note
The pinned Flask version (1.1.1) is several major versions behind current (Flask 3.x). This is intentional for stability of the teaching example but means the web app uses deprecated patterns such as
SEND_FILE_MAX_AGE_DEFAULTconfiguration.
Data Flow
Learner reads daily markdown lesson
→ Runs companion .py file(s) to see concepts in action
→ Completes exercises at end of markdown
→ Progresses to next day
Flask app (Day 26):
Browser → GET / → app.py:home() → home.html (techs list)
Browser → GET /about → app.py:about() → about.html
Browser → GET/POST /post → app.py:post() → post.html / redirect to /result
Browser → GET /result → app.py:result() → result.html
2. System Requirements
| Requirement | Minimum | Notes |
|---|---|---|
| Python | 3.6+ | f-strings used throughout; 3.10+ recommended |
| Git | Any | For cloning the repository |
| Disk space | ~50 MB | Includes all data files and images |
| MongoDB | Optional | Day 27 lesson; MongoDB Atlas (cloud) works |
| Web browser | Any | For Flask app and MongoDB Atlas setup |
Optional Software (by lesson day)
| Day | Software | Purpose |
|---|---|---|
| 22 | pip install beautifulsoup4 requests |
Web scraping |
| 24 | pip install numpy |
Statistics/numerical computing |
| 25 | pip install pandas |
Data analysis |
| 26 | pip install -r python_for_web/requirements.txt |
Flask web app |
| 27 | pip install pymongo + MongoDB instance |
Database lessons |
| 28–29 | pip install requests flask |
API consumption and creation |
3. Configuration Reference
Config Files
| File | Format | Location | Purpose |
|---|---|---|---|
python_for_web/requirements.txt |
pip freeze | python_for_web/ |
Flask app dependencies |
python_for_web/.gitignore |
gitignore | python_for_web/ |
Flask app exclusions |
python_for_web/Procfile |
Heroku | python_for_web/ |
Heroku deployment descriptor |
.gitignore |
gitignore | Root | Repository-level exclusions |
Environment Variables
| Variable | Type | Default | Description | Required? |
|---|---|---|---|---|
PORT |
Integer | 5000 |
Flask web server listening port | No |
Important
The
PORTenvironment variable is the only runtime configuration. It is read inpython_for_web/app.pyviaos.environ.get("PORT", 5000). All other behavior is hardcoded in the example scripts.
Flask Application Configuration
The Flask app sets one configuration value programmatically:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
This disables static file caching during development. The app also runs with debug=True and binds to 0.0.0.0, which is appropriate for local development but not for production deployment.
4. Deployment & Scaling
Local Development
No deployment steps are required for the core curriculum. Clone and run:
git clone https://github.com/Asabeneh/30-Days-Of-Python.git
cd 30-Days-Of-Python
Flask App Deployment
The python_for_web/ directory includes a Procfile, indicating it was designed for Heroku deployment:
web: python app.py
Warning
The Flask app runs with
debug=Trueand binds to0.0.0.0. For any deployment beyond local learning, disable debug mode and configure a proper WSGI server (Gunicorn, uWSGI) in front of the Flask app.
Heroku deployment:
- Create a Heroku app
- Push the
python_for_web/directory - The
Procfileandrequirements.txthandle the rest
Docker deployment (custom):
FROM python:3.10-slim
WORKDIR /app
COPY python_for_web/ .
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
Hosting the Curriculum
For classroom or workshop use, the markdown files can be served via:
- GitHub Pages — push to a
gh-pagesbranch - MkDocs — add a
mkdocs.ymland build a static site - Raw GitHub — link directly to markdown files on GitHub (renders natively)
5. Operations
Content Update Workflow
To update lesson content:
- Edit the relevant day's markdown file
- If code examples changed, update the corresponding
.pyfile - If translations exist for the changed day, flag them for translation update
Tip
The Spanish translation includes actual
.pycode files (Spanish/01_Day_Introduction/helloworld.py,Spanish/02_Day_Variables_builtin_functions/variables.py,Spanish/03_Day_Operators/day-3.py). Other translations only have markdown. When updating code examples, check if Spanish.pyfiles need updating too.
Translation Management
| Language | Maintainer Directory | File Naming Pattern | Status |
|---|---|---|---|
| Chinese | Chinese/ |
{NN}_{topic}_cn.md or {NN}_{topic}.md |
Near-complete |
| Korean | Korean/ |
{NN}_{topic}_ko.md or subdirectories |
Partial |
| German | German/ |
{NN}_{topic}_de.md |
Near-complete |
| Spanish | Spanish/ |
{NN}_{topic}_sp.md + subdirectories with code |
Complete |
| Persian | Persain/ |
{NN}_{topic}.md |
Near-complete |
| Portuguese | Portuguese/ |
README.md in subdirectories |
Minimal |
| Ukrainian | Ukrainian/ |
readme.md |
README only |
Note
The Persian directory is spelled
Persain/(sic) throughout the repository. This is a known typo but renaming it would break existing links and forks.
Monitoring Content Quality
Known community-reported issues to track:
| Issue | Day | Description |
|---|---|---|
| #823 | 7 | Says "list" where it should say "set" |
| #813 | — | Missing space after comma |
| #808 | 14 | Wrong question text |
| #807 | 1 | Minor code mistake |
| #797 | 4 | Incorrect boolean comment |
| #796 | 4 | Content error |
| #795 | — | Typo |
| #769 | — | Ukrainian Day 2 returns 404 |
| #565 | 4 | Duplicated exercises |
6. Performance
Repository Size
| Metric | Value |
|---|---|
| Total files | 305 |
| Total source characters | 99,463 |
| Python source files | 21 |
| Markdown lesson files | ~90 |
| Image files | ~50 |
| Data files | ~17 |
| Translation files | ~130 |
The data/ directory contributes the bulk of file size (242,022 characters) due to large CSV and JSON datasets (Hacker News posts, Fortune 500 companies, cat breeds API data, country information).
Tip
If forking for a trimmed version, the
data/directory,images/, and translation directories are the largest space consumers. The core English curriculum (Days 1–30) pluspython_for_web/andmypackage/are under 50KB of source.
7. Security
Flask Application Security Considerations
The python_for_web/app.py has several security-relevant characteristics:
| Concern | Status | Detail |
|---|---|---|
| Debug mode | Enabled (debug=True) |
Exposes Werkzeug debugger — never use in production |
| Binding | 0.0.0.0 |
Accepts connections from any interface |
| Static caching | Disabled (SEND_FILE_MAX_AGE_DEFAULT = 0) |
Appropriate for dev only |
| Input handling | Minimal | /post reads request.form['content'] but discards it on redirect |
| CSRF protection | None | No CSRF tokens on the POST form |
| Authentication | None | No login or access control |
Caution
The Flask application is a teaching example and should never be deployed to a public-facing server without significant hardening: disable debug mode, add CSRF protection, implement input validation, use a production WSGI server, and configure proper security headers.
Dependency Security
The pinned dependencies in requirements.txt are from 2019:
| Package | Pinned Version | Known Issues |
|---|---|---|
| Flask | 1.1.1 | Multiple CVEs in older Flask/Werkzeug |
| Werkzeug | 0.16.0 | Pre-dates debugger PIN hardening |
| Jinja2 | 2.10.3 | Pre-dates several security patches |
For any use beyond local learning, update all dependencies to their latest versions.
Data Files
The data/ directory contains only public/synthetic datasets. No credentials, API keys, or sensitive information is present in the repository.
8. Developer Internals
Repository Structure
30-Days-Of-Python/
├── .gitignore
├── mymodule.py # Root-level module example (Day 12)
├── numpy.md # NumPy reference notes
├── readme.md # Project README
│
├── 01_Day_Introduction/ # Day 1: Python basics
│ └── helloworld.py
├── 02_Day_Variables_builtin_functions/ # Day 2: Variables
│ ├── 02_variables_builtin_functions.md
│ └── variables.py
├── 03_Day_Operators/ # Day 3: Operators
│ ├── 03_operators.md
│ └── day-3.py
├── 04_Day_Strings/ # Day 4: Strings
│ ├── 04_strings.md
│ └── day_4.py
├── 05_Day_Lists/ # Day 5: Lists
│ ├── 05_lists.md
│ └── day_5.py
├── 06_Day_Tuples/ through 30_Day_Conclusions/ # Days 6-30
│ └── {NN}_{topic}.md # Markdown lesson (all days)
│ └── [optional .py file] # Code examples (some days)
│
├── 12_Day_Modules/ # Day 12: Modules
│ ├── 12_modules.md
│ ├── main.py # Entry point importing mymodule
│ └── mymodule.py # Local copy of root mymodule
│
├── 20_Day_Python_package_manager/ # Day 20: Packages
│ ├── 20_python_package_manager.md
│ ├── __init__.py
│ ├── arithmetic.py # Math functions
│ └── greet.py # Greeting function
│
├── mypackage/ # Standalone package example
│ ├── __init__.py
│ ├── arithmetics.py # Math functions (mirrors Day 20)
│ └── greet.py # Greeting function
│
├── python_for_web/ # Day 26: Flask web app
│ ├── .gitignore
│ ├── Procfile # Heroku deployment
│ ├── app.py # Flask application entry point
│ ├── requirements.txt # Pinned dependencies
│ ├── static/css/main.css # Stylesheet
│ └── templates/ # Jinja2 templates
│ ├── layout.html # Base template
│ ├── home.html # Home page
│ ├── about.html # About page
│ ├── post.html # Text input form
│ └── result.html # Analysis result
│
├── data/ # Sample datasets
│ ├── cats.json # Cat breeds (API example)
│ ├── countries_data.json # Country information
│ ├── countries_data_long.json # Extended country data
│ ├── countries.py # Country lists as Python
│ ├── countries-data.py # Country data as Python
│ ├── stop_words.py # Stop words list
│ ├── *.csv # Various CSV datasets
│ └── *.txt # Text files for exercises
│
├── files/ # File handling examples
│ ├── csv_example.csv
│ ├── json_example.json
│ ├── xml_example.xml
│ ├── example.txt
│ ├── reading_file_example.txt
│ └── excel_example.xlsx
│
├── images/ # Instructional screenshots
│ ├── *.png # IDE, shell, concept diagrams
│ └── mongoDB/ # MongoDB Atlas setup screenshots
│
├── Chinese/ # Chinese translation
├── Korean/ # Korean translation (partial)
├── German/ # German translation
├── Spanish/ # Spanish translation (with code)
├── Persain/ # Persian translation
├── Portuguese/ # Portuguese translation (minimal)
├── Ukrainian/ # Ukrainian (readme only)
│
├── old_files/ # Legacy multi-day READMEs
├── numpy_files/ # NumPy lesson images
└── test_files/ # Test output images
Module Reference
mymodule.py (Root)
A teaching module demonstrating Python module creation. Exists in two locations with identical functionality:
| Location | Purpose |
|---|---|
mymodule.py (root) |
Importable from root-level scripts |
12_Day_Modules/mymodule.py |
Local to the Day 12 lesson directory |
Exported symbols:
| Symbol | Type | Description |
|---|---|---|
generate_full_name(firstname, lastname) |
Function | Concatenates first and last name with space |
sum_two_nums(num1, num2) |
Function | Returns sum of two numbers |
gravity |
Float (9.81) |
Gravitational constant |
person |
Dict | Sample person data (firstname, age, country, city) |
mypackage/ Package
Demonstrates Python package creation with __init__.py.
mypackage/arithmetics.py:
| Function | Signature | Returns |
|---|---|---|
add_numbers |
(*args) |
Sum of all arguments (variadic) |
subtract |
(a, b) |
a - b |
multiple |
(a, b) |
a * b |
division |
(a, b) |
a / b |
remainder |
(a, b) |
a % b |
power |
(a, b) |
a ** b |
mypackage/greet.py:
| Function | Signature | Returns |
|---|---|---|
greet_person |
(firstname, lastname) |
"{firstname} {lastname}, welcome to 30DaysOfPython Challenge!" |
Note
The
20_Day_Python_package_manager/directory containsarithmetic.pyandgreet.pywith identical functionality tomypackage/arithmetics.pyandmypackage/greet.py. The only difference is the filename:arithmetic.py(Day 20) vs.arithmetics.py(mypackage). Both also include an__init__.py.
python_for_web/app.py — Flask Application
A Flask web application with 4 routes serving Jinja2 templates:
| Route | Method(s) | Handler | Template | Context Variables |
|---|---|---|---|---|
/ |
GET | home() |
home.html |
techs=['HTML','CSS','Flask','Python'], name, title='Home' |
/about |
GET | about() |
about.html |
name, title='About Us' |
/result |
GET | result() |
result.html |
(none) |
/post |
GET, POST | post() |
post.html / redirect |
name='Text Analyzer', title; POST reads request.form['content'] then redirects to /result |
Application configuration:
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 # Disable static file caching
Startup:
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
Warning
The
/postPOST handler readsrequest.form['content']but does not pass it to the redirect target (/result). The analyzed content is discarded. This appears to be an intentional exercise gap for learners to complete.
Code Patterns and Conventions
Naming:
- Day directories:
{NN}_Day_{Topic}/with underscores (e.g.,04_Day_Strings/) - Markdown files:
{NN}_{topic}.md(lowercase, underscores) - Python files: inconsistent —
helloworld.py,day_4.py,day-3.py,variables.py - Translation files:
{NN}_{topic}_{lang_code}.md(e.g.,03_operators_de.md)
Code style:
- No type hints used anywhere
- Inline comments extensively used to explain each line
- Print statements used for all output (no logging)
- No unit tests
- No linting configuration
- Snake_case for variables and functions (Python convention)
Duplicate code:
The following code is duplicated between locations:
| Code | Location 1 | Location 2 |
|---|---|---|
generate_full_name() |
mymodule.py (root) |
12_Day_Modules/mymodule.py |
sum_two_nums() |
mymodule.py (root) |
12_Day_Modules/mymodule.py |
add_numbers() through power() |
mypackage/arithmetics.py |
20_Day_Python_package_manager/arithmetic.py |
greet_person() |
mypackage/greet.py |
20_Day_Python_package_manager/greet.py |
This duplication is intentional — each copy exists in its lesson context for standalone execution.
Data Files Reference
data/ directory — large datasets:
| File | Size | Format | Content |
|---|---|---|---|
cats.json |
Large JSON | JSON array | Cat breed information from TheCatAPI |
countries_data.json |
JSON | JSON array | Country name, capital, population, etc. |
countries_data_long.json |
JSON | Extended JSON | Detailed country data |
countries.py |
Python | List | Country names as Python list |
countries-data.py |
Python | Dict list | Country data as Python structures |
stop_words.py |
Python | List | English stop words |
HN_posts_year_to_Sep_26_2016.csv |
CSV | Tabular | Hacker News posts |
hacker_news.csv |
CSV | Tabular | Hacker News subset |
F500.csv |
CSV | Tabular | Fortune 500 data |
fortune1000_final.csv |
CSV | Tabular | Fortune 1000 data |
fortune_500_companies_2017.csv |
CSV | Tabular | Fortune 500 (2017) |
weight-height.csv |
CSV | Tabular | Height/weight measurements |
result.csv |
CSV | Tabular | Analysis output |
donald_speech.txt |
TXT | Plain text | Speech text for regex exercises |
melina_trump_speech.txt |
TXT | Plain text | Speech text for exercises |
michelle_obama_speech.txt |
TXT | Plain text | Speech text for exercises |
obama_speech.txt |
TXT | Plain text | Speech text for exercises |
romeo_and_juliet.txt |
TXT | Plain text | Literary text for exercises |
email_exchanges.txt |
TXT | Plain text | Email samples for exercises |
email_exchanges_big.txt |
TXT | Plain text | Larger email dataset |
files/ directory — small teaching examples:
| File | Format | Purpose |
|---|---|---|
csv_example.csv |
CSV | Demonstrates CSV reading |
json_example.json |
JSON | Demonstrates JSON parsing: {"name":"Asabeneh","country":"Finland","city":"Helsinki","skills":["JavaScrip","React","Python"]} |
xml_example.xml |
XML | Demonstrates XML parsing |
example.txt |
TXT | General file reading |
reading_file_example.txt |
TXT | File I/O exercises |
excel_example.xlsx |
XLSX | Excel file reading with openpyxl |
Note
The
json_example.jsonfile contains a typo:"JavaScrip"instead of"JavaScript". This exists in the source and may be intentional as a teaching moment about data validation.
Testing Strategy
The repository contains no automated tests. The .py files in each day's directory serve as executable examples that demonstrate correct behavior through print() output. Verification is manual — the learner compares console output against the inline comments.
Recommended additions for contributors:
- Add
pytestconfiguration and unit tests formypackage/functions - Add integration tests for the Flask application routes
- Add a CI pipeline to validate Python syntax across all
.pyfiles
Potential Improvements
-
Consolidate duplicate code —
mypackage/and20_Day_Python_package_manager/contain identical function implementations. Consider having Day 20 referencemypackage/directly or documenting the intentional duplication. -
Update Flask dependencies — The pinned versions (Flask 1.1.1, Werkzeug 0.16.0) have known security vulnerabilities. Update to Flask 3.x for learners who might deploy the example.
-
Add automated testing — A simple CI workflow validating Python syntax (
python -m py_compile *.py) would catch syntax errors. Some existing code has bugs (e.g.,fruits.list(3, 'lime')in Day 5 should befruits.insert(3, 'lime');fruits.remove()should befruits.pop()). -
Fix known code errors:
05_Day_Lists/day_5.py:fruits.list(3, 'lime')→ should befruits.insert(3, 'lime')05_Day_Lists/day_5.py:fruits.remove()→ should befruits.pop()04_Day_Strings/day_4.py:area = pi # radius ## 2→ broken expression (should bepi * radius ** 2)
-
Standardize Python file naming — Current mix of
helloworld.py,day_4.py,day-3.py,variables.pyis inconsistent. A convention likeday_{NN}.pywould improve navigation. -
Complete translation coverage — Korean (5 days) and Portuguese (1 day) translations are fragmentary. Either complete them or mark them clearly as "work in progress."
-
Fix the
/postroute — The Flask app captures form content but discards it on redirect. Either implement the text analysis or document it explicitly as an exercise. -
Add a unified
requirements.txt— A root-level requirements file covering all lessons (Flask, beautifulsoup4, requests, numpy, pandas, pymongo) would simplify setup. -
Fix the
Persain/directory name — The Persian translation directory is misspelled. A rename toPersian/with a symlink for backward compatibility would be clean.
Contributing Guide
The repository accepts community contributions primarily through GitHub issues. Based on the issue history:
- Content corrections (typos, wrong examples) are the most common contribution type
- Issues #565, #795, #796, #797, #807, #808, #813, #823 all report content errors
- Translation contributions follow a directory-per-language pattern
To contribute:
- Fork the repository
- Create a branch for your change
- Follow the existing naming conventions for the relevant language/day
- Open a pull request with a clear description of the correction
Tip
When contributing code fixes, verify the
.pyfile output matches the inline comments. Several existing scripts have mismatches between code behavior and comments (e.g., Day 4 string examples have dead code fragments).
9. Integration Points
Flask Template System
The Flask app uses Jinja2 templates with a layout inheritance pattern:
templates/
├── layout.html # Base template (HTML structure, CSS link)
├── home.html # Extends layout, renders tech list
├── about.html # Extends layout, about page
├── post.html # Extends layout, text input form
└── result.html # Extends layout, analysis results
Static assets are served from python_for_web/static/css/main.css.
Heroku Integration
The Procfile in python_for_web/ declares a web process:
web: python app.py
Combined with requirements.txt, this provides Heroku buildpack auto-detection for Python applications.
MongoDB Atlas (Day 27)
The Day 27 lesson references MongoDB Atlas (cloud-hosted MongoDB). Setup screenshots are provided in images/mongoDB/:
| Screenshot | Purpose |
|---|---|
mongodb-register.png |
Atlas registration |
mongodb-signup-page.png |
Sign-up form |
mongodb-free.png |
Free tier selection |
mongodb-sandbox.png |
Sandbox cluster |
mongodb-cluster-name.png |
Cluster naming |
mongodb-add-user.png |
Database user creation |
mongodb-allow-ip-access.png |
IP whitelist |
mongodb-create-uri.png |
Connection string |
mongodb-python-driver.png |
Python driver selection |
mongodb-creating_database.png |
Database creation |
External APIs (Day 28)
The Day 28 lesson teaches consuming REST APIs. The included data/cats.json contains sample data from TheCatAPI, providing offline practice data for learners without API access.