• اگر سمپادی هستی همین الان عضو شو :
    ثبت نام عضویت

پایتون! (چرا برنامه‌نویسی بامزه و جالب هست...)

  • شروع کننده موضوع
  • #1

Yabançı

کاربر نیمه‌حرفه‌ای
ارسال‌ها
255
امتیاز
387
نام مرکز سمپاد
طلایه داران
شهر
لاچین
رشته دانشگاه
JLE
چرا همه باید برنامه‌نویسی یاد بگیرند ؟
به نظرم فرقی نمیکنه چند سالتون باشه ، تو چه رشته‌ای تحصیل میکنید و یا چه آینده‌ی شغلی واسه خودتون در نظر گرفتید ، یادگرفتن برنامه‌نویسی میتونه به شما نحوه‌ی درست فکر‌کردن رو یاد بده ، علاوه بر این برنامه‌نویسی دید شما رو نسبت به مسائل وسیع‌تر میکنه.

چرا پایتون؟
اگه سمپادی باشین به احتمال زیاد با چند تا زبان‌برنامه‌نویسی آشنا هستید و احتمالا مبانی یکی از زبان‌ها مثل سی یا سی‌پلاس‌پلاس یا بیسیک رو بلدید ، یادمه ما تو دوره‌ی دبیرستان cpp رو یاد میگرفتیم که به نظرم بد‌ترین گزینه برای یاد‌دادن به یک دانش‌آموز بود چون زبان های سطح پایین و میانی اصلا برای کاربرد‌‌ های علمی و عمومی مناسب نیستند بعد‌ها آموزش‌وپروش نشون داد که همیشه گزینه بد‌تری هم وجود داره و یک زبان تجاری و تاریخ‌گذشته و کم‌کاربرد و ضعیف به نام vb رو بهمون یاد داد.
من به دلیل علاقم به برنامه‌نویسی با زبان‌های برنامه‌نویسی زیادی کار کردم و برنامه نوشتم از سی و سی‌پلاس‌پلاس و جاوا گرفته تا زبون‌های تحت وب مثل پی‌اچ‌پی و زبون‌های فریمورک دات نت مثل سی‌شارپ و ... ، در بین این زبان ها تا چند ماه پیش جاوا به عنوان انتخاب اصلیم برای کار‌های کوچیک و شبه‌علمیم بود مثلا یادمه وقتی کتاب ساعت‌ساز نابینای داوکینز رو میخوندم باهاش پروژه تفریحی فرگشت-کلمات رو شبیه‌سازی کردم.
تو دانشگاه به صورت اجباری با متلب آشنا شدم نفرت‌انگیز‌ترین زبان ممکن! به معنای واقعی از ساختارش حالت تهوع میگرفتم کتابخونه های بسته و تجاری! البته دقیقا مطابق با ساختار علمی ایران!
تا اینکه پایتون رو شناختم! به معنای واقعی کلمه فوق‌العاده هست ، پایتون زبان اول برنامه‌نویسی هست که تو اکثر کالج های آمریکا یاد میدن و همچنین شرکت‌هایی مثل گوگل و یاهو و ناسا پروژه‌های زیادی رو تو این زبان پیاده کردند. پایتون آزاد و سریع و آسون و سطح‌بالا و قابل‌حمل و زیبا و رایگان هست.

نمیخوام در مورد تاریخچه پایتون بگم میتونید اینجا بخونید : https://en.wikipedia.org/wiki/Python_%28programming_language%29



پیش‌فرض این پست این هست که شما در حد متوسط انگلیسی و به طور حرفه‌ای کار با کامپیوتر رو بلدید و حداقل با یک زبان‌برنامه نویسی آشنایی دارید.
ضمنا تو این تاپیک قرار نیست زبان پایتون رو یاد بدم فقط میخوام یاد بدم با پایتون چی کار میشه کرد و چرا برنامه‌نویسی بامزه و جالب هست ، البته واسه کسایی که دارن یاد میگرن یه سرنخ‌هایی میدم که برن پیدا کنن و یاد بگیرن!

لطفا هر سوال و پیشنهادی داشتید تو قسمت سوالات بپرسید.

* واسه اجرای کدهام از سایت https://wakari.io استفاده میکنم که مفسر آنلاین کد پایتون هست(فوق‌العاده نیست!؟) ، شما هر کجا دلتون خواست میتونید کداتون رو اجرا کنید.



طرح مسئله : الان به سرم زد دوباره فیلم «One Flew Over The Cuckoos Nest» رو ببینم و چون تصمیم گرفتم یکمی انگلیسیم رو تقویت کنم زیرنویس انگلیسی فیلم رو هم دانلود کردم اما از اونجایی که زبان انگلیسی من خوب نیست خیلی دلم میخواد یه ترجمه‌نصفه و نیمه هم از زیر‌نویس‌ها یه جایی داشته باشم.

حل مسئله : زیرنویس فیلم یک فایل متنی با فرمت srt هست ، من فایل زیرنویس انگلیسیمو با یه ویرایشگر متن (مثل notepad) باز میکنم بزار اسکرین شاتش رو هم بزارم!

4f1wrnkjtb3m.png

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

...
شماره بخش
زمان شروع نمایش --> زمان پایان نمایش
متن جمله انگلیسی
سطر خالی
...

من میخوام همچین چیزی داشته باشم :

...
شماره بخش
زمان شروع نمایش --> زمان پایان نمایش
متن جمله انگلیسی
متن جمله ترجمه‌شده
سطر خالی
...

خوب وارد اکانتم در سایت wakari میشم و به کمک ابزار های پنل چپ (مخصوص مدیریت فایل‌ها) یه پوشه واسه پروژه میسازم و زیرنویس رو هم آپلود میکنم تو همون پوشه :

i9yxoomvczkf.png


تو wakari باید کدهامون رو تو یه notebook بنویسیم پس با گزینه new notebook یه دفترچه جدید میسازیم ، میتونیم بنویسیم 1+1 بعد اجراش کنیم تا ببینیم کار میکنه یا نه :

hf5a9tvnlt4t.png

خوب حالا آماده‌ایم که کار رو شروع کنیم.
اول باید فایل زیرنویس رو بخونیم واسه خوندن فایل متنی یه تابعی هست تو پایتون به شکل زیر :
[ltr]open (name , mode , buffering)[rtl]
این تابع سه تا آرگومان داره که name آدرس و اسم فایل هست ، mode کاری هست که میخوایم رو فایل انجام بدیم مثلا خوندن یا نوشتن و بافرینگ هم بافرینگ فایل رو کنترل میکنه!
خوب مورد دوم و سوم اختیاری هستند و کلا نیاز نداریم از مورد سوم استفاده بکنیم واسه همین توضیحش نمیدم.

در برنامه نویسی یک نوع متغیر وجود داره به نام رشته یا string که شامل یه تعداد کاراکتر پشت سر هم هست.ما رشته ها رو داخل کوتیشن نشون میدیم مثلا اینطوری : "python"
تو پایتون میشه با تابع print یک رشته رو نشون دارد مثلا اینو ببینید:


5v74xk7wber9.png

یادتون باشه تو wakari کد شما به سلول های مختلفی تقسیم میشه که میتونید با گزینه ران فقط یک سلول رو اجرا کنید ولی برای اجرای تمام کد باید از قمست cell گزینه run all رو بزنید.
تو رشته ها بعضی کاراکترهای ویژه هستند مثل سطر بعدی و ... که برای نشون دادنشون از بک‌اسلش استفاده میکنیم.با فرمت "x\" که ایکس نشون دهنده کاراکتر ويژمون هست فرض کنید یه رشته‌ای داریم که توش کوتیشن داریم اینطوری میتونیم نشونش بدیم :

9k2ukkadjezb.png

یا مثلا برای یک رشته چند سطری میتونیم اینکارو بکنیم :


ge6qvzq5sq4r.png

برای اینکه به پایتون بگیم که بک‌اسلش نشانه‌ی کاراکتر خاص نیست و منظورمون خود بک اسلش هست میتونیم یه r پشت رشته بزاریم که به معنی raw string یا رشته خام هست این دستورات رو با دستورات قبلی مقایسه کنید :

t0cpetoidebc.png

حالا برگردیم سراغ تابع open و آرگومان هاش ، آرگومان اسم فایل اینطوری میشه :
[ltr]name = "/user_home/w_sadiq/subtitle/ofotcn.srt"[rtl]
به آدرس فایل دقت کنید که sadiq اسم یوزر من تو wakari هست و شما باید یوزر خودتون رو بزنید یا مثلا اگه کد پایتونتون رو تو ویندوز اجرا کنید همچین آدرسی میشه :
[ltr]name = r"c:\subtitle\ofotcn.srt"[rtl]
آرگومان مدش هم اینطوری میشه:
[ltr]mode = "r"[rtl]
که به معنی خوندن هست.
با دستورات زیر فایل رو میریزیم تو متغیر file :

ja0rzedacibq.png

خوب متغیر file در واقع مثل رشته و عدد نیست و یک شی یا object هست.میتونیم با دستور زیر متن فایل رو بخونیم و بریزیم تو یک متغیر :
[ltr]subtitle_text = file.read()[rtl]

با دستور print میتونیم رشته subtitle_text رو ببینیم :

9kjfzd0d5qtp.png

کار بعدی که میخوام بکنم اینه که هر قسمت زیرنویس رو جدا کنم و یه آرایه از این قسمت‌های زیرنویس بسازم.قبلا بهتون گفتم که سطر بعدی رو تو یک رشته به شکل "n\" نشون میدیم ، این نحوه واسه سیستم‌های یونیکس بیس هست ولی تو ویندوز از دو کاراکتر "r\n\" استفاده میکنیم.میتونید اینطوری تصور کنید که تو آخر هر سطری این کاراکتر ها وجود دارند ولی دیده نمیشن، حالا میتونیم با استفاده از تابع split قسمت‌های بین سطر‌های خالی زیر نویس رو جدا کنیم ، حالا به طور مثال میتونم قسمت 56ام زیر‌نویس رو جدا بکنم و نمایش بدم :

x74lk61hlji9.png

یکی از قدرت های پایتون ماژول ها یا کتابخونه های گسترده و غنی اون هستند ، ماژول ها رو میشه بسته‌های توابع آماده در نظر گرفت برای مثال کتابخانه استاندارد math شامل توابع ریاضی مثل توابع مثلثاتی و ... هست.با یه جست‌و‌جوی ساده میتونید ماژول‌های مختلف ترجمه رو پیدا کنید.من میخوام از ماژول goslate استفاده کنم که میتونید document های مربوط به این ماژول رو تو این آدرس بخونید:
http://pythonhosted.org/goslate/
برای نصب این کتابخانه کافی هست تو کنسول shell سایت wakari این دستور رو وارد کنید:
[ltr]pip install goslate[rtl]

cvv2ybglk5v0.png

برای استفاده از یک ماژول باید به این روش اون رو import بکنید:
[ltr]import modulename[rtl]

این هم روش استفاده ازش :

rn06surko30q.png

خوب اینجا باید حواسمون باشه که اگه بخوایم همه‌ی چند صد خط زیر‌نویس رو یکی‌یکی بفرستیم به سرور گوگل ترنسلیت و ترجمشو بگیریم گوگل تشخیص میده که این کار یک آدم نیست بلکه کار یک برنامه هست و دسترسی بهش رو واسه شما میبنده.متاسفانه من حواسم نبود و در نتیجه گوگل کلا آدرس ip سایت wakari رو بن کرد!!
روش درست اینکار به نظرم این بود که همه‌ی زیر‌نویس ها رو ترکیب میکردم و تو یک درخواست میفرستادیم به مترجم گوگل نه درخواست های متوالی یا حداقل بین درخواست‌هایی که برای ترجمه به سرور گوگل میفرستادم یکمی تاخیر زمانی قرار میدادم ، در هر حال به اشتباه یه نوع حمله denial of services رو سرور های گوگل انجام دادیم!
خوب میریم سراغ راه حل بعدی!
از اونجایی که از مترجم گوگل محروم شدم میریم سراغ مترجم bing متعلق به مایکروسافت با ماژول mstranslator که میتونید داکیومنتاش رو تو لینک زیر پیدا کنید :
https://pypi.python.org/pypi/mstranslator

برای نصبش تو کنسول shell سایت wakari این دستور رو وارد کنید:
[ltr]pip install mstranslator[rtl]



خوشبختانه ماژول مایکروسافت تا یک‌میلیون کاراکتر رو رایگان ترجمه کنید برای استفاده ازش باید در سایت مایکروسافت نرم‌افزارتون رو ریجستر کنید و کلید ارتباطی بگیرید.
این لینک مرحله‌به مرحله یاد داده چیکار باید کرد :
http://blogs.msdn.com/b/translation/p/gettingstarted1.aspx

بعد از اینکه نرم‌افزارتون رو ریجستر کردین و دو مقدار <Client ID> و <Client secret> رو از ماکروسافت دریافت کردین میتونید از ماژول به شکل زیر استفاده کنید :


82m0d1tyi2ag.png


خوب بقیه مراحل خیلی آسون هست باید در یک حلقه for تک‌تک المان های آرایه بخش‌های ترجمه رو بگیریم و ترجمه کنیم و به آرایه اضافه کنیم.برای آشنا شدن با حلقه‌ی for تو پایتون به لینک پایین برید :
https://wiki.python.org/moin/ForLoop

مشکلی که وجود داره این هست که چون ارسال درخواست ترجمه و دریافتش زمانبر هست بهتره با استفاده از نشان دادن شماره بخش در حال ترجمه از روند ترجمه مطلع شیم ، میشد این کار رو با تابع print انجام بدیم اما چون این تابع هر خروجی رو در سطر مجزا چاپ میکنه به جاش از تابع stdout.write استفاده کردم که در ماژول استاندارد sys هست :

7p5a0iubsawq.png

تنها کار باقیمونده اینه که دوباره یک فایل زیر نویس بسازیم و ذخیرش کنیم.

کد کل برنامه اینطوری میشه :

[ltr]
from mstranslator import Translator
from sys import stdout

name = "/user_home/w_sadiq/subtitle/ofotcn.srt"
mode = "r"
file = open (name,mode)
subtitle_text = file.read()
subs_array = subtitle_text.split("\r\n\r\n")
translator = Translator('<Client ID>', '<Client secret>')
for i,part in enumerate(subs_array):
text_part="".join(part.splitlines()[2:])
translated_text=translator.translate(text_part, lang_from='en', lang_to='fa')
subs_array=part+"\r\n"+translated_text
stdout.write(part.splitlines()[0]+",")
subtitle_result="\r\n\r\n".join(subs_array)
r_name = "/user_home/w_sadiq/subtitle/result_ofotcn.srt"
r_mode = "w"
result_file = open (r_name,r_mode)
result_file.write(subtitle_result.encode('utf8'))
result_file.close()


[rtl]
حالا باید زیر نویس رو امتحان کنیم! :

w4o19cqas835.png
 
  • شروع کننده موضوع
  • #2

Yabançı

کاربر نیمه‌حرفه‌ای
ارسال‌ها
255
امتیاز
387
نام مرکز سمپاد
طلایه داران
شهر
لاچین
رشته دانشگاه
JLE
حرف نزن! که از حرافی و پرگویی... (بررسی آماری)

طرح مسئله: یه کمی مهندسی داده و بررسی آماری تاپیک حرف بزن

از اونجایی که من در یکی از نقاط محروم دنیا زندگی میکنم چند ساعتی هست سرعت نت به اندازه‌ای افت کرده که نمیتونم اسکرین‌شات آپلود کنم!


قدم اول - به دست آوردن داده! :D
خوب برای شروع میریم صفحه ورود سمپادیا ، میخواهیم بدونیم واسه ورود به سمپادیا چه اطلاعاتی نیاز هست پس باید بسته‌هایی که مرورگرمون میفرسته رو بررسی کنیم.
پیشنهاد من پلاگین poster فایرفاکس هست.بعد از نصب ، فعالش کنید ،برید صفحه ورود یوز و پسوردتون رو وارد کنید و ورود رو بزنید.
با بررسی اطلاعات ارسالی و بررسی نه چندان خوشایند کد های جاوا‌اسکریپت و اچ‌تی‌ام‌ال صفحه ورود سایت متوجه شدم که سایت سمپادیا برای ورود یک هش ترکیبی از یوزر و پسوردم میسازه و میفرسته به سایت.
اما هش کردن چی هست؟ این چیزیه که حتما باید یاد بگیرین! هش کردن به طور خلاصه تبدیل یک فایل یا متن به عدد n رقمی هست به طوری که هر فایل یا متن هش اختصاصی خودش رو داشته باشه و پیدا کردن دو فایل با هش یکسان بسیار بسیار سخت باشه.یادتون باشه هش کردن یک عمل یکطرفه هست و بازگشت پذیر نیست.
https://en.wikipedia.org/wiki/Hash_function

چون موضوع هش کردن وجود داره شما ماژول hashlib پایتون رو حتما نیاز پیدا خواهید کرد!

با بررسی کد جاوا‌اسکریپت سایت من این دو تا تابع رو نوشتم:[ltr]
def hex_sha1(value):
return hashlib.sha1(value).hexdigest()

def sampadia_hash(user,passwrd,cur_session_id):
return hex_sha1(hex_sha1(user.encode("utf8").lower()+passwrd.encode("utf8"))+cur_session_id)
[rtl]
اگه به تابع سمپادیاـ‌هش دقت کنید میبینید که سه تا آرگومان دریافت میکنه اولیش یوزرنیم هست بعدیش پسورد و آخریش شماره جلسه!

اما شماره جلسه چی هست؟ وقتی تو سایت وارد میشید سایت شما رو با شماره جلستون میشناسه ، به طور مثال وقتی تو سایت خبری مورد علاقتون میزنید صفحه بعد سایت با توجه به شماره جلسه شما میفهمه که چه صفحه‌ای هستید و باید چه صفحه‌ای برید و چه خبر‌هایی مورد علاقه‌شما هست و ...
نحوه به دست آوردن شماره جلسه رو بهتون خواهم گفت!

میریم سراغ پایتون اول باید جلسه‌مون رو فعال کنیم : [ltr]
sampadia = requests.session()
[rtl]
تو مرحله‌ی بعدی باید ماژول فوق‌العاده requests پایتون رو import کنیم و صفحه ورود رو از سرور سمپادیا دریافت کنیم : [ltr]
login_page=sampadia.get("http://www.sampadia.com/forum/index.php?action=login")
[rtl]

اما شماره جلسه! شماره جلسه تو کد اچ‌تی‌ام‌الی که از سایت دریافت کردین وجود داره و برای دریافتش باید با مفهومی آشنا بشین به نام regular expression ، که روشی برای جدا کردن قسمت‌های مورد علاقمون از یک رشته کاراکتر هست برای مثال میتونید با re تمام آدرس های ایمیل رو از یک رشته جدا کنید.
تو این لینک میفهمین عبارت‌های با قاعده دقیقا چی هستند :
https://en.wikipedia.org/wiki/Regular_expression
این لینک هم یه سایت فوق‌العاده برای یاد گرفتنش هست :
http://regexone.com/
اگه سرعت نتتون شبیه من نیست این ویدیو رو حتما ببینید :
http://jadi.net/2016/01/jaditv-009-regex-is-the-star/

برگردیم سراغ شماره جلسه ، اول ماژول re رو import میکنید و بعد : [ltr]
t=re.search("hashLoginPassword\(this, '(\w*)'\);", login_page.content)
cur_session_id=t.group(1)
[rtl]
خوب حالا که هر سه مقدار رو داریم بریم از تابع sampadia_hash استفاده بکنیم : [ltr]
sh=sampadia_hash(username,"password,cur_session_id)
[rtl]
خوب وقت ورود به سایته : [ltr]
cache=dict(user="username",passwrd="",cookielength="120",hash_passwrd=sh)
home_page=sampadia.post("http://www.sampadia.com/forum/index.php?action=login2",data=cache)
[rtl]
نکته جالبش اینه که تو قسمت کش پسورد رو خالی میزارید! بله پسوردتون ارسال نمیشه ، تنها چیزی که ارسال میشه ترکیب یوزر و پسورد هش شدتون هست.
خوب الان وارد سایت شدیم. به کارهایی که ازین به بعد قراره انجام بدم میگن web scrapping ، در واقع میخوام به برنامه بگم که برو و تمام پست‌های حرف بزن رو پیدا کن و ذخیره کن !!! فوق‌العاده هست نه؟
اول این لینک رو بخونید :
https://en.wikipedia.org/wiki/Web_scraping

تو مرحله بعدی با ماژول فوق‌العاده Beautiful Soup آشنا بشین و سریع bs4 رو import بکنید :
http://www.crummy.com/software/BeautifulSoup/bs4/doc/#beautiful-soup-documentation
قرار هست این ماژول تکه‌هایی از صفحه که نیاز داریم رو با css selector ها واسمون برگردونه! برای پیدا کردن css selector یه کم تجربه وب و برنامه‌نویسی css نیاز هست + پلاگین گوگل‌کروم به نام SelectorGadget .
ادامه کد دیگه خیلی ساده هست.
کد این قسمت از برنامه :[ltr]

import hashlib
import bs4
import requests
import urllib
import re
import time
from sys import stdout

def hex_sha1(value):
return hashlib.sha1(value).hexdigest()

def sampadia_hash(user,passwrd,cur_session_id):
return hex_sha1(hex_sha1(user.encode("utf8").lower()+passwrd.encode("utf8"))+cur_session_id)
sampadia = requests.session()
login_page=sampadia.get("http://www.sampadia.com/forum/index.php?action=login")
t=re.search("hashLoginPassword\(this, '(\w*)'\);", login_page.content)
cur_session_id=t.group(1)
sh=sampadia_hash("username","password",cur_session_id)
cache=dict(user="username",passwrd="",cookielength="120",hash_passwrd=sh)
home_page=sampadia.post("http://www.sampadia.com/forum/index.php?action=login2",data=cache)

h_poster=[]
h_text=[]
h_post=[]
for i in range(0,900):
link="http://www.sampadia.com/forum/index.php/topic,109165."+str(i*15)+".html"
page=sampadia.get(link)
soup=bs4.BeautifulSoup(page.content)
post=soup.select(".post_wrapper")
for j in range(0,14):
p_soup=bs4.BeautifulSoup(str(post[j]))
p_poster=p_soup.select("h4 a")[0].string
p_text=p_soup.select(".inner")[0].text
h_poster.append(p_poster)
h_text.append(p_text)
h_post.append(str(post[j]))
stdout.write("-"+p_poster.encode("utf8")+"-")
stdout.write(str(i)+",")
time.sleep(4)

f_pposter=open("/home/sadiq/pposter.txt","w")
f_ptext=open("/home/sadiq/ptext.txt","w")
f_post=open("/home/sadiq/post.txt","w")
for item in h_poster:
f_pposter.write("%s\n" % item.encode("utf8"))
for item in h_text:
f_ptext.write("%s\n\n*\n\n" % item.encode("utf8"))
for item in h_post:
f_post.write("%s\n\n*\n\n" % item)
f_pposter.close()
f_ptext.close()
f_post.close()

[rtl]


این قسمت ما 900 صفحه حرف‌بزن رو استخراج کردیم و حالا باید بریم قدم دوم :


قدم دوم - تحلیل‌های آماری :
برای پیدا کردن بیشترین فراوانی تو هر لیست قراره از ماژول collections استفاده کنیم پس اضافش کنید :
[ltr]
from collections import Counter
[rtl]

برای ساختن دیکشنری از نام کاربری و تعداد پست :

[ltr]
poster_cnt=Counter()}
file_name="/home/sadiq/pposter.txt"
f_pposter=open(file_name,"r")
pposter=f_pposter.read()
poster=pposter.split("\n")
for one in poster:
poster_cnt[one] += 1
[rtl]

پیدا کردن ده کاربری که بیشترین پست رو دادن :
[ltr]
print poster_cnt.most_common(10)
[rtl]
برای ساخت دیکشنری از لغت‌ها و تکرارشون + تعداد کل کارکتر ها + تعداد کل کلمات :
[ltr]
word_cnt=Counter()
w=0
char=0
file_name="/home/sadiq/ptext.txt"
f_ptext=open(file_name,"r")
ptext=f_ptext.read()
text=ptext.split("\n\n*\n\n")
for post in text:
char+=len(post)
words=post.split()
for word in words:
word_cnt[word] += 1
w+=1
[rtl]
تا این قسمت از کد تعداد کل کاراکتر‌ها(char) و تعداد کل کلمات(w) و دیکشنری تکرار کلمات(word_cnt) رو بدست آوردیم.
اگه دیکشنری تکرار کلمات رو چاپ کنیم میبینیم که همه‌ی لغت‌های پر تکرار ، حروف اضافه و ربط هستند. اما من میخوام حذفشون کنم و فقط کلماتی رو داشته باشم که به طور مستقل معنی میدن پس کد پایین رو هم اضافه میکنیم :

[ltr]
entriestoberemoverd=["و","با","که","به","از","در","تا","این","اون","بود"
,"رو","یه","می","ی","بعد","دیگه","،","که","ولی"
,"هر","باید","‌",".","كه","\xc2\xa0","وقتی","هم"
,"یا","های","\xda\xa9","ها","برای","دارم","کنم","فقط"]
for i,key in enumerate(entriestoberemoverd):
entriestoberemoverd=str(key)

for key in entriestoberemoverd:
if key in word_cnt:
del word_cnt[key]
[rtl]

حالا میتونیم با کد پایین خیلی راحت بیست‌کلمه‌ی پر کاربرد حرف بزن رو ببینیم :
[ltr]
common_words=word_cnt.most_common(20)
[rtl]



* خیلی دوست داشتم پست مفصل‌تر با توضیحات بهتری مینوشتم اما نتم مشکل پیدا کرد و فردا میرم مسافرت و برگشتنم ممکنه طول بکشه ، به نظرم اومد که پست کردنش کار بهتری هست!
*خیلی دوست داشتم با ماژول matplotlib پایتون نمودار‌های بیشتری مثل توزیع زمانی پست‌ها و نسبت‌لایک به تعداد پست رو هم پیدا میکردیم!
*پیشنهاد ها و نظراتتون رو تو تاپیک سوال‌های پایتون بگین!



نمودار ها با کمک LibreOffice Calc:


۱- 10 کاربر با بیشترین پست (اسامی به دلیل حفظ حریم شخصی تار شدند!) :



zv6307cvhcho.png




۲- بررسی جنسیتی 10 کاربر با بیشترین پست :




bgvrfj54z2oi.png


۳- 20 کلمه‌ی پر کاربرد در حرف بزن :


ukflsm7xxevy.png





۴- تعداد کلمات :

658,662



۵- تعداد کاراکتر ها :

5,938,723
 
  • شروع کننده موضوع
  • #3

Yabançı

کاربر نیمه‌حرفه‌ای
ارسال‌ها
255
امتیاز
387
نام مرکز سمپاد
طلایه داران
شهر
لاچین
رشته دانشگاه
JLE
حدس کلمه با پایتون!

نمیخوام در مورد درست یا غلط بودنش بحث کنم اما من در هر بازی که بتونم تقلب کنم حتما تقلب میکنم! :D تو این پست میخوام تلاش کنم تا برای تقلب در بازی حدس کلمه یه راه‌حل پیدا کنم.
499_001.jpg
وقتی در مورد برنامه‌نویسی حرف میزنیم معمولا انتظار سه ویژگی سرعت، دقت و راحتی رو از برنامه داریم. در ورود به حیطه‌ی زبان‌ انسان باید از ویژگی‌های سرعت و دقت چشم‌پوشی کنیم[nb]برای اطلاعات بیشتر در این زمینه و مقایسه‌ی مغز و پردازشگر برید به این تاپیک.[/nb] مگر اینکه چیزی به قدرت واتسون در دست داشته باشیم. کمترین انتظار ما باید چیزی باشه که کمک کنه راحت‌تر کلمه رو حدس بزنیم.
فرض کنید میخوایم کلمه‌ای 8 حرفی پیدا کنیم، این 8 حرف !8 جایگشت مختلف دارند که هر کدوم میتونه یک کلمه باشه. !8 میشه 40320 جایگشت مختلف.
هر کلمه هشت‌حرف رو در حافظه اشغال میکنه که با در نظر گرفتن دوبایت برای هر حرف(کاراکترهای یونیکد)، حافظه‌ی اشغال شده میشه: n*n!*2 بایت ، با این حساب حافظه‌ی من مشکلی برای محاسبه‌ تا کلمات هشت حرفی نخواهد داشت.
برای اینکه بررسی کنم یک ترکیب خاص از حروف کلمه‌‌ی معنی‌دار هست، اون رو در گوگل سرچ میکنم و با توجه به تعداد نتایج سعی میکنم قابل‌قبول بودن اون رو تشخیص بدم.
چنین جست‌وجویی به طور تقریبی[nb]بخاطر این که بین جست‌و‌جو ها باید به طور تصادفی صفر تا سه ثانیه تاخیر ایجاد کنم، برای فهمیدن دلیلش مراجعه کنید به پست اول تاپیک![/nb] برای کلمه‌ی ۵ حرفی ۱۸۰ ثانیه، برای کلمه‌ی ۶ حرفی ۱۰۸۰ ثانیه(۱۸ دقیقه) و برای کلمه‌ی ۷ حرفی ۱۲۶ دقیقه طول میکشه! میبینیم که عملا این روش برای کلمات بالاتر از پنج حرف کاربردی نیست.
باید یه راهی پیدا کنیم که قسمت بزرگی از این ترکیب‌ها رو قبل از جست‌و‌جو در گوگل بتونیم حذف کنیم،به عبارت دیگه برای رسیدن به سرعت بیشتر باید راهی پیدا کنیم که تشخیص بدیم ترکیبی از حروف میتونه کلمه‌ی فارسی[nb]اگر کلمات ترکی بودند میشد با رابطه‌ی مصوت‌ها و صامت ها حدود 70 درصد جایگشت ها رو حذف کرد.[/nb] باشه یا نه!
من در این مرحله از ایده‌ی خود بازی کمک میگیرم، وقتی یک نفر حروف رو در ترتیب خاص به عنوان سوال قرار میده مطمئنا تلاش کرده که ترتیب قرار‌گیری حروف تا حد ممکن از ترتیب درست قرار‌گیری اون‌ها دور باشه تا فرد جواب‌دهنده نتونه به راحتی کلمه‌ رو تشخیص بده! برای اینکار باید بعد از ساخت جایگشت‌های حروف اون‌هارو با ترتیب اولیه مقایسه کنیم تا بیش از اندازه شبیه نباشند. :)
در واقع باید یکی از الگوریتم‌های string similarity metric رو استفاده کنیم، از اونجایی که من هیچ چیز از این الگوریتم‌ها نمیدونم از الگوریتم پیش‌فرض پایتون استفاده میکنم و با آزمون و خطا به دقت مناسب میرسم، برای کلمات شش حرفی درجه‌شباهت کمتر از ۰.۴۵ مقدار جایگشت ها رو از ۷۲۰ حالت به ۲۳۸ حالت کاهش میده که نتیجه‌ی قابل قبولی هست، همچنین زمان محاسبه‌ی یک کلمه‌ی هفت‌حرفی رو هم از ۱۲۶ دقیقه به ۴۲ دقیقه کاهش میده.
کد نهایی در پایتون به این صورت میشه [nb]برای اینکه حدالامکان نتایج زبان‌های دیگه رو از نتایج گوگل حذف کنم عبارت «در یک» رو به ابتدای جست‌و‌جو‌ها اضافه کردم.[/nb]:

کد:
#itertools is a library of iteration toolds
import itertools
import difflib 
import requests
from bs4 import BeautifulSoup
import time
from random import randint
import re
from sys import stdout

letters=r"نایجس"
words=[]
for i in itertools.permutations(letters):
    word="".join(i)
    if difflib.SequenceMatcher(None,word,letters).ratio()<0.45:
        words.append(word)

print("we have "+str(len(words))+" word\n")
print(words)
print("\nestimated time = "+str(len(words)*3)+"s \n")
word_results=[]
print("working on :")
for word in words:
    stdout.write(str(words.index(word))+",")
    r = requests.get("https://www.google.com/search", params={'q':"در یک "+word})
    soup = BeautifulSoup(r.text, "lxml")
    res = soup.find("div", {"id": "resultStats"})
    m=re.search(r"(\d+\s)", res.text.replace(",", ""))
    try:
        word_results.append(int(m.group(0)))
    except:
        word_results.append(-1)
    time.sleep(randint(0,3))

ls=list(zip(word_results,words))
ls.sort(reverse=True)
print("\nWords :")
print("1. "+str(ls[1]))
print("2. "+str(ls[2]))
print("3. "+str(ls[3]))
print("4. "+str(ls[4]))
print("5. "+str(ls[5]))
print("...")

نتیجه‌ی برنامه برای حدس کلمه‌ی کاربر Sanctum :
حروف : ن ا ی ج س

m.png

کلمه‌ی «نساجی» در پیشنهاد چهارم برنامه دیده میشه (;
 

ememlia

⁦(⊙_◎)⁩
عضو مدیران انجمن
ارسال‌ها
856
امتیاز
19,970
نام مرکز سمپاد
شهید بهشتی
شهر
.
سال فارغ التحصیلی
1397
خدا میدونه من چقد این تاپیک رو دوس دارم8->8->
سلام ...بازم من:))
داشتم تاپیک سرعت تایپ رو نگاه میکردم و در عجب بودم ک چرا انقد سرعت تایپ من ب نسبت بده:-?
واضحه ک آمار صفحه آخر فیکه
ب سرم زد یجوری تقلب کنم ک کسی نتونه ثابتش کنه:)):)):))
قدم اول :
خب اول باید بفهمیم ک چی رو باید تایپ کنیم:
ساده اس ...میریم تو https://10fastfingers.com/typing-test/english و پیچ رو سیو میکنیم تو آدرسی ک میخوایم
با notepad بازش میکنیم اون وسطا خیلی شیک متن رو پیدا میکنیم
wy58_screenshot_from_2020-03-24_01-09-24.png

خب اینهاش:))
قدم دوم:
خب باید تایپش کنیم:
پایتون یه کتابخونه داره ب اسم pynput ک توش یه کلاس هست ب اسم keyboard
خیلی کارکردن باهاش راحته داکیومنتش رو از اینجا بخونید:-"
mzoc_screenshot_from_2020-03-24_01-14-02.png

من یه کد درپیت نوشتم:-"
خط ۸ بهمون ۳ ثانیه فرصت میده تا بهش بفهمونیم کجا باید تایپ کنه
توی متغیر خط ۴ باید اون متنی ک قراره تایپ بشه قرار بگیره
اون دوتا حلقه هم دونه دونه کاراکتر ها رو تایپ میکنن
قدم سوم :
ترکیب مرحله اول و دوم:
ahjc_screenshot_from_2020-03-24_01-20-05.png

قدم چهارم :
تستش میکنیم:
p1ut_screenshot_from_2020-03-24_01-21-27.png

سرعتش ک خوبه ولی چندتا سوتی داد اون وسط ک بخاطر \n آخر هر خطه
درست کردنش سخت نیس ولی من حالشو ندارم:-"/m\
قدم پنجم :
آپلود تو تاپیک مربوطه و طلبیدن حریف:))
فعلاh-:
 

ememlia

⁦(⊙_◎)⁩
عضو مدیران انجمن
ارسال‌ها
856
امتیاز
19,970
نام مرکز سمپاد
شهید بهشتی
شهر
.
سال فارغ التحصیلی
1397
دیشب این پست از ریحانه رو تو ح.ب دیدم :
اگه ی روز بتونم ی اختراع انجام بدم
ی دکمه به همه لوازمی که کیبورد جدا دارن مثل لپ تاب/کامپیوتر اضافه میکنم
که هر وقت اونو بزنی هرچی اشتباه به انگلیسی تایپ کردی یا به فارسی !
و خلاصه که یادت رفته دکمه شیفت و آلت رو بگیری رو برعکس کنه
یعنی اگ انگلیسی نوشتی فارسی و بلعکس:)

+امیدوارم تونسته باشم منظورمو برسونم=)
+خیلی زخم خورده م=)
ایده جالبی بود .... از خودم هم بیکار تر خودمم :))
so let's do it :)

اول دوتا دیکشنری درست میکنم ک رابطه بین کلید هارو داشته باشیم :
Python:
e2f = {'q': 'ض',
       'w': 'ص',
       'e': 'ث',
       'r': 'ق',
       't': 'ف',
       'y': 'غ',
       'u': 'ع',
       'i': 'ه',
       'o': 'خ',
       'p': 'ح',
       '[': 'ج',
       ']': 'چ',
       'a': 'ش',
       's': 'س',
       'd': 'ی',
       'f': 'ب',
       'g': 'ل',
       'h': 'ا',
       'j': 'ت',
       'k': 'ن',
       'l': 'م',
       ';': 'ک',
       "'": 'گ',
       'z': 'ظ',
       'x': 'ط',
       'c': 'ز',
       'v': 'ر',
       'b': 'ذ',
       'n': 'د',
       'm': 'پ',
       ',': 'و',
       'H': 'آ'}

f2e = {'ض': 'q',
       'ص': 'w',
       'ث': 'e',
       'ق': 'r',
       'ف': 't',
       'غ': 'y',
       'ع': 'u',
       'ه': 'i',
       'خ': 'o',
       'ح': 'p',
       'ج': '[',
       'چ': ']',
       'ش': 'a',
       'س': 's',
       'ی': 'd',
       'ب': 'f',
       'ل': 'g',
       'ا': 'h',
       'ت': 'j',
       'ن': 'k',
       'م': 'l',
       'ک': ';',
       'گ': "'",
       'ظ': 'z',
       'ط': 'x',
       'ز': 'c',
       'ر': 'v',
       'ذ': 'b',
       'د': 'n',
       'پ': 'm',
       'و': ',',
       'آ': 'H'}
الان ما میدونیم هرکدوم از دکمه های انگلیسی کیبورد، کدوم کاراکتر فارسی رو تایپ میکنن و برعکس
اینا بر اساس کیبورد من نوشته شدن .... مثلا جای "پ" تو کیبورد من و شما فرق داره(ویندوز و لینوکس)
حالا میخوایم متن رو سلکت کنیم -> کپی کنیم -> توی متغیر ذخیره کنیم
روش های زیادی هستن واسه اینکار :
مثلا کیلپبورد رو از سیستم عامل بگیری یا از ماژول tkinter استفاده کنی
مثلا تی کی اینجوری کار میکنه :
Python:
from tkinter import Tk
root = Tk()
root.withdraw()
text = root.clipboard_get()
ولی تو استاندارد لیب های پایتون یه کتابخونه هست ب اسم pyperclip که دوتا متود داره به اسم copy , paste و کلیپبورد رو میخونه و یا آپدیت میکنه:
Python:
import pyperclip
pyperclip.copy("salam")
text = pyperclip.paste()
print(text)
# --> salam
یه روش درپیت هم واسه خود کات کردن و پیست کردن تو فیلد استفاده میکنم:
alt+a و ctrl+x و ctrl+v خیلی شیک و سرراست سلکت میکنه , کات میکنه , پیست میکنه
کتابخونه pynput دوتا کلاس داره یکیش key هستش ک همه کلید های کیبورد توشن و یکیش کنترولر و باهاش میشه به کیبورد فرمان داد:
Python:
from pynput.keyboard import Key, Controller

# alt + a -> select
    keyboard.press(Key.alt)
    keyboard.press('a')
    keyboard.release(Key.alt)
    keyboard.release('a')
# ctrl + x -> cut
    keyboard.press(Key.ctrl)
    keyboard.press('x')
    keyboard.release(Key.ctrl)
    keyboard.release('x')
# ctrl + v -> paste
    keyboard.press(Key.ctrl)
    keyboard.press('v')
    keyboard.release(Key.ctrl)
    keyboard.release('v')
با چیزایی ک میدونیم دوتا تابع مینویسم :
Python:
def get_text():

    keyboard.press(Key.alt)
    keyboard.press('a')
    keyboard.release(Key.alt)
    keyboard.release('a')
    keyboard.press(Key.ctrl)
    keyboard.press('x')
    keyboard.release(Key.ctrl)
    keyboard.release('x')
    return paste()
    
    def paste_text(text):

    copy(text)
    keyboard.press(Key.ctrl)
    keyboard.press('v')
    keyboard.release(Key.ctrl)
    keyboard.release('v')
تابع اول وقتی صدا زده میشه -> متنی ک پوینتر روشه رو سلکت میکنه -> کات میکنه ->برمیگردونه
تابع دوم یه ورودی میگیره -> تو کلیپ‌بورد کپیش میکنه -> پیستش میکنه

حالا باید عملیات تغیر زبان رو روی متن کات شده پیاده کنیم :
آسونه :
Python:
def process(inputText):
    print(inputText)
    outputText = ''
    for i in inputText:
        if i in e2f:
            outputText += e2f[i]
        elif i in f2e:
            outputText += f2e[i]
        else:
            outputText += i

    return outputText
این تابع یه متن رو میگیره و با زبون مخالف تایپش میکنه و بهمون پسش میده
تمومه دیگه فقط کافیه این سه تا تابع پست سر هم کال بشن:
Python:
paste_text(process(get_text()))
کد کامل یه همچین چیزیه:
Python:
from pynput.keyboard import Key, Controller
from pyperclip import copy, paste

keyboard = Controller()

e2f = {'q': 'ض',
       'w': 'ص',
       'e': 'ث',
       'r': 'ق',
       't': 'ف',
       'y': 'غ',
       'u': 'ع',
       'i': 'ه',
       'o': 'خ',
       'p': 'ح',
       '[': 'ج',
       ']': 'چ',
       'a': 'ش',
       's': 'س',
       'd': 'ی',
       'f': 'ب',
       'g': 'ل',
       'h': 'ا',
       'j': 'ت',
       'k': 'ن',
       'l': 'م',
       ';': 'ک',
       "'": 'گ',
       'z': 'ظ',
       'x': 'ط',
       'c': 'ز',
       'v': 'ر',
       'b': 'ذ',
       'n': 'د',
       'm': 'پ',
       ',': 'و',
       'H': 'آ'}

f2e = {'ض': 'q',
       'ص': 'w',
       'ث': 'e',
       'ق': 'r',
       'ف': 't',
       'غ': 'y',
       'ع': 'u',
       'ه': 'i',
       'خ': 'o',
       'ح': 'p',
       'ج': '[',
       'چ': ']',
       'ش': 'a',
       'س': 's',
       'ی': 'd',
       'ب': 'f',
       'ل': 'g',
       'ا': 'h',
       'ت': 'j',
       'ن': 'k',
       'م': 'l',
       'ک': ';',
       'گ': "'",
       'ظ': 'z',
       'ط': 'x',
       'ز': 'c',
       'ر': 'v',
       'ذ': 'b',
       'د': 'n',
       'پ': 'm',
       'و': ',',
       'آ': 'H'}


def get_text():

    keyboard.press(Key.alt)
    keyboard.press('a')
    keyboard.release(Key.alt)
    keyboard.release('a')
    keyboard.press(Key.ctrl)
    keyboard.press('x')
    keyboard.release(Key.ctrl)
    keyboard.release('x')
    return paste()


def paste_text(text):

    copy(text)
    keyboard.press(Key.ctrl)
    keyboard.press('v')
    keyboard.release(Key.ctrl)
    keyboard.release('v')


def process(inputText):
    print(inputText)
    outputText = ''
    for i in inputText:
        if i in e2f:
            outputText += e2f[i]
        elif i in f2e:
            outputText += f2e[i]
        else:
            outputText += i

    return outputText


paste_text(process(get_text()))
خب توی فایلtypeHelper.py سیوش میکنم و یه پوشه به اسم .myScripts توی home درست میکنم
فایلایی ک با دات شروع میشن یجورایی هیدن ان تو لینوکس.
حالا یه شرتکات میخوام ک وقتی اجراش کردم -> این اسکریپت ران بشه
من تو یه لینوکس با دسکتاپ kde هستم و رو بقیه سیستم عامل ها فرق میکنه
تو تنظیمات تب shortcuts رو باز میکنم و یه کاستوم شرتکات درست میکنم :Screenshot_20201016_210650.png
الان اگه ctrl + alt + p رو بزنم برنامه ای ک نوشتیم اجرا میشه
و در نهایت تستش کنیم :


https://uupload.ir/files/998l_2020-10-16_21-23-53.gifدر همین حد کارمو راه میندازه
ولی واسه اینکه واقعا کاربرد داشته باشه یسری تغیرات لازم داره مثلا:
-> چک کنه ببینه اگه یوزر چیزی رو سلکت کرده فقط همون قسمت ترجمه!؟ بشه و در غیر این صورت کل فیلد رو کات کنه
-> کاراکتر های بیشتری به دیکشنری اضافه بشن تا مثلا کلمه ای مثل سلــام هم ترجمه بشه
-> واسه کار کردن به پایتون و کتابخونه های سیستم عامل وابسته نباشه
و...
 
بالا