نظرات نظرسنجی‌ها
آخرین باری که یک کتاب فارسی را در زمینه‌ی دات نت خریدید، کی بوده؟
با سلام خدمت همه دوستان
بنده هم با معرفی یکی از دوستانم کتاب آقای بهروز راد ASP.NET MVC4 انتشارات پندارپارس را خریداری کردم.
البته کتاب sharepoint 2010 همین انتشارات را نیز قبلا خریداری کرده بودم.
بسیار کتاب خوبی بود و هست. میشه به کسانی که میخواهند MVC را بصورت علمی یاد بگیرند توصیه کرد.
اما انتقادهایی هم میتوان به این کتاب داشت که از جناب بهروز راد بعنوان یک همکار بسیار سپاسگذاریم که توانسته کتابی در این حد تهیه و ارائه نماید.
عموما از کتابهای فارسی استفاده نمیکنم و رفرنسهای خارجی را بیشتر میپسندم اما اگر کتابی در حد و اندازه‌های کتاب مذکور آقای بهروز راد ارائه شود حتما خریداری و در آرشیو کتابخانه برنامه نویسی خودم قرار میدهم.
امیدوارم هر کجای این کره زیبای خاکی باشند موفق و پیروز باشند در ضمن از آقای نصیری نیز بابت همه کارهای شایانی که همچنان ادامه دارد و ما نیز حمایتش خواهیم نمود کمال تشکر و سپاس را دارم.
به امید روزهای پر از موفقیت و پیروزی بیش از پیش در زمینه علوم کامپیوتر ، تولید نرم افزار و برنامه نویسی.
اشتراک‌ها
تفاوت توسعه‌دهندگان کم تجربه با توسعه‌دهندگان حرفه ای

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

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

تفاوت توسعه‌دهندگان کم تجربه با توسعه‌دهندگان حرفه ای
مطالب
استفاده از Re-Captcha
در اینجا استفاده از re-CAPTCHA برای ASP.Net و در اینجا برای ASP.Net MVC با استفاده از سرویس گوگل نسخه 1 آن آشنا شدید. در این مقاله می‌خواهیم توضیحاتی را در مورد دلیل استفاده و نحوه‌ی ثبت re-CAPTCHA نسخه 2 برای تکنولوژی‌های ASP.Net و ASP.Net MVC ارائه کنیم.

  reCAPTCHA چیست؟

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



دلیل استفاده از reCAPTCHA:

  1. گزارش روزانه از وضعیت موفقیت آمیز بودن هویت سنجی
  2. سهولت استفاده برای کاربران
  3. سهولت استفاده جهت برنامه نویسان
  4. دسترسی پذیری مناسب بدلیل وجود سؤالات تصویری و تلفظ و پخش عبارت بصورت صوتی
  5. امنیت بالا 

آیا می‌توان قالب reCAPTCHA را تغییر داد؟

جواب این سوال بله می‌باشد. این سرویس در دو قالب سفید و مشکی ارائه شده‌است که به صورت پیش فرض قالب سفید آن انتخاب می‌شود. در تصویر زیر قالب‌های این سرویس را مشاهده خواهید کرد.



زبان‌های پشتیبانی شده در این سرویس:


اضافه نمودن reCAPTCHA به سایت:

اگر قبلا در گوگل ثبت نام نموده‌اید کافیست وارد این سایت شوید و بر روی Get reCAPTCHA کلیک نمائید؛ در غیر اینصورت می‌بایستی یک حساب کاربری ایجاد نماید. بعد از ورود، به کنترل پنل هدایت خواهید شد. در نمای اول به تصویر زیر برخورد خواهید کرد که از شما ثبت سایت جدید را خواستار است:



نام، دامنه سایت و مالک را وارد و ثبت نام نماید.

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


گام‌های لازم جهت نمایش سرویس در سایت:

  1. دستورات سمت کاربر
  2. دستورات سمت سرور 

دستورات سمت کاربر:

کد زیر را در قبل از بسته شدن تک <head/> قرار دهید:

<script src='https://www.google.com/recaptcha/api.js'></script>
کد زیر را در داخل تگ فرمی که می‌خواهید کپچا نمایش داده شود قرار دهید:
<div data-sitekey="6LdHGgwTAAAAAClKFhGthRrjBXh5AUGd4eWNCQq7"></div>

نکته: مقدار data-sitekey برابر است با رشته Site Key که گوگل برای شما ثبت نمود.



دستورات سمت سرور:

وقتی کاربر فرم حاوی کپچا را که به صورت صحیح هویت سنجی آن انجام شده باشد به سمت سرور ارسال کند، به عنوان بخشی از داده‌ی ارسال شده، یک رشته با نام g-recaptcha-response  با دستور Request دریافت خواهید کرد که به منظور بررسی اینکه آیا گوگل تایید کرده است که کاربر، یک درخواست POST ارسال نمود‌است. با این پارامترها یک مقدار json برگشت داده خواهد شد که می‌بایستی کلاسی متناظر با آن جهت خواندن ساخته شود.

با استفاده از کد زیر مقدار برگشتی Json را در کلاس مپ می‌نمائیم:
using System.Collections.Generic;
using Newtonsoft.Json;

namespace BaseConfig.Security.Captcha
{
    public class RepaptchaResponse
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("error-codes")]
        public List<string> ErrorCodes { get; set; }
    }
}

با استفاده از کلاس زیر درخواستی به گوگل ارسال شده و در صورتیکه با خطا مواجه شود با استفاده از دستور switch به آن دسترسی خواهیم یافت.
using System.Configuration;
using System.Net;
using Newtonsoft.Json;

namespace BaseConfig.Security.Captcha
{
    public class ReCaptcha
    {
        public static string _secret;

        static ReCaptcha()
        {
            _secret = ConfigurationManager.AppSettings["ReCaptchaGoogleSecretKey"];
        }

        public static bool IsValid(string response)
        {
            //secret that was generated in key value pair
            var client = new WebClient();
            var reply = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={_secret}&response={response}");

            var captchaResponse = JsonConvert.DeserializeObject<RepaptchaResponse>(reply);

            // when response is false check for the error message
            if (!captchaResponse.Success)
            {
                //if (captchaResponse.ErrorCodes.Count <= 0) return View();

                //var error = captchaResponse.ErrorCodes[0].ToLower();
                //switch (error)
                //{
                //    case ("missing-input-secret"):
                //        ViewBag.Message = "The secret parameter is missing.";
                //        break;
                //    case ("invalid-input-secret"):
                //        ViewBag.Message = "The secret parameter is invalid or malformed.";
                //        break;

                //    case ("missing-input-response"):
                //        ViewBag.Message = "The response parameter is missing.";
                //        break;
                //    case ("invalid-input-response"):
                //        ViewBag.Message = "The response parameter is invalid or malformed.";
                //        break;

                //    default:
                //        ViewBag.Message = "Error occured. Please try again";
                //        break;
                //}
                return false;
            }
            // Captcha is valid
            return true;
        }
    }
}

تابع IsValid از نوع برگشتی Boolean بوده و خطایی برگشت داده نخواهد شد و از این جهت به صورت کامنت برای شما گذاشته شده که می‌توان متناظر با کد نویسی آن را تغییر دهید.
در اکشن زیر مقدار response برسی می‌شود تا خالی نباشد و همچنین مقدار آن را می‌توان با استفاده از تابع IsValid در کلاس ReCaptcha به سمت گوگل فرستاد.
        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public virtual async Task<ActionResult> Login(LoginPageModel model, string returnUrl)
        {
            var response = Request["g-recaptcha-response"];
            if (response != null && ReCaptcha.IsValid(response))
            {
                // 
            }
         }

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

/**
 * 
 * @param {} data 
 * @returns {} 
 */
function Success(data) {
    grecaptcha.reset();
}

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

برای این کار دستور
<div data-sitekey="6LdHGgwTAAAAAClKFhGthRrjBXh5AUGd4eWNCQq7"></div>  
که در بالا تعریف شد، به شکل زیر تغییر خواهد کرد:

    <script>
        var recaptcha1;
        var recaptcha2;
        var myCallBack = function () {
            //Render the recaptcha1 on the element with ID "recaptcha1"
            recaptcha1 = grecaptcha.render('recaptcha1', {
                'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9',
                'theme': 'light'
            });

            //Render the recaptcha2 on the element with ID "recaptcha2"
            recaptcha2 = grecaptcha.render('recaptcha2', {
                'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9',
                'theme': 'light'
            });

            //Render the recaptcha3 on the element with ID "recaptcha3"
            recaptcha2 = grecaptcha.render('recaptcha3', {
                'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9',
                'theme': 'light'
            });
        };
    </script>

برای نمایش کپچا، تگ‌های div با id متناظر با recaptcha1, recaptcha2, recaptcha3 ( در این مثال از سه کپچا در صفحه استفاده شده است ) در صفحه قرار خواهند گرفت.

<div id="recaptcha1"></div>
<div id="recaptcha2"></div>
<div id="recaptcha3"></div>

کار ما تمام شد. حال اگر پروژه را اجرا نمائید، در صفحه سه کپچا مشاهده خواهید کرد.


چند زبانه کردن کپچا:

برای چند زبانه کردن کافیست با مراجعه به این لینک و یا استفاده از تصویر بالا ( زبان‌های پشتیبانی ) مقدار آن زبان را برابر با پراپرتی hl که به صورت کوئری استرینگ برای گوگل ارسال می‌گردد، استفاده نمود. کد زیر نمونه‌ی استفاده شده برای زبان‌های انگلیسی و فارسی می‌باشد که با ریسورس مقدار دهی می‌شود.
<script src='https://www.google.com/recaptcha/api.js?hl=@(App_GlobalResources.CP.CurrentAbbrivation)'></script>

در صورتی که از فایل ریسوس استفاده نمی‌کنید می‌توان به صورت مستقیم مقدار دهی نمائید:
<script src='https://www.google.com/recaptcha/api.js?hl=fa'></script>



برای دوستانی که با تکنولوژی ASP.Net کار می‌کنند، این روال هم برای آنها هم صادق می‌باشد.

برای دریافت پروژه اینجا کلیک نمائید.
مطالب
مقدمه‌ای بر یادگیری ماشین در #C با استفاده از ML.NET

هنگامی که درباره‌ی علم و یادگیری ماشینی فکر می‌کنیم، دو زبان برنامه‌نویسی بلافاصله به ذهن متبادر می‌شوند: پایتون و R. این دو زبان به شکل عمومی از بسیاری از الگوریتم‌های یادگیری ماشین رایج، تکنیکهای پیش‌پردازش داده‌ها و خیلی بیشتر از اینها پشتیبانی می‌کنند؛ بنابراین برای -تقریباً- هر مساله‌ی یادگیری ماشینی مورد استفاده قرار می‌گیرند. 
 با این‌حال، گاهی فرد یا شرکتی نمی‌تواند از پایتون یا R استفاده کند که می‌تواند به یکی از دلایل متعدد، از جمله وجود کد منبع در زبان دیگر یا نداشتن هیچ تجربه‌ای در پایتون یا R باشد. یکی از محبوب‌ترین زبان‌های امروزی، #C است که برای بسیاری از کاربردها مورد استفاده قرار می‌گیرد. مایکروسافت برای استفاده از قدرت یادگیری ماشین در #C، یک بسته را به نام ML.NET ایجاد کرده که همه‌ی قابلیت‌های یادگیری ماشین پایه را فراهم می‌کند. 
در این مقاله، به شما نشان خواهم داد که چگونه از ML.NET برای ایجاد یک مدل دسته‌بندی دوتایی بهره ببرید؛ قابلیت‌های AutoML را مورد استفاده قرار داده و از یک مدل Tensorflow با ML.NET استفاده کنید. کد کامل مخصوص مدل دسته‌بندی دوتایی را می‌توانید در GitHub بیابید.

افزودن ML.NET به پروژه‌ی #C
اضافه کردن ML.NET به یک پروژه‌ی #C یا #F آسان است. تنها کار لازم، اضافه کردن بسته‌ی Microsoft.ML یا در برخی موارد، -بسته به نیازمندی‌های پروژه- بسته‌های اضافی مانند: Microsoft.ML.ImageAnalytics, Microsoft.ML.TensorFlow یا Microsoft.ML.OnnxTransformer است. 


بارگذاری در یک دیتاست و ایجاد pipeline داده‌ها
بارگذاری و پیش‌پردازش یک مجموعه داده در ML.NET کاملا ً متفاوت از زمانی است که با دیگر بسته‌ها / چارچوب‌های یادگیری ماشین کار می‌کنیم. چون ما نیاز داریم به طور واضح، ساختار داده‌ها را بیان کنیم. برای انجام این کار، فایلی به نام ModelInput.cs را درون یک پوشه به نام DataModels ایجاد کرده و داخل این فایل، همه‌ی ستون‌های مجموعه داده‌های خود را ثبت خواهیم کرد. برای این مقاله، ما از مجموعه داده‌های ردیابی کلاه‌برداری کارت اعتباری استفاده می‌کنیم که می‌تواند آزادانه از Kaggle بارگیری شود. این مجموعه‌داده‌ها شامل ۳۱ ستون است. کلاس تراکنش (۰ یا ۱)، مقدار تراکنش، زمان تراکنش و نیز ۲۸ ویژگی بی‌نام (anonymous). 


using Microsoft.ML.Data;

namespace CreditCardFraudDetection.DataModels
{
    public class ModelInput
    {
        [ColumnName("Time"), LoadColumn(0)]
        public float Time { get; set; }

        [ColumnName("V1"), LoadColumn(1)]
        public float V1 { get; set; }

        [ColumnName("V2"), LoadColumn(2)]
        public float V2 { get; set; }

        [ColumnName("V3"), LoadColumn(3)]
        public float V3 { get; set; }

        [ColumnName("V4"), LoadColumn(4)]
        public float V4 { get; set; }

        [ColumnName("V5"), LoadColumn(5)]
        public float V5 { get; set; }

        [ColumnName("V6"), LoadColumn(6)]
        public float V6 { get; set; }

        [ColumnName("V7"), LoadColumn(7)]
        public float V7 { get; set; }

        [ColumnName("V8"), LoadColumn(8)]
        public float V8 { get; set; }

        [ColumnName("V9"), LoadColumn(9)]
        public float V9 { get; set; }

        [ColumnName("V10"), LoadColumn(10)]
        public float V10 { get; set; }

        [ColumnName("V11"), LoadColumn(11)]
        public float V11 { get; set; }

        [ColumnName("V12"), LoadColumn(12)]
        public float V12 { get; set; }

        [ColumnName("V13"), LoadColumn(13)]
        public float V13 { get; set; }

        [ColumnName("V14"), LoadColumn(14)]
        public float V14 { get; set; }

        [ColumnName("V15"), LoadColumn(15)]
        public float V15 { get; set; }

        [ColumnName("V16"), LoadColumn(16)]
        public float V16 { get; set; }

        [ColumnName("V17"), LoadColumn(17)]
        public float V17 { get; set; }

        [ColumnName("V18"), LoadColumn(18)]
        public float V18 { get; set; }

        [ColumnName("V19"), LoadColumn(19)]
        public float V19 { get; set; }

        [ColumnName("V20"), LoadColumn(20)]
        public float V20 { get; set; }

        [ColumnName("V21"), LoadColumn(21)]
        public float V21 { get; set; }

        [ColumnName("V22"), LoadColumn(22)]
        public float V22 { get; set; }

        [ColumnName("V23"), LoadColumn(23)]
        public float V23 { get; set; }

        [ColumnName("V24"), LoadColumn(24)]
        public float V24 { get; set; }

        [ColumnName("V25"), LoadColumn(25)]
        public float V25 { get; set; }

        [ColumnName("V26"), LoadColumn(26)]
        public float V26 { get; set; }

        [ColumnName("V27"), LoadColumn(27)]
        public float V27 { get; set; }

        [ColumnName("V28"), LoadColumn(28)]
        public float V28 { get; set; }

        [ColumnName("Amount"), LoadColumn(29)]
        public float Amount { get; set; }

        [ColumnName("Class"), LoadColumn(30)]
        public bool Class { get; set; }
    }
} 
در اینجا یک فیلد را برای هر یک از ستون‌های داخل مجموعه داده‌مان ایجاد می‌کنیم. نکته‌ی مهم، تعیین شاخص (Index)، نوع و ستون، به شکل صحیح است. حالا که داده‌های ما مدل‌سازی شده‌اند، باید قالب و شکل داده‌های خروجی خود را مدل کنیم. این کار می‌تواند به روشی مشابه با کدهای بالا انجام شود. 
 using Microsoft.ML.Data;

namespace CreditCardFraudDetection.DataModels
{
    public class ModelOutput
    {
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }

        public float Score { get; set; }
    }
}  
ما در این‌جا ۲ فیلد داریم. فیلد score نشان‌دهنده‌ی خروجی به شکل درصد است؛ در حالیکه فیلد prediction از نوع بولی است. اکنون که هر دو داده ورودی و خروجی را مدل‌سازی کرده‌ایم، می‌توانیم داده‌های واقعی خود را با استفاده از روش مونت‌کارلو بارگذاری کنیم.
IDataView trainingDataView = mlContext.Data.LoadFromTextFile<ModelInput>(
                                            path: dataFilePath,
                                            hasHeader: true,
                                            separatorChar: ',',
                                            allowQuoting: true,
                                            allowSparse: false);

ساخت و آموزش مدل
برای ایجاد و آموزش مدل، نیاز به ایجاد یک pipeline داریم که شامل پیش‌پردازش داده‌های مورد نیاز و الگوریتم آموزش است. برای این مجموعه داده‌ی خاص، انجام هر پیش‌پردازش بسیار دشوار است زیرا ۲۸ ویژگی بی‌نام دارد. بنابراین تصمیم گرفتم که آن را ساده نگه دارم و تنها همه‌ی ویژگی‌ها را الحاق کنم (این کار باید در ML.NET انجام شود).
var dataProcessPipeline = mlContext.Transforms.Concatenate("Features", new[] { "Time", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28", "Amount" });
برای مدل، الگوریتم LightGBM را انتخاب می‌کنم. این الگوریتم در واقع در Microsoft.ML از ابتدا وجود ندارد؛ بنابراین شما باید Microsoft.ML.LightGbm را نصب کنید تا قادر باشید از آن استفاده کنید.
// Choosing algorithm
var trainer = mlContext.BinaryClassification.Trainers.LightGbm(labelColumnName: "Class", featureColumnName: "Features");

// Appending algorithm to pipeline
var trainingPipeline = dataProcessPipeline.Append(trainer);
اکنون می‌توانیم مدل را با متد Fit، آموزش داده سپس با استفاده از mlContext.model.save ذخیره کنیم:
ITransformer model = trainingPipeline.Fit(trainingDataView);
mlContext.Model.Save(model , trainingDataView.Schema, <path>);

ارزیابی مدل
حالا که مدل ما آموزش دیده است، باید عملکرد آن را بررسی کنیم. ساده‌ترین راه برای انجام این کار، استفاده از اعتبارسنجی متقاطع (cross-validation) است. ML.Net به ما روش‌های اعتبارسنجی متقاطع را برای انواع مختلف داده‌های مختلف، ارایه می‌دهد. از آنجا که مجموعه داده‌های ما یک مجموعه داده دسته‌بندی دودویی است، ما از روش mlContext.BinaryClassification.CrossValidateNonCalibrated برای امتیازدهی به مدل خود استفاده خواهیم کرد:
var crossValidationResults = mlContext.BinaryClassification.CrossValidateNonCalibrated(trainingDataView, trainingPipeline, numberOfFolds: 5, labelColumnName: "Class");

انجام پیش‌بینی
پیش بینی داده‌های جدید با استفاده از ML.NET واقعاً سرراست و راحت است. ما فقط باید یک PredictionEngine، نمایشی دیگر را از مدل خود که به طور خاص، برای استنباط ساخته شده است، ایجاد کنیم و متد Predict آن را به عنوان یک شی ModelInput فراخوانی کنیم. 
var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);

ModelInput sampleData = new ModelInput() {
    time = 0,
    V1 = -1.3598071336738,
    ...
};

ModelOutput predictionResult = predEngine.Predict(sampleData);

Console.WriteLine($"Actual value: {sampleData.Class} | Predicted value: {predictionResult.Prediction}"); 

Auto-ML 
نکته جالب دیگر در مورد ML.NET اجرای عالی Auto ML است. با استفاده از  Auto ML  فقط با مشخص کردن اینکه روی چه مشکلی کار می‌کنیم و ارائه داده‌های خود، می‌توانیم راه‌حل‌های اساسی و پایه‌ی یادگیری ماشین را بسازیم.
برای شروع کار با ML خودکار در ML.NET، باید  Visual Studio Extension - ML.NET Model Builder (Preview)  را بارگیری کنیم. این کار را می‌توان از طریق تب extensions انجام داد.
پس از نصب موفقیت آمیز افزونه، با کلیک راست روی پروژه‌ی خود در داخل Solution Ex می‌توانیم از Auto ML استفاده کنیم.

با این کار پنجره Model Builder باز می‌شود. سازنده‌ی مدل، ما را در روند ساخت یک مدل یادگیری ماشین راهنمایی می‌کند.
   
برای کسب اطلاعات در مورد چگونگی گذراندن مراحل مختلف، حتماً آموزش رسمی شروع کار را در سایت مایکروسافت، بررسی کنید. بعد از تمام مراحل، Model Builder به طور خودکار کد را تولید می‌کند.
 
استفاده از یک مدل پیش‌آموزش‌داده‌شده‌ی تنسورفلو (pre-trained) 
نکته‌ی جالب دیگر در مورد ML.NET این است که به ما امکان استفاده از مدل‌های Tensorflow و ONNX را برای استنباط ( inference ) می‌دهد. برای استفاده از مدل Tensorflow باید Microsoft.ML.TensorFlow را با استفاده از NuGet نصب کنیم. پس از نصب بسته‌های لازم، می‌توانیم با فراخوانی متد Model.LoadTensorFlowModel، یک مدل Tensorflow را بارگذاری کنیم. پس از آن، باید متد ScoreTensorFlowModel را فراخوانی کرده و نام لایه‌ی ورودی و خروجی را به آن ارسال کنیم.  
private ITransformer SetupMlnetModel(string tensorFlowModelFilePath)
{
    var pipeline = _mlContext.<preprocess-data>
           .Append(_mlContext.Model.LoadTensorFlowModel(tensorFlowModelFilePath)
                                               .ScoreTensorFlowModel(
                                                      outputColumnNames: new[]{TensorFlowModelSettings.outputTensorName },
                                                      inputColumnNames: new[] { TensorFlowModelSettings.inputTensorName },
                                                      addBatchDimensionInput: false));
 
    ITransformer mlModel = pipeline.Fit(CreateEmptyDataView());
 
    return mlModel;
}

اطلاعات بیشتر در مورد نحوه استفاده از مدل Tensorflow در ML.NET:
مطالب
آشنایی با نسخه بندی و چرخه انتشار نرم افزارها
نسخه بندی و چرخه انتشار یک نرم افزار، اهمیت زیادی در ارائه یک نرم افزار خوب دارد. هر چه نرم افزار شما بزرگ‌تر و از کتابخانه‌های بیشتری در تولید آن استفاده شده باشد، در بروز رسانی و نسخه بندی آن دقت بیشتری باید داشت و کار دشوار‌تری است. اما چگونه به بهترین روش، نسخه بندی نرم افرار خود را مدیریت نمایید.

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

چرخه انتشار نرم افزار:
 چرخه انتشار نرم افزار از زمان شروع کد نویسی تا عرضه نسخه نهایی می‌باشد که شامل چندین مرحله و عرضه نرم افزار می‌باشد.
  1. Pre-alpha
    این مرحله شامل تمام فعالیت‌های انجام شده قبل از مرحله تست می‌باشد. در این دوره آنالیز نیازمندیها، طراحی نرم افزار، توسعه نرم افزار و حتی تست واحد باشد. در نرم افزار‌های سورس باز چندین نسخه قبل از آلفا ممکن است عرضه شوند.
  2. Alpha
    این مرحله شامل همه فعالیت‌ها از زمان شروع تست می‌باشد. البته منظور از تست، تست تیمی و تست خود نرم افزار می‌باشد. نرم افزار‌های آلفا هنوز ممکن است خطا و اشکالاتی داشته باشند و ممکن است اطلاعات شما از بین رود. در این مرحله امکانات جدیدی مرتبا به نرم افزار اضافه می‌گردد.
  3. Beta
    نرم افزار بتا، همه قابلیت‌های آن تکمیل شده و خطا‌های زیادی برای کامل شدن نرم افزار وجود دارد. در این مرحله بیشتر به تست کاهش تاثیرات به کاربران و تست کارایی دقت می‌شود. نسخه بتا، اولین نسخه‌ای خواهد بود که بیرون شرکت و یا سازمان در دسترس قرار می‌گیرد. برخی توسعه دهندگان به این مرحله preview، technical preview یا early access نیز می‌گویند.
  4. Release candidate
    در این مرحله نرم افزار، آماده عرضه به مصرف کنندگان است و نرم افزارهایی مثل سیستم عامل‌های ویندوز در دسترس تولید کنندگان قرار گرفته تا با جدید‌ترین سخت افزار خود یکپارچه شوند.
  5.  General availability (GA)
    در این مرحله، عرضه عمومی نرم افزار و بازاریابی و فروش نرم افزار مد نظر است و علاوه بر این تست امنیتی و در نرم افزار‌های خیلی بزرگ عرضه جهانی صورت می‌گیرد 
مراحلی همچون عرضه در وب و پشتیبانی نیز وجود دارند.

نسخه بندی نرم افزار:
برنامه‌های ویندوزی یا وب در ویژوال استادیو یک فایل AssemblyInfo دارند که در قسمت آخر آن، اطلاعات مربوط به نسخه نرم افزار ذخیره می‌شود. هر نسخه نرم افزار شامل چهار عدد می‌باشد که با نقطه از هم جدا شده است.
  • Major Version
    وقتی افزایش می‌یابد که تغییرات قابل توجهی در نرم افزار ایجاد شود
  • Minor Version
    وقتی افزایش یابد که ویژگی جزئی یا اصلاحات قابل توجهی به نرم افزار ایجاد شود.
  • Build Number
    به ازای هر بار ساخته شدن پروژه افزایش می‌یابد.
  • Revision
    وقتی افزایش می‌یابد که نواقص و باگ‌های کوچکی رفع شوند. 
وقتی که major یا minor افزایش یابد می‌تواند با کلماتی همچون alpha، beta یا release candidate همراه شود.در اکثر برنامه‌های تجاری اولین شمارهٔ انتشار یک محصول از نسحهٔ شمارهٔ یک شروع می‌شود. ترتیب نسخه بندی هم ممکن است تغییر یابد
major.minor[.build[.reversion]]
یا
major.minor[.maintenance[.build]]
نسخه بندی مایکروسافت:
اگر به نسخه برنامه Office توجه کرده باشید مثلا Office 2013 نسخه 15.0.4481.1508 می‌باشد که در این روش از تاریخ شروع پروژه و تعداد ماه‌ها یا روز‌ها و یا ثانیه‌ها با یک الگوریتم خاص برای تولید نسخه نرم افزار استفاده می‌شود.
نسخه بندی معنایی:

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

علیرغم آن، مهم است که این API، روشن و دقیق باشد. هنگامیکه API عمومی خود را تعیین کردید، تغییرات برنامه شما بر روی نسخه API عمومی تاثیر خواهد داشت و آنرا افزایش خواهد داد. بر این اساس، این مدل نسخه‌بندی را در نظر بگیرید: X.Y.Z یعنی (Major.Minor.Patch).

رفع حفره‌هایی که بر روی API عمومی تاثیر نمی‌گذارند، مقدار Patch را افزایش می‌دهند، تغییرات جدیدی که سازگار با نسخه قبلی است، مقدار Minor را افزایش می‌دهند و تغییرات جدیدی که کاملا بدیع هستند و به نحوی با تغییرات قبلی سازگار نیستند مقدار Major را افزایش می‌دهند. 

  1. نرم‌افزارهایی که از نسخه بندی معنایی استفاده می‌کنند، باید یک API عمومی داشته باشند. این API می‌تواند در خود کد یا و یا به طور صریح در مستندات باشد که باید دقیق و جامع باشد.
  2. یک شماره نسخه صحیح باید به شکل X.Y.Z باشد که در آن X،Y و Z اعداد صحیح غیر منفی هستند. X نسخه‌ی Major می‌باشد، Y نسخه‌ی Minor و Z نسخه‌ی Patch می‌باشد. هر عنصر باید یک به یک و بصورت عددی افزایش پیدا کند. به عنوان مثال: 1.9.0 -> 1.10.0 -> 1.11.0
  3. هنگامی که به یک نسخه‌ی Major یک واحد اضافه می‌شود، نسخه‌ی Minor و Patch باید به حالت 0 (صفر) تنظیم مجدد گردد. هنگامی که به شماره نسخه‌ی Minor یک واحد اضافه می‌شود، نسخه‌ی Patch باید به حالت 0 (صفر) تنظیم مجدد شود. به عنوان مثال: 1.1.3 -> 2.0.0 و 2.1.7 -> 2.2.0
  4. هنگامیکه یک نسخه از یک کتابخانه منتشر می‌شود، محتوای کتابخانه مورد نظر نباید به هیچ وجه تغییری داشته باشد. هر گونه تغییر جدیدی باید در قالب یک نسخه جدید انتشار پیدا کند.
  5. نسخه‌ی Major صفر (0.Y.Z) برای توسعه‌ی اولیه است. هر چیزی ممکن است در هر زمان تغییر یابد. API عمومی را نباید پایدار در نظر گرفت.
  6. نسخه 1.0.0 در حقیقت API عمومی را تعریف می‌کند. چگونگی تغییر و افزایش هر یک از نسخه‌ها بعد از انتشار این نسخه، وابسته به API عمومی و تغییرات آن می‌باشد.
  7. نسخه Patch یا (x.y.Z | x > 0) فقط در صورتی باید افزایش پیدا کند که تغییرات ایجاد شده در حد برطرف کردن حفره‌های نرم‌افزار باشد. برطرف کردن حفره‌های نرم‌افزار شامل اصلاح رفتارهای اشتباه در نرم‌افزار می‌باشد.
  8. نسخه Minor یا (x.Y.z | x > 0) فقط در صورتی افزایش پیدا خواهد کرد که تغییرات جدید و سازگار با نسخه قبلی ایجاد شود. همچنین این نسخه باید افزایش پیدا کند اگر بخشی از فعالیت‌ها و یا رفتارهای قبلی نرم‌افزار به عنوان فعالیت منقرض شده اعلام شود. همچنین این نسخه می‌تواند افزایش پیدا کند اگر تغییرات مهم و حیاتی از طریق کد خصوصی ایجاد و اعمال گردد. تغییرات این نسخه می‌تواند شامل تغییرات نسخه Patch هم باشد. توجه به این نکته ضروری است که در صورت افزایش نسخه Minor، نسخه Patch باید به 0 (صفر) تغییر پیدا کند.
  9. نسخه Major یا (X.y.z | X > 0) در صورتی افزایش پیدا خواهد کرد که تغییرات جدید و ناهمخوان با نسخه فعلی در نرم‌افزار اعمال شود. تغییرات در این نسخه می‌تواند شامل تغییراتی در سطح نسخه Minor و Patch نیز باشد. باید به این نکته توجه شود که در صورت افزایش نسخه Major، نسخه‌های Minor و Patch باید به 0 (صفر) تغییر پیدا کنند.
  10. یک نسخه قبل از انتشار می‌تواند توسط یک خط تیره (dash)، بعد از نسخه Patch (یعنی در انتهای نسخه) که انواع با نقطه (dot) از هم جدا می‌شوند، نشان داده شود. نشان‌گر نسخه قبل از انتشار باید شامل حروف، اعداد و خط تیره باشد [0-9A-Za-z-]. باید به این نکته دفت داشت که نسخه‌های قبل از انتشار خود به تنهایی یک انتشار به حساب می‌آیند اما اولویت و اهمیت نسخه‌های عادی را ندارد. برای مثال: 1.0.0-alpha ، 1.0.0-alpha.1 ، 1.0.0-0.3.7 ، 1.0.0-x.7.z.92
  11. یک نسخه Build می‌تواند توسط یک علامت مثبت (+)، بعد از نسخه Patch یا نسخه قبل از انتشار (یعنی در انتهای نسخه) که انواع آن با نقطه (dot) از هم جدا می‌شوند، نشان داده شود. نشان‌گر نسخه Build باید شامل حروف، اعداد و خط تیره باشد [0-9A-Za-z-]. باید به این نکته دقت داشت که نسخه‌های Build خود به تنهایی یک انتشار به حساب می‌آیند و اولویت و اهمیت بیشتری نسبت به نسخه‌های عادی دارند. برای مثال: 1.0.0+build.1 ، 1.3.7+build.11.e0f985a
  12. اولویت‌بندی نسخه‌ها باید توسط جداسازی بخش‌های مختلف یک نسخه به اجزای تشکیل دهنده آن یعنی Minor، Major، Patch، نسخه قبل از انتشار و نسخه Build و ترتیب اولویت بندی آن‌ها صورت گیرد. نسخه‌های Minor، Major و Patch باید بصورت عددی مقایسه شوند. مقایسه نسخه‌های قبل از انتشار و نسخه Build باید توسط بخش‌های مختلف که توسط جداکننده‌ها (نقطه‌های جداکننده) تفکیک شده است، به این شکل سنجیده شود:

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

بخش‌های عددی همواره اولویت پایین‌تری نسبت به بخش‌های غیر عددی دارند. برای مثال:

1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0-rc.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a

منبع نسخه بندی معنایی : semver.org

 
مطالب
خواندنی‌های 16 تیر

اس کیوال سرور

توسعه وب

دات نت فریم ورک

دبلیو پی اف و سیلور لایت

سی و مشتقات

شیرپوینت

کتاب‌های رایگان

مای اس کیوال

متفرقه

وب سرورها

پی اچ پی

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

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

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

کدهای ملی که همه ارقام آنها مثل هم باشند معتبر نیستند مثل:

۰۰۰۰۰۰۰۰۰۰
۱۱۱۱۱۱۱۱۱۱
۲۲۲۲۲۲۲۲۲۲
۳۳۳۳۳۳۳۳۳۳
۴۴۴۴۴۴۴۴۴۴
۵۵۵۵۵۵۵۵۵۵
۶۶۶۶۶۶۶۶۶۶
۷۷۷۷۷۷۷۷۷۷
۸۸۸۸۸۸۸۸۸۸
۹۹۹۹۹۹۹۹۹۹

روش اعتبار سنجی کد ملی :

دهمین رقم شماره ملی را (از سمت چپ) به عنوان TempAدر نظر می‌گیریم.

یک مقدار TempB در نظر می‌گیریم و آن را برابر با =

(اولین رقم * ۱۰) + ( دومین رقم * ۹ ) + ( سومین رقم * ۸ ) + ( چهارمین رقم * ۷ ) + ( پنجمین رقم * ۶) + ( ششمین رقم * ۵ ) + ( هفتمین رقم * ۴ ) + ( هشتمین رقم * ۳ ) + ( نهمین رقم * ۲ )

قرار می‌دهیم.

مقدار TempC را برابر با = TempB  – (TempB/11)*11 قرار می‌دهیم.

اگر مقدار TempC برابر با صفر باشد و مقدار TempA  برابر TempC  باشد کد ملی صحیح است.

اگر مقدار TempC برابر با ۱ باشد و مقدار TempA  برابر با ۱ باشد کد ملی صحیح است.

اگر مقدار TempC  بزرگتر از ۱ باشد و مقدار TempA برابر با ۱۱ – TempC  باشد کد ملی صحیح است.

در ادامه متد نوشته شده به زبان C#.NET را مشاهده می‌کنید.
public static class Helpers
    {
        /// <summary>
        /// تعیین معتبر بودن کد ملی
        /// </summary>
        /// <param name="nationalCode">کد ملی وارد شده</param>
        /// <returns>
        /// در صورتی که کد ملی صحیح باشد خروجی <c>true</c> و در صورتی که کد ملی اشتباه باشد خروجی <c>false</c> خواهد بود
        /// </returns>
        /// <exception cref="System.Exception"></exception>
        public static Boolean IsValidNationalCode(this String nationalCode)
        {
           //در صورتی که کد ملی وارد شده تهی باشد
if (String.IsNullOrEmpty(nationalCode)) throw new Exception("لطفا کد ملی را صحیح وارد نمایید");
//در صورتی که کد ملی وارد شده طولش کمتر از 10 رقم باشد if (nationalCode.Length != 10) throw new Exception("طول کد ملی باید ده کاراکتر باشد"); //در صورتی که کد ملی ده رقم عددی نباشد var regex = new Regex(@"\d{10}"); if (!regex.IsMatch(nationalCode)) throw new Exception("کد ملی تشکیل شده از ده رقم عددی می‌باشد؛ لطفا کد ملی را صحیح وارد نمایید"); //در صورتی که رقم‌های کد ملی وارد شده یکسان باشد var allDigitEqual = new[]{"0000000000","1111111111","2222222222","3333333333","4444444444","5555555555","6666666666","7777777777","8888888888","9999999999"}; if (allDigitEqual.Contains(nationalCode)) return false;
//عملیات شرح داده شده در بالا var chArray = nationalCode.ToCharArray(); var num0 = Convert.ToInt32(chArray[0].ToString())*10; var num2 = Convert.ToInt32(chArray[1].ToString())*9; var num3 = Convert.ToInt32(chArray[2].ToString())*8; var num4 = Convert.ToInt32(chArray[3].ToString())*7; var num5 = Convert.ToInt32(chArray[4].ToString())*6; var num6 = Convert.ToInt32(chArray[5].ToString())*5; var num7 = Convert.ToInt32(chArray[6].ToString())*4; var num8 = Convert.ToInt32(chArray[7].ToString())*3; var num9 = Convert.ToInt32(chArray[8].ToString())*2; var a = Convert.ToInt32(chArray[9].ToString()); var b = (((((((num0 + num2) + num3) + num4) + num5) + num6) + num7) + num8) + num9; var c = b%11; return (((c < 2) && (a == c)) || ((c >= 2) && ((11 - c) == a))); } }
نحوه استفاده از این متد به این صورت می‌باشد:

if(TextBoxNationalCode.Text.IsValidNationalCode ())
     //some code

//OR

if(Helpers.IsValidNationalCode (TextBoxNationalCode.Text))
     //some code
موفق وموید باشید
نظرات مطالب
اعتبارسنجی درخواست های http$ با استفاده از یک Interceptor

با سلام و احترام

ممنون بابت مقاله خوبتون

ولی این شرط

filterContext.HttpContext.Request.IsAjaxRequest

معنی

یعنی اعتبارسنجی نشده است

را نمی‌دهد.

شما در متد HandleUnauthorizedRequest هستید و بالطبع اعتبار درخواست رد شده است، کاری که می‌خواهید انجام دهید، اعتبارسنجی نیست، بلکه اصلاح Response درخواست‌های Ajax ای است که Status Code آنها ۲۰۰ است که نباید باشد.

این نوع دقت داشتن و شفافیت لازمه ایجاد یک کد صحیح است، چون الآن و در مرحله ای بالاتر، می‌توانیم بگویم که هر Response ای که وارد متد HandleUnauthorizedRequest شده است، اگر Status Code 401 ندارد، Status Code آن برابر ۴۰۱ قرار داده شود. فارغ از Ajax بودن یا نبودن.

و باز در مرحله ای بالاتر اگر در پروژه از Owin استفاده شده باشد، یک Owin Middleware و اگر نه یک ASP.NET Module جای مناسب‌تری برای نوشتن این چنین کدی است.

از این که IsAjaxRequest همیشه درست کار نمی‌کند و فقط وقتی درخواست Ajax ای بگوید که Ajax ای است، کار خواهد کرد نیز بگذریم.

موفق و پایدار باشید.

نظرات مطالب
چندین Submit در یک Html Form و انتساب Action های مجزا به هر یک از Submit ها در MVC
ممنون دوست عزیز که توجه میکنی به مطالب بنده . به جز روشی که در مقاله بالا ذکر شد استفاده از data-form-action موجود در نگارش 5 از HTML اصولیترین روش یا بهتره بگیم تمیز‌ترین روش در بین مواردی هست که ذکر کردید ولی خب برنامه نویسای وب همیشه با مرورگرهای مختلف در جنگ هستن و فعلا زیاد استفاده از این روش جایز نیست چون بعضی از مرورگرهای کمی قدیمیتر پشتیبانی نمیکنند پس بهتره از تکنیکهای مورد اطمینانتر استفاده کنیم که نمونش در مقاله‌ی بالا ذکر شد ... 
 
این نمونه روش‌های خلاقانه و جالب از جمله ActionNameSelectorAttribute  به وفور در نسخه‌های جدید mvc وجود داره خوشبختانه . در مقالات بعدیم سعی میکنم مطالب تخصصی و تکنیکهای جالب دیگرو هم با دوستان به اشتراک بزارم . انصافا mvc یکی از شیرین‌ترین تکنلوژی هایی هست که هر سری سورسش رو مطالعه میکنم راه کارهای جدیدی برای پیاده سازی نرم افزارها توسط اون تکنیک‌ها دستگیرم میشه ...
 
پاینده باشید و موفق


مطالب
Fluent Linq to Sql

نگارش بعدی یا چهارم entity framework چیزی است شبیه به Fluent NHibernate . یعنی اگر مقاله‌ای را در این زمینه مطالعه کنید و عنوان آن حذف شود، نمی‌توان تشخیص داد که این مقاله مربوط به entity framework است یا Fluent NHibernate. هر چند entity framework حداقل دو نگارش دیگر لازم دارد تا NHibernate را کاملا پشت سر بگذارد.
از آن طرف محبوبیت Linq to SQL هم هنوز پابرجا است و برای مثال سایت پر ترافیکی مثل stack overflow از آن استفاده می‌کند و بسیار هم موفق بوده و کارش را به خوبی انجام می‌دهد.
پروژه مکملی به نام Fluent Linq to Sql با الهام گیری از Fluent NHibernate در سایت codeplex موجود است که این نوع نگاشت‌ها را برای Linq to Sql نیز میسر می‌سازد. به این صورت دیگر نیازی به استفاده از attributes و یا فایل‌های xml نگاشت‌های Linq to Sql نخواهد بود. همچنین مدل کاری اول کد بعد دیتابیس نیز به این صورت محقق می‌شود.