Python Coding Academy
135 subscribers
7 photos
3 files
4 links
🐍 Learn Python. Build Skills. Create the Future.

📚 Python lessons from beginner to advanced
💻 Clear explanations & real-world examples
🚀 Learn to code. Learn to build.
Download Telegram
🐍 آموزش جامع Python — پست ۱۶۹
اضافه کردن داده به CSV با DictWriter
در پست قبل یاد گرفتیم با DictWriter اطلاعات را در CSV ذخیره کنیم.
حالا می‌خواهیم داده جدید را به فایل موجود اضافه کنیم؛ بدون اینکه اطلاعات قبلی پاک شوند.
🔹 مشکل حالت w
اگر فایل را با حالت:
open("users.csv", "w")

باز کنیم، محتوای قبلی هنگام نوشتن جایگزین می‌شود.
پس برای اضافه کردن اطلاعات از:
a → append

استفاده می‌کنیم.
🔹 اضافه کردن یک کاربر
فرض کنیم فایل users.csv از قبل این محتوا را دارد:
name,age,city
Ali,25,Baku
Sara,22,Tehran

حالا می‌خواهیم Reza را اضافه کنیم:
import csv

with open("users.csv", "a", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(
file,
fieldnames=["name", "age", "city"]
)

writer.writerow({
"name": "Reza",
"age": 30,
"city": "Tabriz"
})

فایل حالا:
name,age,city
Ali,25,Baku
Sara,22,Tehran
Reza,30,Tabriz

⚠️ Header را دوباره ننویسیم
وقتی از حالت a استفاده می‌کنیم، معمولاً فایل از قبل Header دارد.
بنابراین نباید هر بار این را اجرا کنیم:
writer.writeheader()

وگرنه ممکن است نتیجه‌ای شبیه این ایجاد شود:
name,age,city
Ali,25,Baku
name,age,city
Reza,30,Tabriz

🔹 بررسی وجود فایل
اگر برنامه ممکن است برای اولین بار اجرا شود، بهتر است ابتدا بررسی کنیم فایل وجود دارد یا نه:
from pathlib import Path
import csv

file_path = Path("users.csv")

file_exists = file_path.exists()

with file_path.open(
"a",
newline="",
encoding="utf-8"
) as file:

writer = csv.DictWriter(
file,
fieldnames=["name", "age", "city"]
)

if not file_exists:
writer.writeheader()

writer.writerow({
"name": "Reza",
"age": 30,
"city": "Tabriz"
})

در این حالت:
فایل وجود ندارد → Header ساخته می‌شود
فایل وجود دارد → فقط داده جدید اضافه می‌شود

🔹 اضافه کردن چند رکورد
می‌توانیم چند Dictionary را هم‌زمان اضافه کنیم:
users = [
{"name": "Reza", "age": 30, "city": "Tabriz"},
{"name": "Mina", "age": 27, "city": "Baku"}
]

with file_path.open(
"a",
newline="",
encoding="utf-8"
) as file:

writer = csv.DictWriter(
file,
fieldnames=["name", "age", "city"]
)

if not file_exists:
writer.writeheader()

writer.writerows(users)

🧠 خلاصه
"w" → ایجاد/بازنویسی فایل
"a" → اضافه کردن به انتهای فایل

writeheader()
→ فقط زمانی که Header وجود ندارد

writerow()
→ اضافه کردن یک رکورد

writerows()
→ اضافه کردن چند رکورد

🎯 تمرین
برنامه‌ای بنویس که فایل:
products.csv

را بررسی کند.
اگر فایل وجود نداشت، Header زیر را ایجاد کند:
name,price,stock

سپس محصول زیر را به فایل اضافه کند:
Laptop,1200,5

اگر برنامه را چند بار اجرا کردی، Header نباید هر بار تکرار شود.
پست ۱۶۹ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۷۰
جست‌وجو و فیلتر داده‌ها در CSV
تا اینجا یاد گرفتیم:
csv.reader       → خواندن CSV به صورت List
csv.DictReader → خواندن CSV به صورت Dictionary
csv.writer → نوشتن List
csv.DictWriter → نوشتن Dictionary

حالا می‌توانیم روی اطلاعات CSV جست‌وجو و فیلتر انجام دهیم.
🔹 مثال ساده
فرض کنیم products.csv این محتوا را دارد:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,0
Monitor,300,8

می‌خواهیم فقط محصولاتی را پیدا کنیم که موجود هستند:
import csv

with open("products.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)

for product in reader:
if int(product["stock"]) > 0:
print(product["name"])

خروجی:
Laptop
Mouse
Monitor

🔹 فیلتر بر اساس قیمت
مثلاً محصولاتی که قیمت آن‌ها کمتر از 100 است:
with open("products.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)

for product in reader:
if float(product["price"]) < 100:
print(product["name"])

خروجی:
Mouse
Keyboard

دقت کن که مقدار CSV رشته است؛ بنابراین برای مقایسه عددی از:
int()
float()

استفاده کردیم.
🔹 ترکیب چند شرط
می‌توانیم چند شرط را هم‌زمان بررسی کنیم:
with open("products.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)

for product in reader:
price = float(product["price"])
stock = int(product["stock"])

if price < 500 and stock > 0:
print(product["name"])

خروجی:
Mouse
Monitor

چون هر دو شرط باید درست باشند.
🔹 ذخیره نتایج فیلترشده
گاهی فقط چاپ کردن کافی نیست و می‌خواهیم نتایج را در یک لیست ذخیره کنیم:
import csv

available_products = []

with open("products.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)

for product in reader:
if int(product["stock"]) > 0:
available_products.append(product)

print(available_products)

حالا available_products شامل Dictionaryهای محصولات موجود است.
⚠️ نکته مهم
قبل از مقایسه عددی، مقدار CSV را به نوع مناسب تبدیل کن:
int(product["stock"])

یا:
float(product["price"])

چون:
"100" > "20"

یک مقایسه رشته‌ای است و نتیجه آن با مقایسه عددی متفاوت است.
🧠 خلاصه
DictReader
↓
خواندن هر سطر به صورت Dictionary
↓
تبدیل مقدارهای عددی
↓
بررسی شرط
↓
فیلتر کردن داده‌ها

🎯 تمرین
فایل زیر را در نظر بگیر:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,0
Monitor,300,8

برنامه‌ای بنویس که فقط محصولاتی را نمایش دهد که:
price < 500
stock > 0

خروجی مورد انتظار:
Mouse
Monitor

پست ۱۷۰ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۷۱
ویرایش داده‌های CSV
در پست‌های قبل یاد گرفتیم چطور داده‌های CSV را بخوانیم و رکورد جدید اضافه کنیم.
حالا می‌خواهیم یک رکورد موجود را ویرایش کنیم.
مثلاً قیمت یک محصول تغییر کرده است.
🔹 چرا نمی‌توانیم مستقیماً یک سطر را ویرایش کنیم؟
CSV یک فایل متنی ساده است و مثل Database امکان تغییر مستقیم یک رکورد مشخص را ندارد.
روش معمول این است:
خواندن فایل
↓
تغییر داده در Python
↓
نوشتن دوباره فایل

🔹 مثال
فرض کنیم products.csv:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10

می‌خواهیم قیمت Mouse را از 25 به 30 تغییر دهیم.
ابتدا داده‌ها را می‌خوانیم:
import csv

with open("products.csv", "r", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
products = list(reader)

حالا داخل لیست، محصول موردنظر را پیدا می‌کنیم:
for product in products:
if product["name"] == "Mouse":
product["price"] = "30"

در این مرحله داده داخل Python تغییر کرده است.
🔹 نوشتن دوباره فایل
حالا باید اطلاعات جدید را دوباره در CSV ذخیره کنیم:
with open("products.csv", "w", newline="", encoding="utf-8") as file:
fieldnames = ["name", "price", "stock"]

writer = csv.DictWriter(
file,
fieldnames=fieldnames
)

writer.writeheader()
writer.writerows(products)

فایل حالا:
name,price,stock
Laptop,1200,5
Mouse,30,20
Keyboard,70,10

🔹 یک مثال کامل
import csv

file_path = "products.csv"

with open(file_path, "r", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
products = list(reader)

for product in products:
if product["name"] == "Mouse":
product["price"] = "30"

with open(file_path, "w", newline="", encoding="utf-8") as file:
fieldnames = ["name", "price", "stock"]

writer = csv.DictWriter(
file,
fieldnames=fieldnames
)

writer.writeheader()
writer.writerows(products)

⚠️ نکته مهم
در CSV، مقدارها هنگام خواندن معمولاً str هستند.
بنابراین:
product["price"] = "30"

در اینجا یک رشته است.
اگر داده را به عدد تبدیل کنیم:
price = float(product["price"])

برای انجام محاسبات مناسب است؛ اما هنگام ذخیره CSV، csv می‌تواند مقدار عددی را نیز به شکل متنی در فایل بنویسد.
🔹 اگر محصول پیدا نشود چه؟
می‌توانیم یک متغیر برای بررسی این موضوع داشته باشیم:
updated = False

for product in products:
if product["name"] == "Mouse":
product["price"] = "30"
updated = True

if updated:
print("Product updated")
else:
print("Product not found")

این روش در برنامه‌های واقعی کاربردی‌تر است.
🧠 خلاصه
برای ویرایش CSV معمولاً:
CSV
↓
DictReader
↓
list
↓
تغییر رکورد
↓
DictWriter
↓
CSV جدید

CSV برای داده‌های ساده و جدولی مناسب است، اما اگر تعداد داده‌ها زیاد شود یا عملیات پیچیده‌ای مثل جست‌وجو، تراکنش و هم‌زمانی داشته باشیم، معمولاً Database انتخاب مناسب‌تری است.
🎯 تمرین
فایل زیر را در نظر بگیر:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10

برنامه‌ای بنویس که:
محصول Keyboard را پیدا کند.
قیمت آن را از 70 به 80 تغییر دهد.
فایل CSV را دوباره ذخیره کند.
اگر محصول وجود نداشت، عبارت زیر را چاپ کند:
Product not found

پست ۱۷۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۲
حذف داده از CSV
در پست قبل یاد گرفتیم چگونه یک رکورد CSV را ویرایش کنیم.
حالا می‌خواهیم یک رکورد را حذف کنیم.
چون CSV مثل Database نیست، برای حذف معمولاً این مراحل را انجام می‌دهیم:
خواندن CSV
↓
حذف رکورد از داده‌های Python
↓
نوشتن دوباره CSV

🔹 مثال
فرض کنیم products.csv شامل این اطلاعات است:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10

می‌خواهیم Mouse را حذف کنیم.
ابتدا فایل را می‌خوانیم:
import csv

with open("products.csv", "r", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
products = list(reader)

حالا محصول موردنظر را حذف می‌کنیم:
products = [
product
for product in products
if product["name"] != "Mouse"
]

در نتیجه Mouse از لیست حذف می‌شود.
🔹 ذخیره دوباره فایل
with open("products.csv", "w", newline="", encoding="utf-8") as file:
fieldnames = ["name", "price", "stock"]

writer = csv.DictWriter(
file,
fieldnames=fieldnames
)

writer.writeheader()
writer.writerows(products)

فایل نهایی:
name,price,stock
Laptop,1200,5
Keyboard,70,10

🔹 بررسی اینکه رکورد وجود داشته است
می‌توانیم قبل و بعد از حذف، تعداد رکوردها را مقایسه کنیم:
old_count = len(products)

products = [
product
for product in products
if product["name"] != "Mouse"
]

if len(products) < old_count:
print("Product deleted")
else:
print("Product not found")

اگر محصول وجود داشته باشد:
Product deleted

و اگر وجود نداشته باشد:
Product not found

🔥 مثال کامل
import csv

file_path = "products.csv"

with open(file_path, "r", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
products = list(reader)

old_count = len(products)

products = [
product
for product in products
if product["name"] != "Mouse"
]

if len(products) < old_count:

with open(
file_path,
"w",
newline="",
encoding="utf-8"
) as file:

fieldnames = ["name", "price", "stock"]

writer = csv.DictWriter(
file,
fieldnames=fieldnames
)

writer.writeheader()
writer.writerows(products)

print("Product deleted")

else:
print("Product not found")

⚠️ نکته مهم
در این روش ابتدا کل فایل را در حافظه می‌خوانیم:
products = list(reader)

برای فایل‌های کوچک مشکلی نیست.
اما برای فایل‌های بسیار بزرگ، بهتر است معماری مناسب‌تری استفاده کنیم یا از Database استفاده کنیم.
🧠 خلاصه
ویرایش CSV:
خواندن → تغییر → بازنویسی

حذف CSV:
خواندن → حذف → بازنویسی

یعنی CSV امکانات مستقیم UPDATE و DELETE مانند Database ندارد.
🎯 تمرین
فایل زیر را در نظر بگیر:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10

برنامه‌ای بنویس که:
محصول Keyboard را حذف کند.
فایل را دوباره ذخیره کند.
اگر محصول وجود نداشت، چاپ کند:
Product not found

بعد از اجرای موفق، فایل باید شامل این موارد باشد:
Laptop,1200,5
Mouse,25,20

پست ۱۷۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۳
جداکننده‌ها در CSV | delimiter
تا اینجا همه فایل‌های CSV ما با کاما جدا می‌شدند:
name,age,city
Ali,25,Baku
Sara,22,Tehran

اما در دنیای واقعی ممکن است فایل‌ها از جداکننده‌های دیگری استفاده کنند.
مثلاً:
name;age;city
Ali;25;Baku
Sara;22;Tehran

یا:
name|age|city
Ali|25|Baku

برای مشخص کردن جداکننده از پارامتر:
delimiter

استفاده می‌کنیم.
🔹 خواندن CSV با ;
اگر فایل این‌طور باشد:
name;age;city
Ali;25;Baku
Sara;22;Tehran

باید بنویسیم:
import csv

with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(
file,
delimiter=";"
)

for row in reader:
print(row["name"], row["city"])

خروجی:
Ali Baku
Sara Tehran

🔹 نوشتن CSV با جداکننده دلخواه
همین موضوع برای DictWriter هم وجود دارد:
import csv

users = [
{"name": "Ali", "age": 25},
{"name": "Sara", "age": 22}
]

with open(
"users.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.DictWriter(
file,
fieldnames=["name", "age"],
delimiter=";"
)

writer.writeheader()
writer.writerows(users)

فایل ایجادشده:
name;age
Ali;25
Sara;22

🔹 delimiter فقط برای کاما نیست
می‌توانیم از جداکننده‌های مختلف استفاده کنیم:
delimiter=","

یا:
delimiter=";"

یا حتی:
delimiter="|"

البته باید فایل را مطابق همان فرمت بخوانیم.
⚠️ نکته مهم
اگر جداکننده فایل ; باشد ولی ما از حالت پیش‌فرض , استفاده کنیم، داده‌ها درست به ستون‌های مختلف تقسیم نمی‌شوند.
مثلاً:
name;age;city

اگر با delimiter="," بخوانیم، Python این خط را عملاً یک فیلد در نظر می‌گیرد.
پس هنگام خواندن CSV باید ساختار واقعی فایل را بدانیم.
🔹 جداکننده با داده داخل متن
فرض کنیم یک مقدار خودش شامل کاما باشد:
name,description
Laptop,"Fast, powerful computer"

ماژول csv می‌تواند این مقدار را به‌درستی مدیریت کند:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for row in reader:
print(row["description"])

خروجی:
Fast, powerful computer

یعنی نباید CSV را با split(",") به‌صورت دستی تجزیه کنیم؛ چون CSV می‌تواند قوانین مربوط به Quote و delimiter را داشته باشد.
🧠 خلاصه
delimiter="," → جداکننده کاما
delimiter=";" → جداکننده نقطه‌ویرگول
delimiter="|" → جداکننده Pipe

و:
csv.reader / DictReader
↓
خواندن CSV با ساختار صحیح

csv.writer / DictWriter
↓
نوشتن CSV با ساختار صحیح

🎯 تمرین
فایل زیر را در نظر بگیر:
name;price;stock
Laptop;1200;5
Mouse;25;20
Keyboard;70;10

برنامه‌ای بنویس که:
فایل را با DictReader بخواند.
از delimiter=";" استفاده کند.
نام و قیمت محصولات را چاپ کند.
خروجی:
Laptop 1200
Mouse 25
Keyboard 70

پست ۱۷۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۴
مدیریت Quote و Escape در CSV
در پست قبل با delimiter آشنا شدیم.
اما یک سؤال مهم وجود دارد:
اگر خود داده شامل کاما یا جداکننده باشد، Python چطور تشخیص می‌دهد که آن کاما بخشی از متن است یا جداکننده ستون‌ها؟
برای این کار CSV از Quote استفاده می‌کند.
🔹 مشکل بدون Quote
فرض کنیم اطلاعات یک محصول این باشد:
name,description
Laptop,Fast, powerful computer

اینجا مشخص نیست:
Fast, powerful computer

یک مقدار است یا دو ستون جدا.
🔹 استفاده از Quote
در CSV می‌توانیم مقدار را داخل " " قرار دهیم:
name,description
Laptop,"Fast, powerful computer"

حالا Python می‌فهمد که کامای داخل " " بخشی از مقدار description است.
🔹 خواندن با csv
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for row in reader:
print(row["name"])
print(row["description"])

خروجی:
Laptop
Fast, powerful computer

🔹 نوشتن داده‌ای که کاما دارد
اگر با csv.writer یا csv.DictWriter بنویسیم، Python خودش Quote مناسب را مدیریت می‌کند:
import csv

products = [
{
"name": "Laptop",
"description": "Fast, powerful computer"
},
{
"name": "Mouse",
"description": "Small, wireless mouse"
}
]

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.DictWriter(
file,
fieldnames=["name", "description"]
)

writer.writeheader()
writer.writerows(products)

فایل CSV به شکل مناسب ذخیره می‌شود:
name,description
Laptop,"Fast, powerful computer"
Mouse,"Small, wireless mouse"

🔹 اگر خود متن شامل " باشد چه؟
مثلاً:
He said "Hello"

در CSV برای نمایش " داخل یک مقدار، معمولاً از دو Quote استفاده می‌شود:
"He said ""Hello"""

ماژول csv این جزئیات را هنگام خواندن و نوشتن مدیریت می‌کند.
⚠️ نکته مهم
به همین دلیل بهتر است CSV را با:
csv.reader()
csv.writer()
csv.DictReader()
csv.DictWriter()

مدیریت کنیم.
استفاده از:
line.split(",")

برای CSVهای واقعی قابل اعتماد نیست؛ چون ممکن است داده‌ها شامل:
کاما
Quote
جداکننده‌های مختلف
باشند.
🧠 خلاصه
delimiter → جداکننده ستون‌ها

"..." → مشخص کردن یک مقدار شامل delimiter

"" داخل مقدار → با Quote اضافی مدیریت می‌شود

csv module → مدیریت صحیح قوانین CSV

🎯 تمرین
داده زیر را در نظر بگیر:
name,description
Phone,"Large screen, fast processor"
Laptop,"Lightweight, powerful"

برنامه‌ای بنویس که با DictReader فایل را بخواند و فقط description هر محصول را چاپ کند.
خروجی:
Large screen, fast processor
Lightweight, powerful

پست ۱۷۴ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۵
کنترل Quote در CSV با quoting
در پست قبل دیدیم که Python چگونه داده‌هایی را که شامل کاما یا " هستند، در CSV مدیریت می‌کند.
حالا می‌توانیم مشخص کنیم چه زمانی مقدارها داخل Quote قرار بگیرند.
برای این کار از پارامتر:
quoting

استفاده می‌کنیم.
🔹 csv.QUOTE_MINIMAL
حالت پیش‌فرض csv است.
Python فقط زمانی از Quote استفاده می‌کند که لازم باشد.
import csv

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.writer(
file,
quoting=csv.QUOTE_MINIMAL
)

writer.writerow(["Laptop", 1200])
writer.writerow(["Mouse", "Fast, wireless"])

خروجی:
Laptop,1200
Mouse,"Fast, wireless"

چون ردیف اول به Quote نیاز ندارد، اما ردیف دوم شامل کاماست.
🔹 csv.QUOTE_ALL
با این حالت، تمام مقدارها داخل Quote نوشته می‌شوند:
import csv

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.writer(
file,
quoting=csv.QUOTE_ALL
)

writer.writerow(["Laptop", 1200])
writer.writerow(["Mouse", "Fast, wireless"])

خروجی:
"Laptop","1200"
"Mouse","Fast, wireless"

🔹 csv.QUOTE_NONNUMERIC
در این حالت مقدارهای متنی Quote می‌شوند و مقدارهای عددی بدون Quote نوشته می‌شوند:
import csv

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.writer(
file,
quoting=csv.QUOTE_NONNUMERIC
)

writer.writerow(["Laptop", 1200])

خروجی:
"Laptop",1200

🔹 csv.QUOTE_NONE
در این حالت Python به‌صورت معمول Quote اضافه نمی‌کند.
اگر داده شامل delimiter باشد، باید آن را به شکل مناسب Escape کنیم؛ در غیر این صورت ممکن است خطا ایجاد شود.
برای CSVهای معمولی، معمولاً نیازی به استفاده از این حالت نداریم.
🧠 مقایسه
QUOTE_MINIMAL
→ فقط وقتی لازم باشد Quote می‌گذارد.

QUOTE_ALL
→ همه مقدارها را Quote می‌کند.

QUOTE_NONNUMERIC
→ مقدارهای غیرعددی را Quote می‌کند.

QUOTE_NONE
→ Quote خودکار را غیرفعال می‌کند.

⚠️ نکته مهم
در بیشتر پروژه‌ها لازم نیست quoting را دستی تنظیم کنیم.
حالت پیش‌فرض:
csv.QUOTE_MINIMAL

برای بسیاری از فایل‌های CSV کافی است.
تنظیم quoting زمانی مفید است که فرمت خروجی CSV مشخص و اجباری باشد.
🎯 تمرین
کد زیر را تغییر بده تا تمام مقدارهای CSV داخل Quote نوشته شوند:
import csv

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.writer(file)

writer.writerow(["Laptop", 1200])
writer.writerow(["Mouse", 25])

فایل خروجی باید شبیه این باشد:
"Laptop","1200"
"Mouse","25"

پست ۱۷۵ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۶
مدیریت فایل‌های CSV با DictReader و DictWriter در یک برنامه کامل
تا اینجا یاد گرفتیم:
CSV را بخوانیم.
داده جدید اضافه کنیم.
داده‌ها را فیلتر کنیم.
رکوردها را ویرایش و حذف کنیم.
delimiter و quoting را مدیریت کنیم.
حالا یک برنامه کوچک می‌سازیم که چند عملیات را روی یک فایل CSV انجام دهد.
🔹 ساخت فایل اولیه
ابتدا یک فایل به نام:
products.csv

می‌سازیم:
import csv

products = [
{"name": "Laptop", "price": 1200, "stock": 5},
{"name": "Mouse", "price": 25, "stock": 20},
{"name": "Keyboard", "price": 70, "stock": 10}
]

with open(
"products.csv",
"w",
newline="",
encoding="utf-8"
) as file:

writer = csv.DictWriter(
file,
fieldnames=["name", "price", "stock"]
)

writer.writeheader()
writer.writerows(products)

🔹 خواندن اطلاعات
حالا فایل را می‌خوانیم:
with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for product in reader:
print(product)

هر ردیف به شکل یک Dictionary در اختیار ما قرار می‌گیرد.
مثلاً:
{
'name': 'Laptop',
'price': '1200',
'stock': '5'
}

⚠️ توجه کن که مقدارهای CSV هنگام خواندن معمولاً str هستند.
🔹 تبدیل مقدارهای عددی
اگر بخواهیم روی قیمت محاسبه انجام دهیم:
with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for product in reader:
price = float(product["price"])
stock = int(product["stock"])

print(
product["name"],
price,
stock
)

🔹 فیلتر کردن محصولات
مثلاً فقط محصولاتی را نمایش دهیم که موجود هستند:
with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for product in reader:
if int(product["stock"]) > 0:
print(product["name"])

خروجی:
Laptop
Mouse
Keyboard

🔹 یک نکته مهم درباره reader
این دو روش را با هم اشتباه نکن:
csv.reader()

هر ردیف را به شکل List می‌دهد:
["Laptop", "1200", "5"]

اما:
csv.DictReader()

هر ردیف را به شکل Dictionary می‌دهد:
{
"name": "Laptop",
"price": "1200",
"stock": "5"
}

برای فایل‌هایی که ستون‌های مشخص دارند، DictReader معمولاً خواندن و کار با داده‌ها را واضح‌تر می‌کند.
🧠 خلاصه
DictReader
↓
CSV → Dictionary

DictWriter
↓
Dictionary → CSV

و اگر مقدار عددی باشد:
int(product["stock"])
float(product["price"])

چون CSV خودش نوع داده‌های Python را حفظ نمی‌کند و مقادیر را هنگام خواندن معمولاً به صورت متن در اختیار ما قرار می‌دهد.
🎯 تمرین
برنامه‌ای بنویس که:
فایل products.csv را با DictReader بخواند.
فقط محصولاتی را نمایش دهد که:
قیمت کمتر از 100 دارند.
موجودی بیشتر از 0 دارند.
قیمت را با float() و موجودی را با int() تبدیل کند.
با این داده‌ها:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10
Monitor,300,0

خروجی باید شامل:
Mouse
Keyboard

باشد.
پست ۱۷۶ از دوره جامع Python 🐍
👍1
🐍 آموزش جامع Python — پست ۱۷۷
مدیریت خطاهای تبدیل داده در CSV
در CSV تقریباً همه مقدارها هنگام خواندن به شکل str در اختیار ما قرار می‌گیرند.
مثلاً:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,unknown,10

اگر بخواهیم price را به float تبدیل کنیم:
price = float(product["price"])

برای مقدار:
unknown

با خطای:
ValueError

مواجه می‌شویم.
🔹 استفاده از try و except
می‌توانیم تبدیل داده را داخل try قرار دهیم:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

for product in reader:

try:
price = float(product["price"])
stock = int(product["stock"])

print(
product["name"],
price,
stock
)

except ValueError:
print(
f"Invalid data: {product['name']}"
)

اگر یکی از مقدارها قابل تبدیل نباشد، برنامه متوقف نمی‌شود و except اجرا می‌شود.
🔹 مثال با داده نامعتبر
فرض کنیم CSV این باشد:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,unknown,10
Monitor,300,0

خروجی:
Laptop 1200.0 5
Mouse 25.0 20
Invalid data: Keyboard
Monitor 300.0 0

پس فقط رکورد نامعتبر رد می‌شود و پردازش بقیه داده‌ها ادامه پیدا می‌کند.
🔹 مدیریت جداگانه قیمت و موجودی
گاهی بهتر است بدانیم کدام ستون مشکل دارد:
try:
price = float(product["price"])
except ValueError:
print(f"Invalid price: {product['name']}")
continue

try:
stock = int(product["stock"])
except ValueError:
print(f"Invalid stock: {product['name']}")
continue

در اینجا:
continue

باعث می‌شود پردازش همین رکورد متوقف شود و حلقه سراغ رکورد بعدی برود.
🔹 بررسی مقدار خالی
ممکن است مقدار یک ستون کاملاً خالی باشد:
name,price,stock
Laptop,,5

در این حالت:
float("")

باعث ValueError می‌شود.
می‌توانیم قبل از تبدیل بررسی کنیم:
price_text = product["price"].strip()

if not price_text:
print(f"Price is missing: {product['name']}")
continue

try:
price = float(price_text)
except ValueError:
print(f"Invalid price: {product['name']}")
continue

⚠️ نکته مهم
برای داده‌های CSV فقط این کافی نیست:
price = float(product["price"])

چون داده ممکن است:
خالی
متنی
اشتباه

باشد.
بهتر است هنگام ورود داده به برنامه، آن را اعتبارسنجی و تبدیل کنیم.
🧠 الگوی پیشنهادی
برای CSV می‌توانیم این الگو را داشته باشیم:
CSV
↓
خواندن داده
↓
بررسی وجود مقدار
↓
تبدیل نوع
↓
مدیریت ValueError
↓
استفاده از داده معتبر

مثلاً:
try:
price = float(product["price"])
except ValueError:
print("Invalid price")
continue

🎯 تمرین
فایل زیر را در نظر بگیر:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,unknown,10
Monitor,,15
Phone,800,invalid

برنامه‌ای بنویس که:
CSV را با DictReader بخواند.
price را به float تبدیل کند.
stock را به int تبدیل کند.
خطاهای ValueError را مدیریت کند.
رکوردهای نامعتبر را رد کند.
فقط محصولات معتبر را چاپ کند.
خروجی معتبر باید شامل:
Laptop
Mouse

باشد.
پست ۱۷۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۸
تشخیص خودکار ساختار CSV با csv.Sniffer
گاهی نمی‌دانیم یک فایل CSV با چه جداکننده‌ای ساخته شده است.
ممکن است فایل با:
,

یا:
;

یا:
|

جدا شده باشد.
در چنین شرایطی می‌توانیم از:
csv.Sniffer

استفاده کنیم.
🔹 تشخیص delimiter
فرض کنیم فایل ما این باشد:
name;price;stock
Laptop;1200;5
Mouse;25;20
Keyboard;70;10

اما نمی‌دانیم جداکننده ; است.
می‌توانیم از Sniffer استفاده کنیم:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

sample = file.read(1024)

dialect = csv.Sniffer().sniff(
sample,
delimiters=",;|"
)

print(dialect.delimiter)

خروجی:
;

Python توانسته جداکننده را از محتوای فایل تشخیص دهد.
🔹 استفاده از جداکننده تشخیص‌داده‌شده
حالا می‌توانیم همان dialect را به DictReader بدهیم:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

sample = file.read(1024)

dialect = csv.Sniffer().sniff(
sample,
delimiters=",;|"
)

file.seek(0)

reader = csv.DictReader(
file,
dialect=dialect
)

for product in reader:
print(product["name"])

خروجی:
Laptop
Mouse
Keyboard

🔹 چرا file.seek(0)؟
در این قسمت:
sample = file.read(1024)

ما ۱۰۲۴ کاراکتر از فایل را می‌خوانیم.
مکان فعلی فایل دیگر ابتدای فایل نیست.
بنابراین:
file.seek(0)

مکان خواندن را به ابتدای فایل برمی‌گرداند.
بعد می‌توانیم فایل را کامل با DictReader بخوانیم.
🔹 تشخیص Header
Sniffer قابلیت دیگری هم دارد.
می‌توانیم از:
has_header()

استفاده کنیم:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

sample = file.read(1024)

has_header = csv.Sniffer().has_header(sample)

print(has_header)

ممکن است خروجی:
True

باشد.
یعنی Sniffer تشخیص داده که احتمالاً فایل دارای Header است.
⚠️ نکته مهم
Sniffer همیشه نمی‌تواند با اطمینان کامل ساختار فایل را تشخیص دهد.
مثلاً اگر فایل خیلی کوچک یا نامنظم باشد، ممکن است تشخیص اشتباه انجام شود.
پس:
csv.Sniffer()

یک ابزار تشخیص احتمالی است، نه تضمینی.
اگر ساختار CSV را از قبل می‌دانیم، بهتر است مستقیماً بنویسیم:
reader = csv.DictReader(
file,
delimiter=";"
)

🧠 خلاصه
csv.Sniffer().sniff()
↓
تشخیص Dialect / delimiter

file.seek(0)
↓
بازگشت به ابتدای فایل

csv.Sniffer().has_header()
↓
تشخیص احتمالی وجود Header

🎯 تمرین
فایل زیر را در نظر بگیر:
name|price|stock
Laptop|1200|5
Mouse|25|20
Keyboard|70|10

برنامه‌ای بنویس که:
فایل را باز کند.
با csv.Sniffer().sniff() جداکننده را تشخیص دهد.
فایل را با seek(0) به ابتدا برگرداند.
با DictReader اطلاعات را بخواند.
نام محصولات را چاپ کند.
خروجی:
Laptop
Mouse
Keyboard

پست ۱۷۸ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۷۹
مثال کامل و مقاوم در برابر خطا برای CSV
حالا چند مفهوم CSV را در یک برنامه واقعی ترکیب می‌کنیم:
بررسی وجود فایل
تشخیص delimiter
بررسی Header
تبدیل price و stock
مدیریت خطاهای تبدیل
رد کردن رکوردهای نامعتبر
🔹 فایل نمونه
name;price;stock
Laptop;1200;5
Mouse;25;20
Keyboard;unknown;10
Monitor;300;invalid
Phone;800;15

🔹 برنامه کامل
import csv
from pathlib import Path


file_path = Path("products.csv")

try:
if not file_path.exists():
raise FileNotFoundError("File not found")

with file_path.open(
"r",
encoding="utf-8",
newline=""
) as file:

sample = file.read(1024)

if not sample.strip():
raise ValueError("CSV file is empty")

try:
dialect = csv.Sniffer().sniff(
sample,
delimiters=",;|"
)
except csv.Error:
print("Could not detect delimiter")
raise SystemExit

file.seek(0)

reader = csv.DictReader(
file,
dialect=dialect
)

required = {"name", "price", "stock"}

if not required.issubset(
set(reader.fieldnames or [])
):
print("Required columns are missing")
raise SystemExit

for row_number, product in enumerate(
reader,
start=2
):
try:
name = product["name"].strip()
price = float(product["price"])
stock = int(product["stock"])

if not name or price < 0 or stock < 0:
raise ValueError("Invalid data")

print(
f"{name} - ${price} - Stock: {stock}"
)

except (ValueError, TypeError):
print(
f"Invalid row: {row_number}"
)

except FileNotFoundError:
print("File not found")

except PermissionError:
print("Permission denied")

except UnicodeDecodeError:
print("Invalid file encoding")

except csv.Error as error:
print(f"CSV error: {error}")

🔹 نتیجه
رکوردهای معتبر پردازش می‌شوند:
Laptop - $1200.0 - Stock: 5
Mouse - $25.0 - Stock: 20
Phone - $800.0 - Stock: 15

و رکوردهای خراب فقط گزارش می‌شوند:
Invalid row: 4
Invalid row: 5

برنامه به خاطر یک رکورد خراب متوقف نمی‌شود.
🧠 الگوی کلی
فایل
↓
بررسی ساختار
↓
خواندن CSV
↓
تبدیل نوع داده
↓
اعتبارسنجی
↓
مدیریت خطا
↓
استفاده از داده معتبر

⚠️ اگر delimiter را از قبل می‌دانیم، بهتر است به‌جای Sniffer مستقیماً آن را مشخص کنیم:
csv.DictReader(file, delimiter=";")

🎯 تمرین
کد را تغییر بده تا ستون category را هم بررسی کند و اگر خالی بود، رکورد را نامعتبر اعلام کند.
پست ۱۷۹ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۸۰
تبدیل CSV به JSON
تا اینجا با خواندن، نوشتن، ویرایش، حذف و اعتبارسنجی داده‌های CSV آشنا شدیم.
حالا می‌خواهیم داده‌های CSV را به JSON تبدیل کنیم.
این کار زمانی مفید است که داده را از یک فایل جدولی به ساختاری مناسب برای برنامه‌ها و APIها منتقل کنیم.
🔹 فایل CSV
فرض کنیم products.csv این باشد:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10

ابتدا CSV را با DictReader می‌خوانیم:
import csv

with open(
"products.csv",
"r",
encoding="utf-8"
) as file:

reader = csv.DictReader(file)

products = list(reader)

حالا:
print(products)

تقریباً:
[
{'name': 'Laptop', 'price': '1200', 'stock': '5'},
{'name': 'Mouse', 'price': '25', 'stock': '20'},
{'name': 'Keyboard', 'price': '70', 'stock': '10'}
]

⚠️ توجه کن که مقدارها هنوز str هستند.
🔹 تبدیل نوع داده
قبل از تبدیل به JSON بهتر است نوع داده‌های عددی را اصلاح کنیم:
for product in products:
product["price"] = float(product["price"])
product["stock"] = int(product["stock"])

حالا می‌توانیم داده را به JSON تبدیل کنیم:
import json

json_data = json.dumps(
products,
indent=4,
ensure_ascii=False
)

print(json_data)

خروجی:
[
{
"name": "Laptop",
"price": 1200.0,
"stock": 5
},
{
"name": "Mouse",
"price": 25.0,
"stock": 20
}
]

🔹 ذخیره JSON در فایل
می‌توانیم نتیجه را مستقیماً در یک فایل ذخیره کنیم:
with open(
"products.json",
"w",
encoding="utf-8"
) as file:

json.dump(
products,
file,
indent=4,
ensure_ascii=False
)

حالا یک فایل به نام:
products.json

داریم.
⚠️ مدیریت خطا
اگر CSV شامل مقدار نامعتبر باشد:
name,price,stock
Laptop,unknown,5

تبدیل:
float("unknown")

باعث ValueError می‌شود.
پس در برنامه واقعی بهتر است:
try:
product["price"] = float(product["price"])
product["stock"] = int(product["stock"])

except ValueError:
print("Invalid product data")

را در نظر بگیریم.
🧠 خلاصه
CSV
↓
DictReader
↓
Dictionary
↓
تبدیل نوع داده
↓
JSON
↓
json.dump()

🎯 تمرین
فایل products.csv را به products.json تبدیل کن.
شرایط:
name به صورت str
price به صورت float
stock به صورت int
رکوردهای دارای داده نامعتبر نادیده گرفته شوند.
پست ۱۸۰ از دوره جامع Python 🐍
🤖 معرفی چند پروژه و ابزار جالب در حوزه AI
اگر به دنبال پروژه‌های جدید و متن‌باز در حوزه هوش مصنوعی هستید، این دو مورد را هم می‌توانید بررسی کنید:
🔹 JEV
🌐 وب‌سایت:
typesafe.ai
JEV یک پروژه/پلتفرم در حوزه AI است که می‌توانید برای آشنایی بیشتر با قابلیت‌ها و نحوه استفاده از آن، وب‌سایت رسمی آن را بررسی کنید.
🔗 لینک:
https://typesafe.ai
🔹 LAYA
یک پروژه متن‌باز مرتبط با اجرای مدل‌های هوش مصنوعی و اکوسیستم MLX.
💻 GitHub:
Laya — GitHub
🤗 Hugging Face:
Laya — Hugging Face
اگر به مدل‌های AI، اجرای مدل‌ها و پروژه‌های متن‌باز علاقه دارید، بررسی Repository و فایل‌های پروژه می‌تواند اطلاعات بیشتری درباره نحوه استفاده و قابلیت‌های آن ارائه دهد.
📌 لینک‌ها
🔹 JEV:
typesafe.ai
🔹 LAYA — GitHub:
mizorewww/laya-mlx
🔹 LAYA — Hugging Face:
aac6fef
اگر پروژه‌های AI متن‌باز و ابزارهای جدید هوش مصنوعی را دنبال می‌کنید، این موارد می‌توانند برای بررسی و یادگیری جالب باشند. 🤖
🐍 آموزش جامع Python — پست ۱۸۱
آشنایی با دیتابیس SQLite در Python
تا اینجا اطلاعات را در فایل‌هایی مثل:
CSV
JSON

ذخیره و مدیریت کردیم.
اما وقتی حجم داده بیشتر شود، جست‌وجو، ویرایش و حذف اطلاعات در فایل‌ها می‌تواند سخت‌تر شود.
اینجاست که Database وارد می‌شود.
یکی از ساده‌ترین دیتابیس‌ها برای شروع در Python، SQLite است.
🔹 SQLite چیست؟
SQLite یک دیتابیس سبک و فایل‌محور است.
برخلاف بعضی دیتابیس‌ها، برای شروع نیاز نداریم یک Server جداگانه نصب و اجرا کنیم.
Python نیز ماژول استاندارد:
sqlite3

را در اختیارمان قرار می‌دهد.
🔹 ساخت اولین دیتابیس
import sqlite3

connection = sqlite3.connect("users.db")

print("Database created")

connection.close()

با اجرای این کد، فایل:
users.db

ایجاد می‌شود.
اگر فایل از قبل وجود داشته باشد، SQLite همان دیتابیس را باز می‌کند.
🔹 Connection چیست؟
این خط:
connection = sqlite3.connect("users.db")

یک Connection به دیتابیس ایجاد می‌کند.
از طریق این Connection می‌توانیم:
دستور SQL اجرا کنیم
داده اضافه کنیم
داده بخوانیم
داده تغییر دهیم
داده حذف کنیم

در پایان نیز بهتر است Connection را ببندیم:
connection.close()

🔹 ساخت Table
برای ذخیره اطلاعات، ابتدا یک جدول ایجاد می‌کنیم.
import sqlite3

connection = sqlite3.connect("users.db")

cursor = connection.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
""")

connection.commit()
connection.close()

در اینجا جدول:
users

ساخته می‌شود.
و سه ستون دارد:
id    → INTEGER
name → TEXT
age → INTEGER

🔹 cursor چیست؟
با:
cursor = connection.cursor()

یک Cursor ایجاد می‌کنیم.
Cursor برای اجرای دستورات SQL استفاده می‌شود:
cursor.execute(...)

مثلاً:
cursor.execute("SELECT * FROM users")

⚠️ commit() را فراموش نکن
بعد از تغییرات دیتابیس معمولاً باید تغییرات را ثبت کنیم:
connection.commit()

مثلاً هنگام:
INSERT
UPDATE
DELETE

استفاده از commit() اهمیت دارد.
🧠 خلاصه
sqlite3.connect()
↓
Connection
↓
Cursor
↓
cursor.execute()
↓
connection.commit()
↓
connection.close()

در پست بعد یاد می‌گیریم چگونه با INSERT اطلاعات را داخل SQLite ذخیره کنیم.
🎯 تمرین
برنامه‌ای بنویس که:
یک دیتابیس به نام school.db ایجاد کند.
جدولی به نام students بسازد.
جدول شامل این ستون‌ها باشد:
id     → INTEGER PRIMARY KEY
name → TEXT
score → REAL

از:
CREATE TABLE IF NOT EXISTS

استفاده کن.
پست ۱۸۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۸۲
درج چند رکورد با executemany()
در پست قبل یاد گرفتیم با INSERT یک رکورد را داخل SQLite ذخیره کنیم.
اما اگر بخواهیم چند رکورد را هم‌زمان اضافه کنیم، استفاده از چندین execute() کار چندان مناسبی نیست.
برای این کار می‌توانیم از:
executemany()

استفاده کنیم.
🔹 مثال ساده
فرض کنیم جدول زیر را داریم:
import sqlite3

connection = sqlite3.connect("users.db")
cursor = connection.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
""")

حالا چند کاربر داریم:
users = [
("Ali", 25),
("Sara", 22),
("Reza", 30)
]

می‌توانیم همه را با یک دستور درج کنیم:
cursor.executemany(
"INSERT INTO users (name, age) VALUES (?, ?)",
users
)

connection.commit()

🔹 executemany() چگونه کار می‌کند؟
این کد:
cursor.executemany(
"INSERT INTO users (name, age) VALUES (?, ?)",
users
)

عبارت SQL را برای هر عضو users اجرا می‌کند:
("Ali", 25)
("Sara", 22)
("Reza", 30)

یعنی تقریباً مثل این است:
cursor.execute(
"INSERT INTO users (name, age) VALUES (?, ?)",
("Ali", 25)
)

cursor.execute(
"INSERT INTO users (name, age) VALUES (?, ?)",
("Sara", 22)
)

cursor.execute(
"INSERT INTO users (name, age) VALUES (?, ?)",
("Reza", 30)
)

اما executemany() برای درج مجموعه‌ای از رکوردها مناسب‌تر و خواناتر است.
🔹 مثال کامل
import sqlite3

connection = sqlite3.connect("users.db")
cursor = connection.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
""")

users = [
("Ali", 25),
("Sara", 22),
("Reza", 30)
]

cursor.executemany(
"INSERT INTO users (name, age) VALUES (?, ?)",
users
)

connection.commit()
connection.close()

بعد از اجرای برنامه، سه رکورد به جدول اضافه می‌شود.
🔹 استفاده از ?
همانند execute() بهتر است مقدارها را با Parameterized Query ارسال کنیم:
"INSERT INTO users (name, age) VALUES (?, ?)"

و داده‌ها جداگانه قرار بگیرند:
users = [
("Ali", 25),
("Sara", 22)
]

این روش هم خواناتر است و هم از قرار دادن مستقیم مقدارها داخل SQL جلوگیری می‌کند.
🔹 executemany() با lastrowid
یک نکته مهم:
cursor.lastrowid

برای درج چند رکورد، روش مناسبی برای دریافت ID همه رکوردهای جدید نیست.
اگر به ID رکوردهای ایجادشده نیاز دارید، بهتر است بعداً آن‌ها را با یک Query مناسب از دیتابیس دریافت کنید.
⚠️ نکته مهم
ساختار داده‌ها باید با تعداد ?ها هماهنگ باشد.
مثلاً:
"VALUES (?, ?)"

یعنی هر رکورد باید دو مقدار داشته باشد:
("Ali", 25)

اما این اشتباه است:
("Ali", 25, "Extra")

چون تعداد مقادیر با Placeholderها هماهنگ نیست.
🧠 خلاصه
execute()      → اجرای یک عملیات
executemany() → اجرای یک عملیات برای چند مجموعه داده

الگوی اصلی:
cursor.executemany(
"INSERT INTO table_name (column1, column2) VALUES (?, ?)",
data
)

🎯 تمرین
جدول زیر را در نظر بگیر:
students

با ستون‌های:
id     → INTEGER PRIMARY KEY
name → TEXT
score → REAL

با استفاده از executemany() این سه دانش‌آموز را اضافه کن:
students = [
("Ali", 18.5),
("Sara", 19.0),
("Reza", 17.25)
]

در پایان commit() را اجرا کن.
پست ۱۸۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۸۳
خواندن اطلاعات از SQLite با SELECT
تا اینجا یاد گرفتیم چگونه اطلاعات را با INSERT و executemany() داخل SQLite ذخیره کنیم.
حالا می‌خواهیم اطلاعات ذخیره‌شده را بخوانیم.
برای این کار از دستور SQL زیر استفاده می‌کنیم:
SELECT

🔹 خواندن همه رکوردها
فرض کنیم جدول students را داریم:
import sqlite3

connection = sqlite3.connect("school.db")
cursor = connection.cursor()

cursor.execute("SELECT * FROM students")

rows = cursor.fetchall()

for row in rows:
print(row)

connection.close()

مثلاً خروجی:
(1, 'Ali', 18.5)
(2, 'Sara', 19.0)
(3, 'Reza', 17.25)

هر رکورد به شکل یک tuple برگردانده می‌شود.
🔹 fetchall() چیست؟
بعد از اجرای:
cursor.execute("SELECT * FROM students")

می‌توانیم با:
rows = cursor.fetchall()

تمام رکوردهای نتیجه را دریافت کنیم.
مثلاً:
[
(1, 'Ali', 18.5),
(2, 'Sara', 19.0),
(3, 'Reza', 17.25)
]

🔹 خواندن فقط یک رکورد
اگر فقط یک رکورد می‌خواهیم، می‌توانیم از:
row = cursor.fetchone()

استفاده کنیم:
cursor.execute("SELECT * FROM students")

row = cursor.fetchone()

print(row)

خروجی:
(1, 'Ali', 18.5)

fetchone() هر بار یک رکورد از نتیجه را برمی‌گرداند.
🔹 دریافت چند رکورد با fetchmany()
اگر تعداد مشخصی رکورد بخواهیم:
cursor.execute("SELECT * FROM students")

rows = cursor.fetchmany(2)

print(rows)

مثلاً:
[(1, 'Ali', 18.5), (2, 'Sara', 19.0)]

🔹 انتخاب ستون‌های مشخص
لازم نیست همیشه از * استفاده کنیم.
مثلاً فقط نام و نمره:
cursor.execute(
"SELECT name, score FROM students"
)

rows = cursor.fetchall()

for name, score in rows:
print(name, score)

خروجی:
Ali 18.5
Sara 19.0
Reza 17.25

⚠️ نکته مهم
SELECT اطلاعات را تغییر نمی‌دهد.
یعنی:
SELECT → خواندن
INSERT → اضافه کردن
UPDATE → تغییر دادن
DELETE → حذف کردن

🧠 خلاصه
execute("SELECT ...")
↓
fetchone()
fetchmany()
fetchall()

سه روش اصلی دریافت نتیجه:
cursor.fetchone()
cursor.fetchmany(n)
cursor.fetchall()

🎯 تمرین
از جدول students فقط name و score را دریافت کن و نام و نمره هر دانش‌آموز را چاپ کن.
جدول:
id | name | score

خروجی باید چیزی شبیه این باشد:
Ali 18.5
Sara 19.0
Reza 17.25

پست ۱۸۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۸۴
جست‌وجو و فیلتر داده‌ها در SQLite با WHERE
در پست قبل یاد گرفتیم با SELECT اطلاعات را از SQLite بخوانیم.
اما معمولاً نمی‌خواهیم همه رکوردها را دریافت کنیم.
مثلاً می‌خواهیم فقط دانش‌آموزانی را پیدا کنیم که نمره‌شان بیشتر از 18 است.
برای این کار از:
WHERE

استفاده می‌کنیم.
🔹 یک شرط ساده
import sqlite3

connection = sqlite3.connect("school.db")
cursor = connection.cursor()

cursor.execute(
"SELECT * FROM students WHERE score >= ?",
(18,)
)

rows = cursor.fetchall()

for row in rows:
print(row)

connection.close()

اگر داده‌ها این باشند:
(1, 'Ali', 18.5)
(2, 'Sara', 19.0)
(3, 'Reza', 17.25)

خروجی:
(1, 'Ali', 18.5)
(2, 'Sara', 19.0)

🔹 جست‌وجو بر اساس متن
مثلاً فقط کاربری با نام Ali:
cursor.execute(
"SELECT * FROM students WHERE name = ?",
("Ali",)
)

row = cursor.fetchone()

print(row)

نکته مهم: ( "Ali", ) یک tuple تک‌عضوی است.
🔹 استفاده از AND
می‌توانیم چند شرط داشته باشیم:
cursor.execute(
"""
SELECT * FROM students
WHERE score >= ? AND name = ?
""",
(18, "Ali")
)

در اینجا هر دو شرط باید برقرار باشند.
🔹 استفاده از OR
اگر کافی باشد یکی از شرط‌ها برقرار باشد:
cursor.execute(
"""
SELECT * FROM students
WHERE name = ? OR name = ?
""",
("Ali", "Sara")
)

در این حالت دانش‌آموزانی با نام Ali یا Sara پیدا می‌شوند.
🔹 WHERE فقط برای SELECT نیست
WHERE در دستورات دیگری مثل:
UPDATE
DELETE

هم استفاده می‌شود.
مثلاً بعداً می‌توانیم فقط نمره یک دانش‌آموز مشخص را تغییر دهیم:
UPDATE students
SET score = 20
WHERE name = 'Ali';

یا فقط یک رکورد مشخص را حذف کنیم:
DELETE FROM students
WHERE name = 'Ali';

⚠️ نکته امنیتی
مقدارهای دریافت‌شده از کاربر را مستقیماً داخل SQL قرار نده.
❌ روش نامناسب:
name = input("Name: ")

cursor.execute(
f"SELECT * FROM students WHERE name = '{name}'"
)

✅ روش مناسب:
name = input("Name: ")

cursor.execute(
"SELECT * FROM students WHERE name = ?",
(name,)
)

با ? از Parameterized Query استفاده می‌کنیم.
🧠 خلاصه
SELECT → خواندن داده
WHERE → فیلتر کردن داده
AND → هر دو شرط
OR → حداقل یکی از شرط‌ها
? → پارامتر امن

الگوی اصلی:
cursor.execute(
"SELECT * FROM students WHERE score >= ?",
(18,)
)

🎯 تمرین
از جدول students فقط دانش‌آموزانی را پیدا کن که:
score >= 18

و سپس فقط name و score آن‌ها را چاپ کن.
خروجی مثلاً:
Ali 18.5
Sara 19.0

پست ۱۸۴ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۸۵
مرتب‌سازی و محدود کردن نتایج با ORDER BY و LIMIT
در پست قبل یاد گرفتیم با WHERE اطلاعات موردنظرمان را فیلتر کنیم.
حالا می‌خواهیم نتیجه‌ها را:
مرتب کنیم.
تعداد نتیجه‌ها را محدود کنیم.
برای این کار از ORDER BY و LIMIT استفاده می‌کنیم.
🔹 مرتب‌سازی با ORDER BY
فرض کنیم می‌خواهیم دانش‌آموزان را بر اساس نمره مرتب کنیم:
import sqlite3

connection = sqlite3.connect("school.db")
cursor = connection.cursor()

cursor.execute("""
SELECT name, score
FROM students
ORDER BY score
""")

rows = cursor.fetchall()

for row in rows:
print(row)

connection.close()

به‌صورت پیش‌فرض مرتب‌سازی صعودی (ASC) است:
17.25
18.5
19.0

🔹 مرتب‌سازی نزولی با DESC
اگر بخواهیم بالاترین نمره ابتدا نمایش داده شود:
cursor.execute("""
SELECT name, score
FROM students
ORDER BY score DESC
""")

نتیجه:
Sara 19.0
Ali 18.5
Reza 17.25

پس:
ASC  → صعودی
DESC → نزولی

🔹 مرتب‌سازی بر اساس چند ستون
می‌توانیم چند ستون را هم مشخص کنیم:
cursor.execute("""
SELECT name, score
FROM students
ORDER BY score DESC, name ASC
""")

ابتدا بر اساس score مرتب می‌شود.
اگر چند رکورد نمره یکسان داشته باشند، name برای مرتب‌سازی بعدی استفاده می‌شود.
🔹 محدود کردن نتایج با LIMIT
فرض کنیم فقط می‌خواهیم سه دانش‌آموز اول را دریافت کنیم:
cursor.execute("""
SELECT name, score
FROM students
ORDER BY score DESC
LIMIT 3
""")

در اینجا ابتدا نمره‌ها از بیشترین به کمترین مرتب می‌شوند و سپس فقط ۳ نتیجه برگردانده می‌شود.
🔥 پیدا کردن بالاترین نمره
ترکیب ORDER BY و LIMIT کاربرد زیادی دارد:
cursor.execute("""
SELECT name, score
FROM students
ORDER BY score DESC
LIMIT 1
""")

top_student = cursor.fetchone()

print(top_student)

مثلاً:
('Sara', 19.0)

🔹 LIMIT بدون ORDER BY
این کد:
SELECT * FROM students LIMIT 3

فقط سه رکورد را درخواست می‌کند؛ اما نباید فرض کنیم این سه رکورد حتماً «اولین» یا «بهترین» رکوردها هستند.
اگر ترتیب مشخصی می‌خواهیم، بهتر است ORDER BY را هم مشخص کنیم.
🧠 خلاصه
ORDER BY → مرتب‌سازی
ASC → صعودی
DESC → نزولی
LIMIT → محدود کردن تعداد نتایج

مثلاً:
cursor.execute("""
SELECT name, score
FROM students
WHERE score >= ?
ORDER BY score DESC
LIMIT 3
""", (18,))

یعنی:
1. فقط نمره‌های ۱۸ و بالاتر
2. مرتب‌سازی از بیشترین به کمترین
3. فقط ۳ نتیجه

🎯 تمرین
از جدول students، دو دانش‌آموز با بالاترین نمره را پیدا کن.
شرایط:
ORDER BY → score نزولی
LIMIT → 2

پست ۱۸۵ از دوره جامع Python 🐍
🤖 مقایسه Claude و ChatGPT در کدنویسی Python
برای یک آزمایش، دقیقاً یک مسئله و یک درخواست یکسان را به Claude و ChatGPT دادم و از هر دو خواستم راه‌حل را با Python پیاده‌سازی کنند.
در تصاویر، خروجی و کدی که هر کدام تولید کرده‌اند را می‌توانید ببینید. 👇
در این مقایسه می‌شود مواردی مثل:
🔹 ساختار و خوانایی کد
🔹 منطق حل مسئله
🔹 رعایت اصول Python
🔹 مدیریت خطاها
🔹 سادگی و قابل‌فهم بودن کد
را بررسی کرد.
هدف این مقایسه این نیست که بگوییم کدام مدل همیشه بهتر است؛ بلکه می‌خواهیم ببینیم برای یک مسئله مشخص، هر مدل چه رویکردی برای حل آن انتخاب می‌کند.
حالا شما کدها را ببینید و نظرتان را بگویید:
به‌نظر شما کدام خروجی بهتر و حرفه‌ای‌تر نوشته شده؟
🟣 Claude
🔵 ChatGPT

اولی با Claude
دومی با ChatGPT

⚠️ این تصاویر شبیه سازی شده هستند

پست مقایسه مدل های هوش مصنوعی🐍