Hai Guys, Long time no see. Di sini saya mau simpan catatan saya terkait aktivitas coba-coba bikin skrip untuk Jadwal Harian menggunakan bahasa pemrograman Python. Aktivitas ini terinspirasi dari Serial Drama Korea (Love Next Door), dimana tokoh utamanya bernama (Bae Seok Ryu) iseng buat jadwal pengangguran ketika lagi gabut :D. Aktivitas coba-coba ini saya implementasikan pada OS Windows 11 Pro dengan bantuan scripting yang saya ambil dari ChatGPT (Thank you ChatGPT). Kemudian saya modifikasi skrip tersebut dengan hasil output seperti pada tahapan yang akan saya infokan berikut. Ikuti langkahnya Guys:
1. Instal aplikasi Python melalui Microsoft Store.2. Instal Dipendensi (Library) berikut melalui command prompt.
1) Buka command prompt melalui Win+R (Run) > cmd
2) Instal paket matplotlib, dengan perintah pip install matplotlib
3) Instal paket pytz, dengan perintah pip install pytz
4) Instal paket ntplib, dengan perintah pip install ntplib
Note: jika instalasi paket di atas gagal, coba ulangi langkahnya dengan menggunakan command prompt as Administrator.
3. Buat skrip Jadwal Harian menggunakan kode Python pada Notepad++ atau bisa menggunakan teks editor lainnya, contoh Sublime.
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.patches import Wedge
from datetime import datetime, timedelta
import pytz
import math
from tzlocal import get_localzone # To fetch local timezone
from ntplib import NTPClient # For NTP synchronization
from zoneinfo import ZoneInfo # For timezone handling
# Function to synchronize time with an NTP server
def get_ntp_time():
client = NTPClient()
try:
# We are using a public NTP server
response = client.request('pool.ntp.org')
ntp_time = datetime.utcfromtimestamp(response.tx_time) # UTC time
return ntp_time.replace(tzinfo=ZoneInfo("UTC")) # Set the NTP time to UTC
except Exception as e:
print(f"Error while getting NTP time: {e}")
return datetime.now() # Fallback to system time if NTP fails
# Get the current time in the local timezone (based on NTP time)
def get_local_time():
local_tz = get_localzone() # Automatically fetch the local timezone
ntp_time = get_ntp_time() # Get the current time using NTP
return ntp_time.astimezone(local_tz) # Convert NTP time to local time
# Function to draw the clock
def draw_clock(ax, current_time, busy_slots, start_of_day, end_of_day):
ax.clear() # Clear the previous drawing on the canvas
# Set the aspect ratio of the clock to be equal (circular)
ax.set_aspect(1)
ax.set_axis_off()
# Draw the clock circle
ax.add_patch(plt.Circle((0.5, 0.5), 0.45, color='lightgray'))
# Draw the hour and minute ticks (24-hour clock)
for i in range(24):
angle = math.radians(i * 15) # Each hour is 15 degrees (360 degrees / 24 hours)
# Menggeser angka jam ke kanan sebanyak 19 jam (menggeser posisi jam)
adjusted_angle = math.radians((i + 19) % 24 * 15) # Shift by 19 hours (9 * 15 degrees)
x_start = 0.5 + 0.45 * math.cos(adjusted_angle)
y_start = 0.5 + 0.45 * math.sin(adjusted_angle)
x_end = 0.5 + 0.4 * math.cos(adjusted_angle)
y_end = 0.5 + 0.4 * math.sin(adjusted_angle)
ax.plot([x_start, x_end], [y_start, y_end], color='black', lw=2)
# Add the hour number (1-24)
hour_label = str((i + 1) % 24) if i != 23 else '00' # Show 24-hour time format (1-24)
ax.text(x_end, y_end, hour_label, color='black', ha='center', va='center', fontsize=16)
# Draw the time hands (adjusted to be proportional)
current_seconds = current_time.second + current_time.minute * 60 + current_time.hour * 3600
total_seconds_in_day = (end_of_day - start_of_day).total_seconds()
# Hour hand calculation (clockwise direction from top, 12 o'clock position)
hour_angle = (current_seconds / total_seconds_in_day) * 360 - 90 # Subtract 90 to adjust to 12 o'clock
ax.plot([0.5, 0.5 + 0.3 * math.cos(math.radians(hour_angle))],
[0.5, 0.5 + 0.3 * math.sin(math.radians(hour_angle))],
lw=6, color="black")
# Minute hand calculation (clockwise direction from top, 12 o'clock position)
#minute_angle = ((current_seconds % 3600) / 60) / 60 * 360 - 90 # Subtract 90 for 12 o'clock
#ax.plot([0.5, 0.5 + 0.4 * math.cos(math.radians(minute_angle))],
# [0.5, 0.5 + 0.4 * math.sin(math.radians(minute_angle))],
# lw=4, color="blue")
# Second hand calculation (clockwise direction from top, 12 o'clock position)
second_angle = ((current_seconds % 60) / 60) * 360 - 90 # Subtract 90 for 12 o'clock
ax.plot([0.5, 0.5 + 0.45 * math.cos(math.radians(second_angle))],
[0.5, 0.5 + 0.45 * math.sin(math.radians(second_angle))],
lw=2, color="red")
# Mark busy/free time slots (the colored wedges) and activity names
for busy_start, busy_end, color, activity in busy_slots:
# If the end time is earlier than the start time, it means the activity spans across midnight
if busy_end < busy_start:
# Adjust the end time by adding 24 hours to handle the crossing over midnight
busy_end = busy_end + timedelta(days=1)
start_angle = (busy_start - start_of_day).total_seconds() / total_seconds_in_day * 360 - 90
end_angle = (busy_end - start_of_day).total_seconds() / total_seconds_in_day * 360 - 90
ax.add_patch(Wedge((0.5, 0.5), 0.45, start_angle, end_angle, color=color, alpha=0.7))
# Calculate position for activity text
angle_mid = (start_angle + end_angle) / 2
x_text = 0.5 + 0.5 * math.cos(math.radians(angle_mid)) # Adjust to correct position
y_text = 0.5 + 0.5 * math.sin(math.radians(angle_mid)) # Adjust to correct position
# Add activity description with large font and contrasting color
ax.text(x_text, y_text, activity, color='black', ha='center', va='center', fontsize=12, fontweight='bold')
# Add time labels for activity start and finish
start_time_label = busy_start.strftime("%H:%M")
end_time_label = busy_end.strftime("%H:%M")
# Display start and end time
ax.text(x_text, y_text - 0.05, f"{start_time_label} - {end_time_label}", color='black', ha='center', va='center', fontsize=10)
# Add title and date-time info (adjusting y position to place outside the circle)
ax.text(0.5, 1.1, "Jadwal Hamba Allah", color='black', ha='center', va='center', fontsize=16, fontweight='bold')
date_text = current_time.strftime("%A, %d-%m-%Y")
ax.text(0.5, -0.1, date_text, color='black', ha='center', va='center', fontsize=14)
# Main function to update the clock
def update_clock():
current_time = get_local_time() # Get local time from NTP
# Set `start_of_day` and `end_of_day` to be timezone-aware
local_tz = get_localzone() # Fetch the local timezone
start_of_day = datetime(current_time.year, current_time.month, current_time.day, 0, 0, 0, 0)
start_of_day = start_of_day.replace(tzinfo=local_tz) # Apply local timezone to start_of_day
end_of_day = start_of_day.replace(hour=23, minute=59, second=59, microsecond=0)
# Define the busy slots and corresponding colors
busy_slots = [
(datetime(current_time.year, current_time.month, current_time.day, 5, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 7, 0, 0, tzinfo=local_tz), 'white', 'Wake up & \nMorning routine'),
(datetime(current_time.year, current_time.month, current_time.day, 7, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 8, 0, 0, tzinfo=local_tz), 'gray', 'Go to work'),
(datetime(current_time.year, current_time.month, current_time.day, 8, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 12, 0, 0, tzinfo=local_tz), 'white', 'Work'),
(datetime(current_time.year, current_time.month, current_time.day, 12, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 13, 0, 0, tzinfo=local_tz), 'gray', 'Lunch break'),
(datetime(current_time.year, current_time.month, current_time.day, 13, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 17, 0, 0, tzinfo=local_tz), 'white', 'Continue to work'),
(datetime(current_time.year, current_time.month, current_time.day, 17, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 18, 0, 0, tzinfo=local_tz), 'gray', 'Home from work'),
(datetime(current_time.year, current_time.month, current_time.day, 18, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 19, 00, 0, tzinfo=local_tz), 'white', 'Dinner'),
(datetime(current_time.year, current_time.month, current_time.day, 19, 00, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 22, 0, 0, tzinfo=local_tz), 'gray', 'Free time to relax'),
(datetime(current_time.year, current_time.month, current_time.day, 22, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day, 23, 0, 0, tzinfo=local_tz), 'white', 'Prepare for bed'),
# Adjust the sleep time slot to span across midnight
(datetime(current_time.year, current_time.month, current_time.day, 23, 0, 0, tzinfo=local_tz), datetime(current_time.year, current_time.month, current_time.day + 1, 5, 0, 0, tzinfo=local_tz), 'gray', 'Take a break to sleep'),
]
total_seconds_in_day = (end_of_day - start_of_day).total_seconds()
# Redraw the clock
draw_clock(ax, current_time, busy_slots, start_of_day, end_of_day)
canvas.draw() # Redraw the canvas with updated clock
# Update the clock every second (1000 milliseconds)
root.after(1000, update_clock)
# Initialize Tkinter window
root = tk.Tk()
root.title("Time and Schedule Clock")
# Create a figure and axis only once (not inside update_clock)
fig, ax = plt.subplots(figsize=(8, 8)) # Increased figure size for a larger clock
# Embed the plot into the Tkinter window
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) # Ensure the canvas resizes with the window
# Start the clock update process
update_clock()
# Run the Tkinter event loop
root.mainloop()
4. Simpan skrip di atas dengan ekstensi file python (.py). Contoh penamaan filenya yaitu app_schedule.py
5. Jalankan file app_schedule.py
1) Buka command prompt melalui Win+R (Run) > cmd
2) Arahkan folder ke lokasi file app_schedule.py
3) Jalankan file tersebut dengan perintah: python app_schedule.py, kemudian tekan enter, maka akan keluar output dari file python tersebut.
Tidak ada komentar:
Posting Komentar