🐍 آموزش جامع Python — پست ۱۵۸
اعتبارسنجی لیستها و تعداد اعضا در JSON
در پست قبل یاد گرفتیم چطور کلیدهای اجباری و نوع دادههای تودرتو را بررسی کنیم.
حالا یک مرحله جلوتر میرویم و یاد میگیریم چطور لیستها و تعداد اعضای آنها را اعتبارسنجی کنیم.
🔹 بررسی اینکه مقدار یک لیست است
فرض کنیم JSON ما شامل لیستی از کاربران است:
ابتدا نوع
🔹 بررسی خالی نبودن لیست
گاهی وجود لیست کافی نیست و باید حداقل یک عضو داشته باشد:
یا به شکل کوتاهتر:
اما روش اول واضحتر است، چون مشخص میکند دقیقاً چه چیزی را بررسی میکنیم.
🔹 تعیین حداقل تعداد اعضا
مثلاً میخواهیم حداقل ۲ کاربر وجود داشته باشد:
اگر فقط یک کاربر داشته باشیم:
خروجی:
🔹 تعیین حداکثر تعداد اعضا
گاهی تعداد اعضا نباید بیشتر از یک مقدار مشخص باشد:
پس میتوانیم یک محدوده تعیین کنیم:
یعنی:
🔹 اعتبارسنجی اعضای لیست
فقط تعداد اعضا کافی نیست.
هر عضو هم باید ساختار درستی داشته باشد:
اینجا برای هر کاربر بررسی میکنیم:
🔥 ترکیب همه بررسیها
خروجی:
⚠️ نکته مهم
در اعتبارسنجی یک لیست، معمولاً چند مرحله داریم:
این الگو در کار با JSONهای واقعی بسیار کاربردی است.
🧠 خلاصه
بررسی نوع لیست.
تعداد اعضای لیست.
تعیین محدوده مجاز.
و با
🎯 تمرین
داده زیر را اعتبارسنجی کن:
قوانین:
اگر همه موارد درست بودند:
در غیر این صورت:
پست ۱۵۸ از دوره جامع Python 🐍
اعتبارسنجی لیستها و تعداد اعضا در JSON
در پست قبل یاد گرفتیم چطور کلیدهای اجباری و نوع دادههای تودرتو را بررسی کنیم.
حالا یک مرحله جلوتر میرویم و یاد میگیریم چطور لیستها و تعداد اعضای آنها را اعتبارسنجی کنیم.
🔹 بررسی اینکه مقدار یک لیست است
فرض کنیم JSON ما شامل لیستی از کاربران است:
data = {
"users": [
{"name": "Ali", "age": 25},
{"name": "Sara", "age": 22}
]
}ابتدا نوع
users را بررسی میکنیم:users = data.get("users")
if isinstance(users, list):
print("Users is valid")
else:
print("Invalid users")🔹 بررسی خالی نبودن لیست
گاهی وجود لیست کافی نیست و باید حداقل یک عضو داشته باشد:
if isinstance(users, list) and len(users) > 0:
print("Users list is not empty")
یا به شکل کوتاهتر:
if users:
print("Users list is not empty")
اما روش اول واضحتر است، چون مشخص میکند دقیقاً چه چیزی را بررسی میکنیم.
🔹 تعیین حداقل تعداد اعضا
مثلاً میخواهیم حداقل ۲ کاربر وجود داشته باشد:
if isinstance(users, list) and len(users) >= 2:
print("Valid users")
else:
print("Not enough users")
اگر فقط یک کاربر داشته باشیم:
users = [
{"name": "Ali", "age": 25}
]
خروجی:
Not enough users
🔹 تعیین حداکثر تعداد اعضا
گاهی تعداد اعضا نباید بیشتر از یک مقدار مشخص باشد:
if isinstance(users, list) and len(users) <= 100:
print("Users count is valid")
else:
print("Too many users")
پس میتوانیم یک محدوده تعیین کنیم:
if isinstance(users, list) and 1 <= len(users) <= 100:
print("Valid users")
یعنی:
حداقل ۱ عضو
حداکثر ۱۰۰ عضو
🔹 اعتبارسنجی اعضای لیست
فقط تعداد اعضا کافی نیست.
هر عضو هم باید ساختار درستی داشته باشد:
for user in users:
if not isinstance(user, dict):
print("Invalid user")
continue
if "name" not in user or "age" not in user:
print("Missing required key")
continue
print("Valid user")
اینجا برای هر کاربر بررسی میکنیم:
آیا dict است؟
آیا name دارد؟
آیا age دارد؟
🔥 ترکیب همه بررسیها
data = {
"users": [
{"name": "Ali", "age": 25},
{"name": "Sara", "age": 22}
]
}
users = data.get("users")
if not isinstance(users, list):
print("Invalid users")
elif not 1 <= len(users) <= 100:
print("Invalid users count")
else:
valid = True
for user in users:
if not isinstance(user, dict):
valid = False
break
if not all(key in user for key in ["name", "age"]):
valid = False
break
if not isinstance(user["name"], str):
valid = False
break
if not isinstance(user["age"], int):
valid = False
break
if valid:
print("Users data is valid")
else:
print("Invalid user data")خروجی:
Users data is valid
⚠️ نکته مهم
در اعتبارسنجی یک لیست، معمولاً چند مرحله داریم:
لیست وجود دارد؟
↓
نوع آن list است؟
↓
تعداد اعضا مجاز است؟
↓
هر عضو ساختار درستی دارد؟
↓
کلیدهای اجباری وجود دارند؟
↓
نوع مقادیر درست است؟
این الگو در کار با JSONهای واقعی بسیار کاربردی است.
🧠 خلاصه
isinstance(users, list)
بررسی نوع لیست.
len(users)
تعداد اعضای لیست.
1 <= len(users) <= 100
تعیین محدوده مجاز.
و با
for میتوانیم تکتک اعضای لیست را اعتبارسنجی کنیم.🎯 تمرین
داده زیر را اعتبارسنجی کن:
data = {
"products": [
{"name": "Laptop", "price": 1200},
{"name": "Mouse", "price": 25}
]
}قوانین:
products → باید list باشد
تعداد محصولات → بین 1 تا 50
هر محصول → باید dict باشد
name و price → کلیدهای اجباری
name → باید str باشد
price → باید int یا float باشد
اگر همه موارد درست بودند:
Products are valid
در غیر این صورت:
Invalid products
پست ۱۵۸ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۵۹
اعتبارسنجی مقدارهای عددی در JSON
در پست قبل ساختار لیستها و تعداد اعضای آنها را بررسی کردیم.
حالا میخواهیم علاوه بر نوع داده، خودِ محدوده و مقدار عددی را هم اعتبارسنجی کنیم.
🔹 بررسی حداقل و حداکثر مقدار
فرض کنیم اطلاعات یک محصول را داریم:
میتوانیم مشخص کنیم قیمت باید بین
خروجی:
🔹 اعتبارسنجی تعداد موجودی
مثلاً موجودی نباید منفی باشد:
پس:
🔹 چرا ابتدا نوع را بررسی میکنیم؟
این روش مناسب نیست:
چون اگر مقدار
مقایسه با عدد میتواند باعث خطا شود.
بهتر است ابتدا نوع را بررسی کنیم:
به دلیل Short-Circuit، اگر
🔹 تعیین محدوده برای چند مقدار
خروجی:
⚠️ یک نکته مهم درباره
در Python:
نتیجه:
چون
بنابراین اگر میخواهیم مقدار واقعاً عددی باشد و
🔹 اعتبارسنجی مقدارهای اعشاری
مثلاً درصد تخفیف:
مقدارهای:
🧠 الگوی کلی
برای یک مقدار عددی معمولاً این ترتیب را داریم:
مثلاً:
و سپس:
🎯 تمرین
داده زیر را اعتبارسنجی کن:
قوانین:
اگر همه معتبر بودند:
در غیر این صورت:
پست ۱۵۹ از دوره جامع Python 🐍
اعتبارسنجی مقدارهای عددی در JSON
در پست قبل ساختار لیستها و تعداد اعضای آنها را بررسی کردیم.
حالا میخواهیم علاوه بر نوع داده، خودِ محدوده و مقدار عددی را هم اعتبارسنجی کنیم.
🔹 بررسی حداقل و حداکثر مقدار
فرض کنیم اطلاعات یک محصول را داریم:
product = {
"name": "Laptop",
"price": 1200,
"stock": 15
}میتوانیم مشخص کنیم قیمت باید بین
1 تا 10000 باشد:price = product.get("price")
if isinstance(price, (int, float)) and 1 <= price <= 10000:
print("Valid price")
else:
print("Invalid price")خروجی:
Valid price
🔹 اعتبارسنجی تعداد موجودی
مثلاً موجودی نباید منفی باشد:
stock = product.get("stock")
if isinstance(stock, int) and stock >= 0:
print("Valid stock")
else:
print("Invalid stock")پس:
stock = 15 → معتبر
stock = 0 → معتبر
stock = -5 → نامعتبر
🔹 چرا ابتدا نوع را بررسی میکنیم؟
این روش مناسب نیست:
if product["price"] > 0:
print("Valid")
چون اگر مقدار
price رشته باشد:price = "1200"
مقایسه با عدد میتواند باعث خطا شود.
بهتر است ابتدا نوع را بررسی کنیم:
price = product.get("price")
if isinstance(price, (int, float)) and price > 0:
print("Valid")به دلیل Short-Circuit، اگر
isinstance() برابر False باشد، بخش دوم بررسی نمیشود.🔹 تعیین محدوده برای چند مقدار
product = {
"name": "Laptop",
"price": 1200,
"stock": 15,
"discount": 20
}
price = product.get("price")
stock = product.get("stock")
discount = product.get("discount")
if not isinstance(price, (int, float)) or not 1 <= price <= 10000:
print("Invalid price")
elif not isinstance(stock, int) or not 0 <= stock <= 1000:
print("Invalid stock")
elif not isinstance(discount, (int, float)) or not 0 <= discount <= 100:
print("Invalid discount")
else:
print("Product data is valid")خروجی:
Product data is valid
⚠️ یک نکته مهم درباره
boolدر Python:
isinstance(True, int)
نتیجه:
True
چون
bool زیرکلاسی از int است.بنابراین اگر میخواهیم مقدار واقعاً عددی باشد و
True یا False پذیرفته نشود، بهتر است بررسی دقیقتری انجام دهیم:if isinstance(price, (int, float)) and not isinstance(price, bool):
print("Numeric")
🔹 اعتبارسنجی مقدارهای اعشاری
مثلاً درصد تخفیف:
discount = 25.5
if (
isinstance(discount, (int, float))
and not isinstance(discount, bool)
and 0 <= discount <= 100
):
print("Valid discount")
مقدارهای:
0 → معتبر
25.5 → معتبر
100 → معتبر
-5 → نامعتبر
120 → نامعتبر
🧠 الگوی کلی
برای یک مقدار عددی معمولاً این ترتیب را داریم:
نوع داده
↓
عدد بودن واقعی
↓
حداقل مقدار
↓
حداکثر مقدار
مثلاً:
isinstance(value, (int, float))
و سپس:
min_value <= value <= max_value
🎯 تمرین
داده زیر را اعتبارسنجی کن:
product = {
"name": "Phone",
"price": 850,
"stock": 20,
"discount": 15
}قوانین:
name → باید str باشد
price → عدد بین 1 تا 10000
stock → عدد صحیح بین 0 تا 1000
discount → عدد بین 0 تا 100
اگر همه معتبر بودند:
Product is valid
در غیر این صورت:
Invalid product
پست ۱۵۹ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۶۰
اعتبارسنجی رشتهها در JSON
در پست قبل مقدارهای عددی مثل
حالا نوبت رشتهها (
در دادههای واقعی معمولاً لازم است بررسی کنیم:
مقدار واقعاً رشته باشد.
خالی نباشد.
طول آن در محدوده مشخص باشد.
فقط شامل مقدارهای مجاز باشد.
🔹 بررسی نوع رشته
🔹 جلوگیری از رشته خالی
این مقدار:
رشته است، اما ممکن است برای برنامه ما معتبر نباشد.
بنابراین:
🔹 بررسی طول رشته
مثلاً نام کاربر باید بین ۳ تا ۳۰ کاراکتر باشد:
🔹 محدود کردن مقدار به گزینههای مشخص
گاهی رشته باید فقط یکی از چند مقدار مشخص باشد.
مثلاً زبان برنامه:
خروجی:
اگر:
باشد:
🔥 ترکیب چند قانون
فرض کنیم اطلاعات محصول را داریم:
میخواهیم:
خروجی:
⚠️ نکته مهم
در اعتبارسنجی رشتهها،
مثلاً:
این مقدار:
را
پس باید قوانین مربوط به خود مقدار را هم بررسی کنیم:
🧠 خلاصه
بررسی نوع.
بررسی اینکه رشته فقط شامل فاصله نباشد.
بررسی طول.
بررسی مقدارهای مجاز.
🎯 تمرین
داده زیر را اعتبارسنجی کن:
قوانین:
اگر همه موارد معتبر بودند:
در غیر این صورت:
پست ۱۶۰ از دوره جامع Python 🐍
اعتبارسنجی رشتهها در JSON
در پست قبل مقدارهای عددی مثل
price، stock و discount را اعتبارسنجی کردیم.حالا نوبت رشتهها (
str) است.در دادههای واقعی معمولاً لازم است بررسی کنیم:
مقدار واقعاً رشته باشد.
خالی نباشد.
طول آن در محدوده مشخص باشد.
فقط شامل مقدارهای مجاز باشد.
🔹 بررسی نوع رشته
name = "Laptop"
if isinstance(name, str):
print("Valid name")
else:
print("Invalid name")
🔹 جلوگیری از رشته خالی
این مقدار:
name = ""
رشته است، اما ممکن است برای برنامه ما معتبر نباشد.
if isinstance(name, str) and name.strip():
print("Valid name")
else:
print("Invalid name")
strip() فاصلههای ابتدا و انتهای متن را حذف میکند.بنابراین:
"Ali" → معتبر
" Ali " → معتبر
"" → نامعتبر
" " → نامعتبر
🔹 بررسی طول رشته
مثلاً نام کاربر باید بین ۳ تا ۳۰ کاراکتر باشد:
username = "Ali"
if (
isinstance(username, str)
and 3 <= len(username.strip()) <= 30
):
print("Valid username")
else:
print("Invalid username")
🔹 محدود کردن مقدار به گزینههای مشخص
گاهی رشته باید فقط یکی از چند مقدار مشخص باشد.
مثلاً زبان برنامه:
language = "fa"
allowed_languages = {"fa", "en", "ar"}
if language in allowed_languages:
print("Valid language")
else:
print("Invalid language")
خروجی:
Valid language
اگر:
language = "de"
باشد:
Invalid language
🔥 ترکیب چند قانون
فرض کنیم اطلاعات محصول را داریم:
product = {
"name": "Laptop",
"category": "electronics"
}میخواهیم:
name → رشته و غیرخالی
category → یکی از گزینههای مجاز
name = product.get("name")
category = product.get("category")
allowed_categories = {
"electronics",
"clothing",
"books"
}
if not isinstance(name, str) or not name.strip():
print("Invalid name")
elif category not in allowed_categories:
print("Invalid category")
else:
print("Product strings are valid")خروجی:
Product strings are valid
⚠️ نکته مهم
در اعتبارسنجی رشتهها،
isinstance() بهتنهایی کافی نیست.مثلاً:
value = ""
این مقدار:
isinstance(value, str)
را
True میکند، اما ممکن است از نظر برنامه نامعتبر باشد.پس باید قوانین مربوط به خود مقدار را هم بررسی کنیم:
نوع
↓
خالی نبودن
↓
طول
↓
مقدارهای مجاز
🧠 خلاصه
isinstance(value, str)
بررسی نوع.
value.strip()
بررسی اینکه رشته فقط شامل فاصله نباشد.
len(value)
بررسی طول.
value in allowed_values
بررسی مقدارهای مجاز.
🎯 تمرین
داده زیر را اعتبارسنجی کن:
user = {
"username": "Ali",
"language": "fa",
"theme": "dark"
}قوانین:
username → باید str و غیرخالی باشد
username → طول بین 3 تا 20 کاراکتر
language → فقط "fa" یا "en"
theme → فقط "dark" یا "light"
اگر همه موارد معتبر بودند:
User is valid
در غیر این صورت:
Invalid user
پست ۱۶۰ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۶۱
اعتبارسنجی Boolean و مقادیر
در پستهای قبل یاد گرفتیم مقدارهای عددی و رشتهای را اعتبارسنجی کنیم.
حالا میخواهیم مقدارهای Boolean را بررسی کنیم؛ مثل:
در JSON هم Boolean فقط با این دو مقدار نمایش داده میشود:
🔹 بررسی نوع Boolean
برای اینکه مطمئن شویم مقدار واقعاً
خروجی:
🔹 چرا
این کار برای اعتبارسنجی مناسب نیست:
خروجی:
چون
اما مقدار ما باید واقعاً Boolean باشد.
بنابراین:
روش مناسبتری است.
🔹 مثال در تنظیمات برنامه
فرض کنیم:
میتوانیم هر دو مقدار را بررسی کنیم:
خروجی:
⚠️
در Python:
نتیجه:
و:
هم:
بنابراین اگر قانون ما این باشد که مقدار باید واقعاً Boolean باشد:
خروجی:
🔹 اعتبارسنجی چند تنظیم
در این مثال هم وجود کلید و هم نوع مقدار بررسی میشود.
🧠 الگوی اعتبارسنجی Boolean
برای یک مقدار Boolean:
برخلاف رشته یا عدد، برای Boolean معمولاً محدوده یا طول نداریم؛ مهم این است که مقدار واقعاً از نوع
🎯 تمرین
داده زیر را اعتبارسنجی کن:
قوانین:
اگر همه معتبر بودند:
در غیر این صورت:
پست ۱۶۱ از دوره جامع Python 🐍
اعتبارسنجی Boolean و مقادیر
True و False در JSONدر پستهای قبل یاد گرفتیم مقدارهای عددی و رشتهای را اعتبارسنجی کنیم.
حالا میخواهیم مقدارهای Boolean را بررسی کنیم؛ مثل:
True
False
در JSON هم Boolean فقط با این دو مقدار نمایش داده میشود:
true
false
🔹 بررسی نوع Boolean
برای اینکه مطمئن شویم مقدار واقعاً
bool است:notifications = True
if isinstance(notifications, bool):
print("Valid")
else:
print("Invalid")
خروجی:
Valid
🔹 چرا
bool() کافی نیست؟این کار برای اعتبارسنجی مناسب نیست:
value = "yes"
if bool(value):
print("Valid")
خروجی:
Valid
چون
"yes" یک رشته غیرخالی و Truthy است.اما مقدار ما باید واقعاً Boolean باشد.
بنابراین:
isinstance(value, bool)
روش مناسبتری است.
🔹 مثال در تنظیمات برنامه
فرض کنیم:
settings = {
"notifications": True,
"dark_mode": False
}میتوانیم هر دو مقدار را بررسی کنیم:
notifications = settings.get("notifications")
dark_mode = settings.get("dark_mode")
if not isinstance(notifications, bool):
print("Invalid notifications")
elif not isinstance(dark_mode, bool):
print("Invalid dark_mode")
else:
print("Settings are valid")خروجی:
Settings are valid
⚠️
0 و 1 را با Boolean اشتباه نگیریمدر Python:
isinstance(1, bool)
نتیجه:
False
و:
isinstance(0, bool)
هم:
False
بنابراین اگر قانون ما این باشد که مقدار باید واقعاً Boolean باشد:
value = 1
if isinstance(value, bool):
print("Valid")
else:
print("Invalid")
خروجی:
Invalid
🔹 اعتبارسنجی چند تنظیم
settings = {
"notifications": True,
"dark_mode": False,
"auto_save": True
}
required_keys = [
"notifications",
"dark_mode",
"auto_save"
]
valid = True
for key in required_keys:
if key not in settings:
valid = False
break
if not isinstance(settings[key], bool):
valid = False
break
if valid:
print("Settings are valid")
else:
print("Invalid settings")در این مثال هم وجود کلید و هم نوع مقدار بررسی میشود.
🧠 الگوی اعتبارسنجی Boolean
برای یک مقدار Boolean:
کلید وجود دارد؟
↓
مقدار bool است؟
↓
True یا False
برخلاف رشته یا عدد، برای Boolean معمولاً محدوده یا طول نداریم؛ مهم این است که مقدار واقعاً از نوع
bool باشد.🎯 تمرین
داده زیر را اعتبارسنجی کن:
settings = {
"notifications": True,
"dark_mode": False,
"auto_update": True
}قوانین:
notifications → کلید اجباری و bool
dark_mode → کلید اجباری و bool
auto_update → کلید اجباری و bool
اگر همه معتبر بودند:
Settings are valid
در غیر این صورت:
Invalid settings
پست ۱۶۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۶۲
اعتبارسنجی
در پست قبل مقدارهای
حالا میخواهیم با یک حالت مهم دیگر آشنا شویم:
در JSON، مقدار معادل
🔹
مثلاً:
خروجی:
برای بررسی آن بهتر است از
🔹 تفاوت
این دو مقدار یکسان نیستند:
مثلاً:
خروجی:
🔹 مقدار اختیاری
گاهی یک فیلد اجباری نیست.
مثلاً:
در اینجا
میتوانیم این حالت را بررسی کنیم:
🔹
فرض کنیم
پس دو حالت معتبر داریم:
⚠️ تفاوت
این دو حالت را دقت کن:
اگر بنویسیم:
نتیجه:
اما نمیدانیم آیا:
کلید
یا کلید وجود دارد و مقدارش واقعاً
برای تشخیص این دو حالت:
این تفاوت در اعتبارسنجی JSON مهم است.
🔥 مثال کامل
در این مثال:
🧠 خلاصه
برای بررسی
و:
همچنین باید تفاوت این سه حالت را بدانیم:
🎯 تمرین
داده زیر را اعتبارسنجی کن:
قوانین:
اگر معتبر بود:
در غیر این صورت:
پست ۱۶۲ از دوره جامع Python 🐍
اعتبارسنجی
None و مقدارهای اختیاری در JSONدر پست قبل مقدارهای
True و False را اعتبارسنجی کردیم.حالا میخواهیم با یک حالت مهم دیگر آشنا شویم:
None
در JSON، مقدار معادل
None با null نمایش داده میشود:null
🔹
None چیست؟None یعنی در Python مقداری وجود ندارد.مثلاً:
email = None
print(email)
خروجی:
None
برای بررسی آن بهتر است از
is استفاده کنیم:if email is None:
print("Email is not set")
🔹 تفاوت
None با رشته خالیاین دو مقدار یکسان نیستند:
email1 = None
email2 = ""
None یعنی مقدار وجود ندارد، اما "" یک رشته خالی است.مثلاً:
print(email1 is None)
print(email2 is None)
خروجی:
True
False
🔹 مقدار اختیاری
گاهی یک فیلد اجباری نیست.
مثلاً:
user = {
"username": "Ali",
"email": None
}در اینجا
username اجباری است، اما email میتواند None باشد.میتوانیم این حالت را بررسی کنیم:
email = user.get("email")
if email is None:
print("Email is optional")
elif isinstance(email, str):
print("Valid email")
else:
print("Invalid email")🔹
None یا مقدار معتبر؟فرض کنیم
age اختیاری است، اما اگر مقدار داشته باشد باید int باشد:age = user.get("age")
if age is None:
print("Age is not provided")
elif isinstance(age, int) and not isinstance(age, bool):
print("Valid age")
else:
print("Invalid age")پس دو حالت معتبر داریم:
None → معتبر، چون اختیاری است
25 → معتبر
"25" → نامعتبر
True → نامعتبر
⚠️ تفاوت
get() با بررسی کلیداین دو حالت را دقت کن:
user = {
"username": "Ali"
}اگر بنویسیم:
print(user.get("email"))نتیجه:
None
اما نمیدانیم آیا:
کلید
email وجود ندارد؟یا کلید وجود دارد و مقدارش واقعاً
None است؟برای تشخیص این دو حالت:
if "email" not in user:
print("Email key is missing")
elif user["email"] is None:
print("Email is explicitly None")
این تفاوت در اعتبارسنجی JSON مهم است.
🔥 مثال کامل
user = {
"username": "Ali",
"email": None,
"age": 25
}
if "username" not in user:
print("Missing username")
elif not isinstance(user["username"], str):
print("Invalid username")
elif "email" in user and user["email"] is not None:
if not isinstance(user["email"], str):
print("Invalid email")
else:
print("User is valid")
else:
print("User is valid")در این مثال:
username → اجباری
email → اختیاری
age → میتواند بررسی جداگانه داشته باشد
🧠 خلاصه
Python JSON
None → null
True → true
False → false
برای بررسی
None:value is None
و:
value is not None
همچنین باید تفاوت این سه حالت را بدانیم:
کلید وجود ندارد
کلید وجود دارد و مقدار None است
کلید وجود دارد و مقدار واقعی دارد
🎯 تمرین
داده زیر را اعتبارسنجی کن:
user = {
"username": "Ali",
"phone": None
}قوانین:
username → اجباری و باید str باشد
phone → اختیاری
phone → اگر None بود، معتبر است
phone → اگر مقدار داشت، باید str باشد
اگر معتبر بود:
User is valid
در غیر این صورت:
Invalid user
پست ۱۶۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۶۳
ساخت Validator قابل استفاده مجدد برای JSON
تا اینجا یاد گرفتیم بخشهای مختلف JSON را جداگانه اعتبارسنجی کنیم:
کلیدهای اجباری
نوع داده
مقدارهای مجاز
محدوده عددی
رشتهها
لیستها و دادههای تودرتو
اما اگر برای هر فایل JSON این بررسیها را دوباره بنویسیم، کد تکراری و سختنگهداری میشود.
راه بهتر، ساختن یک تابع قابل استفاده مجدد برای اعتبارسنجی است.
🔹 یک Validator ساده
فرض کنیم مشخصات محصول این است:
میتوانیم یک تابع بسازیم:
حالا:
خروجی:
🔹 چرا تابع بهتر است؟
اگر چند محصول داشته باشیم:
میتوانیم همان Validator را دوباره استفاده کنیم:
بدون اینکه قوانین اعتبارسنجی را برای هر محصول دوباره بنویسیم.
🔹 برگرداندن دلیل خطا
گاهی
مثلاً بهتر است بدانیم چرا داده نامعتبر است.
استفاده:
⚠️ چرا
اینجا:
یعنی هیچ خطایی وجود ندارد.
پس:
این الگو در Validatorهای ساده بسیار کاربردی است.
🔥 مثال با چند محصول
خروجی:
🧠 خلاصه
بهجای تکرار قوانین:
Validator میتواند:
یا اطلاعات دقیقتری مثل:
برگرداند.
🎯 تمرین
یک تابع به نام
قوانین:
اگر معتبر بود:
برگرداند.
اگر نامعتبر بود، دلیل خطا را بهصورت یک رشته برگرداند.
مثلاً:
پست ۱۶۳ از دوره جامع Python 🐍
ساخت Validator قابل استفاده مجدد برای JSON
تا اینجا یاد گرفتیم بخشهای مختلف JSON را جداگانه اعتبارسنجی کنیم:
کلیدهای اجباری
نوع داده
مقدارهای مجاز
محدوده عددی
رشتهها
boolNoneلیستها و دادههای تودرتو
اما اگر برای هر فایل JSON این بررسیها را دوباره بنویسیم، کد تکراری و سختنگهداری میشود.
راه بهتر، ساختن یک تابع قابل استفاده مجدد برای اعتبارسنجی است.
🔹 یک Validator ساده
فرض کنیم مشخصات محصول این است:
product = {
"name": "Laptop",
"price": 1200
}میتوانیم یک تابع بسازیم:
def validate_product(product):
if not isinstance(product, dict):
return False
if "name" not in product:
return False
if "price" not in product:
return False
if not isinstance(product["name"], str):
return False
if not isinstance(product["price"], (int, float)):
return False
if isinstance(product["price"], bool):
return False
if not 1 <= product["price"] <= 10000:
return False
return True
حالا:
if validate_product(product):
print("Product is valid")
else:
print("Invalid product")
خروجی:
Product is valid
🔹 چرا تابع بهتر است؟
اگر چند محصول داشته باشیم:
products = [
{"name": "Laptop", "price": 1200},
{"name": "Mouse", "price": 25},
{"name": "Phone", "price": 850}
]
میتوانیم همان Validator را دوباره استفاده کنیم:
for product in products:
if validate_product(product):
print("Valid")
else:
print("Invalid")
بدون اینکه قوانین اعتبارسنجی را برای هر محصول دوباره بنویسیم.
🔹 برگرداندن دلیل خطا
گاهی
True یا False کافی نیست.مثلاً بهتر است بدانیم چرا داده نامعتبر است.
def validate_product(product):
if not isinstance(product, dict):
return "Product must be a dictionary"
if "name" not in product:
return "Missing name"
if "price" not in product:
return "Missing price"
if not isinstance(product["name"], str):
return "Invalid name"
price = product["price"]
if (
not isinstance(price, (int, float))
or isinstance(price, bool)
):
return "Invalid price type"
if not 1 <= price <= 10000:
return "Invalid price range"
return None
استفاده:
error = validate_product(product)
if error is None:
print("Product is valid")
else:
print(error)
⚠️ چرا
None؟اینجا:
return None
یعنی هیچ خطایی وجود ندارد.
پس:
None → معتبر
"Missing name" → نامعتبر
"Invalid price" → نامعتبر
این الگو در Validatorهای ساده بسیار کاربردی است.
🔥 مثال با چند محصول
products = [
{"name": "Laptop", "price": 1200},
{"name": "Mouse"},
{"name": "Phone", "price": True}
]
for product in products:
error = validate_product(product)
if error is None:
print("Valid product")
else:
print(f"Invalid product: {error}")
خروجی:
Valid product
Invalid product: Missing price
Invalid product: Invalid price type
🧠 خلاصه
بهجای تکرار قوانین:
JSON
↓
Validator
↓
اعتبارسنجی
↓
نتیجه
Validator میتواند:
True / False
یا اطلاعات دقیقتری مثل:
None / Error Message
برگرداند.
🎯 تمرین
یک تابع به نام
validate_user() بنویس:def validate_user(user):
# کد اینجا
قوانین:
user → باید dict باشد
username → اجباری و str
age → اجباری و int
age → بین 0 تا 120
اگر معتبر بود:
None
برگرداند.
اگر نامعتبر بود، دلیل خطا را بهصورت یک رشته برگرداند.
مثلاً:
Missing username
Invalid age
Invalid age range
پست ۱۶۳ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۶۴
جمعآوری چند خطای اعتبارسنجی همزمان
در پست قبل Validator ساختیم که هنگام پیدا کردن اولین خطا، همان خطا را برمیگرداند.
اما یک مشکل وجود دارد:
اگر داده چند خطا داشته باشد، کاربر فقط اولین خطا را میبیند.
مثلاً:
اینجا هم
بهتر است بتوانیم همه خطاها را یکجا جمع کنیم.
🔹 ساخت لیست خطاها
حالا:
فعلاً خروجی خالی است، چون هنوز نوع و محدوده را بررسی نکردهایم.
🔹 اضافه کردن قوانین بیشتر
حالا:
خروجی:
هر دو خطا گزارش شدند.
🔹 بررسی معتبر بودن داده
اگر لیست خطاها خالی باشد:
مثلاً:
خروجی:
🔹 چرا لیست خطا بهتر است؟
فرض کن فرم ثبتنامی داریم و کاربر سه مقدار اشتباه وارد کرده است.
روش قبلی:
کاربر باید اصلاح کند و دوباره برنامه را اجرا کند تا خطای بعدی را ببیند.
اما با جمعآوری خطاها:
همه مشکلات را یکجا میبینیم.
⚠️ نکته مهم
در Validator بهتر است بین این دو حالت تفاوت قائل شویم:
مثلاً:
لیست خالی در Python مقدار Falsy دارد.
🧠 خلاصه
بهجای:
میتوانیم:
استفاده کنیم.
در پایان:
و نتیجه میتواند:
یا:
باشد.
🎯 تمرین
تابع زیر را کامل کن:
قوانین:
برای هر خطا یک پیام جداگانه به
اگر داده زیر را بررسی کنیم:
باید هر سه خطا گزارش شوند.
پست ۱۶۴ از دوره جامع Python 🐍
جمعآوری چند خطای اعتبارسنجی همزمان
در پست قبل Validator ساختیم که هنگام پیدا کردن اولین خطا، همان خطا را برمیگرداند.
اما یک مشکل وجود دارد:
اگر داده چند خطا داشته باشد، کاربر فقط اولین خطا را میبیند.
مثلاً:
user = {
"username": 123,
"age": 150
}اینجا هم
username اشتباه است و هم age.بهتر است بتوانیم همه خطاها را یکجا جمع کنیم.
🔹 ساخت لیست خطاها
def validate_user(user):
errors = []
if not isinstance(user, dict):
errors.append("User must be a dictionary")
return errors
if "username" not in user:
errors.append("Missing username")
if "age" not in user:
errors.append("Missing age")
return errors
حالا:
user = {
"username": 123,
"age": 150
}
errors = validate_user(user)
print(errors)فعلاً خروجی خالی است، چون هنوز نوع و محدوده را بررسی نکردهایم.
🔹 اضافه کردن قوانین بیشتر
def validate_user(user):
errors = []
if not isinstance(user, dict):
errors.append("User must be a dictionary")
return errors
if "username" not in user:
errors.append("Missing username")
elif not isinstance(user["username"], str):
errors.append("Invalid username type")
if "age" not in user:
errors.append("Missing age")
elif not isinstance(user["age"], int) or isinstance(user["age"], bool):
errors.append("Invalid age type")
elif not 0 <= user["age"] <= 120:
errors.append("Invalid age range")
return errors
حالا:
user = {
"username": 123,
"age": 150
}
errors = validate_user(user)
for error in errors:
print(error)خروجی:
Invalid username type
Invalid age range
هر دو خطا گزارش شدند.
🔹 بررسی معتبر بودن داده
اگر لیست خطاها خالی باشد:
if not errors:
print("User is valid")
else:
print("User is invalid")
مثلاً:
user = {
"username": "Ali",
"age": 25
}
errors = validate_user(user)
if not errors:
print("User is valid")
else:
print("User is invalid")خروجی:
User is valid
🔹 چرا لیست خطا بهتر است؟
فرض کن فرم ثبتنامی داریم و کاربر سه مقدار اشتباه وارد کرده است.
روش قبلی:
Invalid username
کاربر باید اصلاح کند و دوباره برنامه را اجرا کند تا خطای بعدی را ببیند.
اما با جمعآوری خطاها:
Invalid username type
Invalid age range
Missing email
همه مشکلات را یکجا میبینیم.
⚠️ نکته مهم
در Validator بهتر است بین این دو حالت تفاوت قائل شویم:
[] → هیچ خطایی وجود ندارد
[خطاها] → یک یا چند خطا وجود دارد
مثلاً:
errors = validate_user(user)
if errors:
print("Invalid user")
else:
print("Valid user")
لیست خالی در Python مقدار Falsy دارد.
🧠 خلاصه
بهجای:
return "Invalid age"
میتوانیم:
errors.append("Invalid age")استفاده کنیم.
در پایان:
return errors
و نتیجه میتواند:
[]
یا:
["Invalid username type", "Invalid age range"]
باشد.
🎯 تمرین
تابع زیر را کامل کن:
def validate_product(product):
errors = []
# قوانین اعتبارسنجی
return errors
قوانین:
name → اجباری، str و غیرخالی
price → اجباری، عدد و بین 1 تا 10000
stock → اجباری، int و بین 0 تا 1000
برای هر خطا یک پیام جداگانه به
errors اضافه کن.اگر داده زیر را بررسی کنیم:
product = {
"name": "",
"price": -50,
"stock": 2000
}باید هر سه خطا گزارش شوند.
پست ۱۶۴ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۶۵
اعتبارسنجی شرطی و وابسته در JSON
در پست قبل یاد گرفتیم چند خطای اعتبارسنجی را همزمان جمع کنیم.
اما گاهی معتبر بودن یک فیلد به مقدار فیلد دیگری وابسته است.
مثلاً اگر کاربر حالت اعلانها را فعال کند، باید یک
🔹 یک قانون وابسته
قانون ما:
میتوانیم بنویسیم:
🔹 اگر اعلانها خاموش باشند
اگر:
دیگر
نکته مهم این است که برای مقایسه Boolean بهتر است از:
و:
استفاده کنیم.
🔹 چند شرط وابسته
فرض کنیم یک محصول داریم:
قوانین:
🔥 جمعآوری خطاهای وابسته
میتوانیم این قوانین را با Validator قبلی ترکیب کنیم:
🔹 مثال
خروجی:
چون:
پس
⚠️ نکته مهم
این نوع اعتبارسنجی را Conditional Validation مینامیم.
یعنی:
مثلاً:
یا:
🧠 خلاصه
در اعتبارسنجی واقعی فقط قوانین مستقل نداریم.
ممکن است یک فیلد بر اساس فیلد دیگر:
اجباری شود.
نوع مشخصی داشته باشد.
محدوده مشخصی داشته باشد.
اصلاً نباید وجود داشته باشد.
الگوی کلی:
🎯 تمرین
تابع زیر را کامل کن:
قوانین:
برای هر خطا یک پیام جداگانه به
برای این داده:
باید خطای مربوط به نبودن
پست ۱۶۵ از دوره جامع Python 🐍
اعتبارسنجی شرطی و وابسته در JSON
در پست قبل یاد گرفتیم چند خطای اعتبارسنجی را همزمان جمع کنیم.
اما گاهی معتبر بودن یک فیلد به مقدار فیلد دیگری وابسته است.
مثلاً اگر کاربر حالت اعلانها را فعال کند، باید یک
email معتبر هم داشته باشد.🔹 یک قانون وابسته
user = {
"notifications": True,
"email": "ali@example.com"
}قانون ما:
notifications = True
→ email باید وجود داشته باشد و معتبر باشد
میتوانیم بنویسیم:
if user.get("notifications") is True:
if "email" not in user:
print("Email is required")
elif not isinstance(user["email"], str):
print("Invalid email")
elif not user["email"].strip():
print("Email cannot be empty")🔹 اگر اعلانها خاموش باشند
اگر:
user = {
"notifications": False
}دیگر
email اجباری نیست.if user.get("notifications") is True:
print("Email is required")
else:
print("Email is optional")نکته مهم این است که برای مقایسه Boolean بهتر است از:
is True
و:
is False
استفاده کنیم.
🔹 چند شرط وابسته
فرض کنیم یک محصول داریم:
product = {
"has_discount": True,
"discount": 20
}قوانین:
has_discount = True
→ discount اجباری است
→ discount باید عدد باشد
→ discount باید بین 0 تا 100 باشد
has_discount = product.get("has_discount")
discount = product.get("discount")
if has_discount is True:
if "discount" not in product:
print("Discount is required")
elif (
not isinstance(discount, (int, float))
or isinstance(discount, bool)
):
print("Invalid discount")
elif not 0 <= discount <= 100:
print("Invalid discount range")🔥 جمعآوری خطاهای وابسته
میتوانیم این قوانین را با Validator قبلی ترکیب کنیم:
def validate_product(product):
errors = []
if not isinstance(product, dict):
return ["Product must be a dictionary"]
if "name" not in product:
errors.append("Missing name")
elif not isinstance(product["name"], str) or not product["name"].strip():
errors.append("Invalid name")
if "price" not in product:
errors.append("Missing price")
elif (
not isinstance(product["price"], (int, float))
or isinstance(product["price"], bool)
):
errors.append("Invalid price")
elif not 1 <= product["price"] <= 10000:
errors.append("Invalid price range")
if product.get("has_discount") is True:
if "discount" not in product:
errors.append("Missing discount")
elif (
not isinstance(product["discount"], (int, float))
or isinstance(product["discount"], bool)
):
errors.append("Invalid discount")
elif not 0 <= product["discount"] <= 100:
errors.append("Invalid discount range")
return errors
🔹 مثال
product = {
"name": "Laptop",
"price": 1200,
"has_discount": True
}
errors = validate_product(product)
for error in errors:
print(error)خروجی:
Missing discount
چون:
has_discount → True
پس
discount باید وجود داشته باشد.⚠️ نکته مهم
این نوع اعتبارسنجی را Conditional Validation مینامیم.
یعنی:
اگر A درست بود
→ B اجباری شود
مثلاً:
has_discount = True
↓
discount required
یا:
notifications = True
↓
email required
🧠 خلاصه
در اعتبارسنجی واقعی فقط قوانین مستقل نداریم.
ممکن است یک فیلد بر اساس فیلد دیگر:
اجباری شود.
نوع مشخصی داشته باشد.
محدوده مشخصی داشته باشد.
اصلاً نباید وجود داشته باشد.
الگوی کلی:
شرط اصلی
↓
بررسی فیلد وابسته
↓
بررسی نوع
↓
بررسی مقدار
🎯 تمرین
تابع زیر را کامل کن:
def validate_user(user):
errors = []
# قوانین
return errors
قوانین:
username → اجباری و str و غیرخالی
has_phone → اجباری و bool
اگر has_phone == True:
phone → اجباری و str و غیرخالی
برای هر خطا یک پیام جداگانه به
errors اضافه کن.برای این داده:
user = {
"username": "Ali",
"has_phone": True
}باید خطای مربوط به نبودن
phone گزارش شود.پست ۱۶۵ از دوره جامع Python 🐍
1
🔐 آموزش امنیت Telegram — پست ویژه
رباتهایی که با
احتمالاً بعضی رباتهای Telegram را دیدهاید که فقط با دادن:
اطلاعات زیادی درباره یک کاربر نمایش میدهند؛ مثلاً:
نام و اطلاعات عمومی حساب
گروهها و کانالهایی که کاربر در آنها دیده شده
پیامهای عمومی منتسب به کاربر
فعالیتهای قبلی
اطلاعات مرتبط دیگری که درباره آن حساب جمعآوری شده است
این سرویسها واقعاً وجود دارند و ممکن است اطلاعات قابلتوجهی نمایش دهند.
اما سؤال مهم این است:
🔹 اطلاعات چگونه جمعآوری میشود؟
یک سرویس میتواند اطلاعات را از منابع مختلف جمع کند:
مثلاً ممکن است یک سرویس قبلاً اطلاعات تعداد زیادی گروه و کانال را جمعآوری کرده باشد.
بعد وقتی شما:
را وارد میکنید، سرویس در دیتابیس خودش جستوجو میکند و اطلاعاتی را که قبلاً درباره آن کاربر جمع شده نمایش میدهد.
بنابراین همیشه به این معنی نیست که اطلاعات همین لحظه از حساب کاربر گرفته شده است.
🔹 آیا Bot میتواند همه گروههای یک کاربر را پیدا کند؟
اینجا یک تفاوت مهم وجود دارد.
یک Bot معمولی صرفاً با داشتن username نمیتواند آزادانه فهرست تمام گروههایی را که یک شخص عضو آنهاست دریافت کند.
Telegram برای دسترسی به اطلاعات اعضای Chat محدودیتهایی دارد؛ برای مثال
اما اگر یک Bot در یک گروه حضور داشته باشد و دسترسی لازم به پیامها را داشته باشد، میتواند فعالیتهای همان گروه را مشاهده کند.
بنابراین یک سرویس میتواند با جمعآوری اطلاعات از مکانهای مختلف، یک پروفایل بزرگتر ایجاد کند.
🔥 اما Private Chat چطور؟
این قسمت خیلی مهم است.
اگر رباتی بگوید:
این موضوع با قابلیت معمول Bot API فرق دارد.
یک username بهتنهایی رمز ورود یا مجوز دسترسی به Private Chatهای شخص نیست.
Bot معمولی پیامهایی را که برای خودش ارسال میشوند و بسته به شرایط پیامهای Chatهایی را که به آنها دسترسی دارد دریافت میکند؛ این با دسترسی آزاد به تمام Private Chatهای یک حساب کاملاً متفاوت است.
پس اگر سرویسی اطلاعاتی از Private Chat نشان میدهد، باید منشأ آن اطلاعات را جداگانه بررسی کرد؛ ممکن است داده از تعاملات قبلی، منابع شخص ثالث، دیتابیسهای جمعآوریشده یا منابع دیگری آمده باشد.
⚠️ Username با اطلاعات ورود فرق دارد
این دو مورد را با هم اشتباه نگیرید:
با:
کاملاً متفاوت است.
داشتن username به معنی دسترسی به حساب نیست.
بنابراین برای رباتهای ناشناس هرگز این اطلاعات را ارسال نکن:
🔹 چرا این موضوع مهم است؟
حتی اگر هر اطلاعات بهتنهایی عمومی باشد، کنار هم قرار گرفتن آنها میتواند تصویر نسبتاً دقیقی از فعالیت آنلاین یک شخص ایجاد کند:
به این فرایند در حوزه امنیت و OSINT، تجمیع اطلاعات از منابع مختلف گفته میشود.
🛡 برای محافظت از خودمان
🧠 نکته نهایی
اگر یک ربات با دادن
سؤال اصلی این است:
شناخت این موضوع یکی از بخشهای مهم امنیت و حریم خصوصی در Telegram است.
آموزش امنیت Telegram — پست ویژه 🔐
رباتهایی که با
@username اطلاعات زیادی پیدا میکننداحتمالاً بعضی رباتهای Telegram را دیدهاید که فقط با دادن:
@username
اطلاعات زیادی درباره یک کاربر نمایش میدهند؛ مثلاً:
نام و اطلاعات عمومی حساب
گروهها و کانالهایی که کاربر در آنها دیده شده
پیامهای عمومی منتسب به کاربر
فعالیتهای قبلی
اطلاعات مرتبط دیگری که درباره آن حساب جمعآوری شده است
این سرویسها واقعاً وجود دارند و ممکن است اطلاعات قابلتوجهی نمایش دهند.
اما سؤال مهم این است:
این اطلاعات دقیقاً از کجا آمدهاند؟
🔹 اطلاعات چگونه جمعآوری میشود؟
یک سرویس میتواند اطلاعات را از منابع مختلف جمع کند:
اطلاعات عمومی Telegram
↓
گروهها و کانالهای قابل دسترسی
↓
پیامها و فعالیتهای قابل مشاهده
↓
دادههای جمعآوریشده در گذشته
↓
منابع و دیتابیسهای دیگر
مثلاً ممکن است یک سرویس قبلاً اطلاعات تعداد زیادی گروه و کانال را جمعآوری کرده باشد.
بعد وقتی شما:
@username
را وارد میکنید، سرویس در دیتابیس خودش جستوجو میکند و اطلاعاتی را که قبلاً درباره آن کاربر جمع شده نمایش میدهد.
بنابراین همیشه به این معنی نیست که اطلاعات همین لحظه از حساب کاربر گرفته شده است.
🔹 آیا Bot میتواند همه گروههای یک کاربر را پیدا کند؟
اینجا یک تفاوت مهم وجود دارد.
یک Bot معمولی صرفاً با داشتن username نمیتواند آزادانه فهرست تمام گروههایی را که یک شخص عضو آنهاست دریافت کند.
Telegram برای دسترسی به اطلاعات اعضای Chat محدودیتهایی دارد؛ برای مثال
getChatMember برای سایر کاربران بهطور تضمینی زمانی در دسترس است که Bot در آن Chat ادمین باشد.اما اگر یک Bot در یک گروه حضور داشته باشد و دسترسی لازم به پیامها را داشته باشد، میتواند فعالیتهای همان گروه را مشاهده کند.
بنابراین یک سرویس میتواند با جمعآوری اطلاعات از مکانهای مختلف، یک پروفایل بزرگتر ایجاد کند.
🔥 اما Private Chat چطور؟
این قسمت خیلی مهم است.
اگر رباتی بگوید:
«فقط username بده تا تمام Private Chatهای این شخص را نشان بدهم.»
این موضوع با قابلیت معمول Bot API فرق دارد.
یک username بهتنهایی رمز ورود یا مجوز دسترسی به Private Chatهای شخص نیست.
Bot معمولی پیامهایی را که برای خودش ارسال میشوند و بسته به شرایط پیامهای Chatهایی را که به آنها دسترسی دارد دریافت میکند؛ این با دسترسی آزاد به تمام Private Chatهای یک حساب کاملاً متفاوت است.
پس اگر سرویسی اطلاعاتی از Private Chat نشان میدهد، باید منشأ آن اطلاعات را جداگانه بررسی کرد؛ ممکن است داده از تعاملات قبلی، منابع شخص ثالث، دیتابیسهای جمعآوریشده یا منابع دیگری آمده باشد.
⚠️ Username با اطلاعات ورود فرق دارد
این دو مورد را با هم اشتباه نگیرید:
@username
با:
Login Code
2FA Password
Session
API Credentials
کاملاً متفاوت است.
داشتن username به معنی دسترسی به حساب نیست.
بنابراین برای رباتهای ناشناس هرگز این اطلاعات را ارسال نکن:
❌ کد ورود Telegram
❌ رمز Two-Step Verification
❌ Session String
❌ فایل Session
❌ API ID / API Hash
❌ تأیید QR Login ناشناس
🔹 چرا این موضوع مهم است؟
حتی اگر هر اطلاعات بهتنهایی عمومی باشد، کنار هم قرار گرفتن آنها میتواند تصویر نسبتاً دقیقی از فعالیت آنلاین یک شخص ایجاد کند:
Username
↓
گروههای قابل مشاهده
↓
پیامهای عمومی
↓
کانالها و لینکهای مرتبط
↓
فعالیتهای قبلی
↓
ساخت یک پروفایل کاملتر
به این فرایند در حوزه امنیت و OSINT، تجمیع اطلاعات از منابع مختلف گفته میشود.
🛡 برای محافظت از خودمان
✅ اطلاعات حساس را در گروههای عمومی منتشر نکنیم.
✅ به Botهای ناشناس اعتماد نکنیم.
✅ کد ورود را برای هیچ Botی ارسال نکنیم.
✅ Session و اطلاعات احراز هویت را در اختیار دیگران قرار ندهیم.
✅ قبل از اضافه کردن Bot به گروه، دسترسیهای آن را بررسی کنیم.
✅ روی لینکهای ناشناس ارسالشده توسط Botها کلیک نکنیم.
🧠 نکته نهایی
اگر یک ربات با دادن
@username اطلاعات زیادی درباره یک شخص نشان میدهد، این موضوع میتواند واقعی باشد؛ اما لزوماً به معنی این نیست که ربات مستقیماً وارد حساب Telegram شده است.سؤال اصلی این است:
این اطلاعات از کجا جمع شده، چه مدت ذخیره شده و چه بخشهایی عمومی یا قابلدسترسی بودهاند؟
شناخت این موضوع یکی از بخشهای مهم امنیت و حریم خصوصی در Telegram است.
آموزش امنیت Telegram — پست ویژه 🔐
1
🐍 آموزش جامع Python — پست ۱۶۶
کار با فایلهای CSV در Python
تا اینجا با فایلهای JSON کار کردیم.
حالا یکی از فرمتهای بسیار رایج برای ذخیره دادههای جدولی را یاد میگیریم:
CSV مخفف Comma-Separated Values است.
در CSV، اطلاعات معمولاً به شکل سطر و ستون ذخیره میشوند.
مثلاً فایل:
میتواند این محتوا را داشته باشد:
هر خط یک رکورد و هر مقدار بین جداکنندهها یک فیلد است.
🔹 خواندن CSV
Python برای کار با CSV یک ماژول داخلی به نام
خروجی:
دقت کن که هر
🔹 دسترسی به ستونها
مثلاً میتوانیم نام و سن را جدا کنیم:
خروجی:
🔹 Header چیست؟
در بسیاری از فایلهای CSV، اولین سطر شامل نام ستونهاست:
این سطر را Header مینامیم.
میتوانیم آن را جداگانه دریافت کنیم:
خروجی:
⚠️ نکته مهم
مقادیر CSV معمولاً به صورت رشته (
مثلاً:
خروجی:
پس اگر بخواهیم سن را بهعنوان عدد استفاده کنیم، باید آن را تبدیل کنیم:
🧠 خلاصه
CSV برای دادههای جدولی ساده بسیار کاربردی است؛ در پست بعدی یاد میگیریم چگونه CSV را با نام ستونها و به شکل Dictionary بخوانیم.
🎯 تمرین
فایل زیر را بساز:
محتوای آن:
سپس برنامهای بنویس که نام و نمره هر دانشآموز را چاپ کند.
خروجی مورد انتظار:
پست ۱۶۶ از دوره جامع Python 🐍
کار با فایلهای CSV در Python
تا اینجا با فایلهای JSON کار کردیم.
حالا یکی از فرمتهای بسیار رایج برای ذخیره دادههای جدولی را یاد میگیریم:
CSV
CSV مخفف Comma-Separated Values است.
در CSV، اطلاعات معمولاً به شکل سطر و ستون ذخیره میشوند.
مثلاً فایل:
users.csv
میتواند این محتوا را داشته باشد:
name,age,city
Ali,25,Baku
Sara,22,Tehran
Reza,30,Tabriz
هر خط یک رکورد و هر مقدار بین جداکنندهها یک فیلد است.
🔹 خواندن CSV
Python برای کار با CSV یک ماژول داخلی به نام
csv دارد:import csv
with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.reader(file)
for row in reader:
print(row)
خروجی:
['name', 'age', 'city']
['Ali', '25', 'Baku']
['Sara', '22', 'Tehran']
['Reza', '30', 'Tabriz']
دقت کن که هر
row یک لیست است.🔹 دسترسی به ستونها
مثلاً میتوانیم نام و سن را جدا کنیم:
import csv
with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.reader(file)
for row in reader:
print(row[0], row[1])
خروجی:
name age
Ali 25
Sara 22
Reza 30
🔹 Header چیست؟
در بسیاری از فایلهای CSV، اولین سطر شامل نام ستونهاست:
name,age,city
این سطر را Header مینامیم.
میتوانیم آن را جداگانه دریافت کنیم:
import csv
with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.reader(file)
header = next(reader)
print(header)
for row in reader:
print(row)
خروجی:
['name', 'age', 'city']
['Ali', '25', 'Baku']
['Sara', '22', 'Tehran']
['Reza', '30', 'Tabriz']
next(reader) اولین سطر را مصرف میکند؛ بنابراین حلقه از سطر بعدی شروع میشود.⚠️ نکته مهم
مقادیر CSV معمولاً به صورت رشته (
str) خوانده میشوند.مثلاً:
print(type(row[1]))
خروجی:
<class 'str'>
پس اگر بخواهیم سن را بهعنوان عدد استفاده کنیم، باید آن را تبدیل کنیم:
age = int(row[1])
🧠 خلاصه
csv.reader() → خواندن CSV
row → یک سطر از CSV
next(reader) → دریافت سطر بعدی
Header → نام ستونها
CSV برای دادههای جدولی ساده بسیار کاربردی است؛ در پست بعدی یاد میگیریم چگونه CSV را با نام ستونها و به شکل Dictionary بخوانیم.
🎯 تمرین
فایل زیر را بساز:
students.csv
محتوای آن:
name,score
Ali,18
Sara,20
Reza,15
سپس برنامهای بنویس که نام و نمره هر دانشآموز را چاپ کند.
خروجی مورد انتظار:
Ali 18
Sara 20
Reza 15
پست ۱۶۶ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۶۷
خواندن CSV به صورت Dictionary با
در پست قبل با
مشکل
در فایلهای بزرگ، استفاده از نام ستونها خواناتر است.
برای این کار از:
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم فایل
حالا:
خروجی:
🔹
هر
بنابراین بهجای:
میتوانیم بنویسیم:
این روش مخصوصاً برای فایلهای CSV با ستونهای زیاد خواناتر است.
🔹 تبدیل مقدارها
همانطور که در
مثلاً:
حالا میتوانیم عملیات عددی انجام دهیم:
خروجی:
🔹 چرا
مقایسه کن:
با:
روش دوم مشخصتر است و اگر ترتیب ستونها تغییر کند، کار با دادهها سادهتر میشود.
⚠️ نکته مهم
اگر نام ستونی را اشتباه بنویسیم:
و چنین ستونی در CSV وجود نداشته باشد، با خطای:
مواجه میشویم.
پس نام ستونها باید با Header فایل مطابقت داشته باشد.
🧠 خلاصه
🎯 تمرین
فایل زیر را بساز:
محتوا:
برنامهای بنویس که فقط محصولاتی را چاپ کند که موجودی آنها بیشتر از
خروجی مورد انتظار:
پست ۱۶۷ از دوره جامع Python 🐍
خواندن CSV به صورت Dictionary با
DictReaderدر پست قبل با
csv.reader() آشنا شدیم.مشکل
reader این است که برای دسترسی به ستونها باید از Index استفاده کنیم:row[0]
row[1]
در فایلهای بزرگ، استفاده از نام ستونها خواناتر است.
برای این کار از:
csv.DictReader
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم فایل
users.csv این محتوا را دارد:name,age,city
Ali,25,Baku
Sara,22,Tehran
Reza,30,Tabriz
حالا:
import csv
with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)
for row in reader:
print(row["name"], row["age"], row["city"])
خروجی:
Ali 25 Baku
Sara 22 Tehran
Reza 30 Tabriz
🔹
row چیست؟هر
row یک Dictionary است:{
"name": "Ali",
"age": "25",
"city": "Baku"
}بنابراین بهجای:
row[0]
میتوانیم بنویسیم:
row["name"]
این روش مخصوصاً برای فایلهای CSV با ستونهای زیاد خواناتر است.
🔹 تبدیل مقدارها
همانطور که در
csv.reader() دیدیم، مقدارها معمولاً str هستند.مثلاً:
age = int(row["age"])
حالا میتوانیم عملیات عددی انجام دهیم:
import csv
with open("users.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)
for row in reader:
age = int(row["age"])
if age >= 25:
print(row["name"])
خروجی:
Ali
Reza
🔹 چرا
DictReader مفید است؟مقایسه کن:
row[0]
row[1]
row[2]
با:
row["name"]
row["age"]
row["city"]
روش دوم مشخصتر است و اگر ترتیب ستونها تغییر کند، کار با دادهها سادهتر میشود.
⚠️ نکته مهم
اگر نام ستونی را اشتباه بنویسیم:
print(row["username"])
و چنین ستونی در CSV وجود نداشته باشد، با خطای:
KeyError
مواجه میشویم.
پس نام ستونها باید با Header فایل مطابقت داشته باشد.
🧠 خلاصه
csv.reader() → هر سطر به صورت List
csv.DictReader() → هر سطر به صورت Dictionary
row[0] → دسترسی با Index
row["name"] → دسترسی با نام ستون
🎯 تمرین
فایل زیر را بساز:
products.csv
محتوا:
name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,0
برنامهای بنویس که فقط محصولاتی را چاپ کند که موجودی آنها بیشتر از
0 است.خروجی مورد انتظار:
Laptop 1200
Mouse 25
پست ۱۶۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۶۸
نوشتن داده در CSV با
تا اینجا یاد گرفتیم چگونه فایل CSV را بخوانیم.
حالا میخواهیم اطلاعات جدید را در یک فایل CSV ایجاد و ذخیره کنیم.
برای این کار میتوانیم از:
یا:
استفاده کنیم.
🔹 نوشتن با
فایل
در این روش هر سطر را به صورت List مینویسیم.
🔹
با:
یک سطر به فایل اضافه میکنیم.
مثلاً:
🔹
برای نوشتن چند سطر:
🔹
اگر دادهها را به صورت Dictionary داشته باشیم،
خروجی فایل:
اینجا:
نام ستونها را مینویسد.
و:
Dictionaryها را به سطرهای CSV تبدیل میکند.
🔥 تفاوت
با
دادهها به صورت List نوشته میشوند.
با
دادهها به صورت Dictionary نوشته میشوند.
پس:
اگر دادههای برنامهات از قبل به شکل Dictionary باشند،
🔹 چرا
هنگام کار با
باز کنیم.
این کار باعث میشود ماژول
⚠️
محتوای قبلی فایل را هنگام نوشتن جایگزین میکند.
اما:
برای اضافه کردن داده به انتهای فایل است.
مثلاً:
🧠 خلاصه
🎯 تمرین
فایل زیر را ایجاد کن:
و اطلاعات زیر را با
سعی کن از:
استفاده کنی.
پست ۱۶۸ از دوره جامع Python 🐍
نوشتن داده در CSV با
csv.writer و DictWriterتا اینجا یاد گرفتیم چگونه فایل CSV را بخوانیم.
حالا میخواهیم اطلاعات جدید را در یک فایل CSV ایجاد و ذخیره کنیم.
برای این کار میتوانیم از:
csv.writer
یا:
csv.DictWriter
استفاده کنیم.
🔹 نوشتن با
csv.writerimport csv
with open("users.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["name", "age", "city"])
writer.writerow(["Ali", 25, "Baku"])
writer.writerow(["Sara", 22, "Tehran"])
فایل
users.csv:name,age,city
Ali,25,Baku
Sara,22,Tehran
در این روش هر سطر را به صورت List مینویسیم.
🔹
writerow()با:
writer.writerow(...)
یک سطر به فایل اضافه میکنیم.
مثلاً:
writer.writerow(["Reza", 30, "Tabriz"])
🔹
writerows()برای نوشتن چند سطر:
users = [
["Ali", 25, "Baku"],
["Sara", 22, "Tehran"],
["Reza", 30, "Tabriz"]
]
with open("users.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["name", "age", "city"])
writer.writerows(users)
🔹
DictWriterاگر دادهها را به صورت Dictionary داشته باشیم،
DictWriter خواناتر است:import csv
users = [
{"name": "Ali", "age": 25, "city": "Baku"},
{"name": "Sara", "age": 22, "city": "Tehran"}
]
with open("users.csv", "w", newline="", encoding="utf-8") as file:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(
file,
fieldnames=fieldnames
)
writer.writeheader()
writer.writerows(users)
خروجی فایل:
name,age,city
Ali,25,Baku
Sara,22,Tehran
اینجا:
writer.writeheader()
نام ستونها را مینویسد.
و:
writer.writerows(users)
Dictionaryها را به سطرهای CSV تبدیل میکند.
🔥 تفاوت
writer و DictWriterبا
csv.writer:writer.writerow(["Ali", 25, "Baku"])
دادهها به صورت List نوشته میشوند.
با
csv.DictWriter:writer.writerow({
"name": "Ali",
"age": 25,
"city": "Baku"
})دادهها به صورت Dictionary نوشته میشوند.
پس:
csv.writer
→ مناسب دادههای List
csv.DictWriter
→ مناسب دادههای Dictionary
اگر دادههای برنامهات از قبل به شکل Dictionary باشند،
DictWriter معمولاً خواناتر و مدیریت آن راحتتر است.🔹 چرا
newline=""؟هنگام کار با
csv بهتر است فایل را با:newline=""
باز کنیم.
این کار باعث میشود ماژول
csv مدیریت خطوط فایل را به شکل صحیح انجام دهد و از ایجاد خطوط خالی اضافی در بعضی محیطها جلوگیری شود.⚠️
w و a را اشتباه نکن"w"
محتوای قبلی فایل را هنگام نوشتن جایگزین میکند.
اما:
"a"
برای اضافه کردن داده به انتهای فایل است.
مثلاً:
with open("users.csv", "a", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["Reza", 30, "Tabriz"])🧠 خلاصه
csv.writer() → نوشتن List
csv.DictWriter() → نوشتن Dictionary
writerow() → یک سطر
writerows() → چند سطر
writeheader() → نوشتن Header
"w" → جایگزینی محتوا
"a" → اضافه کردن به انتهای فایل
🎯 تمرین
فایل زیر را ایجاد کن:
products.csv
و اطلاعات زیر را با
DictWriter ذخیره کن:name,price,stock
Laptop,1200,5
Mouse,25,20
Keyboard,70,10
سعی کن از:
writeheader()
writerows()
استفاده کنی.
پست ۱۶۸ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۶۹
اضافه کردن داده به CSV با
در پست قبل یاد گرفتیم با
حالا میخواهیم داده جدید را به فایل موجود اضافه کنیم؛ بدون اینکه اطلاعات قبلی پاک شوند.
🔹 مشکل حالت
اگر فایل را با حالت:
باز کنیم، محتوای قبلی هنگام نوشتن جایگزین میشود.
پس برای اضافه کردن اطلاعات از:
استفاده میکنیم.
🔹 اضافه کردن یک کاربر
فرض کنیم فایل
حالا میخواهیم
فایل حالا:
⚠️ Header را دوباره ننویسیم
وقتی از حالت
بنابراین نباید هر بار این را اجرا کنیم:
وگرنه ممکن است نتیجهای شبیه این ایجاد شود:
🔹 بررسی وجود فایل
اگر برنامه ممکن است برای اولین بار اجرا شود، بهتر است ابتدا بررسی کنیم فایل وجود دارد یا نه:
در این حالت:
🔹 اضافه کردن چند رکورد
میتوانیم چند Dictionary را همزمان اضافه کنیم:
🧠 خلاصه
🎯 تمرین
برنامهای بنویس که فایل:
را بررسی کند.
اگر فایل وجود نداشت، Header زیر را ایجاد کند:
سپس محصول زیر را به فایل اضافه کند:
اگر برنامه را چند بار اجرا کردی، Header نباید هر بار تکرار شود.
پست ۱۶۹ از دوره جامع 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 جستوجو و فیلتر انجام دهیم.
🔹 مثال ساده
فرض کنیم
میخواهیم فقط محصولاتی را پیدا کنیم که موجود هستند:
خروجی:
🔹 فیلتر بر اساس قیمت
مثلاً محصولاتی که قیمت آنها کمتر از
خروجی:
دقت کن که مقدار CSV رشته است؛ بنابراین برای مقایسه عددی از:
استفاده کردیم.
🔹 ترکیب چند شرط
میتوانیم چند شرط را همزمان بررسی کنیم:
خروجی:
چون هر دو شرط باید درست باشند.
🔹 ذخیره نتایج فیلترشده
گاهی فقط چاپ کردن کافی نیست و میخواهیم نتایج را در یک لیست ذخیره کنیم:
حالا
⚠️ نکته مهم
قبل از مقایسه عددی، مقدار CSV را به نوع مناسب تبدیل کن:
یا:
چون:
یک مقایسه رشتهای است و نتیجه آن با مقایسه عددی متفاوت است.
🧠 خلاصه
🎯 تمرین
فایل زیر را در نظر بگیر:
برنامهای بنویس که فقط محصولاتی را نمایش دهد که:
خروجی مورد انتظار:
پست ۱۷۰ از دوره جامع 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 تغییر کرده است.
🔹 نوشتن دوباره فایل
حالا باید اطلاعات جدید را دوباره در CSV ذخیره کنیم:
فایل حالا:
🔹 یک مثال کامل
⚠️ نکته مهم
در CSV، مقدارها هنگام خواندن معمولاً
بنابراین:
در اینجا یک رشته است.
اگر داده را به عدد تبدیل کنیم:
برای انجام محاسبات مناسب است؛ اما هنگام ذخیره CSV،
🔹 اگر محصول پیدا نشود چه؟
میتوانیم یک متغیر برای بررسی این موضوع داشته باشیم:
این روش در برنامههای واقعی کاربردیتر است.
🧠 خلاصه
برای ویرایش CSV معمولاً:
CSV برای دادههای ساده و جدولی مناسب است، اما اگر تعداد دادهها زیاد شود یا عملیات پیچیدهای مثل جستوجو، تراکنش و همزمانی داشته باشیم، معمولاً Database انتخاب مناسبتری است.
🎯 تمرین
فایل زیر را در نظر بگیر:
برنامهای بنویس که:
محصول
قیمت آن را از
فایل CSV را دوباره ذخیره کند.
اگر محصول وجود نداشت، عبارت زیر را چاپ کند:
پست ۱۷۱ از دوره جامع 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 نیست، برای حذف معمولاً این مراحل را انجام میدهیم:
🔹 مثال
فرض کنیم
میخواهیم
ابتدا فایل را میخوانیم:
حالا محصول موردنظر را حذف میکنیم:
در نتیجه
🔹 ذخیره دوباره فایل
فایل نهایی:
🔹 بررسی اینکه رکورد وجود داشته است
میتوانیم قبل و بعد از حذف، تعداد رکوردها را مقایسه کنیم:
اگر محصول وجود داشته باشد:
و اگر وجود نداشته باشد:
🔥 مثال کامل
⚠️ نکته مهم
در این روش ابتدا کل فایل را در حافظه میخوانیم:
برای فایلهای کوچک مشکلی نیست.
اما برای فایلهای بسیار بزرگ، بهتر است معماری مناسبتری استفاده کنیم یا از Database استفاده کنیم.
🧠 خلاصه
یعنی CSV امکانات مستقیم
🎯 تمرین
فایل زیر را در نظر بگیر:
برنامهای بنویس که:
محصول
فایل را دوباره ذخیره کند.
اگر محصول وجود نداشت، چاپ کند:
بعد از اجرای موفق، فایل باید شامل این موارد باشد:
پست ۱۷۲ از دوره جامع 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 |
تا اینجا همه فایلهای CSV ما با کاما جدا میشدند:
اما در دنیای واقعی ممکن است فایلها از جداکنندههای دیگری استفاده کنند.
مثلاً:
یا:
برای مشخص کردن جداکننده از پارامتر:
استفاده میکنیم.
🔹 خواندن CSV با
اگر فایل اینطور باشد:
باید بنویسیم:
خروجی:
🔹 نوشتن CSV با جداکننده دلخواه
همین موضوع برای
فایل ایجادشده:
🔹
میتوانیم از جداکنندههای مختلف استفاده کنیم:
یا:
یا حتی:
البته باید فایل را مطابق همان فرمت بخوانیم.
⚠️ نکته مهم
اگر جداکننده فایل
مثلاً:
اگر با
پس هنگام خواندن CSV باید ساختار واقعی فایل را بدانیم.
🔹 جداکننده با داده داخل متن
فرض کنیم یک مقدار خودش شامل کاما باشد:
ماژول
خروجی:
یعنی نباید CSV را با
🧠 خلاصه
و:
🎯 تمرین
فایل زیر را در نظر بگیر:
برنامهای بنویس که:
فایل را با
از
نام و قیمت محصولات را چاپ کند.
خروجی:
پست ۱۷۳ از دوره جامع 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
در پست قبل با
اما یک سؤال مهم وجود دارد:
اگر خود داده شامل کاما یا جداکننده باشد، Python چطور تشخیص میدهد که آن کاما بخشی از متن است یا جداکننده ستونها؟
برای این کار CSV از Quote استفاده میکند.
🔹 مشکل بدون Quote
فرض کنیم اطلاعات یک محصول این باشد:
اینجا مشخص نیست:
یک مقدار است یا دو ستون جدا.
🔹 استفاده از Quote
در CSV میتوانیم مقدار را داخل
حالا Python میفهمد که کامای داخل
🔹 خواندن با
خروجی:
🔹 نوشتن دادهای که کاما دارد
اگر با
فایل CSV به شکل مناسب ذخیره میشود:
🔹 اگر خود متن شامل
مثلاً:
در CSV برای نمایش
ماژول
⚠️ نکته مهم
به همین دلیل بهتر است CSV را با:
مدیریت کنیم.
استفاده از:
برای CSVهای واقعی قابل اعتماد نیست؛ چون ممکن است دادهها شامل:
کاما
Quote
جداکنندههای مختلف
باشند.
🧠 خلاصه
🎯 تمرین
داده زیر را در نظر بگیر:
برنامهای بنویس که با
خروجی:
پست ۱۷۴ از دوره جامع 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 است.🔹 خواندن با
csvimport 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 با
در پست قبل دیدیم که Python چگونه دادههایی را که شامل کاما یا
حالا میتوانیم مشخص کنیم چه زمانی مقدارها داخل Quote قرار بگیرند.
برای این کار از پارامتر:
استفاده میکنیم.
🔹
حالت پیشفرض
Python فقط زمانی از Quote استفاده میکند که لازم باشد.
خروجی:
چون ردیف اول به Quote نیاز ندارد، اما ردیف دوم شامل کاماست.
🔹
با این حالت، تمام مقدارها داخل Quote نوشته میشوند:
خروجی:
🔹
در این حالت مقدارهای متنی Quote میشوند و مقدارهای عددی بدون Quote نوشته میشوند:
خروجی:
🔹
در این حالت Python بهصورت معمول Quote اضافه نمیکند.
اگر داده شامل delimiter باشد، باید آن را به شکل مناسب Escape کنیم؛ در غیر این صورت ممکن است خطا ایجاد شود.
برای CSVهای معمولی، معمولاً نیازی به استفاده از این حالت نداریم.
🧠 مقایسه
⚠️ نکته مهم
در بیشتر پروژهها لازم نیست
حالت پیشفرض:
برای بسیاری از فایلهای CSV کافی است.
تنظیم
🎯 تمرین
کد زیر را تغییر بده تا تمام مقدارهای CSV داخل Quote نوشته شوند:
فایل خروجی باید شبیه این باشد:
پست ۱۷۵ از دوره جامع 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 با
تا اینجا یاد گرفتیم:
CSV را بخوانیم.
داده جدید اضافه کنیم.
دادهها را فیلتر کنیم.
رکوردها را ویرایش و حذف کنیم.
حالا یک برنامه کوچک میسازیم که چند عملیات را روی یک فایل CSV انجام دهد.
🔹 ساخت فایل اولیه
ابتدا یک فایل به نام:
میسازیم:
🔹 خواندن اطلاعات
حالا فایل را میخوانیم:
هر ردیف به شکل یک Dictionary در اختیار ما قرار میگیرد.
مثلاً:
⚠️ توجه کن که مقدارهای CSV هنگام خواندن معمولاً
🔹 تبدیل مقدارهای عددی
اگر بخواهیم روی قیمت محاسبه انجام دهیم:
🔹 فیلتر کردن محصولات
مثلاً فقط محصولاتی را نمایش دهیم که موجود هستند:
خروجی:
🔹 یک نکته مهم درباره
این دو روش را با هم اشتباه نکن:
هر ردیف را به شکل List میدهد:
اما:
هر ردیف را به شکل Dictionary میدهد:
برای فایلهایی که ستونهای مشخص دارند،
🧠 خلاصه
و اگر مقدار عددی باشد:
چون CSV خودش نوع دادههای 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 تقریباً همه مقدارها هنگام خواندن به شکل
مثلاً:
اگر بخواهیم
برای مقدار:
با خطای:
مواجه میشویم.
🔹 استفاده از
میتوانیم تبدیل داده را داخل
اگر یکی از مقدارها قابل تبدیل نباشد، برنامه متوقف نمیشود و
🔹 مثال با داده نامعتبر
فرض کنیم CSV این باشد:
خروجی:
پس فقط رکورد نامعتبر رد میشود و پردازش بقیه دادهها ادامه پیدا میکند.
🔹 مدیریت جداگانه قیمت و موجودی
گاهی بهتر است بدانیم کدام ستون مشکل دارد:
در اینجا:
باعث میشود پردازش همین رکورد متوقف شود و حلقه سراغ رکورد بعدی برود.
🔹 بررسی مقدار خالی
ممکن است مقدار یک ستون کاملاً خالی باشد:
در این حالت:
باعث
میتوانیم قبل از تبدیل بررسی کنیم:
⚠️ نکته مهم
برای دادههای CSV فقط این کافی نیست:
چون داده ممکن است:
باشد.
بهتر است هنگام ورود داده به برنامه، آن را اعتبارسنجی و تبدیل کنیم.
🧠 الگوی پیشنهادی
برای CSV میتوانیم این الگو را داشته باشیم:
مثلاً:
🎯 تمرین
فایل زیر را در نظر بگیر:
برنامهای بنویس که:
CSV را با
خطاهای
رکوردهای نامعتبر را رد کند.
فقط محصولات معتبر را چاپ کند.
خروجی معتبر باید شامل:
باشد.
پست ۱۷۷ از دوره جامع 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 🐍