Social Tech
A school project made to solve a real-world problem from one of participating company's. The best solution would then be β¦
Social Tech
Social Tech is a school project made to solve a real-world problem from one of the participating companies. The best solution would then be used by the business.
We developed a WebApp for SMILE Business Solutions, the webapp was made to streamline their business and help improve the way they worked with their clients.
SMILE is a life coaching company that helps other SME Businesses and individuals improve their lives by identifying problems and setting goals to alleviate these issues.
The coach would then meet on a regular basis to check up on the client and record the progress made towards their goals and offer advice and suggestions along the way.
Our WebApp got rid of their need for pen and paper and the issues of scheduling in-person meetings (which were oftern cancelled), as they could now do everything online in one place.
The coach would be able to check on their progress and message the client.
We attempted to make a friendly themed site and decided going with a natured themed site
Project Overview
There are 3 main parts this project was split up into:
Database - PostgreSQL API - ExpressJS WebApp - Angular
I did the work on WebApp part while my other 2 team-mates worked on the database and API respectavly
The project is also Hosted on Heroku!
Check it out
User: smile@dev-api.ru
Password: password
Web Preview
Also made to work on mobile devices
Also created a fully functioning dashboard for administrators
Hiragana Handwriting Classifier
None
Hiragana Handwritting Recognition
Using p5.js and my own custom implementation of the knearest algorithm to guess what Hiragana letter you drew
Made just for fun and to help learn the alphabet
Pic to Asscii
Made my own simple implementation converting an image to asscii
"""
Pic to Asscii
Made my own simple implementation converting an image to asscii
"""
import sys, random, argparse
import numpy as np
import math
from PIL import Image
# gray scale level values from:
# http://paulbourke.net/dataformats/asciiart/
# 70 levels of gray
gscale1 = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
# 10 levels of gray
gscale2 = '@%#*+=-:. '
def getAverageL(image):
"""
Given PIL Image, return average value of grayscale value
"""
# get image as numpy array
im = np.array(image)
# get shape
w,h = im.shape
# get average
return np.average(im.reshape(w*h))
def covertImageToAscii(fileName, cols, scale, moreLevels):
"""
Given Image and dims (rows, cols) returns an m*n list of Images
"""
# declare globals
global gscale1, gscale2
# open image and convert to grayscale
image = Image.open(fileName).convert('L')
# store dimensions
W, H = image.size[0], image.size[1]
print("input image dims: %d x %d" % (W, H))
# compute width of tile
w = W/cols
# compute tile height based on aspect ratio and scale
h = w/scale
# compute number of rows
rows = int(H/h)
print("cols: %d, rows: %d" % (cols, rows))
print("tile dims: %d x %d" % (w, h))
# check if image size is too small
if cols > W or rows > H:
print("Image too small for specified cols!")
exit(0)
# ascii image is a list of character strings
aimg = []
# generate list of dimensions
for j in range(rows):
y1 = int(j*h)
y2 = int((j+1)*h)
# correct last tile
if j == rows-1:
y2 = H
# append an empty string
aimg.append("")
for i in range(cols):
# crop image to tile
x1 = int(i*w)
x2 = int((i+1)*w)
# correct last tile
if i == cols-1:
x2 = W
# crop image to extract tile
img = image.crop((x1, y1, x2, y2))
# get average luminance
avg = int(getAverageL(img))
# look up ascii char
if moreLevels:
gsval = gscale1[int((avg*69)/255)]
else:
gsval = gscale2[int((avg*9)/255)]
# append ascii char to string
aimg[j] += gsval
# return txt image
return aimg
# main() function
def main():
# create parser
descStr = "This program converts an image into ASCII art."
parser = argparse.ArgumentParser(description=descStr)
# add expected arguments
parser.add_argument('--file', dest='imgFile', required=True)
parser.add_argument('--scale', dest='scale', required=False)
parser.add_argument('--out', dest='outFile', required=False)
parser.add_argument('--cols', dest='cols', required=False)
parser.add_argument('--morelevels',dest='moreLevels',action='store_true')
# parse args
args = parser.parse_args()
imgFile = args.imgFile
# set output file
outFile = 'out.txt'
if args.outFile:
outFile = args.outFile
# set scale default as 0.43 which suits
# a Courier font
scale = 0.43
if args.scale:
scale = float(args.scale)
# set cols
cols = 80
if args.cols:
cols = int(args.cols)
print('generating ASCII art...')
# convert image to ascii txt
aimg = covertImageToAscii(imgFile, cols, scale, args.moreLevels)
# open file
f = open(outFile, 'w')
# write to file
for row in aimg:
f.write(row + '\n')
# cleanup
f.close()
print("ASCII art written to %s" % outFile)
# call main
if __name__ == '__main__':
main()
Extract Text from Image
Simple script uses pytesseract to pull text from an image.
"""
Extract Text from Image
Simple script uses pytesseract to pull text from an image.
"""
import pytesseract
from PIL import Image
import json
def pro(n):
image = Image.open('1.png')
return pytesseract.image_to_string(image)
t = []
for i in range(1, 13):
print("Doing: ", i)
t.append(pro(i))
open('out', 'w+').write(json.dumps(t))
Find Duplicate Images
Script to try find duplicate images regardless of file type. Converts them into their encoding hash to compare other images.
"""
Find Duplicate Images
Script to try find duplicate images regardless of file type.
Converts them into their encoding hash to compare other images.
"""
from PIL import Image
import imagehash
import os
from pathlib import Path
from imagededup.methods import PHash
phasher = PHash()
# Generate hashes for all images in the folder
encodings = phasher.encode_images(image_dir='D:\My Drive\Shared\Whiteriver')
# Find duplicates
duplicates = phasher.find_duplicates(encoding_map=encodings, min_similarity_threshold=0.9)
# Print the results
for key, value in duplicates.items():
if value:
print(f"{key} is a duplicate of {value}")
# def find_duplicates(directory):
# hashes = {}
# for root, dirs, files in os.walk(directory):
# for f in files:
# filename = os.path.join(root, f)
# if filename.endswith(('png', 'jpg', 'jpeg', 'gif', 'avif')):
# img = Image.open(filename)
# img_hash = imagehash.phash(img) # pHash for similarity detection
# if img_hash in hashes:
# print(f"Duplicate found: {filename} and {hashes[img_hash]}")
# else:
# hashes[img_hash] = filename
# find_duplicates('D:\My Drive\Shared\Whiteriver')
Convert Images to the AVIF format
AVIF is a lot smaller as well as other benifits. Specifically this script was used on my Google Drive root folder finding all images and converting them to avif.
"""
Convert Images to the AVIF format
AVIF is a lot smaller as well as other benifits.
Specifically this script was used on my Google Drive root folder
finding all images and converting them to avif.
"""
import requests
from pathlib import Path
import os
import concurrent.futures
from tqdm import tqdm # Install with: pip install tqdm
from threading import Lock
import shutil
from time import sleep
import json
import psutil
api_url = 'http://localhost:8080/api'
input_dir = 'D:\My Drive\Shared'
output_dir = Path('C:\Processed')
image_extensions = [
".jpeg", ".jpg", ".png", ".gif", ".bmp", ".tiff", ".tif",
".webp", ".heif", ".heic", ".ico", ".svg",
".cr2", ".cr3", ".nef", ".arw", ".raf", ".orf", ".rw2", ".dng"
]
lock = Lock()
def convert(filepath):
suf = Path(filepath).suffix.lower()
if suf in image_extensions:
try:
output_name = str(filepath).split(suf)[0] + '.avif'
with open(filepath, 'rb') as f:
r = requests.post(api_url, data={'quality': 80}, files={'file': f})
if r.status_code == requests.codes.ok and r.headers.get('Content-Type') == 'image/avif':
with open(output_name, 'wb') as f:
f.write(r.content)
full_output_dir = output_dir / '/'.join(filepath.parts[1:-1])
full_output_dir.mkdir(parents=True, exist_ok=True)
shutil.move(filepath, full_output_dir)
else:
print('Error with:', filepath)
except Exception as e:
print(f'Error {e} with:', filepath)
def list_files_and_folders(directory):
# Collect all file and folder paths
items = []
for root, dirs, files in os.walk(directory):
items.extend([Path(os.path.join(root, f)) for f in files])
total_items = len(items)
if total_items == 0:
print("No files or folders found.")
return
# Use tqdm to display a progress bar
with tqdm(total=total_items, desc="Processing", unit="item") as pbar:
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(convert, item) for item in items]
# Update the progress bar as each task completes
for future in concurrent.futures.as_completed(futures):
with lock:
pbar.update(1) # Increment the progress bar by 1
list_files_and_folders(input_dir)
I have my own web server and like to run a few projects.
-
Home
Home Page of my server and domain. π I'm always updating this page since I use it to test out whatever new thing I'm working on.
-
Planka
Self-hosted Planka, an alternative to Trello / Jira. ποΈ I use it to plan my side projects, create cards, and keep track of progress.
-
Jellyfin
Self-hosted Jellyfin, an alternative to Plex. πΆ Makes it easy to access my music from any device.
-
VS Code Web
Self-hosted VS Code Editor π» Runs on my server so I can code and manage it from anywhere, on any device.
-
Excalidraw
Self-hosted Excalidraw βοΈ A draw.io alternative, great for sketching out project ideas and designs.
-
TOTP Authenticator
Side project π I built my own 2FA Authenticator after losing my phone and getting locked out of everything. This way I add my own security and access it from the web instead of being tied to a device.
-
Peer-to-Peer File Transfer
Side project π€ Transfers files directly between devices without storing them on the server.
-
Paste Room
Side project π A simple way to share text between devices (like my PC and laptop). Create a 'room' by changing the URL, and it becomes your unique space for shared text.
-
Media Gallery
I wanted an easy way to show off pictures without filling up my phone storage. πΈ This site displays media from any folder I choose, and I can share it with anyone via ngrok.
-
Suika Game Clone
I made a Suika Game clone in Godot π β simple but fun!
-
EagleCraft
Minecraft in your browser! βοΈ I used to run a dedicated server, but if itβs offline you can always connect to another public server.