مدير وسائل التواصل الاجتماعي
النشر حين يكون جمهورك مستيقظًا فعلًا، بهاشتاغات يبحث عنها الناس فعلًا، هو معظم تسويق المنصات. يبني هذا المشروع مديرًا صغيرًا يدرس بيانات تفاعل سابقة مع pandas، ويتعلم أفضل وقت نشر لكل منصة، ويقترح هاشتاغات لكل موضوع عبر محرك تقييم صغير، ويخطط أسبوعًا من المنشورات في تقويم محتوى، ويختم بتقرير تحليلات matplotlib يمكنك تدويره مباشرة في روتين علامة تجارية حقيقية.
يفترض هذا أساسيات بايثون وارتياحًا مع groupby في pandas ، لا شيء أبعد من ذلك من تحليل البيانات مطلوب. المشروع اختياري وغير مُقيَّم؛ راجع المشاريع الواقعية للقائمة الكاملة المتزايدة.
🎯 ما ستفعله
- توليد مجموعة بيانات تفاعل واقعية وتحميلها مع pandas.
- تجميع التفاعلات حسب المنصة والساعة لإيجاد أفضل نافذة نشر لكل منصة.
- بناء محرك اقتراح هاشتاغات يقيّم الهاشتاغات مقابل موضوع.
- توليد تقويم محتوى لسبعة أيام من ترتيب أفضل الأوقات.
- رسم مخطط تقرير تحليلات أسبوعي لأداء المنصات.
أين تُشغّل هذا
التشغيل محليًا عبر uv هو المسار الأساسي. يثبت pandas وmatplotlib نظيفًا، وخلفية Agg غير التفاعلية لـ matplotlib (المستخدمة في الخطوة 5) تُصيِّر الرسوم حتى على جهاز بلا شاشة، وتصل ملفات CSV وتقرير PNG فعلًا إلى مجلد مشروعك.
Google Colab ودفاتر Kaggle وBinder طرق معقولة لتجربة البناء كله ، يعمل pandas وmatplotlib هناك فورًا. التحفظ الصادق أن نظام ملفات الدفتر الزائل لا يُبقي posts.csv أو تقريرك المحفوظ عبر الجلسات، فتعامل معها كمسارات تجربة وانتقل إلى uv محليًا حين تريد للتقويم ونتاجات التقرير أن يثبتا.
الإعداد
أنشئ المشروع وثبّت المكتبتين اللتين بُنيت الأداة كلها عليهما.
uv init social-media-manager
cd social-media-manager
uv add pandas matplotlib
uv run python -c "import pandas, matplotlib; print('ok')"
pandas طبقة البيانات ، تحميل وتجميع وترتيب التفاعلات ، وmatplotlib طبقة الرسم للتقرير النهائي. تثبيت كلتيهما مسبقًا يجعل كل خطوة أدناه عن أفكار التسويق لا عن معارك التبعيات.
✅ قائمة التحقق
- ✅ انتهى
uv add pandas matplotlibويطبعuv run python -c "import pandas, matplotlib"كلمةok. - ✅ يوجد مشروع
social-media-manager/جديد معpyproject.toml.
الخطوة 1: بناء مجموعة بيانات التفاعل
كل قرار محتوى في هذا المشروع ، أفضل وقت، أفضل هاشتاغات، أفضل منصة ، حساب على تفاعلات سابقة. تبني هذه الخطوة جدول تفاعل واقعيًا قابلًا للتكرار حتى يكون للخطوات التالية شيء حقيقي تُرتَّب عليه.
1.1 توليد مجموعة بيانات قابلة للتكرار
👟 تلميح البداية : استخدم random.seed ليعطي كل تشغيل نفس مجموعة البيانات، ثم ابنِ إطار بيانات pandas بصف واحد لكل منشور سابق واحفظه إلى CSV.
# smm.py
import random
import pandas as pd
PLATFORMS = ["Instagram", "X", "LinkedIn", "TikTok"]
DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
TOPICS = ["python", "data", "career", "product"]
def build_dataset(rows: int = 120, seed: int = 7) -> pd.DataFrame:
random.seed(seed)
df = pd.DataFrame({
"platform": [random.choice(PLATFORMS) for _ in range(rows)],
"topic": [random.choice(TOPICS) for _ in range(rows)],
"day": [random.choice(DAYS) for _ in range(rows)],
"hour": [random.randint(7, 23) for _ in range(rows)],
"engagements": [random.randint(4, 240) for _ in range(rows)],
})
return df
df = build_dataset()
df.to_csv("posts.csv", index=False)
print(df.head(3).to_string(index=False))
print(df.groupby("platform")["engagements"].mean().round(1))
ما يجعل هذه المجموعة قابلة للتكرار هو random.seed(seed): نفس البذرة تعطي نفس ساعة التفاعل «العشوائية» في كل تشغيل، فيكون ترتيب أفضل وقت الذي تحصل عليه في الخطوة 2 هو الترتيب في الناتج المتوقع لا إجابة جديدة في كل مرة. تثبيت seed داخل الدالة ، لا في أعلى الوحدة ، يُبقي الجدول ثابتًا حتى لو ناديت build_dataset أكثر من مرة. وindex=False في to_csv يُبقي عمود فهرس شاردًا خارج الملف فيعيد التحميل إطار بيانات نظيفًا.
🎯 الناتج المتوقع : أعمدة platform وtopic وday وhour وengagements في المعاينة، ثم صف متوسط تفاعل لكل منصة ، مثل Instagram في مكان ما بين 100 و140.
🩹 إذا لم يعمل : إذا اختلفت الأعمدة، تحقق أن مفاتيح القاموس في منشئ DataFrame تتهجى كل عمود. إذا أنتج تشغيل ثانٍ أرقامًا مختلفة، فـ random.seed مفقود أو يُستدعى ببذرة مختلفة عن التي في التوقيع. إذا كتب to_csv عمود Unnamed: 0 عند إعادة التحميل، فـ index=False مفقود.
1.2 التحقق من مجموعة البيانات
✅ قائمة التحقق
- ✅ يعمل
smm.pyويطبع معاينة 3 صفوف إلى جانب جدول متوسط لكل منصة. - ✅ يوجد ملف
posts.csvبـ 120 صفًا والأعمدة الخمسة. - ✅ تشغيل السكربت مرتين يطبع أرقامًا متطابقة (بيانات قابلة للتكرار).
🤔 سؤال (أسئلة) سقراطي(ة)
- لو غيّرت
random.seed(7)إلىrandom.seed(8)، يتغير الملف ، لماذا يهم ذلك لترتيب الخطوة 2 تريد مقارنته مع أصدقاء، وماذا يخبرك عن متى تكون البذرة ميزة لا مصادفة؟ - لا تحتوي مجموعة البيانات عمود
date، بلdayوhourفقط. ما السؤال على مستوى اليوم الذي يمكنك إجابته، وما السؤال على مستوى اليوم الذي يستحيل؟
الخطوة 2: إيجاد أفضل وقت نشر لكل منصة
تقويم محتوى جيد بقدر الأوقات التي يجدولها. تحوّل هذه الخطوة جدول التفاعل إلى الرقم الذي يريده المسوّقون فعليًا: متوسط التفاعل للنشر عند كل ساعة على كل منصة.
2.1 التجميع والحساب والترتيب
👟 تلميح البداية : جمّع التفاعلات بـ groupby(["platform", "hour"]) وخذ المتوسط وتفقد الساعات الأعلى ، هذا هو الترتيب كله، لا حاجة لحلقة.
# smm.py (continued)
def best_times(df: pd.DataFrame, top_n: int = 3) -> pd.DataFrame:
hourly = (
df.groupby(["platform", "hour"])["engagements"]
.mean()
.round(1)
)
ranking = (
hourly.reset_index()
.sort_values(["platform", "engagements"], ascending=[True, False])
.groupby("platform", sort=False)
.head(top_n)
.reset_index(drop=True)
)
return ranking
ranking = best_times(df)
print(ranking.to_string(index=False))
اقرأ السلسلة من الأسفل إلى الأعلى: groupby(["platform", "hour"]) ينشئ مجموعة لكل زوج منصة–ساعة، و["engagements"].mean() تطوي كل مجموعة إلى متوسطها، و.round(1) تُبقي التقرير مرتبًا، وsort_values(["platform", "engagements"], ascending=[True, False]) يرتب بالمنصة أولًا ثم التفاعل تنازليًا فطفو أفضل ساعة لكل منصة إلى قمة كتلتها. و.groupby("platform", sort=False).head(top_n) الأخير يُبقي أعلى top_n صف داخل كل منصة ، هذه هي «أفضل 3 ساعات لكل منصة» التي ستعطيها للتقويم.
🎯 الناتج المتوقع : جدول بأعمدة platform وhour وengagements، تظهر فيه كل منصة بالضبط 3 مرات وصفوفها الثلاثة مرتبة من الأعلى إلى الأدنى.
🩹 إذا لم يعمل : إذا حصلت على كتلة 3 صفوف واحدة بدلًا من أربع، فخطوة sort_values الداخلية مفقودة فانتزعت head(3) المجموعات الأولى لا الأفضل. إذا بدا متوسط الساعات متطابقًا عبر المنصات، فجمّعت على عمود واحد فقط. إذا بدا ترتيب الصفوف مبعثرًا، فقائمة sort_values ذات العمودين بترتيب خاطئ.
2.2 التحقق من الترتيب
✅ قائمة التحقق
- ✅ للـ
rankingبالضبطtop_nصف لكل منصة، مرتبة من الأعلى إلى الأدنى داخل كل منصة. - ✅ أفضل ساعة لمنصة واحدة على الأقل ساعة مسائية متأخرة (18–23)، نافذة تفاعل مرتفعة كلاسيكية في البيانات المزروعة.
- ✅ تستطيع الإشارة إلى السطرين اللذين يقومان بالتجميع والترتيب.
🤔 سؤال (أسئلة) سقراطي(ة)
- يحسب الترتيب متوسط التفاعلات الخام لكل ساعة، فتبدو المنصة ذات الثلاثة منشورات المحظوظة في ساعة واحدة «الأفضل» هناك. ما الذي سيتغير في التوصية لو استخدمت الوسيط بدلًا من المتوسط؟
- جدول ساعة–يوم فيه 7 × 17 خلية. ما الإحصاء الجديد الذي كنت ستضيفه لو نشرت علامة تجارية صباحًا حصرًا ، وكيف تميّز بين «الصباح أفضل أوقاتها» و«لم تنشر مساءً قط»؟
الخطوة 3: بناء محرك اقتراح الهاشتاغات
الهاشتاغات هي فهرس البحث في معظم المنصات: الصحيح منها يرفع المنشور إلى أشخاص كانوا يبحثون أصلًا. تبني هذه الخطوة محرك تقييم صغير يربط موضوعًا بهاشتاغات مرتبة ، الشكل نفسه الذي يعيده واجهة اقتراح حقيقية.
3.1 تقييم الهاشتاغات وترتيبها
👟 تلميح البداية : خزّن كل هاشتاغ مع درجة صلة في قاموس موضوعات، رتّب بالدرجة، واقتطع إلى n ، «المحرك» مجرد بيانات زائد sorted.
# smm.py (continued)
HASHTAG_POOL = {
"python": [("#Python", 95), ("#100DaysOfCode", 88), ("#CodeNewbie", 81),
("#DataScience", 79), ("#PythonTips", 70)],
"data": [("#DataScience", 97), ("#Analytics", 90), ("#DataViz", 84),
("#BigData", 80), ("#DataStorytelling", 72)],
"career": [("#CareerGrowth", 91), ("#TechCareers", 85), ("#JobSearchTips", 78)],
"product":[("#ProductManagement", 92), ("#BuildInPublic", 84), ("#PM", 77)],
}
def suggest_hashtags(topic: str, n: int = 4) -> list[str]:
pool = HASHTAG_POOL.get(topic.lower(), [("#ContentTips", 60)])
pool = sorted(pool, key=lambda item: item[1], reverse=True)
return [tag for tag, _score in pool[:n]]
print(suggest_hashtags("python"))
print(suggest_hashtags("analytics"))
«المحرك» كله sorted على أزواج مُقيَّمة وشريحة. نمذجة كل هاشتاغ كـ ("#Tag", 95) لا كسلسلة تجعل الترتيب سؤال بيانات لا خيارًا مبرمجًا ، reverse=True يضع أعلى درجة أولًا، وpool[:n] يقتطع إلى حجم الدلو المطلوب. الافتراضي .get(topic.lower(), ...) يعني أن الموضوع المجهول يتحول إلى بديل عام بدلًا من تحطيم التقويم الذي ستبنيه في الخطوة 4.
🎯 الناتج المتوقع : ['#Python', '#100DaysOfCode', '#CodeNewbie', '#DataScience'] لسلسلة "python"، وهاشتاغات دلو data لسلسلة "analytics" بفضل .lower().
🩹 إذا لم يعمل : إذا بدا الترتيب عشوائيًا، فمفتاح التقييم key=lambda item: item[1] مفقود فيقارن sorted الأزواج كاملة. إذا أعاد "analytics" البديل العام، فمفاتيح القاموس ، data لا analytics ، لا تطابق؛ وافتراضي .get يخفي ذلك بصمت. إذا عاد طول خاطئ، فالشريحة [:n] تستخدم n مختلفًا عمّا طلبت.
3.2 التحقق من محرك الهاشتاغات
✅ قائمة التحقق
- ✅
suggest_hashtags("python")تعيد 4 هاشتاغات، الأعلى درجة أولًا. - ✅ الموضوع المجهول يعيد البديل
#ContentTipsبدلًا من إطلاقKeyError. - ✅ تستطيع شرح لماذا الهاشتاغات، وترتيبها، بيانات لا منطق.
🤔 سؤال (أسئلة) سقراطي(ة)
- الدرجات (95، 88، …) مكتوبة يدويًا. من ماذا كان مدير حقيقي يحسبها ليتحدث الترتيب تلقائيًا حين يبلى هاشتاغ؟
sortedهنا مستقر للدرجات المتساوية. متى يحتاج هاشتاغان بنفس الدرجة إلى فاصل تعادل، وما الذي سيكون؟
الخطوة 4: توليد تقويم محتوى حقيقي
التقويم هو حيث تصبح القرارات جدولًا. تدمج هذه الخطوة ترتيب أفضل الأوقات من الخطوة 2 مع محرك هاشتاغات الخطوة 3 لتخطط سبعة منشورات ملموسة ، اليوم والمنصة والساعة والموضوع والهاشتاغات ، جاهزة للصق في أي مجدول.
4.1 تخطيط الأسبوع من الترتيب
👟 تلميح البداية : لُفّ الأيام السبعة، اختر منصة اليوم من أفضل نتيجة واحدة وموضوعًا دوّارًا، وأعد استخدام الدالتين اللتين كتبتهما مسبقًا بدلًا من تكرار منطقهما.
# smm.py (continued)
def build_calendar(ranking: pd.DataFrame, topics: list[str], days: int = 7) -> list[dict]:
best_time = (
ranking.groupby("platform", sort=False)
.head(1)
.set_index("platform")["hour"]
.to_dict()
)
calendar = []
for day_offset in range(days):
day = DAYS[day_offset % 7]
platform = list(best_time.keys())[day_offset % len(best_time)]
topic = topics[day_offset % len(topics)]
calendar.append({
"day": day,
"platform": platform,
"hour": best_time[platform],
"topic": topic,
"hashtags": ", ".join(suggest_hashtags(topic)),
})
return calendar
for post in build_calendar(ranking, TOPICS):
print(f"{post['day']:>3} {post['platform']:<10} {post['hour']:>2}:00 "
f"{post['topic']:<10} {post['hashtags']}")
يطوي best_time الترتيب إلى الساعة الفائزة الوحيدة لكل منصة عبر .groupby(...).head(1) ويحوّلها إلى قاموس {platform: hour} مع set_index + to_dict ، ذلك القاموس هو جدول البحث الصغير الذي تستشيره الحلقة. دوران المنصات بالمعامل (% len(best_time)) ودوران الموضوعات بالطريقة نفسها يعني أن خطة 7 أيام تنتشر على المنصات الأربع والموضوعات الأربعة دون أن تتراكم التكرار. إعادة استخدام suggest_hashtags هنا هي مردود الخطوة 3: هاشتاغات التقويم تأتي من محرك التقييم، فتحسين الدرجات يحسّن كل منشور مجدول.
🎯 الناتج المتوقع : سبعة صفوف قابلة للطباعة، واحد لكل يوم، كلٌّ باسم اليوم والمنصة والساعة الفائزة والموضوع وأربعة هاشتاغات مفصولة بفواصل، ولا يشارك صفّان متتاليان منصة.
🩹 إذا لم يعمل : إذا ظهر KeyError على best_time[platform]، فمنصة في الحلقة ليست في القاموس ، تحقق أن ranking يحتوي فعلًا المنصات الأربع من الخطوة 2. إذا كان كل صف المنصة نفسها، فدوران المعامل يستخدم len(best_time) لكنه يفتح بالقيمة الخاطئة. إذا طُبعت الهاشتاغات كقائمة بايثون، فـ ", ".join(...) مفقود.
4.2 التحقق من التقويم
✅ قائمة التحقق
- ✅ للتقويم بالضبط 7 صفوف باليوم والمنصة والساعة والموضوع والهاشتاغات.
- ✅ كل ساعة مجدولة تطابق أفضل ساعة لمنصة من ترتيب الخطوة 2.
- ✅ لا تظهر المنصة مرتين في يومين متتاليين.
🤔 سؤال (أسئلة) سقراطي(ة)
- يدوّر التقويم المنصات بالتساوي متجاهلًا أن بعضها تفوق على أخرى. كيف تزيح الدوران نحو المنصات عالية الأداء دون التخلي تمامًا عن الضعيفة؟
- جدولة منشور واحد يوميًا اعتباطية. ما البيانات ، من ترتيب الخطوة 2 ، التي تبرر النشر مرتين على بعض المنصات وصفرًا على أخرى؟
الخطوة 5: بناء تقرير التحليلات الأسبوعي
التُحوّل الأخير هو الذي تشاركه فعلًا: تقرير مرئي عن أي منصة أنجزت، يُولَّد كـ PNG يمكنك إرفاقه بدعوة اجتماع. ترسم هذه الخطوة الرسم الرئيسي وتطبع جدول ملخص إلى جانبه.
5.1 رسم مخطط أداء المنصة
👟 تلميح البداية : اضبط matplotlib على خلفية Agg بلا رأس، واحسب إجمالي تفاعل كل منصة، واحفظ مخطط الأعمدة في ملف ، ثم اطبع الأرقام نفسها نصًا حتى يعمل التقرير حين لا يستطيع أحد رؤية PNG.
# smm.py (continued)
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def weekly_report(df: pd.DataFrame, out: str = "weekly_report.png") -> None:
totals = df.groupby("platform")["engagements"].sum().sort_values(ascending=False)
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(totals.index, totals.values, color="#4C86C6")
ax.set_title("Engagements per platform (last week)")
ax.set_ylabel("Total engagements")
ax.tick_params(axis="x", rotation=20)
fig.tight_layout()
fig.savefig(out, dpi=100)
plt.close(fig)
print("Total engagements per platform:")
print(totals.to_string())
weekly_report(df)
يجب أن تعمل matplotlib.use("Agg") قبل استيراد pyplot ، تبدل النافذة التفاعلية بخلفية بلا عرض، وهو ما يسمح لهذا المخطط بالرسم على خادم أو داخل دفتر أو على آلة بلا شاشة إطلاقًا. fig.savefig(out, dpi=100) هو السطر الجوهري: يكتب ملف PNG حقيقيًا، وplt.close(fig) بعده يحرر الشكل حتى لا تجمع حلقة تنادي weekly_report مرارًا الذاكرة. طباعة المجاميع نفسها كجدول تُبقي التقرير مفيدًا لمن يقرأ ناتج الطرفية لا الصورة.
🎯 الناتج المتوقع : يظهر ملف weekly_report.png في مجلد المشروع (مرئي في مستكشف الملفات)، وتطبع الطرفية إجماليات المنصات الأربع بترتيب تنازلي.
🩹 إذا لم يعمل : إذا ذكر تتبّع خطأ الخلفية Agg، فـ matplotlib.use("Agg") تأتي بعد سطر import matplotlib.pyplot ، انقلها إلى أعلاه. إذا لم يظهر PNG، تحقق من مسار savefig: يحفظ نسبةً إلى دليل العمل الحالي. إذا كان المخطط فارغًا بخلاف ذلك، فـ plt.close(fig) جرى قبل إنهاء savefig ، ابدل الترتيب.
5.2 التحقق من البداية إلى النهاية
✅ قائمة التحقق
- ✅ يعمل
weekly_report.pyبسلاسة ويكتبweekly_report.pngإلى القرص. - ✅ المجاميع المطبوعة تطابق ارتفاعات أعمدة الرسم.
- ✅ خط الأنابيب كله ، مجموعة البيانات → الترتيب → الهاشتاغات → التقويم → التقرير ، يعمل من
smm.pyوحده دون تعديلات نسخ–لصق بين الخطوات.
🤔 سؤال (أسئلة) سقراطي(ة)
- يجمع التقرير التفاعلات الخام، فتبدو منصة فيها منشور فيروسي واحد مهيمنة. ما المقياس الذي ترسمه بدلًا منه لإظهار أداء مستدام لا يومًا محظوظًا واحدًا؟
- كتب
savefigإلى أي دليل شغّلت منه السكربت. كيف تجعل مسار التقرير صريحًا ومحمولًا لو كان مجلد مشروعك تحتcontent/؟
⚠️ مآزق شائعة
- نسيان البذرة فيُعاد ترتيب كل تشغيل مختلفًا. أرقام التفاعل عشوائية؛ دون
random.seed(seed)في أعلىbuild_datasetتتغير «أفضل ساعة» في الخطوة 2 بين التشغيلات ولا يستطيع الأصدقاء مقارنة النتائج. الإصلاح: أبقِ البذرة معاملًا بقيمة افتراضية ثابتة. - إثبات المكاسب بمجاميع خام لا متوسطات. جمع التفاعلات يكافئ فقط المنصات التي نشرت أكثر. التقرير صادق فقط حين يستخدم متوسط التفاعل (جدولا الخطوتين 2 و5) إلى جانب المجاميع.
- عدم معالجة الموضوعات المجهولة. موضوع أُخطئت كتابته في التقويم يحطم المحرك بـ
KeyError. بديل.get(topic, [("#ContentTips", 60)])يحوّل ذلك الانهيار إلى افتراضي معقول. - تقويم مبرمج يدويًا لا مولَّدًا. كتابة الاثنين–الأحد يدويًا تتجاهل ترتيب الخطوة 2 ودرجات هاشتاغات الخطوة 3. الإصلاح: أبقِ التقويم دالةً في البيانات فتحسين البيانات يحسّن الجدول.
- الرسم مع الاتصال بالعرض. خلفيات matplotlib التفاعلية تنكسر على الآلات بلا رأس (CI وبعض الدفاتر). اضبط
matplotlib.use("Agg")قبلimport pyplotكما في الخطوة 5.
ما بنيته للتو
مدير وسائل تواصل اجتماعي يعمل: يتعلم أفضل نافذة نشر لكل منصة من توزيعات تفاعل حقيقية، ويقترح هاشتاغات مقيَّمة لكل موضوع، ويخطط أسبوعًا كاملًا من المنشورات، ويصيِّر رسمًا تحليليًا قابلًا للمشاركة ، نسخة كاملة من حلقة البحث ثم النشر التي يديرها فريق اجتماعي يدويًا. المهارة القابلة للنقل هي ترك البيانات تتخذ قرارات الجدولة: أي سؤال «متى يجب أن نفعل هذا؟» في مستقبلك، من إرسال البريد إلى جلسات الدراسة، هو نفس نمط groupby-and-rank الذي استخدمته هنا.
شغِّل نسخة أكمل دون أي إعداد محلي
examples/social-media-manager/ في مستودع الدورة نسخة أكمل من الكود أعلاه، مع محرك الهاشتاغات والتقويم موصولين بالفعل في واجهة أوامر واحدة. استنسخه، أو افتح المستودع كله في GitHub Codespace، وشغّله من هناك.
إلى أين تذهب من هنا
- أطعمه بيانات حقيقية: صدّر سجل منشورات منصتك، ضعه في
posts.csv، وراقب إعادة حساب ترتيب أفضل وقت من تفاعلات فعلية لا مزروعة. - أضف عامل اليوم من الأسبوع بالتجميع على
(day, hour)معًا، فلا تطّور نافذة الاثنين 9:00 تعمل لنافذة الثلاثاء 20:00 وتتظاهر بأنهما سواء. - ثبّت التقويم بعمود
datetimeسليم (يوم أسبوع + ساعة + تاريخ) واكتبه إلى CSV ليتسنى استيراده مباشرة في Buffer أو Hootsuite أو مجدول Meta. - قيّم الهاشتاغات من أداء حقيقي ، بربط هاشتاغات كل منشور بتفاعله ، بدلًا من الدرجات المكتوبة يدويًا في الخطوة 3.
شارك مشروعك مع الصف
بنيت شيئًا تفخر به؟ examples/student-projects/ معرض مشاريع قدّمها طلاب آخرون ، وREADME يضم إرشادًا كاملًا صديقًا للمبتدئين لإضافة مشروعك عبر طلب سحب (pull request)، حتى لو لم تستخدم git من قبل: نسخ المستودع، إنشاء فرع، التزام ملفاتك، وفتح PR، خطوة بخطوة. لا تُفترض أي خبرة سابقة بـ git.
مرحبًا بك في كتابة بايثون خارج المتصفح. 🎓
أكمل كل خطوة ثم حدد المشروع كمكتمل لجمع نقاطه.