چرا گنو لینوکس رو دوست دارم: حذف صدای خواننده از یک آهنگ

ما همراهی در دنیای لینوکس داریم به اسم فرشید نوتاش حقیقت که لازم داره صدای خواننده (محمد اصفهانی) از آهنگ «سراب» حذف بشه. کاری که در کاریوکی می کنیم. همه دنیای لینوکس هم علاقمند هستن به ایشون کمک کنن (:

راه حل من طبق معمول یک کامند لینوکسی است:

sox MusicVoroodi.mp3 Music_khorooji_no_vocal.mp3 oops

دستور که مشخصه، فایل ورودی و خروجی داره و تنها یک پارامتر: oops که البته در توضیحش نوشته:

Out Of Phase Stereo effect. Mixes stereo to twin-mono where each mono channel contains the difference between the left and right stereo channels. This is sometimes known as the ‘karaoke’ effect as it often has the effect of removing most or all of the vocals from a recording

در مورد این آهنگ بد هم جواب نداد و امیدوارم باعث بشه ایشون تهدیدش رو عملی نکنه.

چگونه یک گیک لینوکسی در مسابقه حدس زدن کلمه انگلیسی اینستاگرامی شرکت می کنه

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

Screenshot_2015-04-17-14-35-43

موضوع مسابقه پیدا کردن یک کلمه ده حرفی است که مربوط به این شکل باشه و ده حرفی باشه و در جاهای مشخص شده a‌ و q نشسته باشن.

بریم برای جواب؟ در لینوکس بسته scowl‌ رو می‌شناسم (یا با سرچ بهش می رسم) که بقیه غلط‌یاب‌های دیکته ازش استفاده می کنن. این بسته حاوی کلی فایل است که همه کلمات زبان‌ انگلیسی توشه (از آمریکا تا کانادا و دستاشون).

نصبش می کنیم:

jadi@funlife:/tmp$ sudo aptitude install scowl 
[sudo] password for jadi: 
The following NEW packages will be installed:
  scowl 
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,249 kB of archives. After unpacking 7,516 kB will be used.
Get: 1 http://ir.archive.ubuntu.com/ubuntu/ utopic/universe scowl all 7.1-1 [2,249 kB]
Fetched 2,249 kB in 9s (248 kB/s)                                               
Selecting previously unselected package scowl.
(Reading database ... 639459 files and directories currently installed.)
Preparing to unpack .../archives/scowl_7.1-1_all.deb ...
Unpacking scowl (7.1-1) ...
Processing triggers for cracklib-runtime (2.9.1-1build1) ...

و به دایرکتوری اش می ریم. چون برنامه اجرایی نیست و تنظیمات و موقت هم نیست منطقا باید راحت در usr/share بشه پیداش کرد.

jadi@funlife:/usr/share/dict/scowl$ cd /usr/share/dict/scowl/

حالا یک نگاه بندازیم ببینیم چه تیپ چیزهایی داریم اینجا:

jadi@funlife:/usr/share/dict/scowl$ ls -ltrh | tail
-rw-r--r-- 1 root root  13K Oct 23  2011 special-hacker.50
-rw-r--r-- 1 root root 2.4M Oct 23  2011 english-words.95
-rw-r--r-- 1 root root 238K Oct 23  2011 english-words.50
-rw-r--r-- 1 root root  34K Oct 23  2011 english-words.10
-rw-r--r-- 1 root root 787K Oct 23  2011 english-proper-names.95
-rw-r--r-- 1 root root  57K Oct 23  2011 british-words.80
-rw-r--r-- 1 root root  56K Oct 23  2011 american-words.80
-rw-r--r-- 1 root root  15K Oct 23  2011 american-words.70
-rw-r--r-- 1 root root 9.1K Oct 23  2011 american-words.50
-rw-r--r-- 1 root root  303 Oct 23  2011 american-words.10

و توی یکیشون رو به اتفاق نگاه می کنیم:

jadi@funlife:/usr/share/dict/scowl$ tail canadian-words.10
realized
realizes
realizing
recognize
recognized
recognizes
recognizing
rumour
spelled
storey

بعله. فایل های خودمون هستن.

حالا کار راحته: گشتن در همه فایل ها و پیدا کردن چیزی که ترکیب مورد نظر اونها رو داشته باشه. دقت کنیم که در egrep، علامت نقطه یعنی «هرکاراکتری»… علامت ^ یعنی اول خط و علاقمت $ یعنی آخر خط. پس:

jadi@funlife:/usr/share/dict/scowl$ egrep "^a...q.....$" *
english-words.35:antiquated
english-words.35:antiquates
english-words.80:antiquarks
english-words.95:ablaqueate
english-words.95:alfaquin's
english-words.95:antiquer's

یوهاهاها… دو تا آخری که جذاب نیستن. آنتی کوارک که می دونیم چیه، ablaqueate رو توی گوگل سرچ کردم مهم نبود پس جواب ما antiquated است که یعنی کهنه و منسوخ و خارج از مد. جواب رو دادم و منتظرم ببینم چی می‌گن.


آپدیت: نوید راد پیشنهاد می ده به دلیل نبودن بسته اسکاول در اکثر توزیع ها کد زیر رو هم بذارم:

curl -O -J -L http://sourceforge.net/projects/wordlist/files/latest/download?source=typ_redirect
tar -xvf ./scowl-yyyy.mm.dd.tar.gz # say, scowl-2015.02.15.tar.gz
cd scowl-2015.02.15/final
grep -Ea "^a.{3}q.{5}$" *

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

دانلود کل درس‌های صوتی و پی دی اف قرآن مهندس بازرگان

مهشاد برامون نوشته که داره سعی می کنه کل مجموعه تفسیر قرآن مهدس عبدلعلی بازرگان رو از سایت رسمی مهندس بازرگان دانلود کنه ولی چون ساختار سایت خیلی سنتی و صفحه صفحه طراحی شده، اینکار براش سخته و سایت هم جایی رو نذاشته که بتونیم کل جریان رو یکجا دانلود کنیم. با یک نگاه به صفحه مشخص می شه که از این لینک http://bazargan.com/abdolali/main0.html لینک شده به ۱۱۴ سوره و اونجا چندین فایل mp3 در صفحه هست که هر کدوم بخشی از درس های قرآن مربوط به تفسیر اون سوره هستن.

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

$ wget http://bazargan.com/abdolali/main0.html -r -l3 -c -np -k

سوییچ ها مشخص هستن. r برای دانلود ریکرسیو (تو در توی صفحات) ولی فقط تا سه لایه داخلی (l3) چون لایه اول که همین صفحه است، لایه دوم می شه صفحه ای که سوره ها توش هست و لایه سوم می شه فایل های mp3 و یک c هم اضافه می کنیم به معنی continue که اگر قطع شد وسطش راحت ادامه بدیم و یک np یعنی از جایی که هستیم بالاتر نمی خوایم بریم (no parrent).

روی اون سرور تقریبا پنج دقیقه بعد همه چیز دانلود شده:

$ tree -d -L 3 #فقط دایرکتوری ها و فقط سه لایه
.
└── bazargan.com
    └── abdolali
        ├── gifs
        ├── MP3
        ├── PDF
        └── video

خیلی هم خوب. ما فقط دایرکتوری MP3 رو می خوایم. حجمش چقدره؟

$ du -hs bazargan.com/abdolali/MP3/
4.4G    bazargan.com/abdolali/MP3/
$ du -hs bazargan.com/abdolali/PDF/
184M    bazargan.com/abdolali/PDF/

هوم.. حالا که صداها چهارگیگ هستن و پی دی اف ۱۸۴ مگ. تکرار همین کار روی کامپیوتر / سرور شما، همین نتیجه رو خواهد داد. البته اگر راحتتر هستین دوستان خوبم در aivivid که خدمات سرور، میزبانی و خیلی چیزهای دیگه می دن زحمت کشیدن و فایل مگنتی برای تورنت درست کردن و تا مدتی خودشون سید می کنن و بعدش هم اگر کسی دوست داشت، به سید کردن ادامه می ده. تورنت دانلود درس های (صوتی) قران مهندس عبدالعلی بازرگان در صورتی که سید داشته باشه، روشی راحتتر برای دانلود است.

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

پ.ن.۲. به مهندس ایمیل زدم و پرسیدم آیا مشکلی نیست که من فایل هاش رو به صورت تورنت پخش کنم. جوابشون این بود:

جناب جادي، با سلام و تحيت و تشكر از اطلاع دادنتان و رعايت وجداني حقوق ديگران، اما در مورد قرآن، حق شخصي وجود ندارد و كتاب خدا متعلق به همه است و هرگونه تسهيلي كه هركس دراين زمينه فراهم كند، موجب خوشحالي و تشكر هم خواهد بود
موفق باشيد
بازرگان

تغییر صدا به طرزی که شناخته نشه

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

اما این مشکل رو [تاحدی] می شه حل کرد. یعنی می شه روی صدا افکت‌هایی گذاشت که کمی بم‌تر، کندتر و اکودارترش کنن و در نتیجه شناختنشون برای کسی که نمی‌شینه با افکت‌های معکوس اون‌ها رو زیرتر، سریعتر و بدون اکو کنه و به صدای اصلی برسه، سخته.

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

نصب روی لینوکس‌های دبیانی (از جمله اوبونتو) به این شکل است:

$ sudo apt-get install sox

‍‍‍‍
و استفاده برای تغییر صدا به یک صدای بم نسبتا ناشناس چیزی شبیه این:

$ sox input.wav -d pitch -700 contrast 100 echo 0.8 0.88 6 0.4 chorus 0.5 0.9 50 0.4 0.25 2 -t 60 0.32 0.4 2.3 -t 40 0.3 0.3 1.3 -s phaser 0.89 0.85 1 0.24 1 -t

که فایل input.wav رو با صدایی بم و کمی تاخیر دار پخش می کنه.

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

دوستم یک مشکل داره و می دونه شکل مشکل چیزی است از یک کار تکراری که احتمالا در دنیای قشنگ لینوکس می شه براش راه حل های جالب پیدا کرد. صورت مساله اینه:

من تعداد زیادی فایل تبلچر (شیوه اجرای آهنگ) گیتار دارم که اسم خواننده بالاشون نوشته نشده. در نتیجه من نمی تونم سریع توی ذهنم بیارم که آهنگ چه شکلی است. مثلا وقتی بالای آهنگ نوشته شده «عسل» کمک بسیار بزرگی است اگر Ebi رو هم بالاش ببینم. این Ebi اسم فایل است پس من یکسری فایل عکس دارم که می خوام اسم فایل رو روی عکس فایل اضافه کنم

بله! لینوکس که ترکیبی از ابزارهای قدرتمند است، راه حلی عالی داره. اما یک برنامه نویس خوب همیشه اول مسائل رو در ساده ترین حالت حل می کنه و بعد مساله رو پیچیده می کنه. فرض کنیم اصولا فقط یک عکس داریم که می خوایم روش بنویسیم My Happy Text. اسم فایل هم هست Bijan Mortazavi 006. اگر بتونیم این مساله رو حل کنیم، یک قدم جلو افتادیم. در اصل من دارم مساله رو به سه بخش تقسیم می کنم:

1- اضافه کردن یک متن دلخواه به یک عکس
2- در آوردن اسم یک فایل
3- ترکیب کردن دو قدم قبلی برای هر چند تا فایل که داشتیم

قدم اول: نوشتن روی فایل

ساده است. بسته Image Magick ابزاری داره به اسم convert که می تونه تقریبا هر کاری با یک تصویر بکنه! مثلا این تصویر:

Ebi 005

با دستور

$ convert Ebi\ 005.JPG -pointsize 43 -background Khaki label:'My Happy Text' +swap -gravity Center -append out.jpg

تبدیل می شه به:

out

جذاب نیست؟ بخصوص که روی تصویر چیزی ننوشتیم بلکه بالاش کمی تصویر اضافه کردیم! حالا می ریم سراغ قدم دوم.

قدم دوم: درآوردن فهرست فایلها

من احتیاج دارم اسم فایل ها رو بگیرم. اولش که ساده است؛ به لینوکس می گم همه فایل هایی که تهشون JPG هست رو بهم بده:

$ find . -name "*JPG" 
./Bijan Mortazavi 005.JPG
./Ebi 015.JPG
./Ebi 018.JPG
./Ebi 016.JPG
./Darush 007.JPG

بعد کافیه بگم اون /. اول رو حذف کنه:

a$ find . -name "*JPG" | sed "s/\.\///"
Bijan Mortazavi 005.JPG
Ebi 015.JPG
Ebi 018.JPG
Ebi 016.JPG
Darush 007.JPG

و چیز دیگه که بهش احتیاج نداریم اون JPG. آخر است:

$ find . -name "*JPG" | sed "s/\.\///" | sed "s/\.JPG//"
Bijan Mortazavi 005
Ebi 015
Ebi 018
Ebi 016
Darush 007

و قدم دوم هم تموم می شه!

قدم سوم: چسبوندن قدم های قبلی

اینجا گزینه ها خیلی زیادن. بریم جلو ببینیم چی می شه. مثلا من می تونم با دستور xargs ورودی قدم دوم رو استفاده کنم. اصل صفرم برنامه نویسی جادی رو یادتونه دیگه؟ «برنامه پیچیده ای که کار می کنه، برنامه ساده ای بوده که کار می کرده» پس بذارین در ساده ترین حالت، هر کدوم از خطوط ورودی رو بدیم به یک دستور اکو:

$ find . -name "*JPG" | sed "s/\.\///" | sed "s/\.JPG//" \
    | xargs -L1 -I THIS echo my command will work on \"THIS\" happily 
my command will work on Bijan Mortazavi 005 happily
my command will work on Ebi 015 happily
my command will work on Ebi 018 happily
my command will work on Ebi 016 happily
my command will work on Darush 007 happily

عالی! ما قهرمانیم. الان ورودی قدم دوم رو خط به خط دادیم به دستور اکو. (سوییچ I می گه این خط ورودی باید کجای دستور قرار بگیره). بذارین یک ضرب سعی کنیم اصل برنامه رو اجرا کنیم و خروجی رو بریزیم توی دایرکتوری out و البته قبلش طبق همون اصل اول برنامه نویسی جادی، با گذاشتن یک echo جلوی دستوری که ساختیم یک تست هم می گیریم:

$ find . -name "*JPG" | sed "s/\.\///" | sed "s/\.JPG//" | xargs -L1 -I THIS echo convert \"THIS.JPG\" -pointsize 43 -background Khaki label:\'THIS\' +swap -gravity Center -append \"out/THIS.jpg\"
convert "Bijan Mortazavi 005.JPG" -pointsize 43 -background Khaki label:'Bijan Mortazavi 005' +swap -gravity Center -append "out/Bijan Mortazavi 005.jpg"
convert "Ebi 015.JPG" -pointsize 43 -background Khaki label:'Ebi 015' +swap -gravity Center -append "out/Ebi 015.jpg"
convert "Ebi 018.JPG" -pointsize 43 -background Khaki label:'Ebi 018' +swap -gravity Center -append "out/Ebi 018.jpg"
convert "Ebi 016.JPG" -pointsize 43 -background Khaki label:'Ebi 016' +swap -gravity Center -append "out/Ebi 016.jpg"
convert "Darush 007.JPG" -pointsize 43 -background Khaki label:'Darush 007' +swap -gravity Center -append "out/Darush 007.jpg"

بله ظاهرا که همه چیز عالیه. بزن بریم! اکو رو حذف می کنم ولی با اینکه دستورهای بالا درست هستن، به دلیلی که نمی دونم چیه دستورات درست اجرا نمی شن. پس کارم رو راحت می کنم:

$ find . -name "*JPG" | sed "s/\.\///" | sed "s/\.JPG//" | xargs -L1 -I THIS echo convert \"THIS.JPG\" -pointsize 43 -background Khaki label:\'THIS\' +swap -gravity Center -append \"out/THIS.jpg\" > commands.sh
$ sh commands.sh 
$ ls out/
Bijan Mortazavi 001.jpg  Bijan Mortazavi 005.jpg  Darush 003.jpg  Darush 007.jpg  Darush 011.jpg   Delkash 003.jpg  Ebi 004.jpg  Ebi 008.jpg  Ebi 012.jpg  Ebi 016.jpg
Bijan Mortazavi 002.jpg  Bijan Mortazavi 006.jpg  Darush 004.jpg  Darush 008.jpg  Darush 012.jpg   Ebi 001.jpg      Ebi 005.jpg  Ebi 009.jpg  Ebi 013.jpg  Ebi 017.jpg
Bijan Mortazavi 003.jpg  Darush 001.jpg           Darush 005.jpg  Darush 009.jpg  Delkash 001.jpg  Ebi 002.jpg      Ebi 006.jpg  Ebi 010.jpg  Ebi 014.jpg  Ebi 018.jpg
Bijan Mortazavi 004.jpg  Darush 002.jpg           Darush 006.jpg  Darush 010.jpg  Delkash 002.jpg  Ebi 003.jpg      Ebi 007.jpg  Ebi 011.jpg  Ebi 015.jpg  Ebi 019.jpg

بله. دستوراتی که درست کرده بودم رو می ریزم توی یک فایل و بعد فایل رو اجرا می کنم و می بینیم که دایرکتوری out پر شده از فایل هایی که لازم بود این بلا سرشون بیاد. مثلا:

www.guitarestan.com

حالا می تونیم این کدها رو بدیم به دوستمون که روی سیستم خودش روی چند صد تبلچر دیگه اجرا کنه و این می شه یک فعالیت شاد و خوشحال که هم باعث می شه مهارتهای لینوکسی مون بالا بره، هم بهمون خوش بگذره هم مشکل یک دوستمون حل بشه.

چرا گنو/لینوکس رو دوست دارم: ویدئوی یک روز حیاط من در چهل ثانیه

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

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

وبکم رو از لای پنجره بیرون گذاشتم و با وایرلس به رزبری وصل شدم. اولین دستور که این بود:

# at 3:15
>apt-get update
>apt-get -y upgrade
>
>Ctrl+D

که سیستم خودش نصفه شب که اینترنت رایگانه، آپدیت بشه. بعد fswebcam و motion رو نصب کردم که می تونن یک صحنه رو از دوربین نصب کنن یا اصولا ران بشن و حرکات رو تشخیص بدن و ذخیره کنن. حالا دیگه کافیه از سیستم لاگ آوت کنیم و فردا شب به سراغش بریم. اولین قدم اینه:

jadi@funlife:/tmp/motion$ rsync -r pi@192.168.1.11:/home/pi/motion/ .

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

mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800

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

avconv -i movie.mpg -acodec libmp3lame -ac 0 -s 320x240 -r 9   /tmp/out.mp4

و نتیجه می شه این ویدئوی چهل ثانیه ای که خلاصه یک شبانه روز از حیاط خونه من است.

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

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

گیکی‌ترین سیستم اشتراک فایلی که امسال دیدین

اکثر سیستم‌های اشتراک فایل برای من جذاب نیستن، باید برم براوز کنم، فایل انتخاب کنم، منتظر بشم آپلود بشه و بعد لینک رو کپی کنم و بدم به یکی که بره سایت و کپچا بزنه و ببینه که اگر پول نده دانلودش خیلی کنده ولی اگر پول بده دو سوت دانلود می شه – حیونکی نمی دونه ما ایرانیم – و …

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

jadi@funlife:~/Desktop$ curl --upload-file bukowski-best_die_by_their_hand.jpg http://transfer.sh
https://transfer.sh/7xme5/bukowski-best-die-by-their-hand.jpg
jadi@funlife:~/Desktop$ 
بله به همین سادگی لینک دانلود رو هم گرفتیم که تا دو هفته معتبره. اگر گنو/لینوکسی باشین می دونین که این چقدر قابلیت داره، می شه یک اسکریپت کوچیک درست کرد که بگه:
transfer thisfile.jpg jadijadi@gmail.com

و فایل رو آپلود کنه و خروجی کرل رو ایمیل کنه به اون آدرس یا هر چیز دیگه. خود سایت ترنسفر اس اش مثالهای جالبتری هم داره.

وَر رفتن با اعداد، نور خورشید و نموداری که شاید باعث بشه استعفا بدین

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

مشخصه که نیاز به کتابخونه ای داریم که فانکشن های sunrise و غیره رو دارن پس:

> library(maptools)

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

> portsmouth <- matrix(c(51.4231, 35.6961), nrow=1)

و تاریخ:

> for_date <- as.POSIXct("2014-09-25", tz="Asia/Tehran")

و ازش بخوایم ساعت طلوع خورشید امروز رو بده:

> sunriset(portsmouth, for_date, direction="sunrise", POSIXct.out=TRUE)
        day_frac                time
newlon 0.2460366 2014-09-25 05:54:17

بله ظاهرا درسته ! خورشید ما رو ساعت ۵ و ۵۴ دقیقه صبح بیدار می کنه که مثل گرگ پاشیم بریم سر کار. این کتابخونه همچنین می تونه به ما زمان غروب، طول روز و ظهر رو هم بده و از اون باحالتر می تونه ورودی هایی به فرم بردارهایی از روزها قبول کنه. پس این تابع:

# adapted from http://r.789695.n4.nabble.com/maptools-sunrise-sunset-function-td874148.html
ephemeris <- function(lat, lon, date, span=1, tz="UTC") {
 
  # convert to the format we need
  lon.lat <- matrix(c(lon, lat), nrow=1)
 
  # make our sequence - using noon gets us around daylight saving time issues
  day <- as.POSIXct(date, tz=tz)
  sequence <- seq(from=day, length.out=span , by="days")
 
  # get our data
  sunrise <- sunriset(lon.lat, sequence, direction="sunrise", POSIXct.out=TRUE)
  sunset <- sunriset(lon.lat, sequence, direction="sunset", POSIXct.out=TRUE)
  solar_noon <- solarnoon(lon.lat, sequence, POSIXct.out=TRUE)
 
  # build a data frame from the vectors
  data.frame(date=as.Date(sunrise$time),
             sunrise=as.numeric(format(sunrise$time, "%H%M")),
             solarnoon=as.numeric(format(solar_noon$time, "%H%M")),
             sunset=as.numeric(format(sunset$time, "%H%M")),
             day_length=as.numeric(sunset$time-sunrise$time))
 
}

می تونه لت و لانگ (طول و عرض) یک مکان رو بگیره و به اندازه date روز بعد از تاریخی که بهش گفتیم، به ما بگه که وضعیت نور روز چطوریه (اونم توی تایم زون مورد نظر):

> ephemeris(35.6961, 51.4231, "2014-09-25", 10, tz="Asia/Tehran")
         date sunrise solarnoon sunset day_length
1  2014-09-25     554      1156   1757   12.05001
2  2014-09-26     555      1155   1755   12.01276
3  2014-09-27     555      1155   1754   11.97550
4  2014-09-28     556      1155   1752   11.93826
5  2014-09-29     557      1154   1751   11.90104
6  2014-09-30     558      1154   1750   11.86384
7  2014-10-01     558      1154   1748   11.82666
8  2014-10-02     559      1153   1747   11.78952
9  2014-10-03     600      1153   1745   11.75241
10 2014-10-04     601      1153   1744   11.71535

جالبه ولی نه به اندازه کافی. مغز اکثر ما نمودارها رو بهتر از جدول ها می فهمه. پس ما با توابع ggplot دو تا نمودار می کشیم. یکی نمودار نواری که نشون بده چه بخشی از روز نور آفتاب داره و چه بخش هایی تاریکه و یک نمودار دیگه که به سادگی بگه هر روز از سال چند ساعت نور داره.

library(ggplot2)
library(scales)
library(gridExtra)

# create two formatter functions for the x-axis display
 
# for graph #1 y-axis
time_format <- function(hrmn) substr(sprintf("%04d", hrmn),1,2)
 
# for graph #2 y-axis
pad5 <- function(num) sprintf("%2d", num)
 
daylight <- function(lat, lon, place, start_date, span=2, tz="UTC", 
                     show_solar_noon=TRUE, show_now=TRUE, plot=TRUE) {
 
  stopifnot(span>=2) # really doesn't make much sense to plot 1 value
 
  srss <- ephemeris(lat, lon, start_date, span, tz)
 
  x_label = ""
 
  gg <- ggplot(srss, aes(x=date))
  gg <- gg + geom_ribbon(aes(ymin=sunrise, ymax=sunset), fill="#ffeda0")
 
  if (show_solar_noon) gg <- gg + geom_line(aes(y=solarnoon), color="#fd8d3c")
 
  if (show_now) {
    gg <- gg + geom_vline(xintercept=as.numeric(as.Date(Sys.time())), color="#800026", linetype="longdash", size=0.25)
    x_label = sprintf("زمان در لحظه ترسیم نمودار: %s", format(Sys.time(), "%Y-%m-%d / %H:%M"))
  }
 
  gg <- gg + geom_hline(yintercept=as.numeric("0700"), color="#1000F6", linetype="longdash", size=0.25)
  gg <- gg + geom_hline(yintercept=as.numeric("1815"), color="#1000F6", linetype="longdash", size=0.25)

  gg <- gg + scale_x_date(expand=c(0,0), labels=date_format("%b "))
  gg <- gg + scale_y_continuous(labels=time_format, limits=c(0,2400), breaks=seq(0, 2400, 200), expand=c(0,0))
  gg <- gg + labs(x=x_label, y="",
                  title=sprintf("طلوع و غروب خورشید در %s\n%s ", place, paste0(range(srss$date), sep=" ", collapse="تا ")))
  gg <- gg + theme_bw()
  gg <- gg + theme(panel.background=element_rect(fill="#525252"))
  gg <- gg + theme(panel.grid=element_blank())
 
  gg1 <- ggplot(srss, aes(x=date, y=day_length))
  gg1 <- gg1 + geom_area(fill="#ffeda0")
  gg1 <- gg1 + geom_line(color="#525252")
 
  if (show_now) gg1 <- gg1 + geom_vline(xintercept=as.numeric(as.Date(Sys.time())), color="#800026", linetype="longdash", size=0.25)
 
  gg1 <- gg1 + scale_x_date(expand=c(0,0), labels=date_format("%b "))
  gg1 <- gg1 + scale_y_continuous(labels=pad5, limits=c(0,24), expand=c(0,0))
  gg1 <- gg1 + labs(x="", y="", title="طول روز به ساعت")
  gg1 <- gg1 + theme_bw()
 
  if (plot) grid.arrange(gg, gg1, nrow=2)
 
  arrangeGrob(gg, gg1, nrow=2)
 
}

و حالا می تونیم هر چیزی بخوایم بکشیم.. مثلا برای تهران:

daylight(35.6961, 51.4231, "Tehran", "2014-03-21", 365, tz="Asia/Tehran")

باعث می شه به این برسیم:

daylight_tehran

نمودار بالا نشون می ده چه ساعت های از روز صبح است و چه ساعت هایی شب و نمودار پایینی نشون دهنده ساعت های روشنایی است که در هر روز داریم و توش به راحتی می تونین تاثیر اینطرف اونطرف کشیدن ساعت رو ببینین.

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

می بنین اعداد چقدر قشنگن؟