Update examples

This commit is contained in:
Roland Thomas Jr 2023-09-15 12:55:39 -04:00
parent c69e9801e9
commit 1b4ba81ab0
Signed by: roland
GPG Key ID: 7C3C2B085A4C2872
16 changed files with 217 additions and 325 deletions

47
bcrypt_test.py Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""bcrypt_test.py
This module provides utilities for user authentication, including functions to
store hashed passwords, create new users, and authenticate existing users using
bcrypt for password hashing and a CSV file to store user data.
"""
import bcrypt
import csv
def store_password(password):
hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
return hashed_password
def check_password(password, hashed_password):
return bcrypt.checkpw(password.encode("utf-8"), hashed_password)
def create_user(username, password):
hashed_password = store_password(password).decode("utf-8")
with open("passwords_db.csv", "a", newline="") as file:
writer = csv.writer(file)
writer.writerow([username, hashed_password])
def authenticate_user(username, password):
try:
with open("passwords_db.csv", "r") as file:
reader = csv.reader(file)
for row in reader:
if row and row[0] == username:
hashed_password = row[1].encode("utf-8")
return check_password(password, hashed_password)
return False
except FileNotFoundError:
return False
if __name__ == "__main__":
create_user("user1", "mysecurepassword")
if authenticate_user("user1", "mysecurepassword"):
print("Authentication successful")
else:
print("Authentication failed")

17
email_example.py Normal file → Executable file
View File

@ -1,23 +1,22 @@
# Import smtplib for the actual sending function """
This module sends an email with the contents of a specified text file as the
body. The "smtplib" and "email.message" modules are used to construct and send
the email.
"""
import smtplib import smtplib
# Import the email modules we'll need
from email.message import EmailMessage from email.message import EmailMessage
textfile = "textfile" textfile = "textfile"
# Open the plain text file whose name is in textfile for reading.
with open(textfile) as fp: with open(textfile) as fp:
# Create a text/plain message
msg = EmailMessage() msg = EmailMessage()
msg.set_content(fp.read()) msg.set_content(fp.read())
# me == the sender's email address
# you == the recipient's email address
msg["Subject"] = f"The contents of {textfile}" msg["Subject"] = f"The contents of {textfile}"
msg["From"] = "roland@rtj.dev" msg["From"] = "roland"
msg["To"] = "roland@rtj.dev" msg["To"] = "roland"
# Send the message via our own SMTP server.
s = smtplib.SMTP("localhost") s = smtplib.SMTP("localhost")
s.send_message(msg) s.send_message(msg)
s.quit() s.quit()

0
freq.py Normal file → Executable file
View File

2
patch_example.py Normal file → Executable file
View File

@ -3,7 +3,7 @@
import unittest import unittest
from io import StringIO from io import StringIO
from unittest.mock import patch from unittest.mock import patch
import print_things # import the module containing the function with print statements import print_things
class TestPrintFunction(unittest.TestCase): class TestPrintFunction(unittest.TestCase):

0
print_things.py Normal file → Executable file
View File

21
pyqttt.py Normal file → Executable file
View File

@ -1,3 +1,14 @@
#!/usr/bin/env python3
"""
This module contains a Python script utilizing the PyQt5 library to create a
basic graphical user interface (GUI) application. The application showcases a
tabbed window with two tabs, each containing a grid of numbers. The first tab
displays numbers from 1 to 100, and the second tab displays numbers from 101 to
200, arranged in a grid format.
Dependencies:
PyQt5
"""
import sys import sys
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QApplication, QApplication,
@ -13,50 +24,40 @@ class TabbedWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
# Set the main window title and size
self.setWindowTitle("Tabbed Window") self.setWindowTitle("Tabbed Window")
self.resize(300, 300) self.resize(300, 300)
# Create a tab widget
self.tab_widget = QTabWidget() self.tab_widget = QTabWidget()
self.setCentralWidget(self.tab_widget) self.setCentralWidget(self.tab_widget)
# Create the first tab
self.tab1 = QWidget() self.tab1 = QWidget()
self.tab_widget.addTab(self.tab1, "1-100") self.tab_widget.addTab(self.tab1, "1-100")
# Create a grid layout for the first tab
layout1 = QGridLayout() layout1 = QGridLayout()
layout1.setHorizontalSpacing(10) layout1.setHorizontalSpacing(10)
layout1.setVerticalSpacing(10) layout1.setVerticalSpacing(10)
# Add the numbers 1-100 to the layout
for i in range(1, 101): for i in range(1, 101):
column = (i - 1) % 10 column = (i - 1) % 10
row = (i - 1) // 10 row = (i - 1) // 10
label = QLabel(str(i)) label = QLabel(str(i))
layout1.addWidget(label, row, column) layout1.addWidget(label, row, column)
# Set the layout for the first tab
self.tab1.setLayout(layout1) self.tab1.setLayout(layout1)
# Create the second tab
self.tab2 = QWidget() self.tab2 = QWidget()
self.tab_widget.addTab(self.tab2, "101-200") self.tab_widget.addTab(self.tab2, "101-200")
# Create a grid layout for the second tab
layout2 = QGridLayout() layout2 = QGridLayout()
layout2.setHorizontalSpacing(10) layout2.setHorizontalSpacing(10)
layout2.setVerticalSpacing(10) layout2.setVerticalSpacing(10)
# Add the numbers 101-200 to the layout
for i in range(101, 201): for i in range(101, 201):
column = (i - 101) % 10 column = (i - 101) % 10
row = (i - 101) // 10 row = (i - 101) // 10
label = QLabel(str(i)) label = QLabel(str(i))
layout2.addWidget(label, row, column) layout2.addWidget(label, row, column)
# Set the layout for the second tab
self.tab2.setLayout(layout2) self.tab2.setLayout(layout2)

View File

@ -2,13 +2,13 @@
""" """
Generate and Print Random Unicode Characters Generate and Print Random Unicode Characters
This module generates a string of random Unicode characters, specifically avoiding the This module generates a string of random Unicode characters, specifically
surrogate pair range (0xD800 to 0xDFFF). The generated string has a default length of avoiding the surrogate pair range (0xD800 to 0xDFFF). The generated string has
5000 characters. a default length of 5000 characters.
Usage: Usage:
Run the script with an argument to specify the length of the string to be generated: Run the script with an argument to specify the length of the string to be
`python script_name.py 5000` generated: `python script_name.py 5000`
""" """
import random import random
from argparse import ArgumentParser from argparse import ArgumentParser
@ -21,7 +21,11 @@ def generate_string(length):
[ [
chr( chr(
random.choice( random.choice(
[i for i in range(0x0, 0xD7FF + 1) if i < 0xD800 or i > 0xDFFF] [
i
for i in range(0x0, 0xD7FF + 1)
if i < 0xD800 or i > 0xDFFF
]
) )
) )
for _ in range(length) for _ in range(length)
@ -30,7 +34,7 @@ def generate_string(length):
except UnicodeEncodeError as e: except UnicodeEncodeError as e:
print(f"Error encoding character: {e}") print(f"Error encoding character: {e}")
return(characters) return characters
if __name__ == "__main__": if __name__ == "__main__":

28
readline/creatures.py Normal file → Executable file
View File

@ -1,12 +1,21 @@
#!/usr/bin/env
"""
This module implements a simple console application to manage a list of creatures.
It provides functionalities to add a creature to the list, lookup creatures with
autocomplete support (press tab to auto-complete creature names), and quit the
application.
"""
import readline import readline
creatures = [] creatures = []
def add_creature(): def add_creature():
creature = input("Enter a creature name: ") creature = input("Enter a creature name: ")
creatures.append(creature) creatures.append(creature)
print(f"{creature} added to the list of creatures.") print(f"{creature} added to the list of creatures.")
def lookup_creature(): def lookup_creature():
def completer(text, state): def completer(text, state):
options = [c for c in creatures if c.startswith(text)] options = [c for c in creatures if c.startswith(text)]
@ -23,7 +32,9 @@ def lookup_creature():
print(f"- {creature}") print(f"- {creature}")
while True: while True:
creature = input("Enter the name of a creature or press enter to return to the main menu: ") creature = input(
"Enter the name of a creature or press enter to return to the main menu: "
)
if not creature: if not creature:
break break
elif creature in creatures: elif creature in creatures:
@ -34,17 +45,17 @@ def lookup_creature():
readline.set_completer(None) readline.set_completer(None)
readline.parse_and_bind("tab: ") readline.parse_and_bind("tab: ")
def quit(): def quit():
print("Goodbye!") print("Goodbye!")
exit() exit()
menu = {
"1": add_creature,
"2": lookup_creature,
"3": quit
}
while True: menu = {"1": add_creature, "2": lookup_creature, "3": quit}
def main():
while True:
print("Menu:") print("Menu:")
print("[1] Add Creature") print("[1] Add Creature")
print("[2] Lookup Creature") print("[2] Lookup Creature")
@ -57,3 +68,6 @@ while True:
else: else:
print(f"{choice} is not a valid option.") print(f"{choice} is not a valid option.")
if __name__ == "__main__":
main()

29
readline/mtg.py Normal file → Executable file
View File

@ -1,15 +1,25 @@
#!/usr/bin/env python3
"""
This module defines a command-line interface (CLI) application which allows
users to interact with a predefined list of completion options, specifically,
card names from the "Alara Reborn" set.
It leverages the `cmd` module to build the CLI and has tab-completion
functionality for adding items from the predefined list of card names.
"""
import cmd import cmd
completions = [ completions = [
'Mage Slayer (Alara Reborn)', "Mage Slayer (Alara Reborn)",
'Magefire Wings (Alara Reborn)', "Magefire Wings (Alara Reborn)",
'Sages of the Anima (Alara Reborn)', "Sages of the Anima (Alara Reborn)",
'Sanctum Plowbeast (Alara Reborn)', "Sanctum Plowbeast (Alara Reborn)",
'Sangrite Backlash (Alara Reborn)', "Sangrite Backlash (Alara Reborn)",
'Sanity Gnawers (Alara Reborn)', "Sanity Gnawers (Alara Reborn)",
'Sen Triplets (Alara Reborn)' "Sen Triplets (Alara Reborn)",
] ]
class mycmd(cmd.Cmd): class mycmd(cmd.Cmd):
def __init__(self): def __init__(self):
cmd.Cmd.__init__(self) cmd.Cmd.__init__(self)
@ -21,9 +31,10 @@ class mycmd(cmd.Cmd):
pass pass
def complete_add(self, text, line, begidx, endidx): def complete_add(self, text, line, begidx, endidx):
mline = line.partition(' ')[2] mline = line.partition(" ")[2]
offs = len(mline) - len(text) offs = len(mline) - len(text)
return [s[offs:] for s in completions if s.startswith(mline)] return [s[offs:] for s in completions if s.startswith(mline)]
if __name__ == '__main__':
if __name__ == "__main__":
mycmd().cmdloop() mycmd().cmdloop()

View File

@ -1,92 +0,0 @@
import cmd
import os
import readline
import sys
# Set up history file
histfile = os.path.join(os.path.expanduser('~'), '.history')
try:
readline.read_history_file(histfile)
except FileNotFoundError:
open(histfile, 'wb').close()
# Define add and subtract functions
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# Define command processor
class MyCmd(cmd.Cmd):
prompt = '> '
intro = 'Type help for commands'
def do_exit(self, arg):
"""Exit the program"""
return True
def do_add(self, arg):
"""Add two numbers: add <num1> <num2>"""
try:
num1, num2 = map(float, arg.split())
except ValueError:
print('Invalid input')
return
print(add(num1, num2))
def complete_add(self, text, line, begidx, endidx):
if not text:
completions = ['<num1>', '<num2>']
elif '<num1>' in line:
completions = ['<num2>']
else:
completions = ['<num1>']
return [c for c in completions if c.startswith(text)]
def do_subtract(self, arg):
"""Subtract two numbers: subtract <num1> <num2>"""
try:
num1, num2 = map(float, arg.split())
except ValueError:
print('Invalid input')
return
print(subtract(num1, num2))
def complete_subtract(self, text, line, begidx, endidx):
if not text:
completions = ['<num1>', '<num2>']
elif '<num1>' in line:
completions = ['<num2>']
else:
completions = ['<num1>']
return [c for c in completions if c.startswith(text)]
def do_clear(self, arg):
"""Clear the screen"""
if sys.platform.startswith('win'):
os.system('cls')
else:
os.system('clear')
def default(self, line):
print('Invalid command')
def emptyline(self):
pass
# Run command processor
console = MyCmd()
readline.set_completer_delims(' \t\n;')
readline.parse_and_bind('tab: complete')
while True:
try:
line = input(console.prompt)
except EOFError:
break
console.onecmd(line)
# Save history file
with open(histfile, 'w') as f:
readline.write_history_file(histfile)

View File

@ -1,54 +0,0 @@
import readline
# Set up history file
histfile = '.history'
try:
readline.read_history_file(histfile)
except FileNotFoundError:
open(histfile, 'wb').close()
# Define add and subtract functions
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# Loop for user input
while True:
# Read user input
try:
line = input('> ')
except EOFError:
break
# Check for exit command
if line == 'exit':
break
# Parse user input
try:
args = line.split()
if len(args) != 3:
raise ValueError
num1 = float(args[0])
num2 = float(args[2])
op = args[1]
if op not in ['+', '-']:
raise ValueError
except ValueError:
print('Invalid input')
continue
# Perform operation
if op == '+':
result = add(num1, num2)
else:
result = subtract(num1, num2)
# Print result and add command to history
print(result)
readline.add_history(line)
# Save history file
readline.write_history_file(histfile)

View File

@ -1,66 +0,0 @@
import cmd
import os
import readline
# Set up history file
histfile = os.path.join(os.path.expanduser('~'), '.history')
try:
readline.read_history_file(histfile)
except FileNotFoundError:
open(histfile, 'wb').close()
# Define add and subtract functions
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# Define command processor
class MyCmd(cmd.Cmd):
prompt = '> '
intro = 'Type help for commands'
def do_exit(self, arg):
"""Exit the program"""
return True
def do_add(self, arg):
"""Add two numbers: add <num1> <num2>"""
try:
num1, num2 = map(float, arg.split())
except ValueError:
print('Invalid input')
return
print(add(num1, num2))
def do_subtract(self, arg):
"""Subtract two numbers: subtract <num1> <num2>"""
try:
num1, num2 = map(float, arg.split())
except ValueError:
print('Invalid input')
return
print(subtract(num1, num2))
def default(self, line):
print('Invalid command')
def emptyline(self):
pass
# Run command processor
console = MyCmd()
readline.set_completer_delims(' \t\n;')
readline.parse_and_bind('tab: complete')
while True:
try:
line = input(console.prompt)
except EOFError:
break
console.onecmd(line)
# Save history file
with open(histfile, 'w') as f:
readline.write_history_file(histfile)

View File

@ -1,39 +0,0 @@
import atexit
import code
import os
import readline
class HistoryConsole(code.InteractiveConsole):
def __init__(self, locals=None, filename="<console>",
histfile=os.path.expanduser("~/.console-history")):
code.InteractiveConsole.__init__(self, locals, filename)
self.init_history(histfile)
def init_history(self, histfile):
readline.parse_and_bind("tab: complete")
if hasattr(readline, "read_history_file"):
try:
readline.read_history_file(histfile)
except FileNotFoundError:
pass
atexit.register(self.save_history, histfile)
def save_history(self, histfile):
readline.set_history_length(1000)
readline.write_history_file(histfile)
# Run console
console = HistoryConsole()
while True:
try:
line = input('> ')
except EOFError:
break
# Check for exit command
if line == 'exit':
break
# Process user input
console.push(line)

42
set_get_attr_example.py Normal file → Executable file
View File

@ -1,3 +1,37 @@
"""
set_get_attr_example.py
-----------------------
This module contains a class named `Number` which implements special attribute
access methods to demonstrate custom attribute setting and getting behaviors
in a Python class.
Here is a summary of its functionality and methods:
- `__init__(self, number)`: Initializes a new instance with a `number` parameter.
- `power(self)`: Squares the current value of the `_number` attribute. It utilizes
`self.number` to access the `_number` attribute, which works correctly due to
the overridden `__getattribute__` method.
- `another_func(self)`: Prints a message when invoked.
- `__str__(self)`: Returns a string representation of the `_number` attribute.
The class also overrides special methods (`__setattr__`, `__getattribute__`,
`__getattr__`) to define custom behaviors for setting, getting, and accessing
non-existent attributes, respectively.
Usage:
If run as the main program, an instance of `Number` is created with an initial
value of 5. The script then performs various operations to demonstrate the
custom attribute access behaviors.
Note:
The `__getattribute__` method in the `Number` class is implemented such that if
an attribute other than the ones listed in the `options` list is accessed, the
`_number` attribute value is returned. This is demonstrated in the script where
`number.num` and `number.number` (which are non-existing attributes) are accessed,
but the `_number` value is printed instead of raising an AttributeError.
"""
class Number: class Number:
def __init__(self, number): def __init__(self, number):
self._number = number self._number = number
@ -31,3 +65,11 @@ class Number:
def __getattr__(self, name): def __getattr__(self, name):
return self._number return self._number
if __name__ == "__main__":
number = Number(5)
print(number.num)
print(number.number)
number.power()
print(number.num)
number.another_func()

15
test.py
View File

@ -1,15 +0,0 @@
import unittest
class Yest(unittest.TestCase):
def test_int(self):
n1 = 5
self.assertIsInstance(n1, int, "n1 should be an int")
int("124124")
a = 5
self.assertIsInstance(a, int)
assert isinstance(n1, int)
unittest.main()

40
thread_pool.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""
This module demonstrates the use of asyncio to handle asynchronous and blocking
functions in Python. The module contains three functions: a blocking function
that simulates a long-running process with `time.sleep`, an asynchronous
function that demonstrates asyncio's sleep, and a main function that runs
both the blocking and async functions concurrently using a ThreadPoolExecutor
for the blocking function.
"""
import asyncio
from concurrent.futures import ThreadPoolExecutor
import time
def blocking_function():
time.sleep(2)
return "Blocking function completed!"
async def async_function():
print("Async function started!")
await asyncio.sleep(1)
print("Async function completed!")
async def main():
loop = asyncio.get_event_loop()
executor = ThreadPoolExecutor()
async_task = asyncio.create_task(async_function())
result = await loop.run_in_executor(executor, blocking_function)
print(result)
await async_task
if __name__ == "__main__":
asyncio.run(main())