Sixth rule A, Almost all properties apply to the empty set, most of them to finite sets, and dividing by zero is a terrible idea. 0 is not a number, 1 plus one equals zero in ℤ2 and $\sqrt{2}$ and $-\sqrt{2}$ are algebraically the same. Galois’ Theory and Partial differential equations are not for the faint of heart. Absolute numbers have no meaning, Apocalypse, Anawim, #justtothepoint.
This is a collection of useful functions. Maybe, one of the most useful ones is path_file. This function relies on pathlib, a native Python library for handling files and paths on your operating system.
"""
File: util.py
Author: Máximo Núñez Alarcón
Description: This script defines some useful functions for different purposes.
1. my_progress: display the progress of a task using a progress bar.
2. check_all_files: apply "function" recursively to all files with a specific extension in a directory.
3. printUrl: prints each URL in the given list in a very readable nice way.
4: append_to_file: Appends content to a file named "assets/output.txt". It serves as a log.
5. cleanLog: clean or empty the log.
6. border_msg/warning_msg: display messages with borders and warnings.
7. same_domain: check if two URLs belong to the same domain.
8. check_manually: display a notification about invalid content, open the markdown file in VS Code, copy the content to clipboard, and open a web page for manual inspection.
9. path_file: construct the full path to a file based on the relative path from the current Python script
Dependencies: rich, time, dotenv, glob, pyperclip, webbrowser, subprocess, and os.
"""
from rich.progress import Progress # It is used for displaying progress bars
import time # It is used for adding delays
from dotenv import load_dotenv
''' It reads key-value pairs from a .env file in your Python's root folder and can set them as environment variables.
If your application takes its configuration from environment variables, launching it in development is not practical because you have to set those environment variables yourself.
To help you with that, you can add Python-dotenv to your application to make it load the configuration from a .env file.
It requires to install: pip install python-dotenv.'''
import os
import glob
from rich.console import Console # Module for creating colorful terminal output
import pyperclip
import webbrowser
import subprocess
import os # This module provides a way of using operating system dependent functionality. We are going to use it for accessing environment variables
from pathlib import Path
def path_file(relative_path):
"""
Construct the full path to a file based on the relative path from the current Python script.
Parameters:
relative_path (str): The relative path to the file from the current Python script.
Returns:
Path: The full path to the file.
Example:
If the Python script is located at '/home/user/scripts/main.py' and relative_path is 'data/file.txt',
this function will return '/home/user/scripts/data/file.txt'.
Be aware that '/data/file.txt' is interpreted as an absolute path and it will not work!!
"""
script_dir = Path(__file__).resolve().parent
print(script_dir)
print(relative_path)
print("....")
# Construct the full path to the file
file_path = script_dir / relative_path
print(file_path)
return file_path
# Define a function to display progress of a task
# Usage: Import the my_progress function and call it with the name of the task as an argument.
def my_progress(nameTask):
"""
Display the progress of a task.
Parameters:
nameTask (str): The name of the task.
Returns:
None
"""
load_dotenv() # Load environment variables from .env file
totaltime = os.getenv("TIME_PROGRESS")
# Retrieve the total time for the progress from an environment variable TIME_PROGRESS.
# There is a line in the .env file: TIME_PROGRESS = 100
# It's good practice to add .env to your .gitignore, especially if it contains secrets like a password.
with Progress() as progress: # Create a progress bar
task1 = progress.add_task("[red]" + nameTask + "... [/]", totaltime) # Add a task to the progress bar with the specified name
while not progress.finished: # Continue updating the progress until it's finished
progress.update(task1, advance=0.9) # Update the progress bar by a certain amount (0.9 in this case)
time.sleep(0.01) # Add a small delay to control the update frequency of the progress bar
def check_all_files(my_path, extension, function):
"""
Apply "function" recursively to all files with a specific extension in a directory.
Args:
- my_path (str): The directory path where to search for files.
- extension (str): The file extension to filter files. Only files with this extension will be taken into consideration.
- function (function): The function to apply to each file.
Returns:
- None
"""
# Use glob to recursively find all files with the specified extension in the provided directory and its subdirectories.
files = glob.glob(my_path + '/**/*.' + extension, recursive=True)
# Iterate over each found file
for file in files:
# Apply the provided function to the file
function(file)
def printUrl(list):
"""
Prints each URL in the given list in a very readable nice way.
Args:
- list (list): A list of URLs to print.
"""
# Initialize Rich Console for colorful output
console = Console()
# Create a separator line
separator = "-" * 100
append_to_file(f"\n{separator}\n")
# Iterate over each URL in the list
for l in list:
console.print(l) # Print the URL using Rich Console for colorful output
append_to_file(l)
def append_to_file(content):
"""
Appends content to a file named "assets/output.txt". It serves as a log.
Args:
- content (str or list): The content to append to the file. If it's a string,
it will be written directly. If it's a list, each element will be written
on a separate line.
"""
with open("assets/output.txt", "a") as f:
if isinstance(content, str):
f.write(content + "\n")
elif isinstance(content, list):
for line in content:
f.write(str(line) + "\n")
else:
raise ValueError("Content must be a string or a list.")
def cleanLog():
"""
Clean the contents of the log file.
This function opens the log file in write mode, which effectively erases its contents.
Returns:
None
"""
# Open the file in write mode to erase its content. Clean the log.
with open("assets/output.txt", "w"):
pass
def border_msg(msg):
"""
Display a message with a border.
Parameters:
- msg (str): The message to display.
Returns:
- None
"""
row = len(msg)
h = ''.join(['+'] + ['-' *row] + ['+'])
result= h + '\n'"|"+msg+"|"'\n' + h
print(result)
def warning_msg(msg):
"""
Display a warning message with a border and prompt user to continue.
Parameters:
- msg (str): The warning message to display.
Returns:
- None
"""
border_msg(msg)
input("⚡Press to continue" )
os.system("mplayer -ao alsa:device=default /home/nmaximo7/justtothepoint/assets/success.mp3")
def same_domain(url1, url2):
"""
Check if two URLs belong to the same domain.
Parameters:
url1 (str): The first URL.
url2 (str): The second URL.
Returns:
bool: True if both URLs belong to the same domain, False otherwise.
"""
# urlparse parses a URL into its components, such as scheme, netloc, path, etc...
# ... and returns a named tuple (inherits from tuple and whose indexable elements are also accessible using named attributes) representing the URL components.
# The netloc attribute of this named tuple contains the network location, which includes the domain name and port number.
domain1 = urlparse(url1).netloc
domain2 = urlparse(url2).netloc
return domain1 == domain2
def check_manually(content, markdown_file, webpage):
"""
Display a notification about invalid content, open the markdown file in VS Code, copy the content to clipboard, and open a web page for manual inspection.
Parameters:
- content (str): The invalid content detected.
- markdown_file (str): The path to the markdown file where the invalid content was found.
- webpage (str): The URL of the web page related to the content.
Returns:
- None
"""
print(f"{content} is not valid in {markdown_file}") # Display a notification about invalid content
subprocess.Popen(["code", markdown_file]) # Open markdown file in VS Code
pyperclip.copy(content) # Copy invalid content to clipboard
webbrowser.open_new_tab(webpage) # Open web page for manual inspection
wait = input("Press a key to continue...") # Wait for user confirmation