Wednesday, March 4, 2026

Soccer ball

import turtle, math


screen = turtle.Screen()

screen.bgcolor("#1a1a2e")

screen.title("Soccer Ball")

screen.setup(700, 700)

screen.tracer(0)


t = turtle.Turtle()

t.hideturtle(); t.speed(0)


CX, CY, R = 0, 0, 220   # ball centre & radius in pixels


# ── Build 60 correct vertices of a truncated icosahedron ──────────

phi = (1 + math.sqrt(5)) / 2


def norm3(v):

  x, y, z = v

  d = math.sqrt(x*x+y*y+z*z)

  return (x/d,y/d,z/d)


def dot3(a,b):

  return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]


def cross3(a,b):

  return(a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0])


def sub3(a,b):

  return(a[0]-b[0],a[1]-b[1],a[2]-b[2])


raw = set()

for s1 in (-1,1):

  for s2 in (-1,1):

    raw.add((0,   s1,      s2*3*phi))

    raw.add((s2*3*phi, 0,    s1))

    raw.add((s1,  s2*3*phi,  0))

    for s3 in (-1,1):

      raw.add((s1,    s2*(2+phi),   s3*2*phi))

      raw.add((s3*2*phi,  s1,       s2*(2+phi)))

      raw.add((s2*(2+phi),s3*2*phi,   s1))

      raw.add((s1*2,    s2*(1+2*phi), s3*phi))

      raw.add((s3*phi,  s1*2,     s2*(1+2*phi)))

      raw.add((s2*(1+2*phi), s3*phi,  s1*2))


verts = [norm3(v) for v in raw]   # 60 unit-sphere vertices

N = len(verts)


# ── Adjacency (shortest edge) 

def d3(a,b): return math.sqrt(sum((a[k]-b[k])**2 for k in range(3)))


min_d = min(d3(verts[i],verts[j]) for i in range(N) for j in range(i+1,N))

ETOL  = 0.02

adj   = [[] for _ in range(N)]

for i in range(N):

  for j in range(i+1,N):

    if abs(d3(verts[i],verts[j])-min_d) < ETOL:

      adj[i].append(j); adj[j].append(i)


# ── Face enumeration via half-edge walk 

def next_vert(i, j):

  """Return k: the next vertex CCW around the face containing directed edge i→j."""

  others = [k for k in adj[j] if k != i]

  if len(others) == 1:

    return others[0]

  nj = verts[j]

  raw_in  = sub3(verts[i], nj)

  proj_in = dot3(raw_in, nj)

  tang_in = (raw_in[0]-proj_in*nj[0], raw_in[1]-proj_in*nj[1], raw_in[2]-proj_in*nj[2])

  mag = math.sqrt(dot3(tang_in,tang_in))

  if mag > 1e-10: tang_in = tuple(c/mag for c in tang_in)


  best, best_k = None, None

  for k in others:

    raw_out  = sub3(verts[k], nj)

    proj_out = dot3(raw_out, nj)

    tang_out = (raw_out[0]-proj_out*nj[0], raw_out[1]-proj_out*nj[1], raw_out[2]-proj_out*nj[2])

    cr   = cross3(tang_in, tang_out)

    sine = dot3(cr, nj)

    cosine = dot3(tang_in, tang_out)

    angle = math.atan2(sine, cosine)

    if best is None or angle < best:

      best, best_k = angle, k

  return best_k


face_set, face_list = set(), []

for i in range(N):

  for j in adj[i]:

    face = [i, j]

    ci, cj = i, j

    for _ in range(7):

      k = next_vert(ci, cj)

      if k == i: break

      face.append(k); ci, cj = cj, k

    key = frozenset(face)

    if key not in face_set and len(face) in (5, 6):

      face_set.add(key); face_list.append(face)


# ── Rotation & projection 

AY, AX = 0.52, -0.28


def rotate(v, ay, ax):

  x,y,z = v

  x2 =  x*math.cos(ay)+z*math.sin(ay); z2 = -x*math.sin(ay)+z*math.cos(ay); y2=y

  y3 =  y2*math.cos(ax)-z2*math.sin(ax); z3 = y2*math.sin(ax)+z2*math.cos(ax)

  return (x2, y3, z3)


def project(v):

  x,y,z = rotate(v, AY, AX)

  fov   = 3.8

  s   = R * fov / (fov + z + 1)

  return (CX + x*s, CY + y*s, z)


# ── Lighting / shading 

LIGHT = norm3((0.5, 0.7, 1.0))


def shade(face_idxs, is_pent):

  fv  = [verts[i] for i in face_idxs]

  cn  = norm3(tuple(sum(v[k] for v in fv)/len(fv) for k in range(3)))

  rcn = rotate(cn, AY, AX)

  diff = max(0.0, dot3(rcn, LIGHT))

  spec = max(0.0, diff)**12 * 0.5

  if is_pent:

    bright = 0.15 + 0.65*diff + spec

    base   = (18, 18, 18)

  else:

    bright = 0.38 + 0.55*diff + spec

    base   = (248, 248, 248)

  r = int(min(255, base[0]*bright + 255*spec))

  g = int(min(255, base[1]*bright + 255*spec))

  b = int(min(255, base[2]*bright + 255*spec))

  return f"#{r:02x}{g:02x}{b:02x}"


# ── Drawing helpers 

def draw_disk(x, y, r, fill, pen, lw=2):

  t.penup()

  t.goto(x, y-r)

  t.pendown()

  t.pencolor(pen)

  t.pensize(lw)

  t.fillcolor(fill)

  t.begin_fill()

  t.end_fill()


def draw_poly(pts, fill, pen, lw):

  t.penup(); t.goto(pts[0]); t.pendown()

  t.pencolor(pen); t.pensize(lw); t.fillcolor(fill)

  t.begin_fill()

  for p in pts[1:]: t.goto(p)

  t.goto(pts[0]); t.end_fill()


def in_ball(px, py):

  return (px-CX)**2+(py-CY)**2 <= R**2


# ── RENDER 

# Ground shadow

t.penup(); t.pencolor("#0c0c1a"); t.fillcolor("#0c0c1a")

sw, sh = 170, 22

t.goto(CX-sw, CY-R-14); t.pendown(); t.begin_fill()

for s in range(61):

  a = math.pi + s*math.pi/60

  t.goto(CX+sw*math.cos(a), CY-R-14+sh*math.sin(a))

t.end_fill()


# White ball base

draw_disk(CX, CY, R, "white", "#1a1a1a", lw=3)


# Sort faces back→front and draw

sorted_faces = sorted(face_list, key=lambda f: sum(project(verts[i])[2] for i in f)/len(f))


for face in sorted_faces:

  projs  = [project(verts[i]) for i in face]

  avg_z  = sum(p[2] for p in projs)/len(projs)

  if avg_z < -0.10:

    continue              # back-face cull

  pts2d  = [(p[0],p[1]) for p in projs]

  if not any(in_ball(px,py) for px,py in pts2d):

    continue


  is_pent = len(face) == 5

  col   = shade(face, is_pent)

  pen   = "#000000" if is_pent else "#555555"

  lw    = 2.5 if is_pent else 1.2

  draw_poly(pts2d, col, pen, lw)


# Clean ball outline

t.penup(); t.goto(CX, CY-R); t.pendown()

t.pencolor("#111111"); t.pensize(4); t.fillcolor("")


# Specular highlights

for hx,hy,hr,col in [(CX-65,CY+80,40,"#ffffff"),(CX-55,CY+68,20,"#ffffff")]:

  t.penup(); t.goto(hx,hy-hr); t.pendown()

  t.pencolor(col); t.pensize(1); t.fillcolor(col)

  t.begin_fill()

  t.end_fill()


screen.update()

turtle.done()

Read aloud a PDF file

import PyPDF2, pyttsx3


engine = pyttsx3.init()


with open("File.pdf", "rb") as file:

  reader = PyPDF2.PdfReader(file)

  for page in reader.pages:

    text = page.extract_text()

    if text:

      engine.say(text)


engine.runAndWait()


Wednesday, November 26, 2025

Extract pages from PDF

from PyPDF2 import PdfReader, PdfWriter


input_file =  ""    # To enter

output_file = ""    # To enter


startPage, endPage = 104, 196    # To modify


reader = PdfReader(input_file)

writer = PdfWriter()


for i in range(startPage, endPage + 1):

  writer.add_page(reader.pages[i])


with open(output_file, "wb") as f:

  writer.write(f)


print("Pages extracted successfully!")


Wednesday, September 24, 2025

Playing sound or audio in Python

from playsound import playsound

playsound("Sucker.mp3")



import pygame

pygame.mixer.init()

pygame.mixer.music.load(".mp3")

pygame.mixer.music.play()

while pygame.mixer.music.get_busy():

  pygame.time.Clock().tick(10)



import vlc, time

p = vlc.MediaPlayer(".mp3")

p.play()

time.sleep(0.1)

while p.is_playing():

  time.sleep(0.5)


Tuesday, September 2, 2025

Ring alarm sounds in Python

import winsound


for alias in ["SystemExit", "SystemHand"]:

  print("Playing:", alias)

  winsound.PlaySound(alias, winsound.SND_ALIAS)


for freq in range(100, 6001, 100):

  winsound.Beep(freq, 1000)

  print(f"Playing {freq} hertz")


Tuesday, August 19, 2025

ModuloQuiz

import tkinter as tk

from random import randint

import math


class ModQuiz:

  def __init__(self, root):

    self.root = root

    self.root.title("Modulo Quiz")

    self.ctr, self.num, self.den = 0, 0, 0


    self.question_label = tk.Label(root, text="", font=("Arial", 14, "bold"))

    self.question_label.pack(pady=10)


    self.answer_entry = tk.Entry(root, font=("Arial", 14, "bold"))

    self.answer_entry.pack(pady=5)

    self.answer_entry.bind("<Return>", lambda e: self.check_and_next())


    self.check_button = tk.Button(root, text="Check Answer", command=self.check_and_next, font=("Arial", 12, "bold"))

    self.check_button.pack(pady=5)


    self.result_label = tk.Label(root, text="", font=("Arial", 12, "bold"))

    self.result_label.pack(pady=5)


    self.score_label = tk.Label(root, text="Score: 0", font=("Arial", 12, "bold"))

    self.score_label.pack(pady=5)


    self.canvas = tk.Canvas(root, width=400, height=400, bg="white", highlightthickness=0)

    self.canvas.pack(pady=8)


    self.quit_button = tk.Button(root, text="Quit", command=root.destroy, font=("Arial", 12, "bold"))

    self.quit_button.pack(pady=5)


    self.ask_question()


  def ask_question(self):

    self.answer_entry.delete(0, tk.END)

    self.result_label.config(text="")

    self.num, self.den = randint(-7, 7), randint(-7, 7)

    while self.den == 0:

      self.den = randint(-7, 7)

    self.question_label.config(text=f"What is {self.num} % {self.den}?")

    self.answer_entry.focus()

    self.draw_arcs(self.den)


  def draw_arcs(self, den):

    self.canvas.delete("all")

    k = abs(den)

    pad = 20

    x0, y0, x1, y1 = 50, 40, 340, 340  # a little vertical space for labels

    cx, cy = (x0 + x1) / 2, (y0 + y1) / 2

    r = (x1 - x0) / 2 - 18

    step = 360 / k


    base = 90 # Base angle so that numbering starts at 12 o'clock


    self.canvas.create_oval(x0, y0, x1, y1, outline="black", width=1) # Draw outer circle


    for i in range(k):

      if den > 0:        # (b) Positive denominator: clockwise numbering 0..den-1

        start = base - i * step      # move clockwise by decreasing angle

        extent = -step               # draw clockwise

        label_val = i

      else:        # (c) Negative denominator: anti-clockwise numbering 0, -1, -2, ..., -(k-1)

        start = base + i * step      # move anti-clockwise by increasing angle

        extent = step                # draw anti-clockwise

        label_val = -i


      self.canvas.create_arc(x0, y0, x1, y1, start=start, extent=extent, style=tk.ARC, width=2)      # Draw arc segment


      theta_deg = start  # boundary angle      # Place label at boundary (not middle) so 0 is exactly at 12 o’clock

      theta = math.radians(theta_deg)


      r_label = r       # Slightly inside the circle for readability

      tx = cx + r_label * math.cos(theta)

      ty = cy - r_label * math.sin(theta)


      tick_in = r - 12      # Small tick mark at the boundary

      tick_out = r + 2

      tx_in = cx + tick_in * math.cos(theta)

      ty_in = cy - tick_in * math.sin(theta)

      tx_out = cx + tick_out * math.cos(theta)

      ty_out = cy - tick_out * math.sin(theta)

      self.canvas.create_line(tx_in, ty_in, tx_out, ty_out)


      tx_text = cx + (r + 40) * math.cos(theta)      # Offset text a bit towards center from the boundary

      ty_text = cy - (r + 40) * math.sin(theta)


      self.canvas.create_text(tx_text, ty_text, text=str(label_val), font=("Arial", 12, "bold"))


  def check_and_next(self):

    user_ans = self.answer_entry.get()

    try:

      if int(user_ans) == self.num % self.den:

        self.result_label.config(text="Correct!", fg="green")

        self.ctr += 1

        self.score_label.config(text=f"Score: {self.ctr}")

      else:

        self.result_label.config(text=f"Incorrect. It is {self.num % self.den}", fg="red")

    except:

      self.result_label.config(text="Please enter a valid integer.", fg="orange")

    self.root.after(1000, self.ask_question)


root = tk.Tk()

app = ModQuiz(root)

root.mainloop()

Saturday, August 2, 2025

Showing differences between contents of 2 files

with open("Bart.txt") as bart:

  L = bart.readlines()


with open("Joshua.txt") as joshua:

  L1 = joshua.readlines()


ctr = 0

for i in range(len(L)):

  if L[i] != L1[i]:

    ctr += 1

    print(L[i])  # Print differing line of File 1

    print(L1[i]) # Print differing line of File 2

    input()

print(ctr)