Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions Projects/Casino Roulette/App.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import tkinter as tk
from tkinter import messagebox, font
import random

def get_color(number):
if number == 0:
return "green"
elif number in [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36]:
return "red"
else:
return "black"

def tourner_roulette(pari_type, mise, capital, details):
numero = random.randint(0, 36)
couleur = get_color(numero)
gain = 0

if pari_type == "plein":
capital -= mise * len(details)
if numero in details:
gain = mise * 35
elif pari_type == "couleur":
capital -= mise
if couleur == details[0]:
gain = mise * 2
elif pari_type == "pair":
capital -= mise
if numero != 0 and numero % 2 == 0:
gain = mise * 2
elif pari_type == "impair":
capital -= mise
if numero != 0 and numero % 2 == 1:
gain = mise * 2

capital += gain

if gain > 0:
message = f"Bravo ! Vous avez gagné {gain:.2f}€ !\n"
else:
montant_perdu = mise * (len(details) if pari_type == "plein" else 1)
message = f"Désolé, vous avez perdu {montant_perdu:.2f}€.\n"

return capital, numero, couleur, message

class RouletteApp:
def __init__(self, root):
self.root = root
self.root.title("Roulette Casino")
self.root.geometry("400x630")
self.root.configure(bg="#f0f4f8")

self.capital = 100

self.custom_font = font.Font(family="Helvetica", size=12)
self.title_font = font.Font(family="Helvetica", size=16, weight="bold")

self.label_title = tk.Label(root, text="🎰 Roulette Casino 🎰", font=self.title_font, bg="#f0f4f8", fg="#2c3e50")
self.label_title.pack(pady=15)

self.label_capital = tk.Label(root, text=f"Capital : {self.capital}€", font=self.custom_font, bg="#f0f4f8", fg="#34495e")
self.label_capital.pack(pady=5)

frame_options = tk.Frame(root, bg="#f0f4f8")
frame_options.pack(pady=10, fill="x", padx=30)

tk.Label(frame_options, text="Type de mise :", font=self.custom_font, bg="#f0f4f8", fg="#34495e").grid(row=0, column=0, sticky="w")
options = ["plein", "couleur", "pair", "impair"]
self.pari_type_var = tk.StringVar(value=options[0])
self.option_menu = tk.OptionMenu(frame_options, self.pari_type_var, *options, command=self.on_pari_change)
self.option_menu.config(font=self.custom_font, bg="white")
self.option_menu.grid(row=0, column=1, sticky="ew", padx=10)

tk.Label(frame_options, text="Détails du pari :", font=self.custom_font, bg="#f0f4f8", fg="#34495e").grid(row=1, column=0, sticky="w", pady=8)
self.entry_details = tk.Entry(frame_options, font=self.custom_font)
self.entry_details.grid(row=1, column=1, sticky="ew", padx=10)
frame_options.columnconfigure(1, weight=1)

tk.Label(root, text="Mise en € :", font=self.custom_font, bg="#f0f4f8", fg="#34495e").pack(anchor="w", padx=30, pady=(15, 5))
self.entry_mise = tk.Entry(root, font=self.custom_font)
self.entry_mise.pack(fill="x", padx=30)

self.btn_jouer = tk.Button(root, text="Jouer", font=self.custom_font, bg="#27ae60", fg="white", activebackground="#2ecc71", command=self.jouer)
self.btn_jouer.pack(pady=20, ipadx=10, ipady=5)

# Canvas pour afficher le carré avec numéro
self.canvas = tk.Canvas(root, width=100, height=100, bg="#f0f4f8", highlightthickness=0)
self.canvas.pack(pady=5)

self.result_label = tk.Label(root, text="", font=self.custom_font, bg="#f0f4f8", fg="#2c3e50", wraplength=350, justify="left")
self.result_label.pack(padx=30, pady=10)

self.help_label = tk.Label(root, text="", font=("Helvetica", 10, "italic"), fg="#7f8c8d", bg="#f0f4f8", wraplength=350, justify="left")
self.help_label.pack(padx=30, pady=(0, 10))

self.on_pari_change(self.pari_type_var.get())

def on_pari_change(self, value):
if value == "plein":
self.entry_details.config(state="normal")
self.help_label.config(text="Entrez un ou plusieurs numéros séparés par des virgules (ex : 17,22,3). La mise sera appliquée à chaque numéro.")
elif value == "couleur":
self.entry_details.config(state="normal")
self.help_label.config(text="Entrez 'rouge' ou 'noir'.")
elif value == "pair":
self.entry_details.delete(0, tk.END)
self.entry_details.config(state="disabled")
self.help_label.config(text="Vous misez sur les numéros pairs. Aucun détail à entrer.")
elif value == "impair":
self.entry_details.delete(0, tk.END)
self.entry_details.config(state="disabled")
self.help_label.config(text="Vous misez sur les numéros impairs. Aucun détail à entrer.")
else:
self.entry_details.config(state="normal")
self.help_label.config(text="")

def dessiner_carre(self, numero, couleur):
self.canvas.delete("all")
taille = 100
# Dessiner carré coloré
self.canvas.create_rectangle(5, 5, taille-5, taille-5, fill=couleur, outline="black", width=2)
# Afficher le numéro au centre en blanc
self.canvas.create_text(taille//2, taille//2, text=str(numero), fill="white", font=("Helvetica", 36, "bold"))

def jouer(self):
try:
mise = float(self.entry_mise.get())
pari_type = self.pari_type_var.get()
raw_details = self.entry_details.get().strip().lower()

if pari_type == "plein":
if not raw_details:
raise ValueError("Entrez au moins un numéro.")
details = [int(x) for x in raw_details.split(",")]
for num in details:
if num < 0 or num > 36:
raise ValueError("Numéro de plein invalide.")
mise_totale = mise * len(details)
else:
mise_totale = mise

if mise_totale <= 0 or mise_totale > self.capital:
raise ValueError("Mise invalide ou insuffisante pour couvrir tous les paris.")

if pari_type == "couleur":
if raw_details not in ["rouge", "noir"]:
raise ValueError("Couleur invalide.")
details = [raw_details]
elif pari_type in ["pair", "impair"]:
details = []

except Exception as e:
messagebox.showerror("Erreur", f"Erreur dans la mise ou les détails du pari.\n{e}")
return

self.capital, numero, couleur, resultat = tourner_roulette(pari_type, mise, self.capital, details)
# Mise à jour du capital en haut
self.label_capital.config(text=f"Capital : {self.capital:.2f}€")

# Ici, on supprime la phrase "Capital restant" dans le texte de résultat
# Affiche le message résultat (sans capital)
self.result_label.config(text=resultat)

# Dessine le carré avec numéro
self.dessiner_carre(numero, couleur)

if self.capital <= 0:
messagebox.showinfo("Fin", "Vous avez perdu tout votre argent.")
self.root.destroy()

if __name__ == "__main__":
root = tk.Tk()
app = RouletteApp(root)
root.mainloop()
41 changes: 41 additions & 0 deletions Projects/Typing Speed Test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Typing Speed Test

A simple Python GUI application to test your typing speed and accuracy. The user is prompted with a random sentence to type. Once they start typing, a timer begins. When done, the app calculates:

- Time taken
- Typing speed (words per minute)
- Accuracy (percentage of correctly typed words)

This is a great tool to practice and improve your typing skills in a fun and interactive way!

---

### Prerequisites

This script uses one external library:

- `ttkbootstrap` — for a modern themed interface (built on `tkinter`)

You can install it via pip:

```bash
pip install ttkbootstrap
```

**Modules used:**
- `tkinter` — for the graphical user interface (included with Python)
- `random` — for selecting random sentences
- `time` — for measuring duration

> Make sure you are using **Python 3.x**.

---

### How to run the script

1. **Download** the script file (e.g. `typing_speed_test.py`).

2. **Open your terminal** or command prompt, navigate to the directory containing the file, and run:

```bash
python typing_speed_test.py
130 changes: 130 additions & 0 deletions Projects/Typing Speed Test/typing_speed_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import time
import random
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from tkinter import messagebox

# Mathis

#Sample sentences
phrases = [
"The sun shines on the snowy mountains.",
"Python is a versatile programming language.",
"Cats love sleeping near the windows.",
"A good coffee in the morning makes all the difference.",
"The algorithm sorts the data efficiently."
]

start_time = None
timer_running = False
selected_phrase = random.choice(phrases)
timer_job = None

def start_test(event=None):
global start_time, timer_running
if start_time is None:
start_time = time.time()
timer_running = True
update_timer()

def update_timer():
global timer_job
if timer_running and start_time is not None:
elapsed = time.time() - start_time
timer_label.config(text=f"Time elapsed: {elapsed:.1f} sec")
timer_job = app.after(100, update_timer)

def highlight_errors():
typed = entry.get("1.0", "end-1c")
entry.tag_remove("error", "1.0", "end")

for i in range(min(len(typed), len(selected_phrase))):
if typed[i] != selected_phrase[i]:
pos = f"1.{i}"
entry.tag_add("error", pos, f"1.{i+1}")
if len(typed) > len(selected_phrase):
entry.tag_add("error", f"1.{len(selected_phrase)}", f"1.{len(typed)}")

def calculate_speed():
global start_time, timer_running, timer_job
if start_time is None:
messagebox.showwarning("Warning", "Start typing before submitting!")
return

if timer_job:
app.after_cancel(timer_job)
timer_running = False

end_time = time.time()
typed_text = entry.get("1.0", "end-1c")
time_taken = end_time - start_time

if time_taken == 0:
messagebox.showerror("Error", "Invalid time. Please try again.")
return

word_count = len(typed_text.split())
wpm = round((word_count / time_taken) * 60)

correct_chars = sum(1 for i in range(min(len(typed_text), len(selected_phrase))) if typed_text[i] == selected_phrase[i])
total_chars = len(selected_phrase)
accuracy = round((correct_chars / total_chars) * 100)

messagebox.showinfo("Result", f"Time elapsed: {round(time_taken, 2)} sec\n"
f"Speed: {wpm} WPM\n"
f"Accuracy: {correct_chars}/{total_chars} characters ({accuracy}%)")
reset()

def on_key_press(event):
start_test()
highlight_errors()

def on_enter_press(event):
calculate_speed()
return "break"

def reset():
global start_time, selected_phrase, timer_running, timer_job
if timer_job:
app.after_cancel(timer_job)
timer_running = False
start_time = None
selected_phrase = random.choice(phrases)
label_phrase.config(text=selected_phrase)
entry.delete("1.0", "end")
entry.tag_remove("error", "1.0", "end")
timer_label.config(text="Time elapsed: 0.0 sec")

# --- UI Setup ---
app = ttk.Window(themename="flatly")
app.title("Typing Speed Test")
app.geometry("600x420")
app.resizable(False, False)

main_frame = ttk.Frame(app, padding=20)
main_frame.pack(fill=BOTH, expand=True)

ttk.Label(main_frame, text="Type the sentence below as fast and accurately as possible:",
font=("Segoe UI", 12)).pack(pady=(0, 10))

label_phrase = ttk.Label(main_frame, text=selected_phrase, wraplength=560,
font=("Segoe UI", 14), style="info.TLabel", padding=10)
label_phrase.pack(pady=(0, 10))

entry = ttk.Text(main_frame, height=4, width=70, font=("Segoe UI", 12), wrap="word")
entry.pack(pady=(0, 10))
entry.bind("<KeyRelease>", on_key_press)
entry.bind("<Return>", on_enter_press)
entry.tag_config("error", foreground="red")

timer_label = ttk.Label(main_frame, text="Time elapsed: 0.0 sec", font=("Segoe UI", 11, "italic"), foreground="#555")
timer_label.pack(pady=(0, 10))

btn_frame = ttk.Frame(main_frame)
btn_frame.pack(pady=10)

ttk.Button(btn_frame, text="Submit", bootstyle=PRIMARY, command=calculate_speed).grid(row=0, column=0, padx=5)
ttk.Button(btn_frame, text="Reset", bootstyle=SUCCESS, command=reset).grid(row=0, column=1, padx=5)
ttk.Button(btn_frame, text="Quit", bootstyle=DANGER, command=app.destroy).grid(row=0, column=2, padx=5)

app.mainloop()