یک طنز فوق العاده: صحنه‌هایی متحرک از زندگی برنامه نویسان – قسمت دوم

وقتی چیزی که چهارشنبه آخر وقت کار می کرد، شنبه اول وقت از کار می افته

وقتی که بعد از چند ماه بر می‌گردین سر کدی که قبلا نوشتین اما روش کامنت نذاشتین:

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

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

چرا آزادی رو دوست دارم: فراوانی حروف فارسی در یک متن

سوال دوستانی که در مورد صفحه کلید استاندارد بحث می کنن اینه که هر حرف فارسی در متون فارسی چقدر تکرار شده؛ به عبارت دیگه هر کاراکتر چقدر به درد می خوره تو فارسی نوشتن. اینو قبلا هم یک دوست تایپیست حرفه ای ازم خواسته بود بررسی کنم. امروز حوصله کردم و جواب در مورد متنی مثل قانون اساسی اینه (پی نوشت دوم رو بخونین):

درصد استفاده از حروف فارسی در قانون اساسی

و اگر به طور دقیق تعداد کلمات و درصدهای دقیق تر رو می خواین می تونین با دانلود فایل صفحه گسترده فراوانی حروف فارسی در قانون اساسی ایران با ODF فرمت اوپن آفیس بهش برسین.

برنامه ای که اینکار رو می کنه اینه:


#!/usr/bin/perl

use utf8;
binmode STDOUT, ':utf8';
binmode STDIN, ':utf8';

@userinput = ;

$string = ''; #make a single $string from the standard input
foreach $line (@userinput) {
        $string .= $line;
}

# do some adjustments, say replacing arabic Ya with Persian Ya
$string =~ s/ي/ی/g;
$string =~ s/ك/ک/g;

#$allLetters = "آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهیئ۱۲۳۴۵۶۷۸۹۰";
$allLetters = "آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهیئ";

#explode and check the count of each letter
$total = 0;
for (my $key = 0; $key < length($allLetters); $key++) {
	$thisLetter = substr ($allLetters, $key, 1);
	$tedad{$thisLetter} = ()= $string =~ /$thisLetter/g; 
	$total += $tedad{$thisLetter};
}

foreach $key (sort (keys %tedad)) {
	print $key, "\t", $tedad{$key}, "\t", int($tedad{$key} / $total * 1000) / 10, "\n";
}

که همونطور که می بینین اطلاعات رو از ورودی استاندارد می گیره و تعداد هر کاراکتری که در رشته string اومده باشه رو توسط اپراتور مخفی =() می سنجه - برای همینه که می گن پرل زبون پردازش متنه و فوق العاده قشنگ و سخت برای خوندن. مثلا به این خط که قلب این برنامه است نگاه کنین:


	$tedad{$thisLetter} = ()= $string =~ /$thisLetter/g; 


میگه توی رشته فقط «همین حرف که الان داریم می شمریم» رو نگه دار و بعد با اون اپراتور جالب ببین چند تا کاراکتر توش مونده و بعد تعدادش رو بده به متغیر هشی که کلیدش همین کاراکتر است.

اینم بگم که این رو با هر چیز دیگه (مثلا برنامه های غیر آزاد) هم می شه نوشت یا روی ویندوز هم اجرا کرد ولی حالا که من کردم لوگوم رو می زنم پاش (:

نوشته های مشابه:
- بررسی سال های تولد در اطلاعات افشا شده ۳۰۰۰۰۰۰ کارت بانکی
- تعداد فراوانی حروف فارسی در نوشته‌های روزمره (ای بابا قبلا ظاهرا اینو نوشته بودم ولی یادم نبود!)

پی نوشت
۱- اگر واقعا نیاز دارین در مورد متنی این رو بدونین و امکان اجرای برنامه رو توسط خودتون ندارین، برام ایمیل کنین به jadijadi@gmail.com و براتون انجام می دم می فرستم. فقط متن بدون شک باید در فرمت متنی باشه. پی دی اف و اینها نیازمند تبدیل هستن.
۲- همونطور که شاهین هم در کامنت ها گفته، قانون اساسی اصلا متن خوبی برای سنجش «میزان استفاده حروف در زبان فارسی» نیست. اولا که کلمات غیرمرسومی داره و احتمالا سطح عربی اش زیاده و از اونطرف یک متن طبیعی نیست و مثلا کلمه «اصل» توش حداقل به تعداد اصول قانون اساسی استفاده شده و احتمالا هیچ رمانی اینقدر «ص» توش نداره (:

یک سلف برندینگ موفق: به واقعیت پیوستن جیمیل آبی

دروغ اول آپریل و دروغ سیزده بهانه‌هایی هستن برای من که یکی دو روز از اینترنت دوری کنم. نظر من رو بخواین مایی که صبح تا شب تو یه جامعه پر از دروغ غلت می زنیم بهتره برای چند سالی سیزدهم رو روزی اعلام کنیم که توش قراره دروغی نگیم (و البته به جای بیرون رفتن، تنها بمونیم خونه که نیاز به دروغ گفتن تومون بیاد پایینتر).

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

سلف برندینگ جیمیل بلو

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

اما.. چیزی هست به اسم Self Branding. این آقا با یک ایده خوب با یک کار بی فایده ولی باحال در زمان مناسب کلی کلی خودش رو مطرح کرد. سه و نیم میلیون نفر ویدئوی جیمیل آبی رو دیدن و احتمالا بیشتر از سی میلیون نفر در موردش خوندن و الان دقیقا اکثر سایت‌های تکنولوژی و کسایی که توی این حوزه مهم حساب می‌شن دارن (ماشابل و من و تک کرانچ رو کجا می برین؟) به صفحه اش لینک می دن و اسمش رو می نویسن. این یک نمونه از حرکت موفقی است که می تونه یک آدم عادی رو یکهو به یک اسم مشهور تبدیل کنه که سایت های بزرگ ازش حرف زدن، بهش لینک دادن و در آینده هم خیلی ها تحت عنوان «همونی که جیمیل آبی رو نوشت» بهش اشاره خواهند کرد.

فراموش نکنین که افراد کمی هستن که بتونن ادعا کنن دروغ سیزده گوگل رو به یک واقعیت تبدیل کردن.

مرتبط برای خوندن بیشتر در مورد سلف برندینگ:
پنج قدم برای تقویت برند «شما»
سلف برند در ویکپیدیا

یک طنز فوق العاده: صحنه‌هایی متحرک از زندگی برنامه نویسان

آپدیت ۱۴ اسفند: با تشکر از امیر توی کامنت ها، مرجع اصلی این عکس ها اینجاست: www.thecodinglove.com

من همیشه افسوس می خورم که چرا دوران درخشان طنزهای گیکی افول کرده.. اما گاهی جرقه هایی عالی هم توی دنیای طنز گیکی دیده می شن – از جمله این مجموعه فوق العاده از گیف‌های متحرک (یادگار اینترنت دهه نود) که گوشه‌هایی از زندگی کد نویس‌ها رو نشون می ده… از اونجایی که این عکس‌ها خیلی سنگین هستن و من نمی خوام با هر بار ورود به سایت، پهنای باند گرون، سانسور شده و کند دوستان داخل ایران به فنا بره، فقط یک عکس رو گذاشتم در صفحه اول و برای دیدن بقیه مجموعه صحنه‌هایی متحرک از زندگی برنامه نویس هامی تونین روی ادامه مطلب کلیک کنین:

وقتی می خوام فیچر جدیدی رو به مدیرم نشون بدم:

ادامه خواندن “یک طنز فوق العاده: صحنه‌هایی متحرک از زندگی برنامه نویسان”

بش اسکریپت برای تبریک ولنتاین

تبریک گیکی ولنتاین

امسال ولنتاین جالب بود. من تا حالا ندیده بودم که اینقدر دختر و پسر دست تو دست توی خیابون باشن… از کوچه‌های فرعی تا رستوران‌ها. بعضی‌ها هم این روز رو با برنامه‌نویسی و لپ‌تاپ‌هاشون گذروندن (: در صدرشون هم

افشین مهربانی و سالار کابلی که یک اسکریپت بامزه نوشتن که تو یک زمان مکان خیلی خوب منتشر شد و تونست توی هکرنیوز ترند بشه… ولنتاینشون با مک‌بوکشون مبارک (:

مجموعه ای از کارت تبریک‌های گیکی ولنتاین
پروژه روی گیت هاب

قرعه کشی و اعلام اسامی برندگان جایزه‌های مسابقه پیش بینی سورپرایز اوبونتو

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

 3 AliBehjati
 3 Mohammad
 3 Hesam
 1 Ehsan
 1 Amir1207
 1 Ali1217
 6 Ali0202
 1 Voltan
 2 Amir0119
 1 Saeed
 2 Jamshid
 2 Matin
 3 Narcissus
 2 MassoudM

و بعد از ساخت یک فایل جدید که توش هر اسم به تعداد شانسش تکرار شده و صدا زدن پایتون برای عدد رندم، یک خط اتفاقی رو نشون می ده. برنامه درسته و ما هم از همین استفاده می کنیم. البته من خروجی رو با cowsay ایجاد کردم که هیجان انگیزتر بشه (اگر این دستور رو بلد نیستین همین الان یاد بگیرین و لذتش رو ببرین!). سورس برنامه در نهایت اینه:

[jadi@jedora ghore.sh]$ cat ghore_keshi.sh 
#! /bin/bash

if [ ! -f "gklist" ]; then
    echo "Write names and scores to 'gklist' file and execute this script at the same directory"
    exit 1
fi

if [ ! -d /tmp/gk ]; then
    mkdir /tmp/gk
else
    rm /tmp/gk/*
fi
cp "gklist" /tmp/gk
cd /tmp/gk

for ((i=0; i<`cat "gklist" | wc -l`; i++)); do
    S="`cat "gklist" | head -$[i+1] | tail -1`"
    NUM="`echo "$S" | awk '{ print $1 }'`"
    NAME="$(cat "gklist" | head -$[i+1] | tail -1 | cut -d\" -f2)"
    for ((j=0; j<$NUM; j++)); do
	echo $NAME >> result
    done
done

LL="`cat "result" | wc -l`"
RANDNUM="`python -c "import random;print(random.randint(1, $LL))"`"
barande=`cat "result" | head -$RANDNUM | tail -1 | cut -d" " -f2 `
cowsay Winner of $1 $barande

نکته بسیار مهم اینه که در یک رای گیری / قرعه کشی و … تا وقتی از نرم افزار آزاد و پروسه‌های شفاف استفاده نشده یعنی یک جای کار می لنگه (منظور فقط تقلب و خباثت نیست. این لنگش(!) ممکنه سواد یا شعور یا دسترسی فنی برگزار کننده باشه).

حالا که همه پروسه‌ها شفافن و هر کسی هم به سورس برنامه انتخاباتی دسترسی داره، می ریم سراغ قرعه کشی. اگر یک سیستم درست داشتیم این بخش هم باید به شکل مستقیم در اینترنت پخش می شد ولی من به خاطر لنگیدن اینترنت درست، ضبطش کردم و آفلاین گذاشتمش روی اینترنت که شبهات به حداقل برسه. با یک خط دستور دوبار برنامه رو اجرا می کنیم برای دو جایزه: اولی تی شرت و دومی ماگ. دعا هم کنیم که برنده تکراری در نیاد! ویدئوی برگزاری رو ببینین؛ با تشکر از شرکت معظم www.aivivid.com که اسپانسری تی شرت مجری رو بر عهده داشتن



اگر هم حاکم هاتون تصمیم گرفتن که دیدن ویدئو براتون خوب نیست ونمی تونین از برنده ها مطلع بشین نگران نباشین! خودم به شکل متنی هم براتون برنده ها رو اعلام می کنم:

  • برنده اول مسعود.ام تنها شرکت کننده ما از گوگل پلاس با شانس ۲ که برنده این تی شرت میشه:
  • و برنده دوم متین – اونهم با شانس دو – که این ماگ رو از اسپانسر مسابقه یعنی سیتو دریافت می کنه

با برندگان عزیز برای گرفتن آدرس و ارسال جوایزشون تماس گرفته می شه (: خوش باشین تا مسابقه بعدی

پ.ن. ویدئو رو با این دستور گنو/لینوکسی کوچیک کردم

 $ffmpeg -i DSCN3085.AVI -ab 56k -ar 22050 -b 300k -r 15 -s 480x360 DSCN3085.flv                             

چرا گنو/لینوکس رو دوست دارم: شمردن کلمات به کار رفته شده در وبلاگ

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

برنامه پایتون رو اینطوری تغییر می‌دم:

#!/usr/bin/python
# -*- coding: utf8 -*- 

from xml.dom import minidom
import xml.etree.cElementTree as et
import re

tree=et.parse('wordpress.2012-12-05.xml')
root=tree.getroot();

wordCount = {}

for child in root.iter('item'):
	date = child.find('wppost_date').text[:7] #find the year and month
	body = child.find('content_encoded').text # post content
	title = child.find('title').text 	  # post title

	try:
		fulltext = title + "\n" + body # all the text in the post = title + body
	except:
		pass

	fulltext = re.sub(ur'[_»«"\'&?؟a-zA-Z‌0-9/=.*+\n-%<>:;،؛,\-)(،۱۲۳۴۵۶۷۸۹۰]', ' ', fulltext) #replace extra chars
	words = fulltext.split() # words is a list of all words in this post

	for word in words:
		wordCount[word] = wordCount.get(word, 0) + 1 # wordCount[word]++

for word in wordCount:
	thisLine = (str(wordCount[word]) + "\t" + word)
	print thisLine.encode("utf-8", "ignore")


کد کاملا واضحه: هر پست رو نگاه می کنه، حروف غیرفارسی تیتر و متن رو با فاصله جایگزین می کنه و بعد تعداد کلمات رو جمع می‌زنه و همین روند رو روی تمام پست‌ها ادامه می‌ده. به عبارت دیگه خروجی چیزی شبیه به این خواهد بود:

...
4	همسرش
1	آکر
3	خرمش
1	ویسمن
2	خرما
1	یکباری
1	مانغو
2	احساسم
1	عصبي
61	رشد
1	رشت
1	تریلیان
5	همسرم
32	هیات
1	پورتال
2	پیشانی
6	مدیربسته
4	لری
4	وجدان
...


و البته مشخصه که خیلی طولانی‌تر. بذارین بشمریم که من کلا در زندگی چند کلمه استفاده کردم تو وبلاگم:

jadi@jeducation:~/Downloads/weblog_word_usage$ ./count_all_words.py | wc -l
27880


هوم.. بیست و هفت هزار و هشتصد و هشتاد کلمه (: بدک نیست (: چیز خوبیه که روی وبلاگ های مختلف حساب بشه و ببینیم هر وبلاگ با چند تا کلمه مستقل از هم نوشته شده (: البته معلومه که «می‌رود، می رود، میرود» چهار کلمه جدا شمرده شدن… برای حل نسبی این مشکل توی اون خط که رجکس یکسری کاراکتر اضافی رو حذف می کنه، نیم‌فاصله رو هم اضافه می‌کنم و خروجی اینطوری می‌شه:

jadi@jeducation:~/Downloads/weblog_word_usage$ ./count_all_words.py | wc -l
23405


جالب نیست؟‌ برای چهار هزار و چهارصد کلمه، من گاهی از نیم فاصله استفاده کردم و گاهی نکردم. حالا مهم نیست (:‌ قدم بعدی سورت کردن است. با جواهر گنو و نشون دادن بیست تا بالایی:

jadi@jeducation:~/Downloads/weblog_word_usage$ ./count_all_words.py | sort -n -r | head -20

خروجی رو براتون نمی‌ذارم چون فقط یکسری حرف ربط بی ربط است.

پروژه جانبی بسیار مهم برای زبان فارسی: همه زبان‌ها یک فایل دارن به اسم نمی دونم چی (کسی می‌دونست لطفا بگه) که توش کلمات «بی ربط» اون زبان نوشته شدن. به اصطلاح همون am و is و are یا امثال «است» و «شد» و «و» و «یا» و … که در اینجور جاها کاربرد داره (می شه اون کلمات رو از فهرست این کلمات که برنامه بهمون داده حذف کرد تا کلمات اختصاصی من به دست بیاد و نه چیزهایی که برای جمله ساختن همه استفاده می کنن). آیا چنین فایلی داریم برای زبان فارسی؟ تو خارجی‌ها اسمش چیه؟

حالا که بیست تا اولی به درد نخوردن، به جاش کل لیست رو می‌برمش توی لیبره آفیس و مثل همیشه نمودار بیشترین کلمات (غیر حرف ربط و استاندارد مثل است و باشد و شد و اینها) رو می‌کشیم تا با یک نمودار قشنگ کار رو تموم کرده باشیم:

پ.ن. این مجموعه مهمل ، یک قسمت دیگه هم داره (: کمی دیرتر ولی.

چرا گنو/لینوکس رو دوست دارم: اینجا چند بار از کلمه مهمل استفاده شده

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

چیکار می کنیم؟ من با وردپرس وبلاگ می‌نویسم. پس اول از بخش مدیریت از منوی Tools، کل پست‌ها و کامنت‌های سایت رو Export میکنم. اینجوری یک فایل ایکس ام ال دارم که همه مطالب سایت توش هستن.

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


 jadi@jeducation:~/Downloads$ grep -o مهمل wordpress.2012-12-05.xml | wc -l 
 29


بعله (: من بیست و نه بار از کلمه مهمل استفاده کردم (: اما چیزی که جالبتره اینه که از کی شروع کردم به استفاده. اینبار باید برنامه بنویسم. پایتون همیشه انتخاب راحت و خوبیه. برنامه ایکس ام ال رو می خونه، درختش رو بررسی می کنه و توی همه مطالب و کامنت‌هایی که از عبارت مهمل استفاده کردن، تاریخ رو توی خروجی می نویسه:
# -*- coding: utf8 -*- 

from xml.dom import minidom
import xml.etree.cElementTree as et
import re

tree=et.parse('wordpress.2012-12-05.xml')
root=tree.getroot();

for child in root.iter('item'):
	date = child.find('wppost_date').text
	body = child.find('content_encoded').text
	title = child.find('title').text

	try:
		if re.search (u'مهمل', body) or re.search(u'مهمل', title):
			print date;
	except:
		print date;

for child in root.iter('wpcomment'):
	date = child.find('wpcomment_date').text
	body = child.find('wpcomment_content').text

	try:
		if re.search (u'مهمل', body):
			print date
	except:
		print date;


اگر پایتون بلدین (یا حتی بلد نیستین ولی جرات داشتین کد رو نگاه کنین) می بینین که کد اصلا خوب نیست. دلیل تاریخی داره. اول نمی دونستم تو کامنت هم هست و بعد کامنت ها رو با یک کپی پیست جدا کردم. بعد دیدم گاهی اکسپشن می گیرم و بعد از بررسی فهمیدم بعضی مطالب متن یا عنوان نداره (چرا؟!) و در نتیجه خروجی مشکل پیدا می کنه که با یک اکسپشن اضافه کردن سر و ته مشکل رو هم آوردم و رسیدم به نتیجه‌ای که می‌خواستم:
jadi@jeducation:~/Downloads$ time python parsejadi.py 
2011-12
2012-07
2012-11
2011-09
2011-10
2011-10
2012-02
2012-06
2012-10
2012-11
2012-11
2012-11
2012-11
2012-12
2009-06
2009-05
2011-08
2011-09
2011-10
2011-10
2011-11
2012-06
2012-06
2012-08
2012-10
2012-10
2012-10
2012-10
2012-11

real	0m0.738s
user	0m0.700s
sys	0m0.028s
jadi@jeducation:~/Downloads$ 

میبینین که توی اون خطی که تاریخ رو حساب کردیم یک [7:] دارم که باعث می‌شه فقط سال و ماه رو ذخیره کنم چون این نمودار با معنی‌تری بهمون می‌ده. راستی گفتم نمودار. اینم نمودارش (مشخصه که با لیبره آفیس لینوکس):

ظاهرا که همیشه از کلمه مهمل استفاده می‌کردم ولی این دو ماه بیشتر هم شده (:

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

نکته مهم: این مطلب ربط خیلی خاصی به لینوکس نداره. البته ابزار گرپ گنویی است و همینطور لیبره آفیس. پایتون ممکنه هر جا اجرا بشه و شاید نمودار با آفیس مایکروسافت قشنگتر هم می شد ولی به هرحال برای من این یک تجربه لینوکسی است چون لحظه ای که اراده کردم همه اینها زیر دستم بود و از انجامش هم لذت بردم (: چون شبیه سری های چرا گنو لینوکس رو دوست دارم است با همون عنوان رفتم جلو.