اندر احوالات کد کثیفی که از گذشته به ما ارث رسیده و بازسازی اون

شنبه 01 مهر 1396 توسط Ziaa

بسیار سفر باید تا پخته شود خامی

در دنیای برنامه‌نویسی همیشه اینجوری نیست که همه چیز بر وفق مراد باشه؛ درست مثل زندگی. مثلا زیاد پیش میاد که به هر دلیلی کارهای یکی از اعضای تیم به تو واگذار میشه. اینجاست که اگه بین اعضای تیم، استاندارد درستی تعریف نشده باشه یا برنامه‌نویس ارشدی وجود نداشته باشه یا وجود داشته اما وظایفش رو به درستی انجام نداده یا مرور کدی1 در کار نباشه یا خود نفر قبلی مسئولیت‌پذیر نبوده یا ضعف آموزش یا به هزاران دلیل ریز و درشت دیگه، کدی به دست شما میرسه که ناخوانا و شکنندهست. به هر جاش که دست می‌زنیم یه جای دیگه‌اش بهم می‌خوره و یه باگ دیگه پیدا می‌شه. هر اسمی می‌خواید براش بذارید. کد زشت، کثیف، بدبو، اسپاگتی یا هرچیز دیگه‌ای. مهم اینه که شما بتونید این‌ها رو شناسایی و بعد اصلاح کنید. در این موقعیت به نظرم بهتره که:

  • خونسردی خودتون رو حفط کنید (درست مثل توصیه‌های روشنی که برای حوادث طبیعی می‌گن!)
  • برنامه‌نویس‌های قبلی رو قضاوت نکنید چونکه شما در شرایط اونها نبودید و تضمینی وجود نداره که در اون شرایط کار شما بهتر از حالت فعلی از آب در میومد
  • از اشتباهات نفرات قبلی درس بگیرید و سعی کنید شما دیگه تکرارشون نکنید. یه چیزی شبیه «ادب از که آموختی...»
  • غُر نزنید. به جای غر زدن به این موضوع به شکل مسئله‌ای نگاه کنید که وظیفه حل کردنش رو به شما سپردن
  • و در نهایت اینکه بازسازی و ریفکتور2 کردن کد رو یاد بگیرید و با کمک برنامه‌نویس ارشدتر، حتی به اندازه یک خط کد، کدها رو بهبود بدید. تغییرات کوچک بدید و قدم‌های کوچک بردارید.

نمیشه نسخه کلی پیچید؛ اما به نظرم بدترین کار اینه که ما هم همون راه نفرات قبلی رو ادامه بدیم. توسعه‌دهندگی صرفا این نیست که یه چیز جدید رو از صفر خودمون شروع کنیم بلکه بهبود هم بخشی از مسیر توسعه است.


  1. Code review 

  2. Refactoring 

اهمیت لاگ‌ها - در کدهای TSQL چه طور اطلاعات مورد نظر رو به SQL Server Profiler بفرستیم؟

جمعه 10 شهریور 1396 توسط Ziaa

هر گُلی، علت و عیبی دارد گُل بی علت و بی عیب، خداست

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

Log early, log often

در لایه دیتابیس ابزاری که برای شناسایی خطاها و بررسی کارایی کد و پایگاه داده استفاده می‌شه SQL Server Profiler هست. برای اینکه بتونیم در رویه‌ها1 و تابع‌ها2 اطلاعات مورد نظر رو به پروفایلر بفرستیم؛ می‌تونیم از sp_trace_generateevent استفاده کنیم.

این SP سه تا ورودی داره. @eventid و @userinfo و @userdata که از بین اونها فقط @eventid ضروریه. این پارامتر به دلخواه خودمون می‌تونه یکی از اعداد ۸۲ تا ۹۱ باشه و برای شناسایی نوع رویداد و فیلتر کردن اونها استفاده میشه. میشه برای خودمون قرارداد کنیم که هر کدوم از این اعداد نشون دهنده یکی از سطح‌های لاگ‌گیری3 است.

  • DEBUG
  • ERROR
  • FATAL
  • WARN
  • INFO
  • TRACE

از اونجایی که لاگ‌ها بدون پیغام مناسب کاربرد کمی دارن؛ برای فرستادن متن پیام‌ها از @userinfo کمک می‌گیریم.

پس در نهایت توی کدهامون چیزی شبیه کد زیر داریم:

CREATE PROCEDURE [dbo].[usp_TraceSandbox] @Param AS NVARCHAR(128)
AS
    BEGIN TRY

        DECLARE @info NVARCHAR(128);
        SET @info = N'Info: @param = ' + @Param;

        -- Log اطلاعات
        EXEC master..sp_trace_generateevent @eventid = 82, @userinfo = @info;

        THROW 51010, N'مثلا یه خطایی اتفاق افتاده!',1;
    END TRY
    BEGIN CATCH

        DECLARE @error NVARCHAR(128);
        SET @error = N'Error: ' + ERROR_MESSAGE();

        -- Log خطاها
        EXEC master..sp_trace_generateevent @eventid = 83, @userinfo = @error;
    END CATCH;
GO

برای اینکه بتونیم این اطلاعات رو در پروفایلر ببینیم، رویدادهای مورد نظرمون رو از بخش User configurable انتخاب می‌کنیم. همتای هر کدوم از پارامترها در جدول زیر مشخص شدن.

sp_trace_generateevent SQL Server Profiler
@eventid 82-91 User configurable 0-9
@userinfo TextData
@userdata BinaryData

SQL Server Profiler configs

و در نهایت وقتی که مشغول ردگیری خطاها شدیم و پروفایلر رو اجرا کردیم داده‌های مورد نظرمون رو می‌بینیم. Trace


  1. Stored procedure 

  2. Function 

  3. Logging levels 

ساختن بُعد تاریخ شمسی برای استفاده در Cube

سه شنبه 05 بهمن 1395 توسط Ziaa

DimPersianDate

همان‌طور که می‌دانید در مباحث مربوط به هوش تجاری (BI)، یکی از پرکاربردترین عناصر برای گزارش‌گیری‌های سریع، تلفیقی و چندبعدی OLAP Cubeها هستند (اگر نمی‌دانید، این متن برای شما کاربردی ندارد. وقت ارزشمند خود را تلف نکنید!). معمولاً در Cubeها بُعد تاریخ (Date dimension) یکی از اصلی‌ترین ابعاد است و در اکثر گزارش‌ها به آن نیاز خواهد شد.

برای ایجاد بُعد تاریخ با تاریخ‌های شمسی می‌توان ابتدا تابعی برای تبدیل تاریخ میلادی به شمسی در SQL Server نوشت. سپس با استفاده از این تابع، جدول تاریخ‌ها در انبارداده (Data Warehouse) را برای بازه‌ی زمانیِ خاصی ایجاد کرد.

تابع تبدیل میلادی به شمسی در SQL Server

برای این کار «چرخ را دوباره اختراع نمی‌کنیم» و از کد این وبلاگ و البته نسخه سریع‌تر آن (پی‌نوشت هفتم) برای ایجاد تابع GregorianToJalali استفاده می‌کنیم. در عین حال مشکلات و باگ‌های این کد را می‌دانیم.

ایجاد روال (Stored Procedure) برای پرکردن بُعد تاریخ در انبار داده

در اینجا روال spPopulatePersianDateDimension را ایجاد می‌کنیم تا جدولی با عنوان PersianDateDimension در انبارداده ما ایجاد کند (اگر از قبل وجود نداشت) و سپس با توجه به ورودی روال، این جدول را با تاریخ‌های شمسی و میلادی متناظر برای یک بازه زمانی خاص پُر کند.

این روال، همه تاریخ‌های شمسی و میلادی بین تاریخ شروع ‪@FromDate‬ و پایان ‪@ToDate‬ را در جدول PersianDateDimension وارد می‌کند. همان طور که در کد مشخص است ستون‌هایی مانند «روز هفته (GregorianDayNumberOfWeek و PersianDayNumberOfWeek)» و «روز سال (GregorianDayNumberOfYear و PersianDayNumberOfYear)» و ... نیز در این جدول وارد می‌شود که این موارد معمولاً در گزارش‌های جزئی‌تر مورد استفاده قرار می‌گیرند.

پر کردن بُعد تاریخ برای یک بازه زمانی

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

EXECUTE dbo.spPopulatePersianDateDimension @FromDate = '2016-1-1', @ToDate = '2017-1-1'

کار تمام است و شما می‌توانید این بُعد را برای سایر مکعب‌های خود نیز استفاده کنید.

راهنمای استفاده از سایت‌ساز پلیکان - بخش دوم - تغییر قالب و تبدیل تاریخ نوشته‌ها از میلادی به شمسی

شنبه 13 آذر 1395 توسط Ziaa

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

برای پلیکان قالب‌های مختلفی ایجاد شده است. شما به راحتی می‌توانید با نگاهی به آنها و قالب ساده‌ای مثل simple و مستندات jinja قالب دلخواه خود را ایجاد کنید. اگر به قالب راست-به-چپ و مناسب نوشته‌های فارسی نیاز دارید می‌توانید از Pelican-RTL-theme استفاده کنید. این قالب برگرفته از کار خوب تیم سُبحه است.

روش تغییر قالب

بهتر است پوشه‌ای با نام دلخواه مثلا themes برای نگهداری قالب‌های وبلاگ خود در نظر بگیرید. سپس به هر روشی که دوست دارید؛ فایل‌های مورد نیاز هر قالب را به این پوشه انتقال دهید. مثلا می‌توانید به یکی از روش‌های زیر عمل کنید:

۱. کپی کردن مخزن قالب

git clone https://github.com/ziaa/Pelican-RTL-theme.git themes/Pelican-RTL-theme

۲. اضافه کردن قالب به عنوان submodule

git submodule add -b master https://github.com/ziaa/Pelican-RTL-theme.git themes/Pelican-RTL-theme

در مرحله بعد باید مسیر قالب مورد نظر را در فایل تنظیمات پلیکان pelicanconf.py وارد کنید.

#Theme

THEME = 'مسیر/Pelican-RTL-theme' 

همچنین بجای این کار می‌توانید در هنگام تهیه خروجی‌های استاتیک سایت، مسیر قالب را مشخص کنید.

pelican content -s pelicanconf.py -t path/to/themes/Pelican-RTL-theme

روش فارسی کردن تاریخ نوشته‌ها

یکی از قابلیت‌های سایت ساز پلیکان امکان نوشتن پلاگین‌های دلخواه برای آن است. شما می‌توانید فهرستی از پلاگین‌های موجود را در اینجا مشاهده کنید. برای فارسی کردن تاریخ‌ مطالب می‌توانید از پلاگین Pelican Persian date استفاده کنید. برای استفاده از آن ابتدا بهتر است پوشه‌ای با نام دلخواه (مثلا plugins) برای نگهداری پلاگین‌ها ایجاد کنید. سپس به هر روشی که دوست دارید فایل‌های پلاگین را در این پوشه قرار دهید. مثلا می‌توانید از یکی از روش‌های زیر استفاده کنید:

git clone https://github.com/ziaa/pelican_persian_date.git plugins/pelican_persian_date
git submodule add -b master https://github.com/ziaa/pelican_persian_date.git plugins/pelican_persian_date

در مرحله بعد باید مسیر پوشه plugins و پلاگین‌های فعال را در فایل تنظیمات پلیکان pelicanconf.py مشخص کنید. برای اینکار خطوط زیر را به آن اضافه کنید.

# Plugins
PLUGIN_PATHS = ['مسیر/plugins']
PLUGINS = ["pelican_persian_date"]

اگر می‌خواهید شکل خروجی تاریخ‌ها را کنترل کنید، این خطوط را به فایل pelicanconf.py اضافه کنید.

DATE_FORMATS = {
    'fa': '%A %d %B %Y'
}

با این کار می‌توانید مشخص کنید که تاریخ‌های فارسی به چه شکلی نمایش داده شود. مثلا شنبه ۱۳ آذر ۱۳۹۵ یا ۱۳۹۵/۰۹/۱۳ یا هر شکل دلخواه دیگری. برای آشنایی با انواع فرمت‌ها از این لینک کمک بگرید.

در نهایت خروجی وبلاگ را دوباره بسازید و از قالب و تاریخ فارسی لذت ببرید!

pelican content

راهنمای استفاده از سایت‌ساز پلیکان - بخش اول - نصب و راه‌اندازی اولیه

سه شنبه 09 آذر 1395 توسط Ziaa

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

  1. write
  2. build
  3. publish

شما نوشته مورد نظرتان را می‌نویسید، خروجی html را سایت‌ساز برای‌تان ایجاد می‌کند و در نهایت این خروجی را در هاست خود قرار می‌دهید. البته مشخص است که یک برنامه‌نویس فقط مطلب مورد نظر را می‌نویسد و با ابزارها و کدهای مختلف بقیه مراحل را به کامپیوتر واگذار می‌کند. تا حد امکان ما دوست داریم کارها خودکار انجام شوند!

در اینجا به صورت خلاصه راهنمای اولیه نصب پلیکان و ایجاد وبلاگ اولیه با استفاده از آن را می‌نویسم. توجه کنید که این مطلب صرفاً یک یادداشت است. برای راهنمای کامل به مستندات پلیکان مراجعه کنید.

sudo apt-get install python-pip
  • برای به روز رسانی pip در ویندوز
python -m pip install --upgrade pip
  • به روز رسانی pip در توزیع‌های لینوکس
pip install --upgrade pip

در صورت نیاز استفاده از virtualenv برای ایزوله کردن محیط توسعه و بسته‌های پایتون. (راهنمای نصب در اوبونتو)

sudo apt install virtualenv
virtualenv ~/virtualenvs/pelican
cd ~/virtualenvs/pelican
source bin/activate

# Do what ever you want
# example: pip install pelican
# And after you've done your job, deactivate virtualenv
deactivate
  • نصب پلیکان
pip install pelican
  • نصب Markdown‌ (در صورتیکه می‌خواهید نوشته‌ها را با مارک‌داون بنویسید)
pip install Markdown
  • ساختن پوشه سایت و ایجاد ساختار اولیه
mkdir your-project-folder
cd your-project-folder
pelican-quickstart
  • پاسخ‌گویی به سوالات (جواب‌های پیش‌فرض در براکت [] نوشته شده)
...
> What is your time zone? [Europe/Paris] Asia/Tehran
...
  • نوشتن اولین مطلب در یک فایل md و در پوشه content
Title: سلام دنیا!
Slug: Hello-World
Date: 2015-07-21 23:20
Category: Test
Tags: Test

سلام دنیا!
  • ساختن فایل‌های استاتیک وبلاگ (خروجی‌ها در پوشه output)
pelican content
  • راه‌اندازی سرور local
cd output
python -m pelican.server

الان وبلاگ با قالب پیش‌فرض ساخته شده و از طریق آدرس http://localhost:8000 قابل دسترسی است. در بخش‌های بعدی به تغییر قالب، فارسی‌سازی و قرار دادن وبلاگ روی گیت‌هاب اشاره خواهم کرد.

صفحه 1 / 2 »