مروری بر کدهای کلاس SqlHelper
ضمن اینکه مثلا NHibernate قابلیتی دارد به نام second level cache که اساسا برای پروژههای وب طراحی شده. قابلیت کش در سطح کوئری یا اطلاعات پرکاربرد و عمومی سایت را به صورت خودکار دارد. در موردش قبلا مطلب نوشتم : (^). سطح اول کش آن هم پیاده سازی حرفهای همین باز نگه داشتن کانکشنی است که در کد SqlHelper بالا نویسنده موفق به پیاده سازی آن نشده، به علاوه کاهش رفت و آمدها به سرور: (^)
به علاوه NHibernate یک قابلیت دیگر هم دارد به نام ToFuture که میتونه چندین کوئری رو در طی یک رفت و برگشت برای شما انجام بده (^).
و ... خیلی از best practices دیگر هم در آن لحاظ شده. خلاصه اینکه تواناییهای بسیار ارزندهای رو با عدم استفاده از ORMs از دست خواهید داد. منجمله همان بحث کوئریهای پارامتری که عموما از نوشتن آن طفره میروند اما اینجا به صورت خودکار برای شما انجام میشود.
- Entity Framework یا EF چیست؟ | www.nikamooz.com
- انتشار رایگان کتاب راهنمای ساختار شکست کار | www.khorramirad.com
- خواندن فید های RSS از منابع مختلف و انتشار مجموع آن ها با فرمت RSS | www.30sharp.com
- سماموس - TV Series on Computing | somamos.blogfa.com
- گرایشهای طراحی وب سایت در سال 2012 | navid.kashani.ir
- Don't Be A Free User | blog.pinboard.in
- Download: MSDN/TechNet Forum Assistant | www.microsoft.com
- iText is free, not gratis | lowagie.com
- SOLID Casts | dimecasts.net
- Static fields in generic classes | blogs.msdn.com
- بهبود امکانات جهت کار با دایرکت ایکس در ویژوال استودیوی بعدی | blogs.msdn.com
- دریافت آخرین به روز رسانی فایل OPML وبلاگهای IT ایرانی | dotnettipsrepository.svn.codeplex.com
کار کردن با پروتکل Ping-back آنچنان ساده نیست؛ از این جهت که تبادل ارتباطات آن با پروتکل XML-RPC انجام میشود. XML-RPC نیز توسط PHP کارها بیشتر مورد استفاده قرار میگیرد؛ بجای استفاده از پروتکلهای استاندارد وب سرویسها مانند Soap و امثال آن. پیاده سازیهای ابتدایی Pingback نیز مرتبط است به Wordpress معروف که با PHP تهیه شدهاست. در ادامه نگاهی خواهیم داشت به جزئیات پیاده سازی ارسال ping-back توسط برنامههای ASP.NET.
یافتن آدرس وب سرویس سایت پذیرای Pingback
اولین قدم در پیاده سازی Pingback، یافتن آدرسی است که باید اطلاعات مورد نظر را به آن ارسال کرد. این آدرس عموما به دو طریق ارائه میشود:
الف) در هدری به نام x-pingback و یا pingback
ب) در قسمتی از کدهای HTML صفحه به شکل
<link rel="pingback" href="pingback server">
همانطور که ملاحظه میکنید، نیاز است Response header را آنالیز کنیم.
private Uri findPingbackServiceUri() { var request = (HttpWebRequest)WebRequest.Create(_targetUri); request.UserAgent = UserAgent; request.Timeout = Timeout; request.ReadWriteTimeout = Timeout; request.Method = WebRequestMethods.Http.Get; request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; using (var response = request.GetResponse() as HttpWebResponse) { if (response == null) return null; var url = extractPingbackServiceUriFormHeaders(response); if (url != null) return url; if (!isResponseHtml(response)) return null; using (var reader = new StreamReader(response.GetResponseStream())) { return extractPingbackServiceUriFormPage(reader.ReadToEnd()); } } } private static Uri extractPingbackServiceUriFormHeaders(WebResponse response) { var pingUrl = response.Headers.AllKeys.FirstOrDefault(header => header.Equals("x-pingback", StringComparison.OrdinalIgnoreCase) || header.Equals("pingback", StringComparison.OrdinalIgnoreCase)); return getValidAbsoluteUri(pingUrl); } private static Uri extractPingbackServiceUriFormPage(string content) { if (string.IsNullOrWhiteSpace(content)) return null; var regex = new Regex(@"(?s)<link\srel=""pingback""\shref=""(.+?)""", RegexOptions.IgnoreCase); var match = regex.Match(content); return (!match.Success || match.Groups.Count < 2) ? null : getValidAbsoluteUri(match.Groups[1].Value); } private static Uri getValidAbsoluteUri(string url) { Uri absoluteUri; return string.IsNullOrWhiteSpace(url) || !Uri.TryCreate(url, UriKind.Absolute, out absoluteUri) ? null : absoluteUri; } private static bool isResponseHtml(WebResponse response) { var contentTypeKey = response.Headers.AllKeys.FirstOrDefault(header => header.Equals("content-type", StringComparison.OrdinalIgnoreCase)); return !string.IsNullOrWhiteSpace(contentTypeKey) && response.Headers[contentTypeKey].StartsWith("text/html", StringComparison.OrdinalIgnoreCase); }
targetUri، آدرسی است از یک سایت دیگر که در سایت ما درج شدهاست. زمانیکه این صفحه را درخواست میکنیم، response.Headers.AllKeys حاصل میتواند حاوی کلید x-pingback باشد یا خیر. اگر بلی، همینجا کار پایان مییابد. فقط باید مطمئن شد که این آدرس مطلق است و نه نسبی. به همین جهت در متد getValidAbsoluteUri، بررسی بر روی UriKind.Absolute انجام شدهاست.
اگر هدر فاقد کلید x-pingback باشد، قسمت ب را باید بررسی کرد. یعنی نیاز است محتوای Html صفحه را برای یافتن link rel=pingback بررسی کنیم. همچنین باید دقت داشت که پیش از اینکار نیاز است حتما بررسی isResponseHtml صورت گیرد. برای مثال در سایت شما لینکی به یک فایل 2 گیگابایتی SQL Server درج شدهاست. در این حالت نباید ابتدا 2 گیگابایت فایل دریافت شود و سپس بررسی کنیم که آیا محتوای آن حاوی link rel=pingback است یا خیر. اگر محتوای ارسالی از نوع text/html بود، آنگاه کار دریافت محتوای لینک انجام خواهد شد.
ارسال Ping به آدرس سرویس Pingback
اکنون که آدرس سرویس pingback یک سایت را یافتهایم، کافی است ping ایی را به آن ارسال کنیم:
public void Send() { var pingUrl = findPingbackServiceUri(); if (pingUrl == null) throw new NotSupportedException(string.Format("{0} doesn't support pingback.", _targetUri.Host)); sendPing(pingUrl); } private void sendPing(Uri pingUrl) { var request = (HttpWebRequest)WebRequest.Create(pingUrl); request.UserAgent = UserAgent; request.Timeout = Timeout; request.ReadWriteTimeout = Timeout; request.Method = WebRequestMethods.Http.Post; request.ContentType = "text/xml"; request.ProtocolVersion = HttpVersion.Version11; makeXmlRpcRequest(request); using (var response = (HttpWebResponse)request.GetResponse()) { response.Close(); } } private void makeXmlRpcRequest(WebRequest request) { var stream = request.GetRequestStream(); using (var writer = new XmlTextWriter(stream, Encoding.ASCII)) { writer.WriteStartDocument(true); writer.WriteStartElement("methodCall"); writer.WriteElementString("methodName", "pingback.ping"); writer.WriteStartElement("params"); writer.WriteStartElement("param"); writer.WriteStartElement("value"); writer.WriteElementString("string", Uri.EscapeUriString(_sourceUri.ToString())); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteStartElement("param"); writer.WriteStartElement("value"); writer.WriteElementString("string", Uri.EscapeUriString(_targetUri.ToString())); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); } }
در اینجا sourceUri آدرس صفحهای در سایت ما است که targetUri ایی (آدرسی از سایت دیگر) در آن درج شدهاست. در یک pinback، صرفا این دو آدرس به سرویس دریافت کنندهی pingback ارسال میشوند.
سپس سایت دریافت کنندهی ping، ابتدا sourceUri را دریافت میکند تا عنوان آنرا استخراج کند و همچنین بررسی میکند که آیا targetUri، در آن درج شدهاست یا خیر (آیا spam است یا خیر)؟
تا اینجا اگر این مراحل را کنار هم قرار دهیم به کلاس Pingback ذیل خواهیم رسید:
Pingback.cs
نحوهی استفاده از کلاس Pingback تهیه شده
کار ارسال Pingback عموما به این نحو است: هر زمانیکه مطلبی یا یکی از نظرات آن، ثبت یا ویرایش میشوند، نیاز است Pingbackهای آن ارسال شوند. بنابراین تنها کاری که باید انجام شود، استخراج لینکهای خارجی یک صفحه و سپس فراخوانی متد Send کلاس فوق است.
یافتن لینکهای یک محتوا را نیز میتوان مانند متد extractPingbackServiceUriFormPage فوق، توسط یک Regex انجام داد و یا حتی با استفاده از کتابخانهی معروف HTML Agility Pack:
var doc = new HtmlWeb().Load(url); var linkTags = doc.DocumentNode.Descendants("link"); var linkedPages = doc.DocumentNode.Descendants("a") .Select(a => a.GetAttributeValue("href", null)) .Where(u => !String.IsNullOrEmpty(u));
- سرعت بالاتر بارگذاری و اجرای کدها
- استفاده از آخرین فناوریهای وب مانند ES 6 و وب کامپوننتها با پشتیبانی تا IE 9.
- سطح API آن با طراحی جدید آن، به شدت کاهش یافته و خلاصه شدهاست. همین امر یادگیری آنرا نیز سادهتر میکند.
برای یادگیری Angular 2 نیازی به فراگیری Angular 1 نیست. در اینجا با آشنایی با TypeScript، به این نتیجه خواهید رسید که برنامههای Angular 2 چیزی بیشتر از یک مثال عملی TypeScript نیستند. زبان TypeScript، زبان اول و توصیه شدهی کار با Angular 2 است و مزیت آن دسترسی به تمام قابلیتهای ES 6 است؛ با این تفاوت که کامپایلر TypeScript قادر است آنها را به ES 5 یا نگارش فعلی جاوا اسکریپت که توسط تمام مرورگرها پشتیبانی میشود، ترجمه و تبدیل کند. به این نحو به یک طراحی شیءگرا، مدرن و با قابلیت نگهداری بالا خواهید رسید که با تمام مرورگرهای جدید نیز سازگار است.
بنابراین پیشنیازهای اصلی کار با Angular 2، فراگیری ES 6 و TypeScript هستند که دو سری ویژه و مختص به آنها در سایت جاری تهیه شدهاند:
«مبانی ES 6»
«مبانی TypeScript»
در این قسمت قصد داریم پیشنیازهای دریافت و نصب اجزاء و وابستگیهای AngularJS 2 را به همراه TypeScript، در ویژوال استودیو 2015 بررسی کنیم. البته استفاده از ویژوال استودیو در اینجا ضروری نیست و اساسا AngularJS وابستگی به ویژوال استودیو ندارد. اگر به دنبال پشتیبانی بهتری از TypeScript هستید، VSCode رایگان، سورس باز و چند سکویی، گزینهی بسیار بهتری است نسبت به ویژوال استودیوی کامل. البته این مورد تعجبی هم ندارد؛ از این جهت که VSCode با TypeScript نوشته شدهاست.
اهمیت آشنایی با npm
اگر در طی سالهای اخیر با ویژوال استودیو کار کرده باشید، به طور قطع با NuGet نیز آشنا هستید. NuGet به عنوان یک package manager دات نتی شناخته میشود و کار آن دریافت وابستگیهای یک پروژه، از مخزنی مشخص و نصب و به روز رسانی خودکار آنها است. اما این روزها خارج از محیط توسعهی مایکروسافت، مدیرهای بستههای دیگری مانند Bower نیز برای نصب و به روز رسانی بستههای front end مانند کتابخانههای CSS ایی و جاوا اسکریپتی، بسیار رواج پیدا کردهاند. Bower یکی از ابزارهای NodeJS است که توسط NPM یا NodeJS Package Manager نصب میشود. به این معنا که استفاده از Bower به معنای استفاده از NPM است. پیش از این از NPM صرفا جهت نصب بستههای مرتبط با NodeJS استفاده میشد، اما در طی یکسال اخیر، استفاده از NPM نیز برای مدیریت بستههای front end رواج پیدا کردهاست و در صدر مدیر بستههای نصب کتابخانههای front end قرار دارد. همچنین در این حالت شما تنها نیاز به یک ابزار و یک فایل تنظیمات آن خواهید داشت، بجای استفاده از چندین ابزار و چندین فایل تنظیمات جداگانه. به علاوه این روزها انجام کارهای جدی جاوا اسکریپتی بدون دانش NPM دیگر میسر نیست. بهترین ابزارها، کامپایلرها، فشرده کنندههای front end و امثال آنها، تحت NodeJS اجرا میشوند. برای کار با AngularJS 2.0 و دریافت وابستگیهای آن نیز استفاده از npm، روش پیش فرض و توصیه شدهاست.
کار با npm جهت دریافت وابستگیهای کتابخانههای front end
برای کار با npm یا میتوان از دستورات خط فرمان آن به صورت مستقیم استفاده کرد و یا از امکانات یکپارچگی آن با ویژوال استودیو نیز بهره گرفت که ما در ادامه از این روش استفاده خواهیم کرد. البته توانمندیهای خط فرمان npm فراتر است از امکانات توکار VS.NET، اما در اینجا نیازی به آنها نیست و هدف صرفا دریافت و به روز رسانی وابستگیهای مرتبط است.
ویژوال استودیوی 2015 به همراه ابزارهای NodeJS ارائه میشود. اما مشکل اینجا است که این ابزارها هم اکنون قدیمی شدهاند و تطابقی با آخرین نگارش ابزارهای NodeJS ندارند. برای نمونه حین نصب وابستگیهای AngularJS 2.0 که یکی از آنها RxJS است، یک چنین خروجی را در پنجرهی output ویژوال استودیو مشاهده میکنید:
npm WARN engine rxjs@5.0.0-beta.6: wanted: {"npm":">=2.0.0"} (current: {"node":"v0.10.31","npm":"1.4.9"})
همانطور که در تصویر نیز ملاحظه میکنید، به مسیر Tools->Options->Projects and Solutions->External Web Tools مراجعه کرده و متغیر محیطی PATH ویندوز را به ابتدای لیست منتقل کنید. به این صورت ابزارهای به روز شدهی خط فرمان، مقدم خواهند شد بر ابزارهای قدیمی به همراه نگارش فعلی ویژوال استودیو.
البته فرض بر این است که آخرین نگارش nodejs را از آدرس https://nodejs.org/en دریافت و نصب کردهاید. با نصب آن، برنامه npm، در خط فرمان ویندوز به صورت مستقیم قابل استفاده خواهد بود؛ از این جهت که مسیر آن به PATH ویندوز اضافه شدهاست:
افزودن فایل project.json به پروژه
تا اینجا فرض بر این است که nodejs را از سایت آن دریافت و نصب کردهاید. همچنین متغیر PATH را در External Web Tools ویژوال استودیو به ابتدای لیست آن منتقل کردهاید تا همواره از آخرین نگارش npm نصب شدهی در سیستم، استفاده شود.
پس از آن همانند نیوگت که از فایل xml ایی به نام packages.config برای ثبت آخرین تغییرات خودش استفاده میکند، npm نیز از فایلی به نام package.json برای ذکر وابستگیهای مورد نیاز پروژه بهره میبرد. برای افزودن آن، از منوی Project گزینهی Add new item را انتخاب کرده و سپس npm را در آن جستجو کنید:
در اینجا نام پیش فرض package.json را پذیرفته و این فایل را به پروژه و ریشهی آن اضافه کنید.
اگر گزینهی فوق را در لیست Add new item مشاهده نمیکنید، مهم نیست. یک فایل متنی را به نام package.json به ریشهی پروژهی جاری اضافه کنید.
در ادامه محتوای این فایل را به نحو ذیل تغییر دهید:
{ "name": "asp-net-mvc5x-angular2x", "version": "1.0.0", "author": "DNT", "description": "", "scripts": {}, "license": "Apache-2.0", "dependencies": { "jquery": "2.2.3", "angular2": "2.0.0-beta.15", "systemjs": "^0.19.26", "es6-promise": "^3.1.2", "es6-shim": "^0.35.0", "reflect-metadata": "0.1.2", "rxjs": "5.0.0-beta.2", "zone.js": "^0.6.12", "bootstrap": "^3.3.6" }, "devDependencies": { "typescript": "^1.8.9", "typings": "^0.8.1" }, "repository": { } }
چند نکته:
- هر زمانیکه این فایل را ذخیره کنید، بلافاصله کار دریافت این بستهها از اینترنت آغاز خواهد شد. جزئیات آنرا میتوان در پنجرهی output ویژوال استودیو مشاهده کرد (و حتما اینکار را جهت دیباگ کار انجام دهید. بسیاری از مشکلات و خطاها، در اینجا لاگ میشوند). بنابراین اگر قصد دارید کار همگام سازی تغییرات را انجام دهید، فقط کافی است دکمههای ctrl+s یا save را بر روی این فایل اعمال کنید.
- کاری که دکمهی ctrl+s در این فایل انجام میدهد، اعمال خودکار دستور npm install بر روی پوشهای است که package.json در آن قرار دارد. بنابراین برای دریافت این بستهها، روش خط فرمان آن، ابتدا وارد شدن به ریشهی پروژهی جاری و سپس صدور دستور npm install است (که نیازی به آن نیست و ویژوال استودیو اینکار را به صورت خودکار انجام میدهد).
- بستههای دریافت شده، در پوشهای به نام node_modules در ریشهی پروژه ذخیره میشوند:
برای مشاهدهی آنها میتوان بر روی دکمهی show all files در solution explorer کلیک نمائید.
- درون فایل package.json، پشتیبانی کاملی از intellisense وجود دارد. برای مثال اگر علاقمند بودید تا آخرین نگارش AngularJS را مشاهده کنید، پس از خاصیت angular2 در تنظیمات فوق، " را تایپ کنید تا منوی تکمیل کنندهای ظاهر شود:
بدیهی است این منو جهت دریافت آخرین اطلاعات، نیاز به اتصال به اینترنت را دارد.
البته همیشه آخرین شماره نگارش AngularJS 2.0 را در این آدرس نیز میتوانید مشاهده کنید: CHANGELOG.md
- در این فایل شماره نگارش آغاز شدهای با ^ مانند "3.1.2^" به این معنا است که اجازهی نصب نگارشهای جدیدتری از 3.1.2 نیز داده شدهاست.
به روز رسانی کامپایلر TypeScript
نیاز است یکبار مطلب «مبانی TypeScript؛ تنظیمات TypeScript در ویژوال استودیو» را جهت آشنایی با نحوهی به روز رسانی اجزای مرتبط با TypeScript مطالعه کنید.
افزودن فایل tsconfig.json به پروژه
مرحلهی بعد شروع به کار با AngularJS و TypeScript، انجام تنظیمات کامپایلر TypeScript است. برای این منظور از منوی پروژه، گزینهی Add new item، عبارت typescript را جستجو کرده و در لیست ظاهر شده، گزینهی TypeScript JSON Configuration File را با نام پیش فرض آن انتخاب کنید:
اگر این گزینهی ویژه را در لیست add new items ندارید، مهم نیست. یک فایل متنی را به نام tsconfig.json به ریشهی پروژهی جاری اضافه کنید.
پس از افزودن فایل tsconfig.json به ریشهی سایت، تنظیمات آنرا به نحو ذیل تغییر دهید:
{ "compileOnSave": true, "compilerOptions": { "target": "es5", "module": "system", "moduleResolution": "node", "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true }, "exclude": [ "node_modules", "wwwroot", "typings/main", "typings/main.d.ts" ] }
برای نمونه خاصیت compileOnSave سبب خواهد شد تا پس از ذخیره سازی یک فایل ts، بلافاصله فایل js معادل آْن تولید شود. نوع ماژولها در اینجا به system.js تنظیم شدهاست و خروجی کدهای js آن از نوع ES 5 درنظر گرفته شدهاست. همچنین فعال سازی decorators نیز در اینجا صورت گرفتهاست. از این جهت که AngularJS2 استفادهی گستردهای را از این مفهوم، انجام میدهد.
در قسمت excludes به کامپایلر TypeScript اعلام شدهاست تا از یک سری از مسیرها مانند پوشهی node_modules که پیشتر آنرا تنظیم و دریافت کردیم، صرفنظر کند.
خلاصهی بحث
تا اینجا با نحوهی نصب پیشنیازهای AngularJS 2 و همچنین TypeScript آشنا شدیم. به صورت خلاصه:
- nmp اصلی را از سایت nodejs دریافت و نصب کنید.
- متغیر PATH را در ویژوال استودیو، به ابتدای لیست ابزارهای خارجی وب آن منتقل کنید تا از npm اصلی استفاده کند.
- فایل project.json را با محتوای ذکر شده، به ریشهی پروژه اضافه کنید. سپس یکبار آنرا save کنید تا وابستگیها را از اینترنت دریافت کند.
- اطمینان حاصل کنید که آخرین کامپایلر TypeScript را نصب کردهاید.
- فایل tsconfig.json را با محتوای ذکر شده، به ریشهی پروژه اضافه کنید.
پیش نیاز ورود به دنیای داده کاوی
علم داده کاوی از علوم مختلفی از جمله علم آمار، هوش مصنوعی، یادگیری ماشین، شناسائی الگو و پایگاه داده نشات گرفته است و این علوم ریشههای علم داده کاوی هستند. برای مثال الگوریتم هایی که یک مدل را یاد میگیرند یا الگویی را شناسائی میکنند؛ معمولا وجه مشترک یادگیری ماشین و شناسائی الگو با داده کاوی هستند.
در این قسمت پیش از درگیر شدن با جزئیات هر الگوریتم تمایل دارم خوانندگان محترم را با مطالبی که شاید کمتر در دنیای IT با آن درگیر بوده اند؛ آشنا کنم. این کار به این دلیل انجام میشود که برای مثال در کشف قوانین انجمنی یا دسته بند مبتنی بر قانون (مثال متداول آن تحلیل سبد خرید مشتری در هایپر مارکت است) خروجی به شکل مجموعه ای قانون «اگر الف؛ آنگاه ب» و ... بدست میآید. بنابراین برای تفسیر صحیح این مدلها علاوه بر آشنائی با کسب وکار مربوطه؛ نیازی نسبی به آشنائی با سایر علوم نیز میباشد و بدین ترتیب از اتلاف انرژی و زمان و همچنین از بروز خطا در استدلالمان جلوگیری میکنیم. جمله معروفی با این مضمون در سایر فرهنگها وجود دارد که اعداد دروغ نمیگویند؛ ولی فردی دروغگو میتواند از اعداد سوء استفاده کند. بنابراین زمان مناسبی است که با بعضی مغالطات آشنا شویم.
اساس کار علمی به بیان ساده عبارت است از: به پرسش گرفتن همه چیز و دنبال کردن مدارک و شواهد به هر کجا که ما را رهنمون سازد؛ اینکار بوسیله آزمودن هر نظر و ایده ای، با انجام آزمایش روی آنها و مشاهده نتایج بدست آمده و سپس توسعه دادن مواردی که از آزمایشات موفق بیرون آمده اند و رد کردن آنهایی که در آزمون شکست خورده اند، انجام میگیرد. روش علمی آنچنان قدرتمند است که در طی چهار قرن گذشته (قرن 16 میلادی) ما را از نخستین نگاهی که گالیله از درون تلسکوپ به دنیای دیگر انداخت، به گام گذاشتن بر روی ماه رسانده است و به ما اجازه داده تا به پهنه فضا و زمان بنگریم تا کشف کنیم که در کجا و در چه زمانی از عالم قرار داریم.
اجداد ما ستاره شناسان خانه به دوشی بودند که در گروههای کوچک زندگی میکردند، آسمان تقویم و راهنمای زندگی آنها بود، بقای شان به این وابسته بود که بدانند چگونه ستارهها را بخوانند و بدین ترتیب بتوانند فرا رسیدن زمستان را پیش بینی کنند و زمان کوچ کردن را بدست آورند. در واقع نعمت تشخیص الگو باعث شانس بیشتر زنده ماندن و تولید مثل آنها بود و بدین ترتیب ژنهای تشخیص الگو را به نسلهای آینده منتقل میکردند. آنها وقتی که ارتباط مستقیمی بین حرکت ستارگان و گردش فصلی حیات روی زمین پیدا کردند، نتیجه گرفتند که اتفاقاتی که آن بالا میافتد به ما در پائین مربوط میشود و آنرا به خود میگرفتند!؟ آنها توضیح منطقی دیگری برای اتفاق پیش آمده نداشتند. کلمه یونانی Dis-aster به معنی "ستاره شوم" حتی برای اقوام مختلف به معنای جنگ، قحطی، مریضی و ... تعبیر میشد. (در فرهنگ ما نیز جملاتی با این مضمون کم وجود ندارد، برای مثال:" قمر در عقرب است"، پس اتفاق بدی خواهد افتاد!. البته منظور قرار گرفتن ماه در برج عقرب است و ...).
می توان گفت استعداد انسان در تشخیص الگو شمشیری دو لبه است، ما انسانها قادریم در تشخیص الگوهائی که اصلاً وجود ندارند نیز خیلی خوب عمل کنیم!، چیزی که به معنای "تشخیص الگوی اشتباه" است. ما عاشق خاص بودن هستیم و با داشتن این هدف همواره در تلاش برای فریب خود و دیگران هستیم. علم در مرز میان دانایی و جهالت گام بر میدارد، از نظر یک محقق هیچ شرمساری در ندانستن وجود ندارد، تنها شرمساری در آن است که تظاهر کنیم همه جوابها را میدانیم. علم راهی است که انسان را از فریب خود و دیگران باز میدارد و امروزه به نیکی میدانیم هر چه علم بیشتر در اختیار ابنای بشر قرار گیرد، امکان سوء استفاده از آن کمتر خواهد شد. بدین ترتیب با دانستن ارزشهای علمی تقاضا برای جهالت و تعصب کم خواهد شد. ارزشهای علمی مختصراً به شرح زیر هستند: قدرت سوال کردن، وقتی موضوعی را بررسی میکنید تنها چیزی که باید از خودتان بپرسید این است که واقعیتها در این موضوع (فلسفه) چه هست و چه حقایقی در آن نهفته است. هیچگاه به خودتان اجازه ندهید که آنچه را دوست دارید، حقیقت داشته باشد (اگر یک ایده دلخواه در یک آزمایش خوب مردود شد، پس اشتباه است و از آن عبور کنید)، همچنین آنچه را که فکر میکنید حقیقت بودنش برای بشر سودمند است شما را منحرف نکند (برای خودتان فکر کنید و از خودتان بپرسید)، فقط و تنها به این که واقعیت چه هست بنگرید، در ضمن اگر مدرکی ندارید؛ قضاوت نکنید و مهمترین قانون؛ به یاد داشته باشید که شما انسان هستید و میتوانید اشتباه کنید، همانطور که مهمترین دانشمندان در مواردی اشتباهاتی داشته اند.
منطق ابزاری علمی است که بکارگیری آن ذهن انسان را از خطای در تفکر باز میدارد، مبارزه با مغالطات و لغزشهای اندیشه هدف علم منطق است. مغالطه منحصر به استدلال نیست، به بیان دقیقتر شکل هایی از استدلال است که نتیجه تابع مقدمه یا مقدمه هایش نیست. مغالطه ای که عمدی یعنی با آگاهی از عدم اعتبار انجام میشود اما به ظاهر معتبر و مجاب کننده و در واقع فریب دهنده مخاطب است سفسطه نامیده میشود. عدم اعتبار یک استدلال ممکن است به دلایل زیر باشد: ناشی از نادرستی یکی از مقدمات استدلال باشد و یا علی رغم درستی مقدمات؛ نظم و صورت استدلال نادرست باشد. برای آشنایی ذهن خواننده به معرفی نمونه ای از این مغالطات اشاره میشود؛ برای مثال این مغالطه بر این پیش فرض استوار است که هر زمان دو حادثه با یکدیگر اتفاق افتاد؛ میتوان یکی را علت و دیگری را معلول آن به حساب آورد. برای مثال در تحقیقی به ارتباط مستقیم میان وجود داشتن چتر در ماشین به هنگام تصادفات رانندگی پرداخته شده و به این نتیجه رسیده اند زمانی که تصادفی رخ میدهد با احتمال بسیار بالاتری چتر در ماشین وجود دارد به نسبت حالتی که چتر در ماشین وجود ندارد؛ به همین دلیل چتر عامل تصادف است! برای اجتناب از این مغالطات باید قادر به تفکیک اصل علیت (Causality) و همبستگی (Correlation) باشیم. (در توضیح مثال فوق لغزندگی جاده عامل تصادف در روزی بارانی است نه چتر!).
همچنین استفاده از آمار و اطلاعات آماری علی رغم فوائد زیاد در اطلاع رسانی، میتواند لغزشگاهی باشد که زمینه ارتکاب برخی مغالطات را نیز فراهم کند در ادامه به معرفی تعدادی از این مغالطات آماری (Statistical Fallacies) میپردازیم:
مغالطه متوسط که میتواند با سوء استفاده از برخی اصطلاحات آماری مطابق با اهداف و اغراضی که موسسات ارائه دهنده اطلاعات آماری دنبال میکنند، متوسط یک مجموعه را کم یا زیاد اعلام کنند! به بیان دیگر کلمه متوسط در نوبتهای مختلف به معانی متداولی استعمال میشود که عبارتند از:
میانگین (Average) یا معدل که برای چند عدد برابر است با مجموع آنها تقسیم بر تعدادشان.
میانه (Median) که یک مجموعه عددی را به دو نیم تقسیم میکند؛ نیمی که هر یک از اعداد آن بیشتر از میانه و نیمی که کمتر از میانه است.
نما (Mode) که در یک مجموعه؛ عددی است که بیش از دیگر اعداد تکرار شده است.
پس میتوان نتیجه گرفت وقتی اعلام میشود که در یک جامعه آماری فلان عدد یک متوسط است هنوز اطلاع دقیقی داده نشده و باید صراحتا مشخص کنند کدامیک از معانی متوسط مورد نظر است.
باید در نظر داشته باشید این مغالطه زمانی استفاده میشود که دامنه تغییرات در میان جامعه آماری بسیار زیاد است، چنانچه دامنه تغییرات حداقل و حداکثر نسبت به تعداد افراد جامعه زیاد نباشد، مقادیر میانگین؛ میانه و نما تقریبا منطبق بر هم خواهند شد (برای مثال در محاسبه متوسط طول قد افراد یک کشور). اما در مواردی که تغییرات مذکور زیاد باشد باید با هوشیاری از وقوع این مغالطه جلوگیری نمود (از مصادیق و زمینههای بارز و مهم ارتکاب این مغالطه محاسبه متوسط حقوق و درآمد افراد است).
مغالطه نمودارهای گمراه کننده (Misleading Graph) استفاده از نمودار میتواند وسیله ای موثر در بیان مغالطه آمیز بودن اطلاعات آماری باشد. برای مثال نمودار رشد سود خالص شرکتی را در نظر بگیرید که در محور افقی آن بعد زمان و در محور عمودی مقادیر مالی درج شده است. با رسم نمودار مذکور سود خالص هر ماه به صورت واضح و آشکار مثلاْ رشدی ده درصدی را نمایش میدهد چنانچه شرکت مذکور اصول اخلاقی را رعایت نکند و برای جذابیت بیشتر و جذب سرمایههای بیشتر؛ قسمت هایی از نمودار را به گونه ای حذف کند که حاصل کار این شود که خواننده احساس کند سود خالص شرکت در عرض دوازده ماه به بالای کاغذ رسیده (یعنی به طور ضمنی افزایشی معادل صد در صد) و یا نسبت بین خطوط افقی و عمودی را بگونه ای تغییر دهد تا رشد ده درصدی را بسیار بزرگتر نشان داده شود (می تواند با تقلیل مقیاس واحد مالی به یک دهم به این هدف برسد) بدین ترتیب نمودار حاصل چنان جذاب میشود که هر کس با تماشای آن رگههای موفقیت و پیشرفت را در شرکت متقلب بوضوح مشاهده میکند.
مغالطه تصاویر یک بعدی (One Dimensional Pictures) از روشهای تقلب دیگر میتواند باشد که باید توجه کرد آیا نسبت القا شده بوسیله تصاویر با نسبت اعداد مطابقت دارد یا خیر.
می دانیم آنچه پایه و اساس آمار استنباطی را تشکیل میدهد روشهای نمونه گیری است که اتفاقاْ این روشها منشاء برخی مغالطات و ترفندهای آماری نیز هست در این قسمت به معرفی تعدادی از این موارد میپردازیم:
نمونه ناکافی (Deficient Examples) چنانچه در روش نمونه گیری مقدار و نسبت «نمونه» به «جامعه آماری» به اندازه کافی بزرگ باشد و به طرز صحیحی انتخاب شده باشد؛ غالبا میتواند معرف خوبی برای جامعه آماری باشد. اما چنانچه نمونه به اندازه کافی بزرگ نباشد؛ گرچه اطلاعاتی را در خصوص جامعه آماری در اختیارمان قرار میدهد ولیکن احتمال وقوع خطا در چنین حالتی بسیار زیاد است که این مغالطه دارای این شرایط است؛ البته باید توجه داشت که کافی یا ناکافی بودن تعداد نمونهها نسبت به جامعه آماری امری نسبی است. بنابراین جهت اجتناب از بروز این مغالطه باید همواره در نظر داشت آیا تعداد نمونهها در مقایسه با کل جامعه آماری راضی کننده و کافی است یا خیر.
نمونه غیر تصادفی (Deliberate Examples) برای بدست آوردن اطلاعات آماری در روش نمونه برداری؛ کافی بودن نمونهها شرط لازم است و کافی نیست؛ یکی از مواردی که باید مورد توجه قرار داد تصادفی بودن نمونهها میباشد. به بیان دیگر تنها کافی بودن نمونهها یا فراوانی آنها برای تعمیم دادن حکمی به کل آن جامعه آماری کفایت نمیکند. تصادفی بودن نمونهها بدین معناست که نمونهها نباید نماینده و بیانگر دسته و گروه خاصی از جامعه آماری باشند. همچنین در روش نمونه برداری افراد جامعه آماری باید از شانس یکسانی برای انتخاب شدن در نمونه برداری برخوردار باشند از راههای تحقق این هدف تقسیم افراد جامعه آماری به دستهها و طبقات مختلف و تعیین کردن درصد و نسبت هر یک از آنها به کل مجموعه میباشد بدین ترتیب در نمونه برداری نیز سعی میشود این نسبت لحاظ گردد؛ این روش اصطلاحا روش نمونه گیری تصادفی طبقه ای نامیده میشود روشهای دیگری نیز به منظور اینکه کلیه افراد جامعه آماری از شانسی یکسان برای انتخاب شدن در نمونه برخوردار باشند وجود دارد مانند روشهای نمونه گیری تصادفی ساده؛ نمونه گیری تصادفی خوشه ای و نمونه گیری تصادفی سیستماتیک.
عدم واقع نمائی نمونهها (Unrealistic Examples ) در نمونه برداری به صورت پرسشهای شفاهی از جامعه آماری انسانی مسئله عدم واقع نمائی نمونهها رخ میدهد بدین ترتیب همواره موجب بروز خطاهای جدی در بدست آوردن اطلاعات آماری دقیق است. این مشکل عملا به روش جمع آوری دادهها از طریق مصاحبه بر میگردد خواه به صورت نمونه ای یا سرشماری باشد.
استفاده از Async و Await در برنامههای ASP.NET MVC
علت استفاده از اکشن متدهای async در ASP.NET MVC
اگر نیاز دارید که برنامهی وبی، به شدت مقیاس پذیر را تولید کنید، باید بتوانید مجموعه تردهای سیستم را تا حد ممکن مشغول به کار و سرویس دهی نگه دارید. در برنامههای وب ASP.NET تنها تعداد مشخصی ترد، برای پاسخ دهی به درخواستهای رسیده، همواره مشغول به کار میباشند. در اینجا اگر این تردها را برای مدت زمان زیادی جهت اعمال IO مشغول نگه داریم، دست آخر به سیستمی خواهیم رسید که تردهای مفید آن، جهت پایان عملیات مرتبط بیکار شدهاند و دیگر ASP.NET قادر نیست از آنها جهت پاسخدهی به سایر درخواستهای رسیده استفاده کند.
برای مثال یک اکشن متد را درنظر بگیرید که نیاز است با یک وب سرویس، برای دریافت نتیجه کار کند. اگر این عملیات اندکی طول بکشد، به همین میزان ترد جاری درحال پردازش این درخواست، بیکار شده و منتظر دریافت پاسخ خواهد ایستاد و اگر به همین ترتیب تعداد تردهای بیکار، بیشتر و بیشتر شوند، دیگر سیستم قادر نخواهد بود به درخواستهای جدید رسیده پاسخ دهد و ASP.NET مجبور خواهد شد این درخواستها را در صف قرار دهد تا بالاخره زمانی این تردها آزاد شده و قابل استفادهی مجدد گردند. برای رفع این مشکل، استفاده از اعمال غیرهمزمان ابداع گردیدند تا در آنها ترد مورد استفاده جهت پردازش درخواست رسیده را آزاد کرده و به این ترتیب دیگر نیازی نباشد تا تردجاری، تا پایان عملیات IO بلاک شده و بدون استفاده باقی بماند.
در ASP.NET MVC 3 برای نوشتن اکشن متدهای async میبایستی از روش قدیمی مدلهای Async در دات نت مانند APM استفاده میشد و همچنین کنترلر جاری بجای ارث بری از کلاس Controller میبایستی از کلاس AsyncController مشتق میشد. به علت سخت بودن استفاده از آن، این روش و کنترلرهای async در نگاش 3 آن آنچنان مقبولیت و استفادهی گستردهای نیافتند. چون هر اکشن متد تبدیل میشد به دو قسمت Begin و End متداول روشهای APM. سپس در کشن متد دومی، نتیجهی این عملیات به View بازگشت داده میشد.
از ASP.NET MVC 4 به بعد، خالی کردن تردهای سیستم و استفادهی مجدد و مشغول به کار نگه داشتن مداوم آنها با استفاده از امکانات توکار زبانهایی مانند سیشارپ 5، سادهتر و خواناتر شدهاست.
البته باید دقت داشت که این بحث صرفا سمت سرور بوده و ارتباطی به مباحث غیرهمزمان سمت کلاینت، مانند Ajax ندارد (A در Ajax نیز به معنای Async است) و از دید مصرف کنندهی نهایی، نامرئی میباشد. کار Aajx در سمت کلاینت نیز خالی کردن ترد UI مرورگر است (و نه سرور) و در نهایت تهیهی برنامههایی با قابلیت پاسخدهی بهتر.
نوشتن اکشن متدهای Async در ASP.NET MVC
اولین کاری که باید صورت گیرد، اندکی تغییر امضای اکشن متدهای متداول است:
public ActionResult Index()
public async Task<ActionResult> Index()
زمانیکه به امضای متدی، async اضافه میشود، یعنی جایی در داخل بدنهی آن باید await بکار رود:
using System.Net.Http; using System.Threading.Tasks; using System.Web.Mvc; namespace Async11.Controllers { public class HomeController : Controller { public async Task<ActionResult> Index() { var url = "https://www.dntips.ir"; var client = new HttpClient(); // make sure you have an assembly reference to System.Net.Http.dll client.DefaultRequestHeaders.UserAgent.ParseAdd("Test Async"); var result = await client.GetStringAsync(url); return View(result); } } }
یک نکته در مورد WCF 4.5
از WCF 4.5 به بعد، در صفحهی معروف Add service references آن، با کلیک بر روی گزینهی advanced و تنظیمات سرویس، امکان انتخاب گزینهی Create task based operations نیز وجود دارد. این مورد دقیقا برای سهولت استفاده از آن با async و await سیشارپ 5 و مدل TAP آن طراحی شدهاست.
تعیین timeout در اکشن متدهای async
برای مشخص سازی صریح timeout در اکشن متدهای غیرهمزمان، میتوان از ویژگی خاصی به نام AsyncTimeout به نحو ذیل استفاده کرد:
[AsyncTimeout(duration: 1200)] public async Task<ActionResult> Index(CancellationToken ct)
استفاده از قابلیتهای غیرهمزمان EF 6 به همراه ASP.NET MVC 5
EF 6 به همراه یک سری متد و همچنین متد الحاقی جدید است که اعمال Async را پشتیبانی میکنند. اگر در حین انتخاب گزینهی ایجاد کنترلر جدید، گزینهی MVC 5 Controller with views, using EF را انتخاب کنید، امکان تولید اکشن متدهای async نیز به صورت پیش فرض پیش بینی شدهاست:
public async Task<ActionResult> Index() { var model = await db.Books.ToListAsync(); return View(model); }
به علاوه متد Find اکنون معادل FindAsync نیز دارد و همچنین SaveChanges دارای معادل غیرهمزمانی شدهاست به نام SaveChangesAsync .
البته باید دقت داشت که برای Where معادل Async ایی طراحی نشدهاست؛ زیرا نوع IQueryable صرفا یک عبارت است و اجرای آن تا زمانیکه ToList، First و امثال آن فراخوانی نشوند، به تعویق خواهد افتاد.
کار با کلیدهای اصلی و خارجی در EF Code first
پ.ن.
این نوع سؤالات شخصی را لطفا در انجمنها پیگیری کنید.
اخیرا دو برنامه جهت دریافت سادهتر فایلهای PDC 2010 با سیلورلایت تهیه شدهاند که بر اساس قابلیت اجرای خارج از مرورگر آن (OOB=Out Of Browser) طراحی و پیاده سازی شدهاند:
برنامهی آقای Mike Taulty سورس باز بوده و بر اساس الگوی MVVM پیاده سازی شده است.
علاوه بر آن یک لیست دیگر نیز در این زمینه وجود دارد: