📦 المكتبات القياسية والملفات

📦 المكتبات القياسية والتعامل مع الملفات

بايثون يأتي ببطارياته الخاصة — مئات المكتبات الجاهزة دون أي تثبيت. تعلم أشهرها وكيف تتحكم في الملفات والمجلدات.

📁 الملفات (open/read/write) 📂 os — النظام والمجلدات 📅 datetime — التواريخ 🎲 random — العشوائية 🧮 math — الرياضيات 🗃️ json — البيانات ⏱️ time — التوقيت

١. التعامل مع الملفات (File I/O)

أي برنامج حقيقي يحتاج لحفظ البيانات وقراءتها — في الملفات. بايثون يجعل هذا سهلاً جداً.

قراءة وكتابة الملفات

Python — read / write
# ===== الكتابة =====
with open("hello.txt", "w", encoding="utf-8") as f:
    f.write("مرحباً بالعالم!\n")
    f.write("أنا أتعلم بايثون.\n")
# with يغلق الملف تلقائياً — دائماً استخدمه

# ===== القراءة الكاملة =====
with open("hello.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)

# ===== القراءة سطراً سطراً =====
with open("hello.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())   # strip() يزيل \n

# ===== الإضافة (Append) =====
with open("hello.txt", "a", encoding="utf-8") as f:
    f.write("سطر جديد مضاف!\n")  # لا يحذف المحتوى القديم
أوضاع الملف (modes): "r" قراءة فقط · "w" كتابة (يمسح القديم) · "a" إضافة للنهاية · "x" إنشاء جديد (يفشل إن وُجد) · "rb" / "wb" للملفات الثنائية

التحقق من وجود الملف قبل القراءة

Python — safe file read
import os

def read_file_safe(path):
    if not os.path.exists(path):
        return None, f"الملف '{path}' غير موجود"
    try:
        with open(path, "r", encoding="utf-8") as f:
            return f.read(), None
    except PermissionError:
        return None, "لا تملك صلاحية قراءة هذا الملف"

data, err = read_file_safe("notes.txt")
if err:
    print(f"❌ {err}")
else:
    print(data)

🧠 سؤال سريع

ما الوضع الصحيح لفتح ملف لإضافة محتوى جديد دون حذف القديم؟

"w" — write
"a" — append
"r" — read
"x" — create
✅ صحيح! "a" يضيف للنهاية دون حذف القديم. "w" يمسح كل شيء!
❌ خطأ. الوضع الصحيح هو "a" (append) الذي يضيف للنهاية دون حذف المحتوى القديم.

٢. مكتبة os — التحكم في النظام

مكتبة os تتيح التعامل مع الملفات والمجلدات ومتغيرات النظام بشكل مستقل عن نظام التشغيل.

Python — os
import os

# ===== المجلدات =====
print(os.getcwd())             # المجلد الحالي
os.makedirs("data/output", exist_ok=True)  # إنشاء مجلدات متداخلة
os.rename("old_name.txt", "new_name.txt")   # إعادة التسمية
os.remove("temp.txt")                       # حذف ملف

# ===== قائمة الملفات =====
files = os.listdir(".")       # كل محتوى المجلد الحالي
for f in files:
    print(f)

# ===== معلومات الملف =====
info = os.path.getsize("hello.txt")  # الحجم بالبايت
print(f"الحجم: {info} bytes")

# ===== بناء مسارات آمنة =====
base = "C:/Users/Khalil"
path = os.path.join(base, "Documents", "notes.txt")
print(path)   # C:/Users/Khalil/Documents/notes.txt

# ===== المسح الشامل بـ os.walk =====
for root, dirs, files in os.walk("."):
    for file in files:
        if file.endswith(".py"):
            print(os.path.join(root, file))

٣. مكتبة json — حفظ البيانات هيكلياً

JSON هو أشهر صيغة لتبادل البيانات في العالم. بايثون يقرؤه ويكتبه بسهولة — مثالي لحفظ إعدادات أو بيانات التطبيق.

Python — json
import json

# ===== كتابة JSON =====
students = [
    {"name": "خليل", "age": 14, "grades": [18, 16, 19]},
    {"name": "فاطمة", "age": 15, "grades": [19, 20, 17]},
]

with open("students.json", "w", encoding="utf-8") as f:
    json.dump(students, f, ensure_ascii=False, indent=2)
# ensure_ascii=False للعربية | indent=2 لجعله مقروءاً

# ===== قراءة JSON =====
with open("students.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

for s in loaded:
    print(f"{s['name']}: معدل {sum(s['grades'])/len(s['grades']):.1f}")

# ===== تحويل من/إلى نص =====
text = json.dumps(students[0], ensure_ascii=False)
print(text)  # {"name": "خليل", "age": 14, ...}

obj  = json.loads(text)
print(obj["name"])  # خليل

🧠 سؤال سريع

ما الفرق بين json.dump() و json.dumps()؟

لا فرق بينهما
dump() يكتب لملف، dumps() يحول لنص (string)
dumps() أسرع من dump()
dump() يدعم العربية فقط
✅ ممتاز! الـ "s" في dumps تعني "string" — يرجع نصاً بدل الكتابة لملف.
❌ خطأ. dump() يكتب مباشرة لملف، بينما dumps() يحول البيانات لنص JSON تستطيع استخدامه في أي مكان.

٤. مكتبة datetime — التواريخ والأوقات

Python — datetime
from datetime import datetime, date, timedelta

# التاريخ والوقت الحالي
now   = datetime.now()
today = date.today()
print(now)    # 2025-03-20 14:30:00.123
print(today)  # 2025-03-20

# تنسيق التاريخ
print(now.strftime("%d/%m/%Y %H:%M"))   # 20/03/2025 14:30
print(now.strftime("%A, %B %d %Y"))    # Thursday, March 20 2025

# إنشاء تاريخ محدد
birthday = datetime(2011, 5, 15)

# حساب الفرق بين تاريخين
diff = datetime.now() - birthday
print(f"عمرك {diff.days // 365} سنة و {diff.days % 365} يوم")

# إضافة/طرح أيام
tomorrow    = today + timedelta(days=1)
next_week   = today + timedelta(weeks=1)
last_month  = today - timedelta(days=30)
print(f"غداً: {tomorrow} | الأسبوع القادم: {next_week}")

# تحويل نص لتاريخ
date_str = "25/12/2025"
parsed   = datetime.strptime(date_str, "%d/%m/%Y")
print(parsed.year, parsed.month)   # 2025 12

٥. مكتبة random — العشوائية

Python — random
import random

# أرقام عشوائية
print(random.randint(1, 100))   # عدد صحيح بين 1 و 100
print(random.random())          # عشري بين 0.0 و 1.0
print(random.uniform(1.5, 9.5)) # عشري بين 1.5 و 9.5

# اختيار من قائمة
colors = ["أحمر", "أزرق", "أخضر", "أصفر"]
print(random.choice(colors))         # عنصر واحد عشوائي
print(random.choices(colors, k=3))   # 3 عناصر (مع تكرار)
print(random.sample(colors, k=3))    # 3 عناصر (بدون تكرار)

# خلط قائمة
cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle(cards)
print(cards)

# seed — للحصول على نفس النتائج دائماً
random.seed(42)
print(random.randint(1, 100))  # دائماً 52

٦. مكتبة math — الرياضيات المتقدمة

Python — math
import math

# ثوابت
print(math.pi)    # 3.141592653589793
print(math.e)     # 2.718281828459045
print(math.inf)   # infinity

# دوال أساسية
print(math.sqrt(144))      # 12.0  — الجذر التربيعي
print(math.pow(2, 10))    # 1024.0 — قوة
print(math.factorial(6))  # 720  — 6!
print(math.gcd(48, 18))   # 6   — القاسم المشترك الأكبر
print(math.floor(4.7))    # 4   — تقريب للأسفل
print(math.ceil(4.1))     # 5   — تقريب للأعلى
print(math.log(100, 10))  # 2.0  — لوغاريتم

# حساب مساحة دائرة
def circle_area(r):
    return round(math.pi * r ** 2, 4)

print(circle_area(5))   # 78.5398

٧. مكتبة time — قياس الأداء والانتظار

Python — time
import time

# إيقاف مؤقت (Delay)
print("جاري التحميل...")
time.sleep(2)   # انتظر 2 ثانية
print("✅ اكتمل!")

# قياس وقت تنفيذ كود
start = time.perf_counter()

# الكود الذي تريد قياسه
total = sum(range(1_000_000))

end = time.perf_counter()
print(f"النتيجة: {total:,}")
print(f"الوقت : {end - start:.4f} ثانية")

# مؤقت للتحميل التدريجي
def loading_bar(steps=10):
    for i in range(steps + 1):
        bar     = "█" * i + "░" * (steps - i)
        percent = i * 10
        print(f"\r[{bar}] {percent}%", end="")
        time.sleep(0.1)
    print()

loading_bar()

٨. مكتبة collections — هياكل بيانات متقدمة

Python — collections
from collections import Counter, defaultdict, deque, namedtuple

# ===== Counter — عدّ العناصر =====
grades  = ["A", "B", "A", "C", "A", "B", "D", "A"]
counter = Counter(grades)
print(counter)            # Counter({'A': 4, 'B': 2, 'C': 1, 'D': 1})
print(counter.most_common(2))  # أكثر 2 تكراراً

# عدّ الكلمات في نص
text   = "بايثون سهل وبايثون ممتع وبايثون مفيد"
words  = Counter(text.split())
print(words)   # بايثون:3، سهل:1...

# ===== defaultdict — قاموس بقيمة افتراضية =====
students_by_city = defaultdict(list)
data = [("خليل","مراكش"),("فاطمة","الرباط"),("أحمد","مراكش")]
for name, city in data:
    students_by_city[city].append(name)
print(dict(students_by_city))
# {'مراكش': ['خليل', 'أحمد'], 'الرباط': ['فاطمة']}

# ===== namedtuple — tuple بأسماء =====
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 7)
print(p.x, p.y)   # 3 7

# ===== deque — قائمة ثنائية الاتجاه =====
dq = deque([1, 2, 3], maxlen=5)
dq.appendleft(0)   # إضافة يسار
dq.append(4)       # إضافة يمين
print(dq)           # deque([0, 1, 2, 3, 4])

📝 تمارين تطبيقية

تمرين ١ — يوميات بـ JSON

اكتب برنامجاً يسمح للمستخدم بإضافة ملاحظات يومية تُحفظ في ملف JSON. يجب أن يحتوي كل إدخال على التاريخ والنص.

Python — الحل
import json, os
from datetime import datetime

FILE = "diary.json"

def load_entries():
    if not os.path.exists(FILE):
        return []
    with open(FILE, "r", encoding="utf-8") as f:
        return json.load(f)

def save_entries(entries):
    with open(FILE, "w", encoding="utf-8") as f:
        json.dump(entries, f, ensure_ascii=False, indent=2)

entries = load_entries()

while True:
    print("\n1. إضافة ملاحظة  2. عرض الكل  3. خروج")
    choice = input("اختر: ")
    if choice == "1":
        text = input("اكتب ملاحظتك: ")
        entries.append({
            "date": datetime.now().strftime("%Y-%m-%d %H:%M"),
            "text": text
        })
        save_entries(entries)
        print("✅ تم الحفظ")
    elif choice == "2":
        for e in entries:
            print(f"📅 {e['date']}: {e['text']}")
    elif choice == "3":
        break

تمرين ٢ — أكثر 5 كلمات تكراراً

اكتب برنامجاً يقرأ ملف نصي ويطبع أكثر 5 كلمات تكراراً فيه باستخدام Counter.

Python — الحل
from collections import Counter
import re

def top_words(filename, n=5):
    with open(filename, "r", encoding="utf-8") as f:
        text = f.read().lower()
    # استخرج الكلمات فقط (بدون علامات ترقيم)
    words   = re.findall(r'\b\w+\b', text)
    counter = Counter(words)
    print(f"أكثر {n} كلمات تكراراً في '{filename}':")
    for word, count in counter.most_common(n):
        print(f"  {word}: {count} مرة")

top_words("story.txt")

🚀 المشروع — مدير ملفات بسيط

Python — file_manager.py
import os, json, time
from datetime import datetime

def scan_folder(path="."):
    result = []
    for entry in os.scandir(path):
        info = entry.stat()
        result.append({
            "name":     entry.name,
            "type":     "📁" if entry.is_dir() else "📄",
            "size":     f"{info.st_size:,} bytes",
            "modified": datetime.fromtimestamp(info.st_mtime)
                                   .strftime("%Y-%m-%d %H:%M")
        })
    return sorted(result, key=lambda x: x["type"], reverse=True)

def save_report(data):
    filename = f"report_{datetime.now().strftime('%Y%m%d_%H%M')}.json"
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    return filename

print("📂 مسح المجلد الحالي...")
start = time.perf_counter()
files = scan_folder()
print(f"وُجد {len(files)} عنصر في {time.perf_counter()-start:.3f}s\n")

for item in files:
    print(f"{item['type']} {item['name']:30} {item['size']:>15}  {item['modified']}")

rep = save_report(files)
print(f"\n✅ تم حفظ التقرير في: {rep}")

🎉 أتقنت المكتبات القياسية!

الآن تعرف كيف تتعامل مع الملفات وتستخدم os وjson وdatetime وrandom وmath وcollections.

الدرس التالي: المفاهيم المتقدمة ←