Tic Tac Toe
+Classic command-line two-player game with win detection and board rendering.
+ + + View code + + +diff --git a/.github/workflows/clones.yml b/.github/workflows/clones.yml deleted file mode 100644 index 2862628..0000000 --- a/.github/workflows/clones.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Backup On Branch - -on: - push: - branches: - - main # Trigger on the mrayanasim branch - -jobs: - backup: - runs-on: ubuntu-latest - - steps: - - name: Checkout the Branch - uses: actions/checkout@v2 - with: - ref: mrayanasim # Checkout the main branch - - - name: Upload Main Branch to Backup - uses: actions/upload-artifact@v2 - with: - name: repository-backup - path: . # This will upload all files in the main branch diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml deleted file mode 100644 index 08b4290..0000000 --- a/.github/workflows/codacy.yml +++ /dev/null @@ -1,61 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow checks out code, performs a Codacy security scan -# and integrates the results with the -# GitHub Advanced Security code scanning feature. For more information on -# the Codacy security scan action usage and parameters, see -# https://github.com/codacy/codacy-analysis-cli-action. -# For more information on Codacy Analysis CLI in general, see -# https://github.com/codacy/codacy-analysis-cli. - -name: Codacy Security Scan - -on: - push: - branches: [ "main" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main" ] - schedule: - - cron: '18 21 * * 3' - -permissions: - contents: read - -jobs: - codacy-security-scan: - permissions: - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status - name: Codacy Security Scan - runs-on: ubuntu-latest - steps: - # Checkout the repository to the GitHub Actions runner - - name: Checkout code - uses: actions/checkout@v3 - - # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis - - name: Run Codacy Analysis CLI - uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b - with: - # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository - # You can also omit the token and run the tools that support default configurations - project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} - verbose: true - output: results.sarif - format: sarif - # Adjust severity of non-security issues - gh-code-scanning-compat: true - # Force 0 exit code to allow SARIF file generation - # This will handover control about PR rejection to the GitHub side - max-allowed-issues: 2147483647 - - # Upload the SARIF file generated in the previous step - - name: Upload SARIF results file - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: results.sarif diff --git a/.github/workflows/cr.yml b/.github/workflows/cr.yml deleted file mode 100644 index eaafca4..0000000 --- a/.github/workflows/cr.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Code Review - -permissions: - contents: read - pull-requests: write - -on: - pull_request: - types: [opened, reopened, synchronize] - -jobs: - test: - # if: ${{ contains(github.event.*.labels.*.name, 'gpt review') }} # Optional; to run only when a label is attached - runs-on: ubuntu-latest - steps: - - uses: anc95/ChatGPT-CodeReview@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - # Optional - LANGUAGE: Chinese - OPENAI_API_ENDPOINT: https://api.openai.com/v1 - MODEL: gpt-3.5-turbo # https://platform.openai.com/docs/models - PROMPT: # example: Please check if there are any confusions or irregularities in the following code diff: - top_p: 1 # https://platform.openai.com/docs/api-reference/chat/create#chat/create-top_p - temperature: 1 # https://platform.openai.com/docs/api-reference/chat/create#chat/create-temperature - max_tokens: 10000 - MAX_PATCH_LENGTH: 10000 # if the patch/diff length is large than MAX_PATCH_LENGTH, will be ignored and won't review. By default, with no MAX_PATCH_LENGTH set, there is also no limit for the patch/diff length. diff --git a/.github/workflows/datree-validation.yml b/.github/workflows/datree-validation.yml deleted file mode 100644 index 9ef6fd1..0000000 --- a/.github/workflows/datree-validation.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Datree Workflow - -on: - push: - paths: - - '**/*.yaml' - - '**/*.yml' - pull_request: - types: [opened, edited, synchronize, reopened] - paths: - - '**/*.yaml' - - '**/*.yml' - -jobs: - configs-validation: - runs-on: ubuntu-latest - env: - DATREE_TOKEN: ${{ secrets.DATREE_TOKEN }} - steps: - - name: Checkout repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v46 - with: - files: | - *.yaml - *.yml - - - name: List all changed files - run: echo ${{ steps.changed-files.outputs.all_changed_files }} - - - name: Install Datree's CLI - if: steps.changed-files.outputs.any_changed == 'true' - run: curl https://get.datree.io | /bin/bash -s - - # |=========================== Datree Policy Check ===================================| - # | Prevent Kubernetes misconfigurations from reaching production! | - # | Datree is a CLI tool to ensure K8s configs follow stability & security | - # | best practices as well as your organizationβs policies. | - # | For more info visit: https://github.com/datreeio/datree | - # |===================================================================================| - - - name: Datree validate config files - if: steps.changed-files.outputs.any_changed == 'true' - uses: datreeio/action-datree@main # For more info about this Actions visit π https://github.com/datreeio/action-datree - with: - path: ${{ steps.changed-files.outputs.all_changed_files }} - cliArguments: --only-k8s-files - isHelmChart: false - isKustomization: false diff --git a/.github/workflows/depandant.yml b/.github/workflows/depandant.yml deleted file mode 100644 index 77a0c09..0000000 --- a/.github/workflows/depandant.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Dependabot Updates - -on: - push: - branches: - - '*' - -jobs: - dependabot: - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.11 - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Run Dependabot - run: | - curl https://api.github.com/repos/$GITHUB_REPOSITORY -o repo.json - curl -X POST https://api.github.com/repos/$GITHUB_REPOSITORY/dispatches \ - -H "Accept: application/vnd.github.everest-preview+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -d '{"event_type": "dependabot"}' diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml deleted file mode 100644 index e873374..0000000 --- a/.github/workflows/greetings.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Greetings - -on: - pull_request_target: - issues: - types: [opened] - -jobs: - greeting: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: Greet the User - run: | - echo "Hello, ${{ github.actor }}! π Thank you for creating your first issue or pull request in our repository. We appreciate your contribution!" - shell: bash - - - name: Comment Greeting - uses: actions/github-script@v4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const issueComment = `Hello, @${{ github.actor }}! π Thank you for creating your first issue or pull request in our repository. We appreciate your contribution!`; - console.log(issueComment); diff --git a/.github/workflows/indent_check.yml b/.github/workflows/indent_check.yml deleted file mode 100644 index 43e4d76..0000000 --- a/.github/workflows/indent_check.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Python Indentation Check and Pull Request - -on: - push: - branches: - - main # Change this to your main branch name if different - -jobs: - indent_check_and_pr: - name: Indentation Check and Pull Request - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.x' # Replace with the version of Python used in your repository - - - name: Install flake8 and black - run: | - pip install flake8 black - - - name: Run flake8 for Indentation Errors - id: check_indentation - run: | - if flake8 --select=E --show-source --quiet .; then - echo "No indentation errors found." - else - echo "Indentation errors found. Fixing the errors..." - black . - git add . - fi - - - name: Commit and push changes - if: steps.check_indentation.outputs.result == 'failure' - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git commit -m "Fix Python indentation errors" || true - git push origin HEAD - - - name: Create Pull Request - if: steps.check_indentation.outputs.result == 'failure' - uses: peter-evans/create-pull-request@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Fix Python indentation errors" - title: "Fix Python indentation errors" - body: "This pull request fixes Python indentation errors identified by flake8." - base: main - branch: fix-indentation-errors diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml deleted file mode 100644 index 559bddf..0000000 --- a/.github/workflows/jekyll-gh-pages.yml +++ /dev/null @@ -1,51 +0,0 @@ -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll with GitHub Pages dependencies preinstalled - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup Pages - uses: actions/configure-pages@v3 - - name: Build with Jekyll - uses: actions/jekyll-build-pages@v1 - with: - source: ./ - destination: ./_site - - name: Upload artifact - uses: actions/upload-pages-artifact@v2 - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v2 diff --git a/.github/workflows/lines.yml b/.github/workflows/lines.yml deleted file mode 100644 index eb08234..0000000 --- a/.github/workflows/lines.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Check Code Lines - -on: - push: - branches: - - main # Change 'main' to the name of your default branch - -jobs: - check_code_lines: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Count Python lines - id: count_python_lines - run: | - python_lines=$(find . -name '*.py' | xargs cat | wc -l) - python_files=$(find . -name '*.py' | wc -l) - echo "::set-output name=python_lines::$python_lines" - echo "::set-output name=python_files::$python_files" - - - name: Count TXT lines - id: count_txt_lines - run: | - txt_lines=$(find . -name '*.txt' | xargs cat | wc -l) - txt_files=$(find . -name '*.txt' | wc -l) - echo "::set-output name=txt_lines::$txt_lines" - echo "::set-output name=txt_files::$txt_files" - - - name: Count MD lines - id: count_md_lines - run: | - md_lines=$(find . -name '*.md' | xargs cat | wc -l) - md_files=$(find . -name '*.md' | wc -l) - echo "::set-output name=md_lines::$md_lines" - echo "::set-output name=md_files::$md_files" - - - name: Count YAML lines - id: count_yaml_lines - run: | - yaml_lines=$(find . -name '*.yml' | xargs cat | wc -l) - yaml_files=$(find . -name '*.yml' | wc -l) - echo "::set-output name=yaml_lines::$yaml_lines" - echo "::set-output name=yaml_files::$yaml_files" - - - name: Count XML lines - id: count_xml_lines - run: | - xml_lines=$(find . -name '*.xml' | xargs cat | wc -l) - xml_files=$(find . -name '*.xml' | wc -l) - echo "::set-output name=xml_lines::$xml_lines" - echo "::set-output name=xml_files::$xml_files" - - - name: Display results - run: | - echo "Total lines of Python code: ${{ steps.count_python_lines.outputs.python_lines }}" - echo "Total lines of Python files: ${{ steps.count_python_lines.outputs.python_files }}" - echo "Total lines of TXT code: ${{ steps.count_txt_lines.outputs.txt_lines }}" - echo "Total lines of TXT files: ${{ steps.count_txt_lines.outputs.txt_files }}" - echo "Total lines of MD code: ${{ steps.count_md_lines.outputs.md_lines }}" - echo "Total lines of MD files: ${{ steps.count_md_lines.outputs.md_files }}" - echo "Total lines of YAML code: ${{ steps.count_yaml_lines.outputs.yaml_lines }}" - echo "Total lines of YAML files: ${{ steps.count_yaml_lines.outputs.yaml_files }}" - echo "Total lines of XML code: ${{ steps.count_xml_lines.outputs.xml_lines }}" - echo "Total lines of XML files: ${{ steps.count_xml_lines.outputs.xml_files }}" - - total_files=$((steps.count_python_lines.outputs.python_files + steps.count_txt_lines.outputs.txt_files + steps.count_md_lines.outputs.md_files + steps.count_yaml_lines.outputs.yaml_files + steps.count_xml_lines.outputs.xml_files)) - total_lines=$((steps.count_python_lines.outputs.python_lines + steps.count_txt_lines.outputs.txt_lines + steps.count_md_lines.outputs.md_lines + steps.count_yaml_lines.outputs.yaml_lines + steps.count_xml_lines.outputs.xml_lines)) - echo "Total number of files: $total_files" - echo "Total number of lines: $total_lines" diff --git a/.github/workflows/puppet-lint.yml b/.github/workflows/puppet-lint.yml deleted file mode 100644 index 58f57d2..0000000 --- a/.github/workflows/puppet-lint.yml +++ /dev/null @@ -1,55 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# Puppet Lint tests Puppet code against the recommended Puppet language style guide. -# https://puppet.com/docs/puppet/7/style_guide.html -# Puppet Lint validates only code style; it does not validate syntax. -# To test syntax, use Puppet's puppet parser validate command. -# More details at https://github.com/puppetlabs/puppet-lint/ - -name: puppet-lint - -on: - push: - branches: [ "main" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main" ] - schedule: - - cron: '31 17 * * 3' - -permissions: - contents: read - -jobs: - puppet-lint: - name: Run puppet-lint scanning - runs-on: ubuntu-latest - permissions: - contents: read # for checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup Ruby - uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 - with: - ruby-version: 2.7 - bundler-cache: true - - - name: Install puppet-lint - run: gem install puppet-lint - - - name: Run puppet-lint - run: puppet-lint . --sarif > puppet-lint-results.sarif - continue-on-error: true - - - name: Upload analysis results to GitHub - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: puppet-lint-results.sarif - wait-for-processing: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 267b797..0000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: stale issues and pull requests - -on: - push: - branches: - - '*' # Trigger on all branches - pull_request: - types: - - opened - - synchronize - -jobs: - stale: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - uses: actions/stale@v5 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'Stale issue message' - stale-pr-message: 'Stale pull request message' - stale-issue-label: 'no-issue-activity' - stale-pr-label: 'no-pr-activity' diff --git a/Game/colox.py b/Game/colox.py index 0a22b20..8d6039c 100644 --- a/Game/colox.py +++ b/Game/colox.py @@ -72,7 +72,10 @@ # enemy position e_p = [width, random.randint(50, height - 50)] # nosec B311 -e1_p = [random.randint(width, width + 100), random.randint(50, height - 100)] # nosec B311 +e1_p = [ + random.randint(width, width + 100), + random.randint(50, height - 100), +] # nosec B311 # function for game_over diff --git a/Game/snake_game.py b/Game/snake_game.py index 1915b4c..8cb40c9 100644 --- a/Game/snake_game.py +++ b/Game/snake_game.py @@ -51,8 +51,12 @@ snake_length = 1 # Spawn the first food -food_x = round(random.randrange(0, window_width - segment_size) / 20.0) * 20.0 # nosec B311 -food_y = round(random.randrange(0, window_height - segment_size) / 20.0) * 20.0 # nosec B311 +food_x = ( + round(random.randrange(0, window_width - segment_size) / 20.0) * 20.0 +) # nosec B311 +food_y = ( + round(random.randrange(0, window_height - segment_size) / 20.0) * 20.0 +) # nosec B311 # Game over flag game_over = False @@ -87,8 +91,12 @@ # Play eat sound effect eat_sound.play() # Spawn new food - food_x = round(random.randrange(0, window_width - segment_size) / 20.0) * 20.0 # nosec B311 - food_y = round(random.randrange(0, window_height - segment_size) / 20.0) * 20.0 # nosec B311 + food_x = ( + round(random.randrange(0, window_width - segment_size) / 20.0) * 20.0 + ) # nosec B311 + food_y = ( + round(random.randrange(0, window_height - segment_size) / 20.0) * 20.0 + ) # nosec B311 # Create new segment and add to snake's body snake_segments.append((snake_head_x, snake_head_y)) @@ -171,11 +179,15 @@ snake_length = 1 # Spawn new food food_x = ( - round(random.randrange(0, window_width - segment_size) / 20.0) # nosec B311 + round( + random.randrange(0, window_width - segment_size) / 20.0 + ) # nosec B311 * 20.0 ) food_y = ( - round(random.randrange(0, window_height - segment_size) / 20.0) # nosec B311 + round( + random.randrange(0, window_height - segment_size) / 20.0 + ) # nosec B311 * 20.0 ) game_over = False diff --git a/MRayan.png b/MRayan.png deleted file mode 100644 index ed0c9ea..0000000 Binary files a/MRayan.png and /dev/null differ diff --git a/README.md b/README.md index 3be978f..6f36634 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# 80+ Python Projects by M.Rayan Asim +# 82 Python Projects by Muhammad Rayan Asim
-
+
-
-
-
-
diff --git a/Utilities/network.py b/Utilities/network.py
index 3f9b834..21909a7 100644
--- a/Utilities/network.py
+++ b/Utilities/network.py
@@ -26,7 +26,7 @@ def get_wifi_profiles():
capture_output=True,
text=True,
shell=False, # nosec B603
- check=True
+ check=True,
)
output = result.stdout
@@ -63,7 +63,7 @@ def get_wifi_password(profile):
"""
if not profile:
return None
-
+
try:
# Use full path to netsh.exe for security
# shell=False is explicit (default in subprocess.run)
@@ -72,7 +72,7 @@ def get_wifi_password(profile):
capture_output=True,
text=True,
shell=False, # nosec B603
- check=True
+ check=True,
)
output = result.stdout
@@ -97,10 +97,10 @@ def get_wifi_password(profile):
def main():
"""Main function to display Wi-Fi profiles and passwords."""
# Check if running on Windows
- if not sys.platform.startswith('win'):
+ if not sys.platform.startswith("win"):
print("Error: This tool only works on Windows operating systems.")
return
-
+
# Get Wi-Fi profiles
profiles = get_wifi_profiles()
@@ -116,8 +116,10 @@ def main():
password = get_wifi_password(profile)
print("{:<30} | {:<}".format(profile, password or ""))
print("=" * 50)
-
- print("\nNote: This information is retrieved from your system's saved Wi-Fi profiles.")
+
+ print(
+ "\nNote: This information is retrieved from your system's saved Wi-Fi profiles."
+ )
print("Keep this information secure and do not share it with others.")
diff --git a/Utilities/password.py b/Utilities/password.py
index 7801de2..9c89efd 100644
--- a/Utilities/password.py
+++ b/Utilities/password.py
@@ -17,7 +17,7 @@
warnings.warn(
"MD5 is cryptographically broken and insecure. "
"This tool can only attempt to crack MD5 hashes for educational purposes.",
- UserWarning
+ UserWarning,
)
try:
with open(pass_doc, "r", errors="ignore") as pass_file:
@@ -32,7 +32,11 @@
break
except FileNotFoundError:
- print("Error: " + pass_doc + " is not found. Please provide the correct file path.")
+ print(
+ "Error: "
+ + pass_doc
+ + " is not found. Please provide the correct file path."
+ )
quit()
if not pass_found:
@@ -48,7 +52,11 @@
pass_found = True
break
except FileNotFoundError:
- print("Error: " + pass_doc + " is not found. Please provide the correct file path.")
+ print(
+ "Error: "
+ + pass_doc
+ + " is not found. Please provide the correct file path."
+ )
quit()
except Exception as e:
print(f"Error checking password: {e}")
diff --git a/Utilities/password_hash.py b/Utilities/password_hash.py
index 78999b6..77c47d8 100644
--- a/Utilities/password_hash.py
+++ b/Utilities/password_hash.py
@@ -16,13 +16,13 @@
str2hash = input("Enter password to hash: ")
# Check if user wants MD5 (for educational purposes only)
-use_md5 = input("Use MD5 (insecure)? (y/n): ").lower() == 'y'
+use_md5 = input("Use MD5 (insecure)? (y/n): ").lower() == "y"
if use_md5:
warnings.warn(
"MD5 is cryptographically broken and should NOT be used for password hashing. "
"Use bcrypt instead. This is for educational purposes only.",
- UserWarning
+ UserWarning,
)
# Using MD5 only for educational demonstration
result = hashlib.md5(str2hash.encode()) # nosec B324
@@ -36,7 +36,7 @@
print("The bcrypt hash is: ", end="")
print(hashed.decode())
print("\nThis is a secure hash. Store this in your database.")
-
+
# Demonstrate verification
print("\nTo verify a password against this hash, use:")
print("bcrypt.checkpw(password.encode(), hashed_password.encode())")
diff --git a/api/app.py b/api/app.py
index 689c7ca..3afa24e 100644
--- a/api/app.py
+++ b/api/app.py
@@ -1,24 +1,42 @@
from fastapi import FastAPI
+from fastapi.middleware.cors import CORSMiddleware
+from mangum import Mangum
import os
-app = FastAPI()
+app = FastAPI(title="Python Projects API")
+app.add_middleware(
+ CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
+)
-@app.get("/")
+
+@app.get("/api")
async def root():
- return {"message": "Python Projects β minimal API", "routes": ["/projects"]}
+ return {"message": "Python Projects β API", "routes": ["/api/projects"]}
-@app.get("/projects")
+@app.get("/api/projects")
async def projects():
base = os.path.dirname(os.path.dirname(__file__))
items = []
for name in sorted(os.listdir(base)):
- if name.startswith('.') or name in ('__pycache__', '.git'):
+ if name.startswith(".") or name in (
+ "__pycache__",
+ ".git",
+ "api",
+ ".venv",
+ ".venv3",
+ "public",
+ "assets",
+ ):
continue
path = os.path.join(base, name)
if os.path.isdir(path):
- items.append(name)
- elif os.path.isfile(path) and name.endswith('.py'):
- items.append(name)
+ items.append({"name": name, "type": "directory"})
+ elif os.path.isfile(path) and name.endswith(".py"):
+ items.append({"name": name, "type": "file"})
return {"projects": items}
+
+
+# Required for Vercel serverless β wraps ASGI app as Lambda handler
+handler = Mangum(app)
diff --git a/api/index.py b/api/index.py
index a951cf7..b5b23aa 100644
--- a/api/index.py
+++ b/api/index.py
@@ -6,10 +6,7 @@
app = FastAPI(title="Python Projects API")
app.add_middleware(
- CORSMiddleware,
- allow_origins=["*"],
- allow_methods=["*"],
- allow_headers=["*"],
+ CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
)
@@ -23,12 +20,18 @@ async def projects():
base = os.path.dirname(os.path.dirname(__file__))
items = []
for name in sorted(os.listdir(base)):
- if name.startswith('.') or name in ('__pycache__', '.git', 'api', '.venv', '.venv3'):
+ if name.startswith(".") or name in (
+ "__pycache__",
+ ".git",
+ "api",
+ ".venv",
+ ".venv3",
+ ):
continue
path = os.path.join(base, name)
if os.path.isdir(path):
items.append({"name": name, "type": "directory"})
- elif os.path.isfile(path) and name.endswith('.py'):
+ elif os.path.isfile(path) and name.endswith(".py"):
items.append({"name": name, "type": "file"})
return {"projects": items}
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..e6c6d77
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,1106 @@
+
+
+
+ A collection of practical Python projects by Rayan Asim β from simple scripts and games to machine learning models. +
+ + + + +Click any category to filter the projects below.
+Classic command-line two-player game with win detection and board rendering.
+ + + View code + + +Retro snake game built using the Turtle graphics library with score tracking.
+ + + View code + + +Backtracking algorithm that automatically solves any valid 9Γ9 Sudoku puzzle.
+ + + View code + + +Generate scannable QR codes from any text or URL and export as an image file.
+ + + View code + + +NLP model using Naive Bayes to classify SMS messages as spam or ham with high accuracy.
+ + + View code + + +Time-series forecasting using Prophet to predict short-term cryptocurrency price trends.
+ + + View code + + +Analyse the emotional tone of any text using VADER sentiment scoring.
+ + + View code + + +A fully functional desktop calculator built with Tkinter β clean layout, keyboard support.
+ + + View code + + +Instantly shorten any long URL using the pyshorteners library with multiple provider options.
+ + + View code + + +No projects match your search.
+Projects organized from beginner to advanced.
+Core syntax, loops, and basic logic. Great for anyone starting out with Python.
+GUIs, API calls, data scraping, and object-oriented programming.
+Machine learning models, algorithms, and complex applications.
+Fork the repository on GitHub, grab any project, and start learning.
+ + + +