diff --git a/scripts/translation/languages.py b/scripts/translation/languages.py
index a63714594..984a40131 100644
--- a/scripts/translation/languages.py
+++ b/scripts/translation/languages.py
@@ -1,6 +1,7 @@
languages = [
{"code": "en", "name": "English", "native_name": "English"},
{"code": "es", "name": "Spanish", "native_name": "Español"},
+ {"code": "fa", "name": "Persian", "native_name": "فارسی"},
{"code": "fr", "name": "French", "native_name": "Français"},
{"code": "de", "name": "German", "native_name": "Deutsch"},
{"code": "zh", "name": "Chinese", "native_name": "中文"},
diff --git a/static/js/codemirror/codemirror.js b/static/js/codemirror/codemirror.js
index 87339d05f..3a5cc28f4 100644
--- a/static/js/codemirror/codemirror.js
+++ b/static/js/codemirror/codemirror.js
@@ -5247,6 +5247,13 @@ window.CodeMirror = (function() {
if (code <= 0xff) return lowTypes.charAt(code);
else if (0x590 <= code && code <= 0x5f4) return "R";
else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
+ // Treat Arabic Supplement, Arabic Extended-A and Presentation Forms
+ // (which contain Persian/Farsi-specific letters) as AL ("r")
+ // so Persian text is handled like Arabic for bidi ordering.
+ else if ((0x750 <= code && code <= 0x77f) ||
+ (0xfb50 <= code && code <= 0xfdff) ||
+ (0xfe70 <= code && code <= 0xfeff)) return "r";
+ else if (0x700 <= code && code <= 0x8ac) return "r";
else if (0x700 <= code && code <= 0x8ac) return "r";
else return "L";
}
diff --git a/tutorials/learnpython.org/fa/Basic Operators.md b/tutorials/learnpython.org/fa/Basic Operators.md
new file mode 100644
index 000000000..845c8b099
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Basic Operators.md
@@ -0,0 +1,108 @@
+آموزش
+--------
+
+این بخش نحوه استفاده از عملگرهای پایه در پایتون را توضیح میدهد.
+
+### عملگرهای حسابی
+
+مانند سایر زبانهای برنامهنویسی، عملگرهای جمع، تفریق، ضرب و تقسیم را میتوان با اعداد استفاده کرد.
+
+ number = 1 + 2 * 3 / 4.0
+ print(number)
+
+سعی کنید پیشبینی کنید جواب چه خواهد شد. آیا پایتون ترتیب عملیات را رعایت میکند؟
+
+یک عملگر دیگر که وجود دارد عملگر باقیمانده (%) است که باقیمانده صحیح تقسیم را برمیگرداند. تقسیمشونده % تقسیمکننده = باقیمانده.
+
+ remainder = 11 % 3
+ print(remainder)
+
+استفاده از دو علامت ضرب پشت سر هم، توان را نشان میدهد.
+
+ squared = 7 ** 2
+ cubed = 2 ** 3
+ print(squared)
+ print(cubed)
+
+### استفاده از عملگرها با رشتهها
+
+پایتون از الحاق رشتهها با استفاده از عملگر جمع پشتیبانی میکند:
+
+ helloworld = "hello" + " " + "world"
+ print(helloworld)
+
+پایتون همچنین از ضرب رشتهها برای ساخت رشتهای با توالی تکراری پشتیبانی میکند:
+
+ lotsofhellos = "hello" * 10
+ print(lotsofhellos)
+
+### استفاده از عملگرها با لیستها
+
+لیستها را میتوان با عملگر جمع به هم متصل کرد:
+
+ even_numbers = [2,4,6,8]
+ odd_numbers = [1,3,5,7]
+ all_numbers = odd_numbers + even_numbers
+ print(all_numbers)
+
+مانند رشتهها، پایتون از ساخت لیستهای جدید با توالی تکراری با استفاده از عملگر ضرب پشتیبانی میکند:
+
+ print([1,2,3] * 3)
+
+تمرین
+--------
+
+هدف این تمرین ساخت دو لیست به نامهای `x_list` و `y_list` است،
+که هر کدام شامل ۱۰ نمونه از متغیرهای `x` و `y` باشند.
+همچنین باید لیستی به نام `big_list` بسازید که
+متغیرهای `x` و `y` را هر کدام ۱۰ بار، با الحاق دو لیست ساخته شده، داشته باشد.
+
+کد آموزش
+-------------
+
+x = object()
+y = object()
+
+# TODO: این کد را تغییر دهید
+x_list = [x]
+y_list = [y]
+big_list = []
+
+print("x_list شامل %d شیء است" % len(x_list))
+print("y_list شامل %d شیء است" % len(y_list))
+print("big_list شامل %d شیء است" % len(big_list))
+
+# کد تست
+if x_list.count(x) == 10 and y_list.count(y) == 10:
+ print("تقریباً تمام شد...")
+if big_list.count(x) == 10 and big_list.count(y) == 10:
+ print("عالی!")
+
+خروجی مورد انتظار
+---------------
+
+Ex().check_object('x_list').has_equal_value(expr_code = 'len(x_list)')
+Ex().check_object('y_list').has_equal_value(expr_code = 'len(y_list)')
+Ex().check_object('big_list').has_equal_value(expr_code = 'len(big_list)')
+success_msg('کارت عالی بود!')
+
+حل
+--------
+
+x = object()
+y = object()
+
+# TODO: این کد را تغییر دهید
+x_list = [x] * 10
+y_list = [y] * 10
+big_list = x_list + y_list
+
+print("x_list شامل %d شیء است" % len(x_list))
+print("y_list شامل %d شیء است" % len(y_list))
+print("big_list شامل %d شیء است" % len(big_list))
+
+# کد تست
+if x_list.count(x) == 10 and y_list.count(y) == 10:
+ print("تقریباً تمام شد...")
+if big_list.count(x) == 10 and big_list.count(y) == 10:
+ print("عالی!")
diff --git a/tutorials/learnpython.org/fa/Basic String Operations.md b/tutorials/learnpython.org/fa/Basic String Operations.md
new file mode 100644
index 000000000..3add8dd9f
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Basic String Operations.md
@@ -0,0 +1,160 @@
+آموزش
+--------
+
+رشتهها (Strings) قطعاتی از متن هستند. آنها میتوانند هر چیزی بین کوتیشنها باشند:
+
+ astring = "Hello world!"
+ astring2 = 'Hello world!'
+
+همانطور که میبینید، اولین چیزی که یاد گرفتید چاپ یک جمله ساده بود. این جمله توسط پایتون به عنوان یک رشته ذخیره شد. با این حال، به جای اینکه بلافاصله رشتهها را چاپ کنیم، کارهای مختلفی که میتوانید با آنها انجام دهید را بررسی خواهیم کرد.
+همچنین میتوانید از کوتیشن تکی برای مقداردهی به یک رشته استفاده کنید. اما اگر مقدار مورد نظر خودش شامل کوتیشن تکی باشد، با مشکل مواجه میشوید. برای مثال، برای مقداردهی رشتهای که در این براکت است (کوتیشنهای تکی ' ') باید فقط از کوتیشن دوتایی استفاده کنید، مانند این:
+
+ astring = "Hello world!"
+ print("single quotes are ' '")
+
+ print(len(astring))
+
+این مقدار ۱۲ را چاپ میکند، چون "Hello world!" شامل ۱۲ کاراکتر است، شامل علائم نگارشی و فاصلهها.
+
+ astring = "Hello world!"
+ print(astring.index("o"))
+
+این مقدار ۴ را چاپ میکند، چون اولین وقوع حرف "o" چهار کاراکتر بعد از اولین کاراکتر است. توجه کنید که در عبارت دو تا "o" وجود دارد - این متد فقط اولین را پیدا میکند.
+
+اما چرا ۵ چاپ نشد؟ مگر "o" پنجمین کاراکتر رشته نیست؟ برای سادهتر شدن کارها، پایتون (و بیشتر زبانهای برنامهنویسی دیگر) شمارش را از ۰ شروع میکنند نه ۱. پس اندیس "o" برابر با ۴ است.
+
+ astring = "Hello world!"
+ print(astring.count("l"))
+
+برای کسانی که از فونتهای عجیب استفاده میکنند، این یک حرف l کوچک است، نه عدد یک. این تعداد lهای موجود در رشته را میشمارد. بنابراین باید ۳ چاپ کند.
+
+ astring = "Hello world!"
+ print(astring[3:7])
+
+این یک برش (slice) از رشته را چاپ میکند، که از اندیس ۳ شروع و در اندیس ۶ تمام میشود. اما چرا ۶ و نه ۷؟ باز هم، بیشتر زبانهای برنامهنویسی این کار را میکنند - این کار انجام محاسبات داخل براکتها را سادهتر میکند.
+
+اگر فقط یک عدد داخل براکتها بگذارید، کاراکتر همان اندیس را به شما میدهد. اگر عدد اول را حذف کنید اما دونقطه را نگه دارید، از ابتدا تا عدد دوم را میدهد. اگر عدد دوم را حذف کنید، از عدد اول تا انتها را میدهد.
+
+حتی میتوانید اعداد منفی داخل براکتها بگذارید. این یک راه آسان برای شروع از انتهای رشته به جای ابتدای آن است. به این صورت، -۳ یعنی "سومین کاراکتر از انتها".
+
+ astring = "Hello world!"
+ print(astring[3:7:2])
+
+این کاراکترهای رشته را از ۳ تا ۷ با پرش یک کاراکتر چاپ میکند. این سینتکس برش پیشرفته است. فرم کلی آن [شروع:پایان:گام] است.
+
+ astring = "Hello world!"
+ print(astring[3:7])
+ print(astring[3:7:1])
+
+توجه کنید که هر دو خروجی یکسانی دارند.
+
+تابعی مانند strrev در C برای معکوس کردن رشته وجود ندارد. اما با همین نوع سینتکس برش میتوانید به راحتی یک رشته را معکوس کنید:
+
+ astring = "Hello world!"
+ print(astring[::-1])
+
+این
+
+ astring = "Hello world!"
+ print(astring.upper())
+ print(astring.lower())
+
+اینها یک رشته جدید با تمام حروف بزرگ یا کوچک ایجاد میکنند.
+
+ astring = "Hello world!"
+ print(astring.startswith("Hello"))
+ print(astring.endswith("asdfasdfasdf"))
+
+این برای بررسی این است که آیا رشته با چیزی شروع یا تمام میشود. اولی True چاپ میکند چون رشته با "Hello" شروع میشود. دومی False چاپ میکند چون رشته قطعاً با "asdfasdfasdf" تمام نمیشود.
+
+ astring = "Hello world!"
+ afewwords = astring.split(" ")
+
+این رشته را به چند رشته تقسیم میکند که در یک لیست قرار میگیرند. چون این مثال با فاصله تقسیم میکند، اولین آیتم لیست "Hello" و دومی "world!" خواهد بود.
+
+تمرین
+--------
+
+سعی کنید کد را اصلاح کنید تا اطلاعات درست را با تغییر رشته چاپ کند.
+
+کد آموزش
+-------------
+
+s = "Hey there! what should this string be?"
+# طول باید ۲۰ باشد
+print("Length of s = %d" % len(s))
+
+# اولین وقوع "a" باید در اندیس ۸ باشد
+print("The first occurrence of the letter a = %d" % s.index("a"))
+
+# تعداد aها باید ۲ باشد
+print("a occurs %d times" % s.count("a"))
+
+# برش رشته به بخشهای مختلف
+print("The first five characters are '%s'" % s[:5]) # از ابتدا تا ۵
+print("The next five characters are '%s'" % s[5:10]) # ۵ تا ۱۰
+print("The thirteenth character is '%s'" % s[12]) # فقط شماره ۱۲
+print("The characters with odd index are '%s'" %s[1::2]) #(اندیسگذاری از ۰)
+print("The last five characters are '%s'" % s[-5:]) # پنج تای آخر تا انتها
+
+# تبدیل همه چیز به حروف بزرگ
+print("String in uppercase: %s" % s.upper())
+
+# تبدیل همه چیز به حروف کوچک
+print("String in lowercase: %s" % s.lower())
+
+# بررسی شروع رشته
+if s.startswith("Str"):
+ print("String starts with 'Str'. Good!")
+
+# بررسی پایان رشته
+if s.endswith("ome!"):
+ print("String ends with 'ome!'. Good!")
+
+# تقسیم رشته به سه رشته جداگانه،
+# هرکدام فقط شامل یک کلمه
+print("Split the words of the string: %s" % s.split(" "))
+
+خروجی مورد انتظار
+---------------
+
+test_object("s", incorrect_msg="مطمئن شوید که رشته اختصاص داده شده به `s` را طبق دستور تمرین تغییر دادهاید.")
+success_msg("آفرین!")
+
+حل
+--------
+
+s = "Strings are awesome!"
+# طول باید ۲۰ باشد
+print("Length of s = %d" % len(s))
+
+# اولین وقوع "a" باید در اندیس ۸ باشد
+print("The first occurrence of the letter a = %d" % s.index("a"))
+
+# تعداد aها باید ۲ باشد
+print("a occurs %d times" % s.count("a"))
+
+# برش رشته به بخشهای مختلف
+print("The first five characters are '%s'" % s[:5]) # از ابتدا تا ۵
+print("The next five characters are '%s'" % s[5:10]) # ۵ تا ۱۰
+print("The thirteenth character is '%s'" % s[12]) # فقط شماره ۱۲
+print("The characters with odd index are '%s'" %s[1::2]) #(اندیسگذاری از ۰)
+print("The last five characters are '%s'" % s[-5:]) # پنج تای آخر تا انتها
+
+# تبدیل همه چیز به حروف بزرگ
+print("String in uppercase: %s" % s.upper())
+
+# تبدیل همه چیز به حروف کوچک
+print("String in lowercase: %s" % s.lower())
+
+# بررسی شروع رشته
+if s.startswith("Str"):
+ print("String starts with 'Str'. Good!")
+
+# بررسی پایان رشته
+if s.endswith("ome!"):
+ print("String ends with 'ome!'. Good!")
+
+# تقسیم رشته به سه رشته جداگانه،
+# هرکدام فقط شامل یک کلمه
+print("Split the words of the string: %s" % s.split(" "))
diff --git a/tutorials/learnpython.org/fa/Classes and Objects.md b/tutorials/learnpython.org/fa/Classes and Objects.md
new file mode 100644
index 000000000..4d04f0319
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Classes and Objects.md
@@ -0,0 +1,162 @@
+آموزش
+-----------------
+
+اشیاء (Objects) ترکیبی از متغیرها و توابع در یک موجودیت واحد هستند. اشیاء متغیرها و توابع خود را از کلاسها میگیرند. کلاسها در واقع یک قالب برای ساخت اشیاء شما هستند.
+
+یک کلاس بسیار ساده به شکل زیر خواهد بود:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+بعداً توضیح خواهیم داد که چرا باید "self" را به عنوان پارامتر وارد کنید. ابتدا، برای اختصاص کلاس (قالب) بالا به یک شیء، به صورت زیر عمل میکنید:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+ myobjectx = MyClass()
+
+حالا متغیر "myobjectx" یک شیء از کلاس "MyClass" است که متغیر و تابع تعریف شده در کلاس را دارد.
+
+### دسترسی به متغیرهای شیء
+
+برای دسترسی به متغیر داخل شیء تازه ساخته شده "myobjectx" به صورت زیر عمل میکنید:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+ myobjectx = MyClass()
+
+ myobjectx.variable
+
+مثلاً کد زیر رشته "blah" را چاپ میکند:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+ myobjectx = MyClass()
+
+ print(myobjectx.variable)
+
+میتوانید چندین شیء مختلف از یک کلاس بسازید (که متغیرها و توابع یکسانی دارند). اما هر شیء نسخه مستقل خود از متغیرهای تعریف شده در کلاس را دارد. مثلاً اگر یک شیء دیگر با کلاس "MyClass" تعریف کنیم و مقدار متغیر بالا را تغییر دهیم:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+ myobjectx = MyClass()
+ myobjecty = MyClass()
+
+ myobjecty.variable = "yackity"
+
+ # سپس هر دو مقدار را چاپ میکنیم
+ print(myobjectx.variable)
+ print(myobjecty.variable)
+
+
+### دسترسی به توابع شیء
+
+برای دسترسی به یک تابع داخل شیء، مشابه دسترسی به متغیر عمل میکنید:
+
+ class MyClass:
+ variable = "blah"
+
+ def function(self):
+ print("This is a message inside the class.")
+
+ myobjectx = MyClass()
+
+ myobjectx.function()
+
+کد بالا پیام "This is a message inside the class." را چاپ میکند.
+
+### __init__()
+
+تابع `__init__()` یک تابع ویژه است که هنگام مقداردهی اولیه کلاس فراخوانی میشود.
+برای مقداردهی متغیرها در کلاس استفاده میشود.
+
+ class NumberHolder:
+
+ def __init__(self, number):
+ self.number = number
+
+ def returnNumber(self):
+ return self.number
+
+ var = NumberHolder(7)
+ print(var.returnNumber()) # عدد ۷ را چاپ میکند
+
+تمرین
+--------
+
+یک کلاس برای وسایل نقلیه تعریف شده است. دو وسیله نقلیه جدید به نامهای car1 و car2 بسازید.
+car1 را یک کروکی قرمز به ارزش ۶۰٬۰۰۰ دلار با نام Fer قرار دهید،
+و car2 را یک ون آبی به نام Jump به ارزش ۱۰٬۰۰۰ دلار قرار دهید.
+
+کد آموزش
+-------------
+
+# تعریف کلاس Vehicle
+class Vehicle:
+ name = ""
+ kind = "car"
+ color = ""
+ value = 100.00
+ def description(self):
+ desc_str = "%s یک %s %s به ارزش $%.2f است." % (self.name, self.color, self.kind, self.value)
+ return desc_str
+# کد شما اینجا میرود
+
+# کد تست
+print(car1.description())
+print(car2.description())
+
+خروجی مورد انتظار
+---------------
+
+#test_output_contains('Fer is a red convertible worth $60000.00.')
+#test_output_contains('Jump is a blue van worth $10000.00.')
+success_msg("آفرین!")
+
+حل
+--------
+
+# تعریف کلاس Vehicle
+class Vehicle:
+ name = ""
+ kind = "car"
+ color = ""
+ value = 100.00
+ def description(self):
+ desc_str = "%s یک %s %s به ارزش $%.2f است." % (self.name, self.color, self.kind, self.value)
+ return desc_str
+
+# کد شما اینجا میرود
+car1 = Vehicle()
+car1.name = "Fer"
+car1.color = "red"
+car1.kind = "convertible"
+car1.value = 60000.00
+
+car2 = Vehicle()
+car2.name = "Jump"
+car2.color = "blue"
+car2.kind = "van"
+car2.value = 10000.00
+
+# کد تست
+print(car1.description())
+print(car2.description())
diff --git a/tutorials/learnpython.org/fa/Closures.md b/tutorials/learnpython.org/fa/Closures.md
new file mode 100644
index 000000000..8b2161123
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Closures.md
@@ -0,0 +1,83 @@
+آموزش
+--------
+
+کلوجر (Closure) یک شیء تابع است که مقادیر در دامنههای محیطی را حتی اگر آنها دیگر در حافظه محلی نباشند، به خاطر میسپارد. بیایید مرحلهبهمرحله جلو برویم.
+
+اولاً، یک تابع تو در تو (Nested Function) تابعی است که داخل یک تابع دیگر تعریف میشود. بسیار مهم است بدانید که توابع تو در تو میتوانند به متغیرهای دامنه احاطهکننده دسترسی داشته باشند. اما در پایتون به طور پیشفرض فقط قابلقرائت هستند. با این حال، میتوان از کلیدواژه "nonlocal" برای تغییر آنها استفاده کرد.
+
+برای مثال:
+
+ def transmit_to_space(message):
+ "This is the enclosing function"
+ def data_transmitter():
+ "The nested function"
+ print(message)
+
+ data_transmitter()
+
+ print(transmit_to_space("Test message"))
+
+این کار میکند چون data_transmitter میتواند به message دسترسی داشته باشد. برای نشان دادن کاربرد nonlocal، در نظر بگیرید:
+
+ def print_msg(number):
+ def printer():
+ "Here we are using the nonlocal keyword"
+ nonlocal number
+ number=3
+ print(number)
+ printer()
+ print(number)
+
+ print_msg(9)
+
+بدون nonlocal خروجی "3 9" خواهد بود، اما با آن خروجی "3 3" میشود؛ یعنی مقدار number تغییر مییابد.
+
+حال فرض کنید به جای فراخوانی تابع داخلی، خود شیء تابع را برمیگردانیم. (به یاد داشته باشید که توابع هم اشیاء هستند.)
+
+ def transmit_to_space(message):
+ "This is the enclosing function"
+ def data_transmitter():
+ "The nested function"
+ print(message)
+ return data_transmitter
+
+و آنگاه تابع را اینگونه فراخوانی میکنیم:
+
+ fun2 = transmit_to_space("Burn the Sun!")
+ fun2()
+
+حتی اگر اجرای transmit_to_space تمام شود، پیام حفظ میشود. این تکنیک که دادهها به همراه کد بعد از پایان توابع اصلی حفظ میشوند در پایتون به عنوان closure شناخته میشود.
+
+مزیت: کلوجرها میتوانند از استفاده از متغیرهای سراسری جلوگیری کنند و نوعی پنهانسازی داده فراهم کنند.
+
+همچنین دکوراتورها در پایتون به شدت از کلوجرها استفاده میکنند.
+
+تمرین
+--------
+
+یک حلقه تو در تو و یک closure بسازید تا توابع ضرب با ضرایب مختلف تولید کنید، مثلاً تابع multiply_with_5() یا multiply_with_4() با استفاده از closureها.
+
+کد آموزش
+-------------
+
+# your code goes here
+
+multiplywith5 = multiplier_of(5)
+multiplywith5(9)
+
+خروجی مورد انتظار
+---------------
+
+test_output_contains("45")
+success_msg("Great work!")
+
+حل
+--------
+
+def multiplier_of(n):
+ def multiplier(number):
+ return number*n
+ return multiplier
+
+multiplywith5 = multiplier_of(5)
+print(multiplywith5(9))
diff --git a/tutorials/learnpython.org/fa/Code Introspection.md b/tutorials/learnpython.org/fa/Code Introspection.md
new file mode 100644
index 000000000..b8e3d363c
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Code Introspection.md
@@ -0,0 +1,71 @@
+آموزش
+--------
+
+بازبینی کد (Code introspection) قابلیت بررسی کلاسها، توابع و کلمات کلیدی برای دانستن اینکه چه هستند، چه میکنند و چه ویژگیهایی دارند است.
+
+پایتون چندین تابع و ابزار برای بازبینی کد فراهم میکند:
+
+ help()
+ dir()
+ hasattr()
+ id()
+ type()
+ repr()
+ callable()
+ issubclass()
+ isinstance()
+ __doc__
+ __name__
+
+اغلب مهمترین آنها تابع help است، چون میتوانید از آن استفاده کنید تا بفهمید توابع دیگر چه کاری انجام میدهند.
+
+تمرین
+--------
+
+یک لیست از تمام ویژگیهای شیء Vehicle دادهشده چاپ کنید.
+
+کد آموزش
+-------------
+
+# Use the help function to see what each function does.
+# Delete this when you are done.
+help(dir)
+help(hasattr)
+help(id)
+
+# Define the Vehicle class.
+class Vehicle:
+ name = ""
+ kind = "car"
+ color = ""
+ value = 100.00
+ def description(self):
+ desc_str = "%s is a %s %s worth $%.2f." % (self.name, self.color, self.kind, self.value)
+ return desc_str
+
+# Print a list of all attributes of the Vehicle class.
+# Your code goes here
+
+
+خروجی مورد انتظار
+---------------
+
+test_output_contains("['__doc__', '__module__', 'color', 'description', 'kind', 'name', 'value']")
+test_student_typed("print")
+success_msg("Very nice!")
+
+حل
+--------
+
+# Define the Vehicle class
+class Vehicle:
+ name = ""
+ kind = "car"
+ color = ""
+ value = 100.00
+ def description(self):
+ desc_str = "%s is a %s %s worth $%.2f." % (self.name, self.color, self.kind, self.value)
+ return desc_str
+
+# Print a list of all attributes of the Vehicle class.
+print(dir(Vehicle))
diff --git a/tutorials/learnpython.org/fa/Conditions.md b/tutorials/learnpython.org/fa/Conditions.md
new file mode 100644
index 000000000..f8507b395
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Conditions.md
@@ -0,0 +1,151 @@
+آموزش
+--------
+
+پایتون از منطق بولی برای ارزیابی شرایط استفاده میکند. مقادیر بولی True و False هنگام مقایسه یا ارزیابی یک عبارت بازگردانده میشوند. برای مثال:
+
+ x = 2
+ print(x == 2) # True را چاپ میکند
+ print(x == 3) # False را چاپ میکند
+ print(x < 3) # True را چاپ میکند
+
+توجه کنید که انتساب متغیر با یک علامت مساوی "=" انجام میشود، در حالی که مقایسه بین دو مقدار با "==" انجام میشود. عملگر "نابرابر" به شکل "!=" است.
+
+### عملگرهای بولی
+
+عملگرهای بولی "and" و "or" اجازه میدهند عبارات بولی پیچیدهتری بسازید، برای مثال:
+
+ name = "John"
+ age = 23
+ if name == "John" and age == 23:
+ print("Your name is John, and you are also 23 years old.")
+
+ if name == "John" or name == "Rick":
+ print("Your name is either John or Rick.")
+
+### عملگر "in"
+
+عملگر "in" میتواند برای بررسی وجود یک شیء مشخص در یک کانتینر قابل تکرار مانند لیست استفاده شود:
+
+ name = "John"
+ if name in ["John", "Rick"]:
+ print("Your name is either John or Rick.")
+
+پایتون از تورفتگی (indentation) برای تعریف بلوکهای کد استفاده میکند، به جای کروشهها. استاندارد پایتون ۴ فاصله است، اگرچه تب یا اندازه دیگر فضاها نیز کار میکنند تا زمانی که سازگار باشند. بلوکها نیازی به خاتمهدهی ندارند.
+
+مثالی از استفاده از دستور if:
+
+ statement = False
+ another_statement = True
+ if statement is True:
+ # کاری انجام بده
+ pass
+ elif another_statement is True: # else if
+ # کار دیگری انجام بده
+ pass
+ else:
+ # کار دیگری انجام بده
+ pass
+
+برای مثال:
+
+ x = 2
+ if x == 2:
+ print("x equals two!")
+ else:
+ print("x does not equal to two.")
+
+یک عبارت زمانی True ارزیابی میشود که یکی از موارد زیر درست باشد:
+1. مقدار بولی True داده شده باشد یا با یک عبارت محاسبه شود.
+2. شیئی که در نظر گرفته میشود "خالی" نباشد.
+
+مثالهایی از اشیایی که "خالی" محسوب میشوند:
+1. یک رشته خالی: ""
+2. یک لیست خالی: []
+3. عدد صفر: 0
+4. مقدار بولی False
+
+### عملگر 'is'
+
+برخلاف "==" که مقادیر را مقایسه میکند، عملگر "is" نمونهها را مقایسه میکند. برای مثال:
+
+ x = [1,2,3]
+ y = [1,2,3]
+ print(x == y) # True را چاپ میکند
+ print(x is y) # False را چاپ میکند
+
+### عملگر "not"
+
+استفاده از "not" قبل از یک عبارت بولی آن را معکوس میکند:
+
+ print(not False) # True را چاپ میکند
+ print((not False) == (False)) # False را چاپ میکند
+
+تمرین
+--------
+
+متغیرها را در بخش اول تغییر دهید تا هر عبارت if به True ارزیابی شود.
+
+کد آموزش
+-------------
+
+# change this code
+number = 10
+second_number = 10
+first_array = []
+second_array = [1,2,3]
+
+if number > 15:
+ print("1")
+
+if first_array:
+ print("2")
+
+if len(second_array) == 2:
+ print("3")
+
+if len(first_array) + len(second_array) == 5:
+ print("4")
+
+if first_array and first_array[0] == 1:
+ print("5")
+
+if not second_number:
+ print("6")
+
+خروجی مورد انتظار
+---------------
+
+test_output_contains("1", no_output_msg= "Did you print out 1 if `number` is greater than 15?")
+test_output_contains("2", no_output_msg= "Did you print out 2 if there exists a list `first_array`?")
+test_output_contains("3", no_output_msg= "Did you print out 3 if the length of `second_array` is 2?")
+test_output_contains("4", no_output_msg= "Did you print out 4 if len(first_array) + len(second_array) == 5?")
+test_output_contains("5", no_output_msg= "Did you print out 5 if first_array and first_array[0] == 1?")
+test_output_contains("6", no_output_msg= "Did you print out 6 if not second_number?")
+success_msg("Great Work!")
+
+حل
+--------
+
+# change this code
+number = 16
+second_number = 0
+first_array = [1,2,3]
+second_array = [1,2]
+
+if number > 15:
+ print("1")
+
+if first_array:
+ print("2")
+
+if len(second_array) == 2:
+ print("3")
+
+if len(first_array) + len(second_array) == 5:
+ print("4")
+
+if first_array and first_array[0] == 1:
+ print("5")
+
+if not second_number:
+ print("6")
diff --git a/tutorials/learnpython.org/fa/Decorators.md b/tutorials/learnpython.org/fa/Decorators.md
new file mode 100644
index 000000000..f1eaaadbe
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Decorators.md
@@ -0,0 +1,136 @@
+آموزش
+--------
+
+دکوراتورها به شما اجازه میدهند تغییرات سادهای روی اشیاء قابلصدا زدن مثل توابع، متدها یا کلاسها انجام دهید. در این آموزش روی توابع تمرکز میکنیم. سینتکس
+
+ @decorator
+ def functions(arg):
+ return "value"
+
+معادل است با:
+
+ def function(arg):
+ return "value"
+ function = decorator(function) # این تابع را به دکوراتور ارسال میکند و دوباره اختصاص میدهد
+
+همانطور که ممکن است دیده باشید، دکوراتور فقط یک تابع دیگر است که یک تابع را میگیرد و یک تابع بازمیگرداند. برای مثال میتوانید این کار را انجام دهید:
+
+ def repeater(old_function):
+ def new_function(*args, **kwds): # برای نحوه کار *args و **kwds به آموزش مربوطه مراجعه کنید
+ old_function(*args, **kwds) # تابع قدیمی را اجرا میکنیم
+ old_function(*args, **kwds) # دوبار اجرا میکنیم
+ return new_function # باید new_function را برگردانیم تا دوباره اختصاص یابد
+
+این باعث میشود یک تابع دو بار اجرا شود.
+
+ >>> @repeater
+ def multiply(num1, num2):
+ print(num1 * num2)
+
+ >>> multiply(2, 3)
+ 6
+ 6
+
+همچنین میتوانید خروجی را تغییر دهید:
+
+ def double_out(old_function):
+ def new_function(*args, **kwds):
+ return 2 * old_function(*args, **kwds) # مقدار بازگشتی را تغییر میدهد
+ return new_function
+
+یا ورودی را تغییر دهید:
+
+ def double_Ii(old_function):
+ def new_function(arg): # فقط زمانی کار میکند که تابع قدیمی یک آرگومان داشته باشد
+ return old_function(arg * 2) # آرگومان ارسالشده را تغییر میدهد
+ return new_function
+
+و برای اعتبارسنجی استفاده کنید:
+
+ def check(old_function):
+ def new_function(arg):
+ if arg < 0: raise (ValueError, "Negative Argument") # باعث بروز خطا میشود که بهتر از نتیجه اشتباه است
+ old_function(arg)
+ return new_function
+
+فرض کنید میخواهید خروجی را در یک ضریب متغیر ضرب کنید. میتوانید دکوراتور را به صورت زیر بسازید:
+
+ def multiply(multiplier):
+ def multiply_generator(old_function):
+ def new_function(*args, **kwds):
+ return multiplier * old_function(*args, **kwds)
+ return new_function
+ return multiply_generator # یک تولیدکننده دکوراتور بازمیگرداند
+
+ # استفاده
+ @multiply(3) # multiply خودش دکوراتور نیست اما multiply(3) یک دکوراتور ایجاد میکند
+ def return_num(num):
+ return num
+
+ # اکنون return_num دکورت شده و دوباره اختصاص یافته است
+ return_num(5) # باید 15 بازگرداند
+
+شما میتوانید هر کاری با تابع قدیمی انجام دهید، حتی کاملاً آن را نادیده بگیرید! دکوراتورهای پیشرفته میتوانند رشته مستندات و تعداد آرگومان را نیز دستکاری کنند.
+برای دکوراتورهای جالبتر به http://wiki.python.org/moin/PythonDecoratorLibrary مراجعه کنید.
+
+تمرین
+--------
+
+یک کارخانه دکوراتور بسازید که یک دکوراتور برمیگرداند که توابع یک آرگومان را دکورت میکند. این کارخانه یک نوع (type) میگیرد و سپس دکوراتوری بازمیگرداند که چک میکند ورودی از نوع صحیح است؛ در غیر این صورت باید print("Bad Type") کند. از isinstance(object, type_of_object) یا type(object) میتوانید استفاده کنید.
+
+کد آموزش
+-------------
+
+def type_check(correct_type):
+ #put code here
+
+@type_check(int)
+def times2(num):
+ return num*2
+
+print(times2(2))
+times2('Not A Number')
+
+@type_check(str)
+def first_letter(word):
+ return word[0]
+
+print(first_letter('Hello World'))
+first_letter(['Not', 'A', 'String'])
+
+
+خروجی مورد انتظار
+---------------
+
+test_output_contains("4")
+test_output_contains("Bad Type")
+test_output_contains("H")
+test_output_contains("Bad Type")
+success_msg("Good job!")
+
+حل
+--------
+
+def type_check(correct_type):
+ def check(old_function):
+ def new_function(arg):
+ if (isinstance(arg, correct_type)):
+ return old_function(arg)
+ else:
+ print("Bad Type")
+ return new_function
+ return check
+
+@type_check(int)
+def times2(num):
+ return num*2
+
+print(times2(2))
+times2('Not A Number')
+
+@type_check(str)
+def first_letter(word):
+ return word[0]
+
+print(first_letter('Hello World'))
+first_letter(['Not', 'A', 'String'])
diff --git a/tutorials/learnpython.org/fa/Dictionaries.md b/tutorials/learnpython.org/fa/Dictionaries.md
new file mode 100644
index 000000000..65b687b56
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Dictionaries.md
@@ -0,0 +1,102 @@
+آموزش
+--------
+
+دیکشنری یک نوع دادهای مشابه آرایهها است، اما بهجای ایندکسها با کلیدها و مقادیر کار میکند. هر مقدار ذخیرهشده در یک دیکشنری را میتوان با استفاده از یک کلید که میتواند هر نوع شیءای باشد (رشته، عدد، لیست و غیره) دسترسی پیدا کرد، بهجای اینکه از ایندکس آن استفاده شود.
+
+برای مثال، یک پایگاه داده شماره تلفنها میتواند با استفاده از یک دیکشنری به این شکل ذخیره شود:
+
+ phonebook = {}
+ phonebook["John"] = 938477566
+ phonebook["Jack"] = 938377264
+ phonebook["Jill"] = 947662781
+ print(phonebook)
+
+بهطور جایگزین، میتوان دیکشنری را با همان مقادیر به شکل زیر مقداردهی اولیه کرد:
+
+ phonebook = {
+ "John" : 938477566,
+ "Jack" : 938377264,
+ "Jill" : 947662781
+ }
+ print(phonebook)
+
+### تکرار روی دیکشنریها
+
+دیکشنریها را میتوان مانند یک لیست تکرار کرد. با این حال، بر خلاف لیست، دیکشنری ترتیب مقادیری که در آن ذخیره شدهاند را نگهداری نمیکند. برای تکرار روی جفتهای کلید-مقدار از سینتکس زیر استفاده کنید:
+
+ phonebook = {"John" : 938477566,"Jack" : 938377264,"Jill" : 947662781}
+ for name, number in phonebook.items():
+ print("Phone number of %s is %d" % (name, number))
+
+### حذف یک مقدار
+
+برای حذف یک ایندکس مشخص، از یکی از نگارشهای زیر استفاده کنید:
+
+ phonebook = {
+ "John" : 938477566,
+ "Jack" : 938377264,
+ "Jill" : 947662781
+ }
+ del phonebook["John"]
+ print(phonebook)
+
+یا:
+
+ phonebook = {
+ "John" : 938477566,
+ "Jack" : 938377264,
+ "Jill" : 947662781
+ }
+ phonebook.pop("John")
+ print(phonebook)
+
+
+تمرین
+--------
+
+عبارت "Jake" را به phonebook با شماره تلفن 938273443 اضافه کنید و Jill را از phonebook حذف کنید.
+
+کد آموزش
+-------------
+
+phonebook = {
+ "John" : 938477566,
+ "Jack" : 938377264,
+ "Jill" : 947662781
+}
+# کد شما اینجا میرود
+
+# کد تست
+if "Jake" in phonebook:
+ print("Jake is listed in the phonebook.")
+
+if "Jill" not in phonebook:
+ print("Jill is not listed in the phonebook.")
+
+
+خروجی مورد انتظار
+---------------
+
+test_output_contains("Jake is listed in the phonebook.")
+test_output_contains("Jill is not listed in the phonebook.")
+success_msg("Nice work!")
+
+حل
+--------
+
+phonebook = {
+ "John" : 938477566,
+ "Jack" : 938377264,
+ "Jill" : 947662781
+}
+
+# کد شما اینجا میرود
+phonebook["Jake"] = 938273443
+del phonebook["Jill"]
+
+# کد تست
+if "Jake" in phonebook:
+ print("Jake is listed in the phonebook.")
+
+if "Jill" not in phonebook:
+ print("Jill is not listed in the phonebook.")
diff --git a/tutorials/learnpython.org/fa/Exception Handling.md b/tutorials/learnpython.org/fa/Exception Handling.md
new file mode 100644
index 000000000..67633c062
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Exception Handling.md
@@ -0,0 +1,74 @@
+آموزش
+--------
+هنگامی که برنامه مینویسید خطا رخ میدهد — این یک واقعیت است.
+شاید کاربر ورودی نامناسب داد؛ شاید منبع شبکه در دسترس نبود؛ شاید حافظه تمام شد یا خود برنامهنویس اشتباه کرده باشد!
+
+راه حل پایتون برای خطاها استثناها (exceptions) هستند. ممکن است قبلاً یک استثنا دیده باشید.
+
+ print(a)
+
+ #error
+ Traceback (most recent call last):
+ File "", line 1, in
+ NameError: name 'a' is not defined
+
+اوه! فراموش کردیم به متغیر `a` مقدار بدهیم.
+
+گاهی نمیخواهید استثناها اجرای برنامه را کاملاً متوقف کنند. ممکن است بخواهید هنگام وقوع استثنا کار خاصی انجام شود. این کار با بلوک `try/except` انجام میشود.
+
+نمونهای ساده: فرض کنید دارید روی لیستی میچرخید که ممکن است کمتر از 20 عنصر داشته باشد. وقتی به انتهای لیست رسیدید، میخواهید مابقی اعداد را صفر در نظر بگیرید. میتوانید اینگونه عمل کنید:
+
+ def do_stuff_with_number(n):
+ print(n)
+
+ def catch_this():
+ the_list = (1, 2, 3, 4, 5)
+
+ for i in range(20):
+ try:
+ do_stuff_with_number(the_list[i])
+ except IndexError: # Raised when accessing a non-existing index of a list
+ do_stuff_with_number(0)
+
+ catch_this()
+
+کار با استثناها خیلی سخت نیست! برای جزئیات بیشتر به مستندات پایتون مراجعه کنید.
+
+تمرین
+--------
+
+تمام استثناها را مدیریت کنید! با استفاده از درسهای قبلی نام خانوادگی بازیگر را بازگردانید.
+
+Tutorial Code
+-------------
+
+# Setup
+actor = {"name": "John Cleese", "rank": "awesome"}
+
+# Function to modify!!!
+def get_last_name():
+ return actor["last_name"]
+
+# Test code
+get_last_name()
+print("All exceptions caught! Good job!")
+print("The actor's last name is %s" % get_last_name())
+
+Expected Output
+---------------
+
+test_output_contains("Cleese")
+test_output_contains("All exceptions caught! Good job!")
+test_output_contains("The actor's last name is Cleese")
+success_msg("Great work!")
+
+Solution
+--------
+actor = {"name": "John Cleese", "rank": "awesome"}
+
+def get_last_name():
+ return actor["name"].split()[1]
+
+get_last_name()
+print("All exceptions caught! Good job!")
+print("The actor's last name is %s" % get_last_name())
diff --git a/tutorials/learnpython.org/fa/Functions.md b/tutorials/learnpython.org/fa/Functions.md
new file mode 100644
index 000000000..6873a510c
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Functions.md
@@ -0,0 +1,96 @@
+آموزش
+--------
+
+### توابع چیستند؟
+
+توابع راهی مناسب برای تقسیم کد به بلوکهای مفید هستند که به ما کمک میکنند کد را سازماندهی کنیم، قابل خواندنتر کنیم، آن را مجدداً استفاده کنیم و زمان صرفهجویی کنیم. همچنین توابع روش مهمی برای تعریف رابطها (interfaces) بین برنامهنویسان هستند.
+
+### چگونه در پایتون تابع بنویسیم؟
+
+همانطور که در درسهای قبلی دیدید، پایتون از بلوکهای تو در تو استفاده میکند.
+
+یک بلوک به شکل زیر است:
+
+ block_head:
+ 1st block line
+ 2nd block line
+ ...
+
+برای توابع از کلمه کلیدی `def` استفاده میکنیم:
+
+ def my_function():
+ print("Hello From My Function!")
+
+توابع میتوانند آرگومان دریافت کنند:
+
+ def my_function_with_args(username, greeting):
+ print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
+
+توابع میتوانند مقداری بازگردانند با `return`:
+
+ def sum_two_numbers(a, b):
+ return a + b
+
+### نحوه فراخوانی توابع
+
+نام تابع را نوشته و پرانتز باز و بسته میکنیم و آرگومانها را میدهیم.
+
+مثالها در بلوکهای کد حفظ شدهاند.
+
+تمرین
+--------
+
+در این تمرین باید از یک تابع موجود استفاده کنید و توابع خود را اضافه کنید تا برنامه کامل شود.
+
+1. تابع `list_benefits()` را اضافه کنید که لیستی از رشتهها را بازگرداند: "More organized code", "More readable code", "Easier code reuse", "Allowing programmers to share and connect code together"
+
+2. تابع `build_sentence(info)` را اضافه کنید که یک آرگومان رشتهای میگیرد و جملهای را بازمیگرداند که با آن رشته شروع شده و با " is a benefit of functions!" تمام میشود.
+
+3. همه را اجرا کنید و نتیجه را مشاهده کنید.
+
+Tutorial Code
+-------------
+
+# Modify this function to return a list of strings as defined above
+def list_benefits():
+ return []
+
+# Modify this function to concatenate to each benefit - " is a benefit of functions!"
+def build_sentence(benefit):
+ return ""
+
+def name_the_benefits_of_functions():
+ list_of_benefits = list_benefits()
+ for benefit in list_of_benefits:
+ print(build_sentence(benefit))
+
+name_the_benefits_of_functions()
+
+
+Expected Output
+---------------
+
+test_output_contains("More organized code is a benefit of functions!")
+test_output_contains("More readable code is a benefit of functions!")
+test_output_contains("Easier code reuse is a benefit of functions!")
+test_output_contains("Allowing programmers to share and connect code together is a benefit of functions!")
+success_msg("Nice work!")
+
+Solution
+--------
+
+# Modify this function to return a list of strings as defined above
+def list_benefits():
+ return "More organized code", "More readable code", "Easier code reuse", "Allowing programmers to share and connect code together"
+
+# Modify this function to concatenate to each benefit - " is a benefit of functions!"
+def build_sentence(benefit):
+ return "%s is a benefit of functions!" % benefit
+
+
+def name_the_benefits_of_functions():
+ list_of_benefits = list_benefits()
+ for benefit in list_of_benefits:
+ print(build_sentence(benefit))
+
+name_the_benefits_of_functions()
diff --git a/tutorials/learnpython.org/fa/Generators.md b/tutorials/learnpython.org/fa/Generators.md
new file mode 100644
index 000000000..410c8d271
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Generators.md
@@ -0,0 +1,80 @@
+آموزش
+--------
+
+ژنراتورها (Generators) پیادهسازی سادهای دارند اما فهم آن ممکن است کمی دشوار باشد.
+
+ژنراتورها برای ساخت تکرارشوندهها (iterators) استفاده میشوند، اما با رویکردی متفاوت. ژنراتورها توابع سادهای هستند که مجموعهای از آیتمها را یکییکی بازمیگردانند.
+
+زمانی که حلقه `for` روی مجموعهای از آیتمها اجرا میشود، ژنراتور اجرا میشود. هر بار که اجرای تابع به دستور `yield` میرسد، مقدار جدیدی تولید شده و کنترل به حلقه `for` بازمیگردد. تابع ژنراتور میتواند هر تعداد مقدار (حتی بینهایت) را تولید کند.
+
+مثال سادهای از یک ژنراتور که 7 عدد تصادفی برمیگرداند:
+
+ import random
+
+ def lottery():
+ # returns 6 numbers between 1 and 40
+ for i in range(6):
+ yield random.randint(1, 40)
+
+ # returns a 7th number between 1 and 15
+ yield random.randint(1, 15)
+
+ for random_number in lottery():
+ print("And the next number is... %d!" %(random_number))
+
+این تابع خودش تصمیم میگیرد چگونه اعداد تصادفی را تولید کند و هر بار به `yield` میرسد اجرای آن متوقف و مقدار برگردانده میشود.
+
+تمرین
+--------
+
+یک تابع ژنراتور بنویسید که دنباله فیبوناچی را تولید کند. دو عدد اول دنباله همیشه برابر 1 هستند و هر عدد بعدی جمع دو عدد قبلی است.
+راهنما: میتوانید از دو متغیر استفاده کنید و از انتساب همزمان بهره ببرید.
+
+Tutorial Code
+-------------
+
+# fill in this function
+def fib():
+ pass #this is a null statement which does nothing when executed, useful as a placeholder.
+
+# testing code
+import types
+if type(fib()) == types.GeneratorType:
+ print("Good, The fib function is a generator.")
+
+ counter = 0
+ for n in fib():
+ print(n)
+ counter += 1
+ if counter == 10:
+ break
+
+
+
+Expected Output
+---------------
+
+test_output_contains("Good, The fib function is a generator.")
+success_msg('Good work!')
+
+Solution
+--------
+
+# fill in this function
+def fib():
+ a, b = 1, 1
+ while 1:
+ yield a
+ a, b = b, a + b
+
+# testing code
+import types
+if type(fib()) == types.GeneratorType:
+ print("Good, The fib function is a generator.")
+
+ counter = 0
+ for n in fib():
+ print(n)
+ counter += 1
+ if counter == 10:
+ break
diff --git a/tutorials/learnpython.org/fa/Hello, World!.md b/tutorials/learnpython.org/fa/Hello, World!.md
new file mode 100644
index 000000000..d1ced00f7
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Hello, World!.md
@@ -0,0 +1,46 @@
+آموزش
+--------
+
+پایتون زبانی بسیار ساده با نحو (syntax) شفافی است.
+این زبان برنامهنویسان را تشویق میکند تا بدون کدهای تکراری بنویسند.
+سادهترین دستور در پایتون تابع `print` است — که یک خط را چاپ میکند (و یک newline اضافه میکند).
+
+دو نسخه اصلی پایتون وجود دارد: پایتون 2 و پایتون 3. این آموزش از پایتون 3 استفاده میکند چون معانی منطقیتری دارد و از ویژگیهای جدیدتر پشتیبانی میکند.
+
+برای مثال، یکی از تفاوتها بین پایتون 2 و 3 ساختار `print` است.
+در پایتون 2، `print` یک عبارت (statement) است و بدون پرانتز نوشته میشود. در پایتون 3، `print` یک تابع است و باید با پرانتز فراخوانی شود.
+
+برای چاپ یک رشته در پایتون 3 کافیست:
+
+ print("This line will be printed.")
+
+### تورفتگی (Indentation)
+
+پایتون از تورفتگی برای بلوکها استفاده میکند، نه آکولاد. هر دو تب و فاصله پشتیبانی میشوند، اما استاندارد استفاده از چهار فاصله است.
+
+ x = 1
+ if x == 1:
+ # indented four spaces
+ print("x is 1.")
+
+تمرین
+--------
+
+از تابع `print` برای چاپ "Hello, World!" استفاده کنید.
+
+Tutorial Code
+-------------
+
+print("Goodbye, World!")
+
+Expected Output
+---------------
+test_output_contains("Hello, World!")
+success_msg('Great job!')
+
+Solution
+--------
+
+print("Hello, World!")
+
+
diff --git a/tutorials/learnpython.org/fa/Input and Output.md b/tutorials/learnpython.org/fa/Input and Output.md
new file mode 100644
index 000000000..735c8306f
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Input and Output.md
@@ -0,0 +1,89 @@
+آموزش
+--------
+دریافت ورودی و نمایش خروجی به شکل مورد نیاز در برنامههای تعاملی اهمیت زیادی دارد. بنابراین بیایید روی ورودی و خروجی انواع مختلف داده تمرکز کنیم.
+
+### input()
+از این تابع برای خواندن ورودی تا انتهای خط استفاده میشود. توجه کنید که ورودی تا رسیدن به newline خوانده میشود. پس از خواندن میتوان ورودی را با توابعی مثل int()، float()، str() به نوع دلخواه تبدیل کرد.
+
+ # Prints out the input received from stdin
+ astring=input()# give hello as input
+ print(input())
+
+پس از گرفتن ورودی میتوان آن را به نوع دلخواه تبدیل کرد:
+
+ num=int(input())
+ print num
+ decimalnum=input()
+ decimalnum=float(input()
+ print decimalnum
+
+### چگونه چند مقدار از یک خط جدا شده با فاصله بگیریم؟
+از split() و map() استفاده میکنیم:
+
+ #give two integers in first line and more than two integers in third line
+ a, b = map(int, input().split())
+ array = input().split()
+ sum = 0
+ for each in array:
+ sum = sum + int(each)
+ print(a, b, sum) # prints first two integers from first line and sum of integers of second line
+
+### قالببندی خروجی
+تابعی مانند print بهصورت خودکار یک newline اضافه میکند. استفاده از ویرگول در print (در پایتون 2) مقادیر را در یک خط جداشده با فاصله چاپ میکند. ماژول sys توابع متنوعی برای قالببندی خروجی دارد، اما در اینجا نشان میدهیم چگونه با قالببندی ساده خروجی را شکل دهیم.
+
+مثال:
+
+ a = 5
+ b = 0.63
+ c = "hello"
+ print("a is : %d, b is %0.4f,c is %s" % (a,b,c))
+
+تمرین
+--------
+
+برنامهای بنویسید که از کاربر نام، سن و کشور را دریافت کند. سپس پیام حاوی این اطلاعات را چاپ کند. موارد زیر لازم است:
+
+1. گرفتن نام با `input()`.
+2. گرفتن سن با `input()` و تبدیل آن به عدد صحیح.
+3. گرفتن نام کشور با `input()`.
+4. قالببندی خروجی برای نمایش جملهای که نام، سن و کشور را نشان دهد.
+
+Tutorial Code
+-------------
+
+ # Taking the name input using input()
+ name = input("Enter your name: ")
+
+ # Taking the age input using input() and converting it to integer
+ age = int(input("Enter your age: "))
+
+ # Taking the country input using input()
+ country = input("Enter your country: ")
+
+ # Displaying the formatted sentence with name, age, and country
+ print("Hello, my name is {}, I am {} years old, and I am from {}.".format(name, age, country))
+
+
+Expected Output
+---------------
+
+ Enter your name: John
+ Enter your age: 25
+ Enter your country: USA
+ Hello, my name is John, I am 25 years old, and I am from USA.
+
+
+Solution
+-------------
+
+ # Taking the name input using input()
+ name = input("Enter your name: ")
+
+ # Taking the age input using input() and converting it to integer
+ age = int(input("Enter your age: "))
+
+ # Taking the country input using input()
+ country = input("Enter your country: ")
+
+ # Displaying the formatted sentence with name, age, and country
+ print("Hello, my name is {}, I am {} years old, and I am from {}.".format(name, age, country))
diff --git a/tutorials/learnpython.org/fa/Lambda functions.md b/tutorials/learnpython.org/fa/Lambda functions.md
new file mode 100644
index 000000000..175a9852f
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Lambda functions.md
@@ -0,0 +1,55 @@
+آموزش
+--------
+معمولاً یک تابع را با کلمه کلیدی `def` تعریف میکنیم و سپس هر زمان که لازم باشد آن را فراخوانی میکنیم.
+
+ def sum(a,b):
+ return a + b
+
+ a = 1
+ b = 2
+ c = sum(a,b)
+ print(c)
+
+حال بهجای تعریف تابع در جایی جدا، میتوانیم از lambda برای تعریف توابع خطی (inline) استفاده کنیم، بنابراین نیازی به تعریف نام تابع در جای دیگر نداریم. این توابع میتوانند بینام باشند (anonymous).
+
+قالب تعریف lambda:
+
+ your_function_name = lambda inputs : output
+
+مثال بالا با lambda:
+
+ a = 1
+ b = 2
+ sum = lambda x,y : x + y
+ c = sum(a,b)
+ print(c)
+
+در اینجا lambda به متغیر `sum` اختصاص داده شده و هنگام فراخوانی با آرگومانها مثل یک تابع معمولی عمل میکند.
+
+تمرین
+--------
+یک برنامه با استفاده از lambda بنویسید که بررسی کند عددی در لیست داده شده فرد است یا خیر. برای هر عنصر "True" را در صورتی که فرد باشد یا "False" در غیر این صورت چاپ کنید.
+
+Tutorial Code
+-------------
+l = [2,4,7,3,14,19]
+for i in l:
+ # your code here
+
+Expected Output
+---------------
+test_output_contains("False")
+test_output_contains("False")
+test_output_contains("True")
+test_output_contains("True")
+test_output_contains("False")
+test_output_contains("True")
+success_msg("Nice work!")
+
+Solution
+--------
+l = [2,4,7,3,14,19]
+for i in l:
+ # your code here
+ my_lambda = lambda x : (x % 2) == 1
+ print(my_lambda(i))
\ No newline at end of file
diff --git a/tutorials/learnpython.org/fa/List Comprehensions.md b/tutorials/learnpython.org/fa/List Comprehensions.md
new file mode 100644
index 000000000..a0219521f
--- /dev/null
+++ b/tutorials/learnpython.org/fa/List Comprehensions.md
@@ -0,0 +1,46 @@
+آموزش
+--------
+
+List Comprehensions ابزار قدرتمندی است که یک لیست جدید بر اساس لیست دیگری در یک خط خوانا ایجاد میکند.
+
+برای مثال، فرض کنید میخواهیم لیستی از طول هر کلمه در جملهای خاص بسازیم، اما تنها در صورتی که کلمه برابر با "the" نباشد.
+
+ sentence = "the quick brown fox jumps over the lazy dog"
+ words = sentence.split()
+ word_lengths = []
+ for word in words:
+ if word != "the":
+ word_lengths.append(len(word))
+ print(words)
+ print(word_lengths)
+
+با یک لیست کامپرهنشن میتوانیم این را سادهتر بنویسیم:
+
+ sentence = "the quick brown fox jumps over the lazy dog"
+ words = sentence.split()
+ word_lengths = [len(word) for word in words if word != "the"]
+ print(words)
+ print(word_lengths)
+
+تمرین
+--------
+
+با استفاده از یک list comprehension، لیست جدیدی به نام `newlist` از لیست `numbers` بسازید که فقط شامل اعداد مثبت بهصورت عدد صحیح (int) باشد.
+
+Tutorial Code
+-------------
+numbers = [34.6, -203.4, 44.9, 68.3, -12.2, 44.6, 12.7]
+newlist = []
+print(newlist)
+
+Expected Output
+---------------
+
+test_output_contains("[34, 44, 68, 44, 12]")
+success_msg("Very nice!")
+
+Solution
+--------
+numbers = [34.6, -203.4, 44.9, 68.3, -12.2, 44.6, 12.7]
+newlist = [int(x) for x in numbers if x > 0]
+print(newlist)
diff --git a/tutorials/learnpython.org/fa/Lists.md b/tutorials/learnpython.org/fa/Lists.md
new file mode 100644
index 000000000..65e8ef18d
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Lists.md
@@ -0,0 +1,73 @@
+آموزش
+--------
+
+لیستها بسیار شبیه آرایهها هستند. آنها میتوانند هر نوع مقدار را نگهدارند و به هر اندازهای که خواستید عنصر داشته باشند. لیستها را میتوان به راحتی تکرار (iterate) کرد. در اینجا مثالی از ساخت یک لیست آورده شده است.
+
+ mylist = []
+ mylist.append(1)
+ mylist.append(2)
+ mylist.append(3)
+ print(mylist[0]) # prints 1
+ print(mylist[1]) # prints 2
+ print(mylist[2]) # prints 3
+
+ # prints out 1,2,3
+ for x in mylist:
+ print(x)
+
+دسترسی به اندیسی که وجود ندارد یک استثنا (خطا) ایجاد میکند.
+
+ mylist = [1,2,3]
+ print(mylist[10])
+
+تمرین
+--------
+
+در این تمرین باید اعداد و رشتهها را به لیستهای مناسب با استفاده از متد `append` اضافه کنید. باید اعداد 1، 2 و 3 را به لیست `numbers` اضافه کنید و کلمات 'hello' و 'world' را به `strings`.
+
+همچنین باید مقدار `second_name` را با نام دوم در لیست `names` پر کنید، با استفاده از عملگر براکت `[]`. توجه داشته باشید اندیسها از صفر شروع میشوند، بنابراین برای دسترسی به آیتم دوم اندیس 1 است.
+
+Tutorial Code
+-------------
+numbers = []
+strings = []
+names = ["John", "Eric", "Jessica"]
+
+# write your code here
+second_name = None
+
+
+# this code should write out the filled arrays and the second name in the names list (Eric).
+print(numbers)
+print(strings)
+print("The second name on the names list is %s" % second_name)
+
+Expected Output
+---------------
+
+test_output_contains("[1,2,3]", no_output_msg= "Make sure that you have printed the `numbers` list.")
+test_output_contains("['hello', 'world']", no_output_msg= "Make sure that you have printed the `strings` list.")
+test_output_contains("The second name on the names list is Eric", no_output_msg= "Did you fill in the variable `second_name` with the second name in the names list?")
+success_msg("Great Job!")
+
+Solution
+--------
+
+numbers = []
+strings = []
+names = ["John", "Eric", "Jessica"]
+
+# write your code here
+numbers.append(1)
+numbers.append(2)
+numbers.append(3)
+
+strings.append("hello")
+strings.append("world")
+
+second_name = names[1]
+
+# this code should write out the filled arrays and the second name in the names list (Eric).
+print(numbers)
+print(strings)
+print("The second name on the names list is %s" % second_name)
diff --git a/tutorials/learnpython.org/fa/Loops.md b/tutorials/learnpython.org/fa/Loops.md
new file mode 100644
index 000000000..35afbe4a6
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Loops.md
@@ -0,0 +1,131 @@
+آموزش
+--------
+
+در پایتون دو نوع حلقه وجود دارد: for و while.
+
+### حلقه "for"
+
+حلقههای for روی یک دنباله مشخص تکرار میکنند. در اینجا یک مثال آورده شده است:
+
+ primes = [2, 3, 5, 7]
+ for prime in primes:
+ print(prime)
+
+حلقههای for میتوانند روی یک دنباله از اعداد با استفاده از توابع "range" و "xrange" تکرار کنند. تفاوت بین range و xrange این است که تابع range یک لیست جدید با اعداد بازه مشخص شده برمیگرداند، در حالی که xrange یک تکرارگر برمیگرداند که کارآمدتر است. (در پایتون ۳ تابع range مانند xrange عمل میکند). توجه داشته باشید که تابع range از صفر شروع میکند.
+
+ # اعداد ۰، ۱، ۲، ۳، ۴ را چاپ میکند
+ for x in range(5):
+ print(x)
+
+ # اعداد ۳، ۴، ۵ را چاپ میکند
+ for x in range(3, 6):
+ print(x)
+
+ # اعداد ۳، ۵، ۷ را چاپ میکند
+ for x in range(3, 8, 2):
+ print(x)
+
+### حلقههای "while"
+
+حلقههای while تا زمانی که یک شرط بولی برقرار باشد تکرار میشوند. برای مثال:
+
+ # اعداد ۰، ۱، ۲، ۳، ۴ را چاپ میکند
+
+ count = 0
+ while count < 5:
+ print(count)
+ count += 1 # این معادل count = count + 1 است
+
+### دستورات "break" و "continue"
+
+دستور **break** برای خروج از یک حلقه for یا while استفاده میشود، در حالی که **continue** برای رد کردن بلوک فعلی و بازگشت به ابتدای حلقه به کار میرود. چند مثال:
+
+ # اعداد ۰، ۱، ۲، ۳، ۴ را چاپ میکند
+
+ count = 0
+ while True:
+ print(count)
+ count += 1
+ if count >= 5:
+ break
+
+ # فقط اعداد فرد را چاپ میکند - ۱، ۳، ۵، ۷، ۹
+ for x in range(10):
+ # بررسی میکند که آیا x زوج است
+ if x % 2 == 0:
+ continue
+ print(x)
+
+### آیا میتوانیم از بند "else" برای حلقهها استفاده کنیم؟
+
+برخلاف زبانهایی مانند C و ++C، در پایتون میتوانیم از **else** برای حلقهها استفاده کنیم. زمانی که شرط حلقه for یا while برقرار نباشد، بخش کد در "else" اجرا میشود. اگر دستور **break** درون حلقه اجرا شود، بخش "else" اجرا نخواهد شد.
+توجه داشته باشید که بخش "else" حتی اگر دستور **continue** وجود داشته باشد نیز اجرا میشود.
+
+چند مثال:
+
+ # اعداد ۰، ۱، ۲، ۳، ۴ را چاپ میکند و سپس "count value reached 5" را چاپ میکند
+
+ count=0
+ while(count<5):
+ print(count)
+ count +=1
+ else:
+ print("count value reached %d" %(count))
+
+ # اعداد ۱، ۲، ۳، ۴ را چاپ میکند
+ for i in range(1, 10):
+ if(i%5==0):
+ break
+ print(i)
+ else:
+ print("این چاپ نمیشود چون حلقه for به خاطر break متوقف شده نه به خاطر برقرار نبودن شرط")
+
+
+تمرین
+--------
+
+در لیست numbers حلقه بزنید و تمام اعداد زوج را به همان ترتیبی که آمدهاند چاپ کنید. هیچ عددی که بعد از ۲۳۷ در دنباله میآید را چاپ نکنید.
+
+کد آموزش
+-------------
+numbers = [
+ 951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
+ 615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
+ 386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
+ 399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
+ 815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
+ 958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
+ 743, 527
+]
+
+# کد شما اینجا میرود
+for number in numbers:
+
+خروجی مورد انتظار
+---------------
+
+test_object("number", undefined_msg="یک شیء به نام `number` تعریف کنید و از کد آموزش برای چاپ فقط اعداد مورد نظر طبق توضیحات تمرین استفاده کنید.",incorrect_msg="شیء `number` شما صحیح نیست. باید از دستور `if` و `break` برای رسیدن به هدف استفاده کنید.")
+success_msg("Great work!")
+
+حل
+--------
+
+numbers = [
+ 951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
+ 615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
+ 386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
+ 399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
+ 815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
+ 958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
+ 743, 527
+]
+
+# کد شما اینجا میرود
+for number in numbers:
+ if number == 237:
+ break
+
+ if number % 2 == 1:
+ continue
+
+ print(number)
diff --git a/tutorials/learnpython.org/fa/Map, Filter, Reduce.md b/tutorials/learnpython.org/fa/Map, Filter, Reduce.md
new file mode 100644
index 000000000..1af24e09b
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Map, Filter, Reduce.md
@@ -0,0 +1,249 @@
+آموزش
+--------
+Map، Filter و Reduce الگوهایی از برنامهنویسی تابعی هستند. آنها به برنامهنویس امکان میدهند کدی سادهتر و کوتاهتر بنویسد بدون آنکه الزاماً به جزئیات حلقهها و شرطها پرداخته شود.
+
+این سه تابع به شما اجازه میدهند تابعی را روی یک یا چند iterable اعمال کنید. `map` و `filter` در پایتون داخلی هستند و نیازی به وارد کردن ندارند. اما `reduce` در ماژول `functools` قرار دارد و باید وارد شود. بیایید با `map` شروع کنیم.
+
+#### Map
+تابع `map()` در پایتون به شکل زیر است:
+
+```map(func, *iterables)```
+
+که در آن `func` تابعی است که روی هر یک از عناصر `iterables` اعمال میشود. علامت ستاره (`*`) نشان میدهد که میتوان چندین iterable داشت. توجه کنید تابع باید همان تعداد آرگومان را بپذیرد که تعداد iterableها است.
+
+نکات مهم:
+1. در پایتون 2، `map()` یک لیست برمیگرداند. در پایتون 3، `map()` یک شیء map (تولیدکننده) برمیگرداند. برای گرفتن لیست باید `list()` روی آن فراخوانی کنید.
+2. تعداد آرگومانهای `func` باید برابر با تعداد iterableها باشد.
+
+بیایید ببینیم این قوانین چگونه در مثالهای زیر اعمال میشوند.
+
+فرض کنید یک لیست از نامهای حیوانات خانگی مورد علاقهام دارم که همه به حروف کوچک هستند و نیاز دارم که به حروف بزرگ تبدیل شوند. به طور سنتی، در پایتون معمولی، چیزی شبیه به این انجام میدادم:
+
+ my_pets = ['alfred', 'tabitha', 'william', 'arla']
+ uppered_pets = []
+
+ for pet in my_pets:
+ pet_ = pet.upper()
+ uppered_pets.append(pet_)
+
+ print(uppered_pets)
+
+که خروجی آن خواهد بود ```['ALFRED', 'TABITHA', 'WILLIAM', 'ARLA']```
+
+با استفاده از تابع ```map()```، این کار نه تنها آسانتر است، بلکه انعطافپذیری بیشتری نیز دارد. من به سادگی این کار را انجام میدهم:
+
+ # Python 3
+ my_pets = ['alfred', 'tabitha', 'william', 'arla']
+
+ uppered_pets = list(map(str.upper, my_pets))
+
+ print(uppered_pets)
+
+که همچنین همان نتیجه را میدهد. توجه داشته باشید که با توجه به نحو تعریف شده ```map()```، در اینجا ```func``` برابر با ```str.upper``` است و ```iterables``` لیست ```my_pets``` است -- فقط یک iterable. همچنین توجه داشته باشید که ما تابع ```str.upper``` را فراخوانی نکردیم (این کار: ```str.upper()```)، زیرا تابع map این کار را برای ما روی _هر عنصر در لیست ```my_pets```_ انجام میدهد.
+
+نکته مهمتر این است که تابع ```str.upper``` به طور پیشفرض فقط به **یک** آرگومان نیاز دارد و بنابراین ما فقط **یک** iterable به آن دادیم. بنابراین، _اگر تابعی که شما ارسال میکنید به دو، یا سه، یا n آرگومان نیاز دارد_، _پس شما نیز باید به همان تعداد (دو، سه یا n) iterable به آن بدهید_. بیایید این را با یک مثال دیگر روشن کنیم.
+
+فرض کنید یک لیست از مساحتهای دایره دارم که جایی محاسبه کردهام، همه با پنج رقم اعشار. و نیاز دارم که هر عنصر در لیست را به تعداد اعشار موقعیت خود گرد کنم، به این معنی که باید اولین عنصر لیست را به یک رقم اعشار، دومین عنصر را به دو رقم اعشار، سومین عنصر را به سه رقم اعشار و الی آخر گرد کنم. با استفاده از ```map()``` این کار بسیار آسان است. بیایید ببینیم چگونه است.
+
+پایتون به ما تابع داخلی ```round()``` را میدهد که به دو آرگومان نیاز دارد -- عددی که باید گرد شود و تعداد اعشار که باید عدد به آن گرد شود. بنابراین، از آنجا که تابع به **دو** آرگومان نیاز دارد، ما نیز باید **دو** iterable به آن بدهیم.
+
+ # Python 3
+
+ circle_areas = [3.56773, 5.57668, 4.00914, 56.24241, 9.01344, 32.00013]
+
+ result = list(map(round, circle_areas, range(1, 7)))
+
+ print(result)
+
+زیبایی ```map()``` را ببینید؟ آیا میتوانید تصور کنید که این چقدر انعطافپذیر است؟
+
+تابع ```range(1, 7)``` به عنوان آرگومان دوم به تابع ```round``` عمل میکند (تعداد اعشار مورد نیاز در هر تکرار). بنابراین همانطور که ```map``` در حال تکرار در ```circle_areas``` است، در اولین تکرار، اولین عنصر ```circle_areas```، ```3.56773``` به همراه اولین عنصر ```range(1,7)```، ```1``` به ```round``` منتقل میشود، به طوری که به طور مؤثر به ```round(3.56773, 1)``` تبدیل میشود. در دومین تکرار، دومین عنصر ```circle_areas```، ```5.57668``` به همراه دومین عنصر ```range(1,7)```، ```2``` به ```round``` منتقل میشود و آن را به ```round(5.57668, 2)``` تبدیل میکند. این روند تا رسیدن به انتهای لیست ```circle_areas``` ادامه مییابد.
+
+مطمئنم که شما در حال حاضر میپرسید: "اگر یک iterable با طول کمتر یا بیشتر از طول اولین iterable ارسال کنم چه؟ یعنی، اگر ```range(1, 3)``` یا ```range(1, 9999)``` را به عنوان دومین iterable در تابع بالا ارسال کنم چه اتفاقی میافتد". و پاسخ ساده است: هیچچیز! خوب، این درست نیست. "هیچچیز" از آن جهت است که تابع ```map()``` هیچ استثنایی را ایجاد نخواهد کرد، بلکه به سادگی تا زمانی که نتواند یک آرگومان دوم برای تابع پیدا کند، به تکرار عناصر ادامه میدهد، در این نقطه به سادگی متوقف شده و نتیجه را برمیگرداند.
+
+بنابراین، به عنوان مثال، اگر شما ```result = list(map(round, circle_areas, range(1, 3)))``` را ارزیابی کنید، هیچ خطایی دریافت نخواهید کرد حتی اگر طول ```circle_areas``` و طول ```range(1, 3)``` متفاوت باشد. در عوض، این است که پایتون انجام میدهد: اولین عنصر ```circle_areas``` و اولین عنصر ```range(1,3)``` را میگیرد و آنها را به ```round``` میفرستد. ```round``` آن را ارزیابی کرده و نتیجه را ذخیره میکند. سپس به تکرار دوم میرود، دومین عنصر ```circle_areas``` و دومین عنصر ```range(1,3)``` را میگیرد و آنها را به ```round``` میفرستد و دوباره نتیجه را ذخیره میکند. حالا، در تکرار سوم (```circle_areas``` دارای یک عنصر سوم است)، پایتون عنصر سوم ```circle_areas``` را میگیرد و سپس سعی میکند عنصر سوم ```range(1,3)``` را بگیرد اما از آنجا که ```range(1,3)``` دارای یک عنصر سوم نیست، پایتون به سادگی متوقف شده و نتیجه را برمیگرداند، که در این مورد به سادگی ```[3.6, 5.58]``` خواهد بود.
+
+ادامه دهید، امتحان کنید.
+
+ # Python 3
+
+ circle_areas = [3.56773, 5.57668, 4.00914, 56.24241, 9.01344, 32.00013]
+
+ result = list(map(round, circle_areas, range(1, 3)))
+
+ print(result)
+
+
+همین اتفاق میافتد اگر ```circle_areas``` کمتر از طول دومین iterable باشد. پایتون به سادگی زمانی متوقف میشود که نتواند عنصر بعدی را در یکی از iterableها پیدا کند.
+
+برای تثبیت دانش خود از تابع ```map()```، ما قصد داریم از آن برای پیادهسازی تابع ```zip()``` خودمان استفاده کنیم. تابع ```zip()``` تابعی است که تعدادی iterable را میگیرد و سپس یک تاپل حاوی هر یک از عناصر در iterableها را ایجاد میکند. مانند ```map()```, در پایتون 3، یک شیء تولیدکننده برمیگرداند، که میتوان به راحتی با فراخوانی تابع داخلی ```list``` بر روی آن به لیست تبدیل کرد. از جلسه مفسر زیر برای درک بهتر ```zip()``` قبل از ایجاد آن با ```map()``` استفاده کنید
+
+ # Python 3
+
+ my_strings = ['a', 'b', 'c', 'd', 'e']
+ my_numbers = [1, 2, 3, 4, 5]
+
+ results = list(zip(my_strings, my_numbers))
+
+ print(results)
+
+به عنوان یک پاداش، آیا میتوانید حدس بزنید در جلسه بالا چه اتفاقی میافتد اگر ```my_strings``` و ```my_numbers``` از نظر طول برابر نباشند؟ نه؟ امتحان کنید! طول یکی از آنها را تغییر دهید.
+
+به سراغ تابع ```zip()``` سفارشی خودمان برویم!
+
+ # Python 3
+
+ my_strings = ['a', 'b', 'c', 'd', 'e']
+ my_numbers = [1, 2, 3, 4, 5]
+
+ results = list(map(lambda x, y: (x, y), my_strings, my_numbers))
+
+ print(results)
+
+فقط به این نگاه کنید! ما همان نتیجه را به عنوان ```zip``` داریم.
+
+آیا همچنین متوجه شدید که حتی نیازی به ایجاد یک تابع با استفاده از روش استاندارد ```def my_function()``` ندارم؟ اینقدر انعطافپذیر است ```map()```، و به طور کلی پایتون! من به سادگی از یک تابع ```lambda``` استفاده کردم. این به این معنا نیست که استفاده از روش تعریف تابع استاندارد (با ```def function_name()```) مجاز نیست، هنوز هم مجاز است. من فقط ترجیح دادم کد کمتری بنویسم (به طور "پایتونیک").
+
+این تمام چیزی است که درباره map باید بدانید. به سراغ ```filter()``` برویم.
+
+#### Filter
+در حالی که ```map()``` هر عنصر در iterable را از طریق یک تابع عبور میدهد و نتیجه را از همه عناصری که از طریق تابع عبور کردهاند برمیگرداند، ```filter()```، اول از همه، نیاز دارد که تابع مقادیر بولی (درست یا نادرست) برگرداند و سپس هر عنصر در iterable را از طریق تابع عبور میدهد و آنهایی را که نادرست هستند "فیلتر" میکند. این تابع دارای نحو زیر است:
+
+```filter(func, iterable)```
+
+نکات زیر در مورد ```filter()``` باید توجه شود:
+
+1. بر خلاف ```map()```, فقط یک iterable مورد نیاز است.
+2. آرگومان ```func``` نیاز به بازگشت یک نوع بولی دارد. اگر این کار را نکند، ```filter``` به سادگی ```iterable``` را که به آن داده شده است برمیگرداند. همچنین، از آنجا که فقط یک iterable مورد نیاز است، به طور ضمنی اینگونه است که ```func``` باید فقط یک آرگومان بپذیرد.
+3. ```filter``` هر عنصر در iterable را از طریق ```func``` عبور میدهد و فقط آنهایی را که به درستی ارزیابی میشوند برمیگرداند. منظورم این است که، این دقیقاً در نام آن است -- یک "فیلتر".
+
+بیایید چند مثال ببینیم
+
+لیست زیر (```iterable```) نمرات 10 دانشآموز در یک امتحان شیمی است. بیایید آنهایی را که با نمرات بالای 75 قبول شدهاند فیلتر کنیم...با استفاده از ```filter```.
+
+ # Python 3
+ scores = [66, 90, 68, 59, 76, 60, 88, 74, 81, 65]
+
+ def is_A_student(score):
+ return score > 75
+
+ over_75 = list(filter(is_A_student, scores))
+
+ print(over_75)
+
+مثال بعدی یک تشخیصدهنده پالینروم خواهد بود. یک "پالینروم" کلمه، عبارت یا دنبالهای است که به صورت معکوس همانند جلوخوانی میشود. بیایید کلماتی را که پالینروم هستند از یک تاپل (```iterable```) از کلمات مشکوک فیلتر کنیم.
+
+ # Python 3
+ dromes = ("demigod", "rewire", "madam", "freer", "anutforajaroftuna", "kiosk")
+
+ palindromes = list(filter(lambda word: word == word[::-1], dromes))
+
+ print(palindromes)
+
+که باید ```['madam', 'anutforajaroftuna']``` را خروجی دهد.
+
+زیبا نیست؟ بالاخره، ```reduce()```
+
+#### Reduce
+```reduce``` یک تابع **با دو آرگومان** را به طور تجمعی به عناصر یک iterable اعمال میکند، به طور اختیاری با یک آرگومان اولیه شروع میشود. این تابع دارای نحو زیر است:
+
+```reduce(func, iterable[, initial])```
+
+که در آن ```func``` تابعی است که هر عنصر در ```iterable``` به طور تجمعی به آن اعمال میشود، و ```initial``` مقداری اختیاری است که قبل از عناصر iterable در محاسبه قرار میگیرد و زمانی که iterable خالی است به عنوان پیشفرض استفاده میشود. نکات زیر در مورد ```reduce()``` باید توجه شود:
+1. ```func``` به دو آرگومان نیاز دارد، که اولی آن عنصر اول در ```iterable``` (اگر ```initial``` تامین نشود) و دومی عنصر دوم در ```iterable``` است. اگر ```initial``` تامین شود، آنگاه این مقدار به عنوان اولین آرگومان به ```func``` داده میشود و اولین عنصر در ```iterable``` به عنوان دومین عنصر در نظر گرفته میشود.
+2. ```reduce``` ```iterable``` را به یک مقدار واحد "کاهش" میدهد.
+
+همانطور که معمول است، بیایید چند مثال ببینیم.
+
+بیایید نسخه خودمان از تابع داخلی ```sum()``` پایتون را ایجاد کنیم. تابع ```sum()``` مجموع تمام اقلام در iterable داده شده را برمیگرداند.
+
+
+ # Python 3
+ from functools import reduce
+
+ numbers = [3, 4, 6, 9, 34, 12]
+
+ def custom_sum(first, second):
+ return first + second
+
+ result = reduce(custom_sum, numbers)
+ print(result)
+
+
+نتیجه، همانطور که انتظار دارید، ```68``` است.
+
+پس، چه اتفاقی افتاد؟
+
+همانطور که معمول است، همه چیز در مورد تکرار است: ```reduce``` اولین و دومین عناصر را در ```numbers``` میگیرد و آنها را به ترتیب به ```custom_sum``` میفرستد. ```custom_sum``` مجموع آنها را محاسبه کرده و به ```reduce``` برمیگرداند. ```reduce``` سپس آن نتیجه را به عنوان اولین عنصر به ```custom_sum``` میفرستد و عنصر بعدی (سوم) در ```numbers``` را به عنوان دومین عنصر به ```custom_sum``` میفرستد. این کار به طور مداوم (تجمعی) تا زمانی که ```numbers``` تمام شود ادامه مییابد.
+
+بیایید ببینیم وقتی از آرگومان اختیاری ```initial``` استفاده میکنم چه اتفاقی میافتد.
+
+
+ # Python 3
+ from functools import reduce
+
+ numbers = [3, 4, 6, 9, 34, 12]
+
+ def custom_sum(first, second):
+ return first + second
+
+ result = reduce(custom_sum, numbers, 10)
+ print(result)
+
+
+نتیجه، همانطور که انتظار دارید، ```78``` است زیرا ```reduce``` به طور اولیه از ```10``` به عنوان اولین آرگومان به ```custom_sum``` استفاده میکند.
+
+
+این تمام چیزی است که درباره Map، Reduce و Filter در پایتون باید بدانید. سعی کنید تمرینات زیر را برای اطمینان از درک خود از هر تابع انجام دهید.
+
+تمرین
+--------
+در این تمرین، از هر یک از ```map```، ```filter``` و ```reduce``` برای اصلاح کد خراب استفاده خواهید کرد.
+
+کد آموزشی
+-------------
+from functools import reduce
+
+# Use map to print the square of each numbers rounded
+# to three decimal places
+my_floats = [4.35, 6.09, 3.25, 9.77, 2.16, 8.88, 4.59]
+
+# Use filter to print only the names that are less than
+# or equal to seven letters
+my_names = ["olumide", "akinremi", "josiah", "temidayo", "omoseun"]
+
+# Use reduce to print the product of these numbers
+my_numbers = [4, 6, 9, 23, 5]
+
+# Fix all three respectively.
+map_result = list(map(lambda x: x, my_floats))
+filter_result = list(filter(lambda name: name, my_names, my_names))
+reduce_result = reduce(lambda num1, num2: num1 * num2, my_numbers, 0)
+
+print(map_result)
+print(filter_result)
+print(reduce_result)
+
+خروجی مورد انتظار
+---------------
+test_output_contains("[18.922, 37.088, 10.562, 95.453, 4.666, 78.854, 21.068]")
+test_output_contains("['olumide', 'josiah', 'omoseun']")
+test_output_contains("24840")
+success_msg("Congrats! Nice work.")
+
+راه حل
+--------
+#### Map
+from functools import reduce
+
+my_floats = [4.35, 6.09, 3.25, 9.77, 2.16, 8.88, 4.59]
+my_names = ["olumide", "akinremi", "josiah", "temidayo", "omoseun"]
+my_numbers = [4, 6, 9, 23, 5]
+
+map_result = list(map(lambda x: round(x ** 2, 3), my_floats))
+filter_result = list(filter(lambda name: len(name) <= 7, my_names))
+reduce_result = reduce(lambda num1, num2: num1 * num2, my_numbers)
+
+print(map_result)
+print(filter_result)
+print(reduce_result)
diff --git a/tutorials/learnpython.org/fa/Modules and Packages.md b/tutorials/learnpython.org/fa/Modules and Packages.md
new file mode 100644
index 000000000..6224ffa04
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Modules and Packages.md
@@ -0,0 +1,235 @@
+آموزش
+--------
+
+در برنامهنویسی، ماژول بخشی از نرمافزار است که وظیفهای مشخص دارد.
+برای مثال، هنگام ساخت یک بازی پینگپنگ، یک ماژول ممکن است مسئول منطق بازی باشد و ماژول دیگری مسئول رسم بازی روی صفحه باشد. هر ماژول از یک فایل جداگانه تشکیل شده و میتوان آن را مجزا ویرایش کرد.
+
+### نوشتن ماژولها
+
+ماژولها در پایتون صرفاً فایلهای پایتون با پسوند .py هستند. نام ماژول همان نام فایل است.
+یک ماژول پایتون میتواند مجموعهای از توابع، کلاسها یا متغیرها را تعریف و پیادهسازی کند.
+مثال بالا شامل دو فایل است:
+
+mygame/
+
+- mygame/game.py
+
+- mygame/draw.py
+
+
+اسکریپت پایتون `game.py` بازی را پیادهسازی میکند. این اسکریپت از تابع `draw_game` در فایل `draw.py` استفاده میکند، یا به عبارت دیگر از ماژول `draw` که منطق رسم بازی را پیادهسازی میکند.
+
+ماژولها با استفاده از دستور `import` از ماژولهای دیگر فراخوانی میشوند. در این مثال، اسکریپت `game.py` ممکن است به صورت زیر باشد:
+
+ # game.py
+ # import the draw module
+ import draw
+
+ def play_game():
+ ...
+
+ def main():
+ result = play_game()
+ draw.draw_game(result)
+
+ # this means that if this script is executed, then
+ # main() will be executed
+ if __name__ == '__main__':
+ main()
+
+ماژول `draw` ممکن است چیزی شبیه به این باشد:
+
+ # draw.py
+
+ def draw_game():
+ ...
+
+ def clear_screen(screen):
+ ...
+
+در این مثال، ماژول `game` ماژول `draw` را وارد میکند، که به آن اجازه میدهد از توابع پیادهسازیشده در آن استفاده کند. تابع `main` از تابع محلی `play_game` برای اجرای بازی استفاده میکند و سپس نتیجه بازی را با استفاده از تابع `draw_game` که در ماژول `draw` پیادهسازی شده رسم میکند. برای استفاده از تابع `draw_game` از ماژول `draw` باید مشخص کنیم که تابع در کدام ماژول پیادهسازی شده است، با استفاده از عملگر نقطه. برای ارجاع به تابع `draw_game` از ماژول `game`، باید ماژول `draw` را وارد کنیم و سپس آن را با `draw.draw_game()` فراخوانی کنیم.
+
+وقتی دستور `import draw` اجرا میشود، مفسر پایتون به دنبال فایلی با نام ماژول به اضافه پسوند `.py` در دایرکتوری ای که اسکریپت اجرا شده میگردد. در این حالت دنبال `draw.py` خواهد گشت. اگر پیدا شود، وارد میشود. اگر پیدا نشود، به جستجو در ماژولهای داخلی ادامه میدهد.
+
+ممکن است متوجه شده باشید که هنگام وارد کردن یک ماژول، فایلی با پسوند `.pyc` ساخته میشود. این یک فایل بایتکد پایتون است.
+پایتون فایلها را به بایتکد کامپایل میکند تا مجبور نباشد هر بار ماژولها را بارگذاری کند آنها را پارس کند. اگر فایل `.pyc` وجود داشته باشد، آن بارگذاری میشود به جای فایل `.py`. این فرآیند برای کاربر شفاف است.
+
+### وارد کردن اشیاء ماژول به فضای نام فعلی
+
+فضای نام (namespace) سیستمی است که در آن هر شیء نامگذاری شده و قابل دسترسی است. با استفاده از دستور `from` میتوانیم تابع `draw_game` را به فضای نام اسکریپت اصلی وارد کنیم.
+
+ # game.py
+ # import the draw module
+ from draw import draw_game
+
+ def main():
+ result = play_game()
+ draw_game(result)
+
+
+شاید متوجه شده باشید که در این مثال نام ماژول قبل از `draw_game` نوشته نشده است، زیرا با استفاده از دستور `import` مشخص کردهایم کدام تابع را وارد میکنیم.
+
+مزیت این نوشتار این است که نیازی نیست هر بار نام ماژول را تکرار کنیم. با این حال، یک فضای نام نمیتواند دو شیء با یک نام داشته باشد، بنابراین دستور `from ... import ...` ممکن است شیئی موجود در فضای نام را بازنویسی کند.
+
+### وارد کردن همه اشیاء از یک ماژول
+
+میتوانید از دستور `import *` برای وارد کردن تمام اشیاء یک ماژول استفاده کنید:
+
+ # game.py
+ # import the draw module
+ from draw import *
+
+ def main():
+ result = play_game()
+ draw_game(result)
+
+این ممکن است کمی پرخطر باشد چون تغییرات در ماژول واردشده میتواند روی ماژولی که آن را وارد میکند تأثیر بگذارد، اما کوتاهتر است و نیازی به ذکر تکتک اشیاء نیست.
+
+### نام سفارشی برای وارد کردن ماژول
+
+میتوان ماژولها را با هر نامی که خواستید بارگذاری کرد. این زمانی مفید است که بخواهید به صورت شرطی ماژول را وارد کنید و در ادامه کد از همان نام استفاده کنید.
+
+برای مثال، اگر دو ماژول `draw` با نامهای کمی متفاوت داشته باشید، ممکن است به این شکل عمل کنید:
+
+
+ # game.py
+ # import the draw module
+ if visual_mode:
+ # in visual mode, we draw using graphics
+ import draw_visual as draw
+ else:
+ # in textual mode, we print out text
+ import draw_textual as draw
+
+ def main():
+ result = play_game()
+ # this can either be visual or textual depending on visual_mode
+ draw.draw_game(result)
+
+
+### مقداردهی اولیه ماژول
+
+اولین بار که یک ماژول در یک اسکریپت پایتون بارگذاری میشود، با اجرای کد داخل ماژول مقداردهی اولیه میشود (یک بار). اگر ماژول دیگری همان ماژول را دوباره وارد کند، ماژول دوباره بارگذاری نمیشود، بنابراین متغیرهای محلی داخل ماژول مانند یک «singleton» عمل میکنند و تنها یک بار مقداردهی میشوند.
+
+میتوانید از این امکان برای مقداردهی اولیه اشیاء استفاده کنید.
+برای مثال:
+
+ # draw.py
+
+ def draw_game():
+ # when clearing the screen we can use the main screen object initialized in this module
+ clear_screen(main_screen)
+ ...
+
+ def clear_screen(screen):
+ ...
+
+ class Screen():
+ ...
+
+ # initialize main_screen as a singleton
+ main_screen = Screen()
+
+
+### گسترش مسیر بارگذاری ماژول
+
+چند روش وجود دارد که به مفسر پایتون بگویید به جز دایرکتوری محلی و ماژولهای داخلی، از کدام مسیرها ماژولها را بارگذاری کند. میتوانید از متغیر محیطی `PYTHONPATH` استفاده کنید تا مسیرهای اضافی را مشخص کنید:
+
+ PYTHONPATH=/foo python game.py
+
+این `game.py` را اجرا میکند و امکان بارگذاری ماژولها از دایرکتوری `foo` را فراهم میآورد، بهعلاوه دایرکتوری محلی.
+
+همچنین میتوانید از `sys.path.append` استفاده کنید. آن را *قبل از* اجرای دستور `import` فراخوانی کنید:
+
+ sys.path.append("/foo")
+
+اکنون دایرکتوری `foo` به لیست مسیرهایی که در آنها به دنبال ماژول میگردد افزوده شده است.
+
+### بررسی ماژولهای داخلی
+
+فهرست کامل ماژولهای کتابخانه استاندارد پایتون را میتوانید در این لینک ببینید: https://docs.python.org/3/library/.
+
+دو تابع بسیار مفید برای بررسی ماژولها عبارتند از `dir` و `help`.
+
+برای وارد کردن ماژول `urllib` که امکان خواندن داده از URLها را فراهم میکند، آن را وارد میکنیم:
+
+ # import the library
+ import urllib
+
+ # use it
+ urllib.urlopen(...)
+
+میتوانیم با استفاده از تابع `dir` فهرستی از توابع و اشیاء ماژول را ببینیم:
+
+ >>> import urllib
+ >>> dir(urllib)
+ ['ContentTooShortError', 'FancyURLopener', 'MAXFTPCACHE', 'URLopener', '__all__', '__builtins__',
+ '__doc__', '__file__', '__name__', '__package__', '__version__', '_ftperrors', '_get_proxies',
+ '_get_proxy_settings', '_have_ssl', '_hexdig', '_hextochr', '_hostprog', '_is_unicode', '_localhost',
+ '_noheaders', '_nportprog', '_passwdprog', '_portprog', '_queryprog', '_safe_map', '_safe_quoters',
+ '_tagprog', '_thishost', '_typeprog', '_urlopener', '_userprog', '_valueprog', 'addbase', 'addclosehook',
+ 'addinfo', 'addinfourl', 'always_safe', 'basejoin', 'c', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies',
+ 'getproxies_environment', 'getproxies_macosx_sysconf', 'i', 'localhost', 'main', 'noheaders', 'os',
+ 'pathname2url', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote',
+ 'quote_plus', 'reporthook', 'socket', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport',
+ 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', 'test', 'test1',
+ 'thishost', 'time', 'toBytes', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode',
+ 'urlopen', 'urlretrieve']
+
+وقتی تابع مورد نظر را پیدا کردیم، میتوانیم درون مفسر پایتون با `help` دربارهٔ آن اطلاعات بیشتری بخوانیم:
+
+ help(urllib.urlopen)
+
+### نوشتن بستهها (Packages)
+
+بستهها فضای نامی هستند که شامل چندین بسته و ماژول میشوند. آنها در واقع دایرکتوری هستند، با شرایط مشخص.
+
+هر بسته در پایتون یک دایرکتوری است که **باید** شامل فایلی ویژه به نام `__init__.py` باشد. این فایل که میتواند خالی باشد نشان میدهد دایرکتوری مورد نظر یک بسته پایتون است. به این ترتیب میتوان آن را مانند یک ماژول وارد کرد.
+
+اگر دایرکتوریای به نام `foo` بسازیم که نام بسته باشد، سپس درون آن ماژولی به نام `bar` ایجاد کنیم و فایل `__init__.py` را درون دایرکتوری `foo` قرار دهیم، میتوانیم ماژول `bar` را به دو شکل وارد کنیم:
+
+ import foo.bar
+
+یا:
+
+ from foo import bar
+
+در مثال اول، هر بار که به ماژول `bar` دسترسی پیدا کنید باید پیشوند `foo` را بیاورید. در مثال دوم، این پیشوند لازم نیست چون ما `bar` را به فضای نام خود وارد کردهایم.
+
+فایل `__init__.py` میتواند تعیین کند که کدام ماژولها به عنوان API بسته صادر شوند در حالی که ماژولهای دیگر داخلی بمانند، با بازنویسی متغیر `__all__` به این شکل:
+
+ __init__.py:
+
+ __all__ = ["bar"]
+
+تمرین
+--------
+
+در این تمرین، لیستی از تمام توابع در ماژول `re` که شامل کلمه `find` هستند را به ترتیب الفبایی چاپ کنید.
+
+Tutorial Code
+-------------
+
+import re
+
+# Your code goes here
+find_members = []
+
+Expected Output
+---------------
+
+test_object('find_members')
+success_msg('Great work!')
+
+Solution
+--------
+
+import re
+
+# Your code goes here
+find_members = []
+for member in dir(re):
+ if "find" in member:
+ find_members.append(member)
+
+print(sorted(find_members))
diff --git a/tutorials/learnpython.org/fa/Multiple Function Arguments.md b/tutorials/learnpython.org/fa/Multiple Function Arguments.md
new file mode 100644
index 000000000..66f07684d
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Multiple Function Arguments.md
@@ -0,0 +1,101 @@
+آموزش
+--------
+
+هر تابع در پایتون تعداد پیشفرضی از آرگومانها را دریافت میکند اگر بهصورت عادی اعلام شود، مثلاً:
+
+ def myfunction(first, second, third):
+ # do something with the 3 variables
+ ...
+
+امکان اعلام توابعی که تعداد متغیرتری از آرگومانها را دریافت میکنند وجود دارد، با نحو زیر:
+
+ def foo(first, second, third, *therest):
+ print("First: %s" % first)
+ print("Second: %s" % second)
+ print("Third: %s" % third)
+ print("And all the rest... %s" % list(therest))
+
+متغیر "therest" لیستی از آرگومانها را دریافت میکند که پس از سه آرگومان اول به تابع `foo` داده شدهاند. بنابراین `foo(1, 2, 3, 4, 5)` خروجی را نشان خواهد داد:
+
+ def foo(first, second, third, *therest):
+ print("First: %s" %(first))
+ print("Second: %s" %(second))
+ print("Third: %s" %(third))
+ print("And all the rest... %s" %(list(therest)))
+
+ foo(1, 2, 3, 4, 5)
+
+همچنین میتوان آرگومانها را با کلید (keyword) ارسال کرد تا ترتیب اهمیتی نداشته باشد، به شکل زیر. خروجی زیر حاصل میشود:
+```The sum is: 6
+ Result: 1```
+
+ def bar(first, second, third, **options):
+ if options.get("action") == "sum":
+ print("The sum is: %d" %(first + second + third))
+
+ if options.get("number") == "first":
+ return first
+
+ result = bar(1, 2, 3, action = "sum", number = "first")
+ print("Result: %d" %(result))
+
+
+
+تابع "bar" سه آرگومان میگیرد. اگر آرگومان اضافی "action" دریافت شود و مقدار آن برای جمع زدن باشد، مجموع چاپ میشود. همچنین تابع میداند که اگر مقدار پارامتر `number` برابر "first" باشد آرگومان اول را بازگرداند.
+
+تمرین
+--------
+
+تابعهای `foo` و `bar` را تکمیل کنید تا بتوانند تعداد متغیر از آرگومانها را دریافت کنند (3 یا بیشتر)
+تابع `foo` باید تعداد آرگومانهای اضافی را برگرداند.
+تابع `bar` باید `True` را برگرداند اگر آرگومان کلیدی `magicnumber` برابر 7 باشد و در غیر این صورت `False`.
+
+Tutorial Code
+-------------
+
+# edit the functions prototype and implementation
+def foo(a, b, c):
+ pass
+
+def bar(a, b, c):
+ pass
+
+
+# test code
+if foo(1, 2, 3, 4) == 1:
+ print("Good.")
+if foo(1, 2, 3, 4, 5) == 2:
+ print("Better.")
+if bar(1, 2, 3, magicnumber=6) == False:
+ print("Great.")
+if bar(1, 2, 3, magicnumber=7) == True:
+ print("Awesome!")
+
+Expected Output
+---------------
+
+test_output_contains("Good.")
+test_output_contains("Better.")
+test_output_contains("Great.")
+test_output_contains("Awesome!")
+success_msg("Great work!")
+
+Solution
+--------
+# edit the functions prototype and implementation
+def foo(a, b, c, *args):
+ return len(args)
+
+def bar(a, b, c, **kwargs):
+ return kwargs["magicnumber"] == 7
+
+
+# test code
+if foo(1, 2, 3, 4) == 1:
+ print("Good.")
+if foo(1, 2, 3, 4, 5) == 2:
+ print("Better.")
+if bar(1, 2, 3, magicnumber=6) == False:
+ print("Great.")
+if bar(1, 2, 3, magicnumber=7) == True:
+ print("Awesome!")
diff --git a/tutorials/learnpython.org/fa/Parsing CSV Files.md b/tutorials/learnpython.org/fa/Parsing CSV Files.md
new file mode 100644
index 000000000..f1a16d6b5
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Parsing CSV Files.md
@@ -0,0 +1,199 @@
+آموزش
+--------
+
+### CSV چیست؟
+CSV مخفف 'Comma Separated Values' است. فرمت CSV رایجترین فرمت واردات و صادرات برای پایگاهدادهها و صفحات گسترده است. فایل CSV یک فایل متنی ساده است که لیستی از دادهها را در خود دارد. معمولاً از کاما (,) برای جداکردن دادهها استفاده میکنند، اما گاهی از کاراکترهای دیگر مثل سمیکالن یا تب هم استفاده میشود.
+
+نمونهٔ دادهٔ CSV:
+
+...
+column 1 name,column 2 name, column 3 name
+first row data 1,first row data 2,first row data 3
+second row data 1,second row data 2,second row data 3
+...
+
+### ماژول csv در پایتون
+گرچه پایتون تابع داخلی open() را برای کار با فایلهای CSV یا هر فایل متنی دیگر دارد، یک ماژول اختصاصی csv وجود دارد که کلاسهایی برای خواندن و نوشتن داده در قالب CSV پیادهسازی میکند و کار با CSV را بسیار آسانتر میسازد.
+
+### توابع مهم ماژول csv
+
+ csv.field_size_limit – بازگشت حداکثر اندازهٔ فیلد
+ csv.get_dialect – دریافت dialect مرتبط با نام
+ csv.list_dialects – لیست تمام dialectهای ثبتشده
+ csv.reader – خواندن داده از فایل csv
+ csv.register_dialect - ثبت dialect با نام
+ csv.writer – نوشتن داده به فایل csv
+ csv.unregister_dialect - حذف dialect مرتبط با نام از ثبت
+ csv.QUOTE_ALL - همه چیز را quote کن
+ csv.QUOTE_MINIMAL - فیلدهای خاص را quote کن
+ csv.QUOTE_NONNUMERIC - همه فیلدهایی که عدد نیستند را quote کن
+ csv.QUOTE_NONE – هیچ چیز را quote نکن
+
+### چگونه از ماژول csv استفاده کنیم؟
+اول ماژول csv را وارد کنید:
+
+ import csv
+
+توابع writer و reader به شما اجازه میدهند تا دادهها را ویرایش، تغییر و تبدیل کنید.
+
+نحوه خواندن فایل CSV :
+
+برای خواندن داده از فایل CSV از reader استفاده کنید تا یک خواننده (reader) تولید کند.
+
+مثال:
+
+ with open(filename, 'r') as csvfile:
+ csvreader = csv.reader(csvfile)
+
+ابتدا فایل CSV را در حالت خواندن باز میکنیم و آن را csvfile مینامیم. از context manager استفاده میکنیم تا نگران بستن فایل نباشیم. csv.reader یک شیء قابل تکرار برمیگرداند که آن را csvreader نامیدهایم.
+
+از آنجا که csvreader یک iterable است، میتوان با حلقه for آن را پیمایش کرد:
+
+مثال 1:
+
+ with open(filename, 'r') as csvfile:
+ csvreader = csv.reader(csvfile)
+ for row in csvreader:
+ print(row)
+
+در مثال بالا همه ردیفها چاپ میشوند. توجه کنید هنگام باز کردن فایل از حالت 'r' استفاده میکنیم.
+
+چه چیزی بعدی؟
+
+csvreader یک شیء iterable است؛ بنابراین متد .next() ردیف جاری را برمیگرداند و اشارهگر را به ردیف بعدی میبرد.
+
+مثال 2:
+
+ with open(filename, 'r') as csvfile:
+ csvreader = csv.reader(csvfile)
+ fields = csvreader.next()
+ for row in csvreader:
+ print(row)
+
+در مثال 2، .next() هدر را در fields میخواند و اشارهگر را جلو میبرد، بنابراین بقیهٔ ردیفها چاپ میشوند بدون هدر.
+
+نحوه نوشتن در فایل CSV -
+
+برای نوشتن از csv.writer استفاده کنید. فایل را در حالت نوشتن ('w') باز کنید و csv.writer را بسازید.
+
+مثال:
+ #declare header
+ fields = ['column1','column2', 'column3']
+
+ #declare rows
+ rows = [["foo", "bar", "spam"],
+ ["oof", "rab", "maps"],
+ ["writerow", "isn't", "writerows"]]
+
+ filename = "university_records.csv"
+
+ with open(filename, 'w') as csvfile:
+ csvwriter = csv.writer(csvfile)
+ csvwriter.writerow(fields)
+ csvwriter.writerows(rows)
+
+در مثال بالا writerow یک ردیف و writerows چند ردیف را مینویسد.
+
+برای خواندن یک فایل و نوشتن در فایل دیگر:
+
+ with open('newfilename.csv', 'w') as f2:
+ with open('mycsvfile.csv', mode='r') as f1:
+ reader = csv.reader(f1)
+ csvwriter = csv.writer(f2)
+ header = next(reader) # store the headers and advance reader pointer
+ csvwriter.writerow(header) #writes the header into new file
+ for row in reader:
+ csvwriter.writerow(row)
+
+در اینجا با استفاده از next() هدر را خوانده و سپس ردیفها را یکییکی در فایل جدید مینویسیم.
+
+### کلاسهای DictReader و DictWriter در پایتون
+
+دو کلاس مهم برای خواندن و نوشتن CSV وجود دارند: csv.DictReader و csv.DictWriter.
+
+DictReader:
+
+این کلاس شیئی ایجاد میکند که ردیفها را به دیکشنری نگاشت میکند که کلیدهای آن توسط پارامتر fieldnames تعیین میشوند. اگر fieldnames ارائه نشود، ردیف اول فایل بهعنوان کلیدها استفاده میشود.
+
+مثال csv (info.csv)
+
+.....
+firstname, lastname
+foo, bar
+foo1, bar1
+.....
+
+مثال:
+
+ import csv
+ with open('info.csv') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for row in reader:
+ print(row['firstname'], row['lastname'])
+
+DictWriter:
+
+csv.DictWriter همانند writer عمل میکند اما دیکشنریها را به ردیفهای CSV نگاشت میکند. پارامتر fieldnames ترتیب نوشتن مقادیر را مشخص میکند.
+
+مثال:
+
+ import csv
+ f = open('info.csv', 'w')
+ with f:
+
+ fnames = ['firstname', 'lastname']
+ writer = csv.DictWriter(f, fieldnames=fnames)
+
+ writer.writeheader()
+ writer.writerow({'firstname' : 'Rob', 'last_name': 'Scott'})
+ writer.writerow({'firstname' : 'Tom', 'last_name': 'Brown'})
+ writer.writerow({'firstname' : 'Henry', 'last_name': 'Smith'})
+
+
+تمرین
+--------
+
+در این تمرین با دادههای CSV کار خواهید کرد. هدف شما ایجاد برنامهای است که یک فایل CSV را بخواند و فقط ردیفهایی که مقدار ستون اول آنها بزرگتر از 50 است را در فایل خروجی بنویسد.
+
+Tutorial Code
+-------------
+
+ import csv
+
+ # Open the input CSV file
+ with open('inputfile.csv', mode='r') as infile:
+ reader = csv.reader(infile)
+ # Open the output CSV file
+ with open('outputfile.csv', mode='w') as outfile:
+ writer = csv.writer(outfile)
+ # Write header
+ header = next(reader)
+ writer.writerow(header)
+ # Write rows where the value in the first column is greater than 50
+ for row in reader:
+ if int(row[0]) > 50: # Assuming the first column contains numeric values
+ writer.writerow(row)
+
+خروجی مورد انتظار
+---------------
+
+ به دلیل محدودیتهای این محیط، این راهحل در اینجا قابل آزمون نیست چون نیاز به دسترسی به فایلهای خارجی دارد. اما انتظار میرود فایلی به نام `outputfile.csv` ایجاد شود که شامل همان ردیفهای فایل ورودی است، با این تفاوت که فقط ردیفهایی که مقدار ستون اول آنها بزرگتر از 50 است در آن قرار دارند.
+
+راهحل
+--------
+
+ import csv
+
+ # Open the input CSV file
+ with open('inputfile.csv', mode='r') as infile:
+ reader = csv.reader(infile)
+ # Open the output CSV file
+ with open('outputfile.csv', mode='w') as outfile:
+ writer = csv.writer(outfile)
+ # Write header
+ header = next(reader)
+ writer.writerow(header)
+ # Write rows where the value in the first column is greater than 50
+ for row in reader:
+ if int(row[0]) > 50: # Assuming the first column contains numeric values
+ writer.writerow(row)
\ No newline at end of file
diff --git a/tutorials/learnpython.org/fa/Partial functions.md b/tutorials/learnpython.org/fa/Partial functions.md
new file mode 100644
index 000000000..f0b21f86b
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Partial functions.md
@@ -0,0 +1,51 @@
+آموزش
+--------
+
+میتوانید با استفاده از تابع partial از ماژول functools در پایتون توابع جزئی (partial functions) بسازید.
+
+توابع جزئی اجازه میدهند تا تابعی با x پارامتر را به تابعی با پارامترهای کمتر و مقادیر ثابتشده برای پارامترهای اول تبدیل کنید.
+
+واردات مورد نیاز:
+
+ from functools import partial
+
+این کد مقدار 8 را برمیگرداند:
+
+ from functools import partial
+
+ def multiply(x, y):
+ return x * y
+
+ # create a new function that multiplies by 2
+ dbl = partial(multiply, 2)
+ print(dbl(4))
+
+یک نکته مهم: مقادیر پیشفرض از سمت چپ جایگزین متغیرها میشوند. مقدار 2 جایگزین x میشود. y برابر 4 خواهد بود زمانی که dbl(4) فراخوانی میشود. در این مثال فرق چندانی ایجاد نمیکند، ولی در مثال بعدی فرق خواهد داشت.
+
+تمرین
+--------
+تابع ارائهشده را با فراخوانی partial() و جایگزین کردن سه متغیر اول در func() ویرایش کنید. سپس با استفاده از تابع جزئی جدید و تنها یک ورودی چاپ کنید تا خروجی برابر 60 شود.
+
+
+Tutorial Code
+-------------
+#Following is the exercise, function provided:
+from functools import partial
+def func(u, v, w, x):
+ return u*4 + v*3 + w*2 + x
+#Enter your code here to create and print with your partial function
+
+Expected Output
+---------------
+#test_object('p')
+test_output_contains('60')
+success_msg('Good job!')
+
+Solution
+--------
+from functools import partial
+def func(u, v, w, x):
+ return u*4 + v*3 + w*2 + x
+
+p = partial(func,5,6,7)
+print(p(8))
diff --git a/tutorials/learnpython.org/fa/Regular Expressions.md b/tutorials/learnpython.org/fa/Regular Expressions.md
new file mode 100644
index 000000000..f4ad9d132
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Regular Expressions.md
@@ -0,0 +1,65 @@
+آموزش
+--------
+
+عبارات منظم (Regular Expressions) که گاهی regexp، regex یا re نامیده میشوند، ابزاری برای تطابق الگوها در متن هستند. در پایتون ماژول re در دسترس است.
+کاربردهای عبارات منظم گستردهاند اما پیچیده هم هستند، بنابراین قبل از استفاده از regex برای یک کار مشخص، جایگزینها را بررسی کنید و به عنوان آخرین راهحل به regexها فکر کنید.
+
+مثالی از یک regex: `r"^(From|To|Cc).*?python-list@python.org"` حالا توضیح:
+Caret `^` متن در ابتدای خط را مطابقت میدهد. گروه بعدی `(From|To|Cc)` به این معنی است که خط باید با یکی از کلمات داخل گروه شروع شود. این همان عملگر OR است. `.*?` به معنی مطابقت غیرحریصی (non-greedy) با صفر یا بیشمار کاراکتر غیر newline است. `.` هر کاراکتر غیر newline را نشان میدهد، `*` به معنی تکرار 0 یا بیشمار، و `?` حالت غیرحریصی را فعال میکند.
+
+بنابراین خطوط زیر توسط آن regex مطابقت خواهند داشت:
+`From: python-list@python.org`
+`To: !asp]<,. python-list@python.org`
+
+مراجع کامل نحو re در [مستندات پایتون](http://docs.python.org/library/re.html#regular-expression-syntax) موجود است.
+
+برای نمونه یک regex "درست" برای مطابقت ایمیل (مانند تمرین) این لینک را ببینید: http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html
+
+Tutorial Code
+-------------
+# Example:
+import re
+pattern = re.compile(r"\[(on|off)\]") # Slight optimization
+print(re.search(pattern, "Mono: Playback 65 [75%] [-16.50dB] [on]"))
+# Returns a Match object!
+print(re.search(pattern, "Nada...:-("))
+# Doesn't return anything.
+# End Example
+
+# Exercise: make a regular expression that will match an email
+def test_email(your_pattern):
+ pattern = re.compile(your_pattern)
+ emails = ["john@example.com", "python-list@python.org", "wha.t.`1an?ug{}ly@email.com"]
+ for email in emails:
+ if not re.match(pattern, email):
+ print("You failed to match %s" % (email))
+ elif not your_pattern:
+ print("Forgot to enter a pattern!")
+ else:
+ print("Pass")
+pattern = r"" # Your pattern here!
+test_email(pattern)
+
+
+Expected Output
+---------------
+test_output_contains("Pass")
+success_msg("Great work!")
+
+Solution
+--------
+# Exercise: make a regular expression that will match an email
+import re
+def test_email(your_pattern):
+ pattern = re.compile(your_pattern)
+ emails = ["john@example.com", "python-list@python.org", "wha.t.`1an?ug{}ly@email.com"]
+ for email in emails:
+ if not re.match(pattern, email):
+ print("You failed to match %s" % (email))
+ elif not your_pattern:
+ print("Forgot to enter a pattern!")
+ else:
+ print("Pass")
+# Your pattern here!
+pattern = r"\"?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)\"?"
+test_email(pattern)
diff --git a/tutorials/learnpython.org/fa/Serialization.md b/tutorials/learnpython.org/fa/Serialization.md
new file mode 100644
index 000000000..97c7178f8
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Serialization.md
@@ -0,0 +1,82 @@
+آموزش
+--------
+
+پایتون کتابخانههای JSON داخلی برای رمزگذاری و رمزگشایی JSON فراهم میکند.
+
+در پایتون 2.5 از ماژول simplejson استفاده میشد، در حالی که در پایتون 2.7 از ماژول json استفاده میشود. از آنجا که این مفسر از پایتون 2.7 استفاده میکند، ما از json استفاده خواهیم کرد.
+
+برای استفاده از ماژول json ابتدا باید آن را وارد کنید:
+
+ import json
+
+دو قالب پایه برای دادههای JSON وجود دارد: رشته (string) یا ساختار دادهای (object datastructure). ساختار دادهای در پایتون شامل لیستها و دیکشنریهای تو در تو است. با استفاده از ساختار دادهای میتوان با متدهای پایتون روی دادهها کارهایی مثل اضافه کردن، فهرستبرداری، جستجو و حذف انجام داد. فرمت رشته معمولاً برای ارسال داده به برنامهٔ دیگر یا بارگذاری در ساختار دادهای استفاده میشود.
+
+برای بارگذاری JSON به ساختار داده از متد "loads" استفاده کنید. این متد یک رشته میگیرد و آن را به ساختار دادهٔ JSON تبدیل میکند:
+
+ import json
+ print(json.loads(json_string))
+
+برای تبدیل یک ساختار داده به JSON از متد "dumps" استفاده کنید. این متد یک شیء میگیرد و یک رشته برمیگرداند:
+
+ import json
+ json_string = json.dumps([1, 2, 3, "a", "b", "c"])
+ print(json_string)
+
+پایتون از روش سریالسازی اختصاصی خود به نام pickle (و جایگزین سریعتر cPickle) نیز پشتیبانی میکند.
+
+میتوانید از آن به همان شکل استفاده کنید.
+
+ import pickle
+ pickled_string = pickle.dumps([1, 2, 3, "a", "b", "c"])
+ print(pickle.loads(pickled_string))
+
+هدف این تمرین اضافه کردن جفت کلید-مقدار `"Me" : 800` به رشتهٔ JSON داده شده و چاپ آن است.
+
+Tutorial Code
+-------------
+
+import json
+
+# fix this function, so it adds the given name
+# and salary pair to salaries_json, and return it
+def add_employee(salaries_json, name, salary):
+ # Add your code here
+
+ return salaries_json
+
+# test code
+salaries = '{"Alfred" : 300, "Jane" : 400 }'
+new_salaries = add_employee(salaries, "Me", 800)
+decoded_salaries = json.loads(new_salaries)
+print(decoded_salaries["Alfred"])
+print(decoded_salaries["Jane"])
+print(decoded_salaries["Me"])
+
+Expected Output
+---------------
+
+test_output_contains("300")
+test_output_contains("400")
+test_output_contains("800")
+success_msg("Great work!")
+
+Solution
+--------
+
+import json
+
+# fix this function, so it adds the given name
+# and salary pair to salaries_json, and return it
+def add_employee(salaries_json, name, salary):
+ salaries = json.loads(salaries_json)
+ salaries[name] = salary
+
+ return json.dumps(salaries)
+
+# test code
+salaries = '{"Alfred" : 300, "Jane" : 400 }'
+new_salaries = add_employee(salaries, "Me", 800)
+decoded_salaries = json.loads(new_salaries)
+print(decoded_salaries["Alfred"])
+print(decoded_salaries["Jane"])
+print(decoded_salaries["Me"])
diff --git a/tutorials/learnpython.org/fa/Sets.md b/tutorials/learnpython.org/fa/Sets.md
new file mode 100644
index 000000000..87b311795
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Sets.md
@@ -0,0 +1,68 @@
+آموزش
+--------
+
+مجموعهها (Sets) لیستهایی بدون ورودی تکراری هستند. فرض کنید میخواهید لیستی از کلمات بهکاررفته در یک پاراگراف جمعآوری کنید:
+
+ print(set("my name is Eric and Eric is my name".split()))
+
+این مجموعه لیستی شامل "my", "name", "is", "Eric", و "and" را چاپ میکند. از آنجا که بقیهٔ جمله شامل کلماتی است که قبلاً در مجموعه وجود دارند، دوباره اضافه نمیشوند.
+
+مجموعهها ابزار قدرتمندی هستند زیرا میتوانند تفاوتها و اشتراکها را بین مجموعههای دیگر محاسبه کنند. برای مثال، فرض کنید لیست شرکتکنندگان در رویدادهای A و B را دارید:
+
+ a = set(["Jake", "John", "Eric"])
+ print(a)
+ b = set(["John", "Jill"])
+ print(b)
+
+برای یافتن اعضایی که در هر دو رویداد شرکت کردهاند، میتوانید از متد "intersection" استفاده کنید:
+
+ a = set(["Jake", "John", "Eric"])
+ b = set(["John", "Jill"])
+
+ print(a.intersection(b))
+ print(b.intersection(a))
+
+برای یافتن اعضایی که فقط در یکی از رویدادها شرکت کردهاند از "symmetric_difference" استفاده کنید:
+
+ a = set(["Jake", "John", "Eric"])
+ b = set(["John", "Jill"])
+
+ print(a.symmetric_difference(b))
+ print(b.symmetric_difference(a))
+
+برای یافتن اعضایی که فقط در یک رویداد و نه دیگری شرکت کردهاند از متد "difference" استفاده کنید:
+
+ a = set(["Jake", "John", "Eric"])
+ b = set(["John", "Jill"])
+
+ print(a.difference(b))
+ print(b.difference(a))
+
+برای دریافت لیست تمام شرکتکنندگان از متد "union" استفاده کنید:
+
+ a = set(["Jake", "John", "Eric"])
+ b = set(["John", "Jill"])
+
+ print(a.union(b))
+
+در تمرین زیر، با استفاده از لیستهای دادهشده، مجموعهای از تمام شرکتکنندگانی که در رویداد A حضور داشتند اما در رویداد B شرکت نکردهاند را چاپ کنید.
+
+Tutorial Code
+-------------
+a = ["Jake", "John", "Eric"]
+b = ["John", "Jill"]
+
+Expected Output
+---------------
+test_output_contains("['Jake', 'Eric']")
+success_msg("Nice work!")
+
+Solution
+--------
+a = ["Jake", "John", "Eric"]
+b = ["John", "Jill"]
+
+A = set(a)
+B = set(b)
+
+print(A.difference(B))
diff --git a/tutorials/learnpython.org/fa/String Formatting.md b/tutorials/learnpython.org/fa/String Formatting.md
new file mode 100644
index 000000000..801671036
--- /dev/null
+++ b/tutorials/learnpython.org/fa/String Formatting.md
@@ -0,0 +1,65 @@
+آموزش
+--------
+
+پایتون از قالببندی رشته به سبک C برای ساخت رشتههای قالببندیشده استفاده میکند. عملگر "%" برای قالببندی مجموعهای از متغیرها که در یک "tuple" قرار دارند، همراه با یک رشتهٔ قالب استفاده میشود. رشتهٔ قالب شامل متن معمولی و "مشخصکنندههای آرگومان" است، نمادهایی مثل "%s" و "%d".
+
+فرض کنید متغیری به نام "name" دارید که نام کاربری شما در آن است و میخواهید پیغامی برای آن چاپ کنید.
+
+ # This prints out "Hello, John!"
+ name = "John"
+ print("Hello, %s!" % name)
+
+برای استفاده از دو یا چند مشخصکنندهٔ آرگومان از یک tuple (پرانتز) استفاده کنید:
+
+ # This prints out "John is 23 years old."
+ name = "John"
+ age = 23
+ print("%s is %d years old." % (name, age))
+
+هر شیئی که رشته نیست نیز میتواند با `%s` قالببندی شود؛ رشتهٔ برگشتی از متد `repr` آن شیء استفاده میشود. برای مثال:
+
+ # This prints out: A list: [1, 2, 3]
+ mylist = [1,2,3]
+ print("A list: %s" % mylist)
+
+در اینجا چند مشخصکنندهٔ پایهای که باید بدانید آمده است:
+
+
+`%s - رشته (یا هر شیئی با نمایش رشتهای)`
+
+`%d - اعداد صحیح`
+
+`%f - اعداد اعشاری`
+
+`%.<تعداد رقها>f - اعداد اعشاری با تعداد ثابت ارقام اعشار.`
+
+`%x/%X - اعداد صحیح در مبنای هگز (حروف کوچک/بزرگ)`
+
+
+تمرین
+--------
+
+شما باید یک رشتهٔ قالب بنویسید که دادهها را به شکل زیر چاپ کند:
+ `Hello John Doe. Your current balance is $53.44.`
+
+Tutorial Code
+-------------
+
+data = ("John", "Doe", 53.44)
+format_string = "Hello"
+
+print(format_string % data)
+
+Expected Output
+---------------
+#test_output_contains("Hello John Doe. Your current balance is $53.44.", no_output_msg= "Make sure you add the `%s` in the correct spaces to the `format_string` to meeet the exercise goals!")
+test_object('format_string')
+success_msg('Great work!')
+
+Solution
+--------
+
+data = ("John", "Doe", 53.44)
+format_string = "Hello %s %s. Your current balance is $%s."
+
+print(format_string % data)
diff --git a/tutorials/learnpython.org/fa/Variables and Types.md b/tutorials/learnpython.org/fa/Variables and Types.md
new file mode 100644
index 000000000..c344c43f2
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Variables and Types.md
@@ -0,0 +1,111 @@
+آموزش
+--------
+
+پایتون کاملاً شیءگرا است و بهصورت "نوعبندی ایستا" نیست. نیازی به اعلام متغیرها قبل از استفاده یا مشخص کردن نوع آنها ندارید. هر متغیری در پایتون یک شیء است.
+
+این آموزش چند نوع پایهای از متغیرها را مرور میکند.
+
+### اعداد
+پایتون از دو نوع عدد پشتیبانی میکند — اعداد صحیح (integers) و اعداد اعشاری (floating point). (همچنین اعداد مختلط پشتیبانی میشوند که در این آموزش بررسی نمیشوند).
+
+برای تعریف یک عدد صحیح از نحو زیر استفاده کنید:
+
+ myint = 7
+ print(myint)
+
+برای تعریف یک عدد اعشاری میتوانید از یکی از نگارشهای زیر استفاده کنید:
+
+ myfloat = 7.0
+ print(myfloat)
+ myfloat = float(7)
+ print(myfloat)
+
+### رشتهها (Strings)
+
+رشتهها را میتوان با تکنقل یا دوتانقل تعریف کرد.
+
+ mystring = 'hello'
+ print(mystring)
+ mystring = "hello"
+ print(mystring)
+
+تفاوت این دو این است که استفاده از دوتانقل گذاشتن آپاستروف را آسان میکند (در حالی که با تکنقل رشته قطع میشود).
+
+ mystring = "Don't worry about apostrophes"
+ print(mystring)
+
+روشهای دیگری برای تعریف رشته وجود دارد که درج newline، backslash و کاراکترهای یونیکد را آسانتر میکنند. این موارد خارج از محدوده این آموزش است اما در مستندات پایتون پوشش داده شدهاند.
+
+روی اعداد و رشتهها میتوان عملیات ساده انجام داد:
+
+ one = 1
+ two = 2
+ three = one + two
+ print(three)
+
+ hello = "hello"
+ world = "world"
+ helloworld = hello + " " + world
+ print(helloworld)
+
+میتوان چند متغیر را همزمان در یک خط مقداردهی کرد:
+
+ a, b = 3, 4
+ print(a, b)
+
+ترکیب عملیات روی اعداد و رشتهها پشتیبانی نمیشود:
+
+ # This will not work!
+ one = 1
+ two = 2
+ hello = "hello"
+
+ print(one + two + hello)
+
+
+تمرین
+--------
+
+هدف این تمرین ایجاد یک رشته، یک عدد صحیح و یک عدد اعشاری است. رشته باید با نام `mystring` و مقدار "hello" باشد. عدد اعشاری باید `myfloat` و مقدار 10.0 باشد، و عدد صحیح باید `myint` و مقدار 20 باشد.
+
+Tutorial Code
+-------------
+# change this code
+mystring = None
+myfloat = None
+myint = None
+
+# testing code
+if mystring == "hello":
+ print("String: %s" % mystring)
+if isinstance(myfloat, float) and myfloat == 10.0:
+ print("Float: %f" % myfloat)
+if isinstance(myint, int) and myint == 20:
+ print("Integer: %d" % myint)
+
+Expected Output
+---------------
+
+test_object('mystring', incorrect_msg="Don't forget to change `mystring` to the correct value from the exercise description.")
+test_object('myfloat', incorrect_msg="Don't forget to change `myfloat` to the correct value from the exercise description.")
+test_object('myint', incorrect_msg="Don't forget to change `myint` to the correct value from the exercise description.")
+test_output_contains("String: hello",no_output_msg= "Make sure your string matches exactly to the exercise desciption.")
+test_output_contains("Float: 10.000000",no_output_msg= "Make sure your float matches exactly to the exercise desciption.")
+test_output_contains("Integer: 20",no_output_msg= "Make sure your integer matches exactly to the exercise desciption.")
+success_msg("Great job!")
+
+Solution
+--------
+
+# change this code
+mystring = "hello"
+myfloat = 10.0
+myint = 20
+
+# testing code
+if mystring == "hello":
+ print("String: %s" % mystring)
+if isinstance(myfloat, float) and myfloat == 10.0:
+ print("Float: %f" % myfloat)
+if isinstance(myint, int) and myint == 20:
+ print("Integer: %d" % myint)
diff --git a/tutorials/learnpython.org/fa/Welcome.md b/tutorials/learnpython.org/fa/Welcome.md
new file mode 100644
index 000000000..2c0ce46c7
--- /dev/null
+++ b/tutorials/learnpython.org/fa/Welcome.md
@@ -0,0 +1,65 @@
+# خوشآمد
+
+به آموزش تعاملی پایتون در LearnPython.org خوش آمدید.
+
+چه برنامهنویس باتجربهای باشید و چه نه، این وبسایت برای همه کسانی که میخواهند زبان برنامهنویسی پایتون را بیاموزند مناسب است.
+
+شما میتوانید برای پرسشها، بحثها و دریافت بهروزرسانیها به گروه ما در فیسبوک بپیوندید.
+
+پس از اتمام آموزشها، میتوانید در [LearnX](https://www.learnx.org) گواهی دریافت کرده و آن را در پروفایل لینکدین خود اضافه کنید.
+
+فقط روی بخش (chapter) که میخواهید از آن شروع کنید کلیک کنید و دستورالعملها را دنبال کنید. موفق باشید!
+
+
+### یادگیری مباحث پایه
+
+- [[سلام، جهان!]]
+- [[متغیرها و انواع]]
+- [[لیستها]]
+- [[عملیات پایه]]
+- [[قالبدهی رشتهها]]
+- [[عملیات پایه رشتهها]]
+- [[شرطها]]
+- [[حلقهها]]
+- [[توابع]]
+- [[کلاسها و اشتیاء]]
+- [[دیکشنریها]]
+- [[ماژولها و بستهها]]
+- [[ورودی و خروجی]]
+
+
+### آموزشهای مخصوص کودکان
+- [شروع](https://codingforkids.io/play/python/intro-level1)
+- [حرکت با توابع](https://codingforkids.io/play/python/intro-level2)
+- [جمعآوری آیتمها](https://codingforkids.io/play/python/intro-level3)
+- [هل دادن اشیاء](https://codingforkids.io/play/python/intro-level4)
+- [چاپ روی صفحه](https://codingforkids.io/play/python/intro-level5)
+- [ساخت اشیاء](https://codingforkids.io/play/python/intro-level6)
+- [اعمال آنچه آموختهاید](https://codingforkids.io/play/python/intro-level7)
+
+
+### آموزشهای پیشرفته
+
+- [[Generators]]
+- [[List Comprehensions]]
+- [[Lambda functions]]
+- [[Multiple Function Arguments]]
+- [[Regular Expressions]]
+- [[Exception Handling]]
+- [[Sets]]
+- [[Serialization]]
+- [[Partial functions]]
+- [[Code Introspection]]
+- [[Closures]]
+- [[Decorators]]
+- [[Map, Filter, Reduce]]
+- [[Parsing CSV Files]]
+
+### سایر آموزشهای پایتون
+
+- [DataCamp](https://datacamp.pxf.io/c/67577/1012793/13294?sharedId=learnpython.org) دارای مجموعهای از آموزشهای تعاملی عالی در زمینه دستکاری داده، مصورسازی، آمار، یادگیری ماشین و غیره است.
+- دوره [Python Tutorials and References](http://www.afterhoursprogramming.com/index.php?article=181) از After Hours Programming را بخوانید.
+
+### کمک به توسعه آموزشها
+
+جزئیات بیشتر: [[Contributing Tutorials]]
diff --git a/tutorials/learnpython.org/fa/index.json b/tutorials/learnpython.org/fa/index.json
new file mode 100644
index 000000000..28a3ae2d7
--- /dev/null
+++ b/tutorials/learnpython.org/fa/index.json
@@ -0,0 +1,45 @@
+{
+ "basics": {
+ "Hello, World!": "سلام، دنیا!",
+ "Variables and Types": "متغیرها و نوعها",
+ "Lists": "لیستها",
+ "Basic Operators": "عملگرهای پایه",
+ "String Formatting": "قالببندی رشته",
+ "Basic String Operations": "عملیات متنی پایه",
+ "Conditions": "شرایط",
+ "Loops": "حلقهها",
+ "Functions": "توابع",
+ "Classes and Objects": "کلاسها و شیءها",
+ "Dictionaries": "دیکشنریها",
+ "Modules and Packages": "ماژولها و بستهها",
+ "Input and Output": "ورودی و خروجی"
+ },
+ "coding-for-kids": {
+ "Starting Out": "شروع",
+ "Movement with Functions": "حرکت با توابع",
+ "Collecting items": "جمعآوری آیتمها",
+ "Pushing objects": "هل دادن اشیاء",
+ "Printing on screen": "چاپ روی صفحه",
+ "Building objects": "ساخت اشیاء",
+ "Apply what you've learned": "اعمال آنچه آموختهاید"
+ },
+ "advanced": {
+ "Generators": "ژنراتورها",
+ "List Comprehensions": "لیست کامپرهنشن",
+ "Lambda functions": "توابع lambda",
+ "Multiple Function Arguments": "آرگومانهای چندگانه تابع",
+ "Regular Expressions": "عبارات منظم",
+ "Exception Handling": "مدیریت استثنا",
+ "Sets": "مجموعهها",
+ "Serialization": "سریالسازی",
+ "Partial functions": "توابع جزئی",
+ "Code Introspection": "بازبینی کد",
+ "Closures": "closureها",
+ "Decorators": "دکوراتورها",
+ "Map, Filter, Reduce": "Map، Filter، Reduce",
+ "Parsing CSV Files": "تحلیل فایلهای CSV"
+ },
+ "other-tutorials": {
+ "DataCamp": "DataCamp"
+ }
+}
\ No newline at end of file
diff --git a/tutorials/learnrubyonline.org/fa/Arrays.md b/tutorials/learnrubyonline.org/fa/Arrays.md
new file mode 100644
index 000000000..b93b8b2ed
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Arrays.md
@@ -0,0 +1,32 @@
+آموزش
+--------
+
+آرایهها به شما امکان میدهند چند مقدار را در یک لیست گروهبندی کنید. هر مقدار در یک آرایه «عنصر» نامیده میشود.
+
+کد زیر نشان میدهد چگونه آرایهها را ایجاد کنید:
+
+ myArray = [] # an empty array
+ myOtherArray = [1, 2, 3] # an array with three elements
+
+عناصر از عدد صفر شمارهگذاری میشوند و میتوان به آنها از طریق شماره دسترسی پیدا کرد. `myOtherArray[1]` نحوه دسترسی به عنصر دوم در یک آرایه است.
+
+برای افزودن یا تغییر عناصر در یک آرایه، میتوانید به عنصر مورد نظر با شماره مراجعه کنید.
+
+ myOtherArray[3] = 4
+
+تمرین
+--------
+با استفاده از کد دادهشده، ```print``` مقدار "Me!" را در کنسول چاپ کنید.
+
+کد آموزشی
+-------------
+myArray = ["Not me!", "Not me!", "Me!", "Not me!"]
+
+خروجی مورد انتظار
+---------------
+Me!
+
+راه حل
+--------
+myArray = ["Not me!", "Not me!", "Me!", "Not me!"]
+print myArray[2]
diff --git a/tutorials/learnrubyonline.org/fa/Comments.md b/tutorials/learnrubyonline.org/fa/Comments.md
new file mode 100644
index 000000000..2286401a7
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Comments.md
@@ -0,0 +1,47 @@
+آموزش
+--------
+
+هنگامی که شروع به نوشتن برنامههای پیچیدهتر میکنید، استفاده از نظرات ضروری میشود. نظرات به شما امکان میدهند توضیحاتی برای کدتان اضافه کنید، تا سایر توسعهدهندگان (و خود شما) همیشه بتوانند متوجه شوند که یک بخش خاص از کد برای چه کاری است. روش خوبی این است که کد خود را به طور گسترده مورد نظر قرار دهید.
+
+دو نوع نظر وجود دارد: نظرات چند خطی و نظرات تک خطی. نظرات تک خطی با `#` شروع میشوند و نظرات چند خطی با `=begin` شروع و با `=end` پایان مییابند.
+
+ =begin
+ I'm a comment!
+ =end
+
+نظرات تک خطی میتواند بعد از چیز دیگری در همان خط شروع شود.
+
+ puts "Hi!" #I'm a comment, but Hi! will still be printed to the console.
+
+تمرین
+--------
+با استفاده از هر روشی که ترجیح میدهید، همه چیز را نظر کنید به جز "Don't comment me out!" که همچنان باید چاپ شود.
+
+کد آموزشی
+-------------
+puts "Hi!"
+puts "Hi!"
+puts "Hi!"
+puts "Hi!"
+puts "Don't comment me out!"
+puts "Hi!"
+puts "Hi!"
+
+خروجی مورد انتظار
+---------------
+Don't comment me out!
+
+راهحل
+--------
+
+=begin
+puts "Hi!"
+puts "Hi!"
+puts "Hi!"
+puts "Hi!"
+=end
+puts "Don't comment me out!"
+=begin
+puts "Hi!"
+puts "Hi!"
+=end
diff --git a/tutorials/learnrubyonline.org/fa/Conditional Statements.md b/tutorials/learnrubyonline.org/fa/Conditional Statements.md
new file mode 100644
index 000000000..5cebac35c
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Conditional Statements.md
@@ -0,0 +1,85 @@
+آموزش
+--------
+
+شرطها برای اضافه کردن منطق انشعاب به برنامههای شما استفاده میشوند؛ آنها به شما اجازه میدهند رفتاری پیچیده را اضافه کنید که تنها در شرایط خاص اتفاق میافتد.
+
+در اینجا ساختار دستور `if` آمده است:
+
+ if condition
+ something to be done
+ end
+
+`condition` یک عبارتی است که میتواند برای درست بودن بررسی شود. اگر عبارت به `true` ارزیابی شود، کد درون بلوک اجرا میشود.
+
+در اینجا نمونههایی از عباراتای آمدهاند که به `true` ارزیابی میشوند:
+
+ 3 < 4
+ true
+ "cat" == "cat"
+
+میتوانید `if` را با کلیدواژه `else` ترکیب کنید. این به شما اجازه میدهد یک بلوک کد را در صورت درست بودن شرط اجرا کنید، و یک بلوک متفاوت را در صورت غلط بودن آن.
+
+ if condition
+ something to be done
+ else
+ something to be done if the condition evaluates to false
+ end
+
+بلوک `else` تنها در صورتی اجرا میشود که بلوک `if` اجرا نشود، بنابراین هرگز هر دو اجرا نخواهند شد.
+
+هنگامی که بیش از دو گزینه میخواهید، میتوانید از `elsif` استفاده کنید. این به شما اجازه میدهد شرایط بیشتری را برای بررسی اضافه کنید.
+
+در اینجا نحو دستور if/elsif/else آمده است:
+
+ if condition
+ something to be done
+ elsif different condition
+ something else to be done
+ else
+ another different thing to be done
+ end
+
+هنوز تنها یکی از بلوکهای کد اجرا خواهد شد، زیرا دستور تنها کد را در اولین بلوک قابل اجرا اجرا میکند؛ پس از رضایت یک شرط، کل دستور پایان مییابد.
+
+در زیر مثالی واقعی از دستور `if` با هم `elsif` و `else` آمده است.
+
+ booleanOne = true
+ randomCode = "Hi!"
+ if booleanOne
+ puts "I will be printed!"
+ elsif randomCode.length>=1
+ puts "Even though the above code is true, I won't be executed because the earlier if statement was true!"
+ else
+ puts "I won't be printed because the if statement was executed!"
+ end
+
+تمرین
+--------
+مقدار language را تغییر دهید تا دستور elsif تنها بلوکی باشد که اجرا میشود.
+
+کد آموزشی
+-------------
+language = "English"
+if language === "English"
+ puts "Hello!"
+elsif language === "Spanish"
+ puts "Hola!"
+else
+ puts "I don't know that language!"
+end
+
+خروجی مورد انتظار
+---------------
+Hola!
+
+راهحل
+--------
+
+language = "Spanish"
+if language === "English"
+ puts "Hello!"
+elsif language === "Spanish"
+ puts "Hola!"
+else
+ puts "I don't know that language!"
+end
diff --git a/tutorials/learnrubyonline.org/fa/Hashes and Symbols.md b/tutorials/learnrubyonline.org/fa/Hashes and Symbols.md
new file mode 100644
index 000000000..2da935315
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Hashes and Symbols.md
@@ -0,0 +1,65 @@
+آموزش
+--------
+
+درست مثل آرایهها، هشها به شما امکان میدهند چندین مقدار را با هم ذخیره کنید. با این حال، در حالی که آرایهها مقادیر را با یک شاخص عددی ذخیره میکنند، هشها اطلاعات را با استفاده از جفت کلید-مقدار ذخیره میکنند. هر بخش از اطلاعات در هش دارای یک برچسب منحصر به فرد است، و شما میتوانید از آن برچسب برای دسترسی به مقدار استفاده کنید.
+
+برای ایجاد یک هش، از `Hash.new` یا `myHash={}` استفاده کنید. برای مثال:
+
+ myHash={
+ "Key" => "value",
+ "Key2" => "value2"
+ }
+
+این یک هش با دو مقدار ایجاد میکند، که هر یک با یک کلید شاخصدار شده است. شما میتوانید یک مقدار را به این صورت دسترسی کنید:
+
+ puts myHash["Key"] # puts value
+
+روش دیگر ایجاد یک هش به شرح زیر است:
+
+ myHash=Hash.new()
+ myHash["Key"]="value"
+ myHash["Key2"]="value2"
+
+به جای استفاده از یک رشته به عنوان کلید، شما همچنین میتوانید از یک نماد (symbol) استفاده کنید، مثل این:
+
+ myHash=Hash.new()
+ myHash[:Key]="value"
+ myHash[:Key2]="value2"
+
+شما میتوانید یک مقدار که با یک نماد کلیدی شده است را به همان روش دسترسی کنید.
+
+ puts myHash[:Key] # puts "value"
+
+هنگام استفاده از `myHash={}` با نمادها، نمادها به طور متفاوتی استفاده میشوند، مثل این
+
+ myHash={
+ Key: "value",
+ Key2: "value2",
+ }
+ puts myHash[:Key] # puts "value"
+
+تمرین
+--------
+
+یک هش به نام `myFirstHash` ایجاد کنید و اولین کلید را `Dad` برابر با `Dave` قرار دهید.
+
+کد آموزش
+-------------
+
+ #Make your hash below
+
+
+ puts myFirstHash["Dad"]
+
+خروجی مورد انتظار
+---------------
+Dave
+
+حل
+--------
+
+ #Make your hash below
+ myFirstHash={
+ "Dad" => "Dave",
+ }
+ puts myFirstHash["Dad"]
diff --git a/tutorials/learnrubyonline.org/fa/Hello World.md b/tutorials/learnrubyonline.org/fa/Hello World.md
new file mode 100644
index 000000000..3f30b778d
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Hello World.md
@@ -0,0 +1,42 @@
+آموزش
+--------
+
+یکی از ابتداییترین کارهای هر زبان برنامهنویسی، نمایش اطلاعات به کاربر است. برای چاپ چیزی در کنسول تا کاربر بتواند آن را ببیند، از `puts` استفاده کنید.
+
+ puts "I will be printed to the console!"
+
+همه چیزی بین علامتهای نقلقول به کنسول چاپ خواهد شد.
+
+میتوانید از علامتهای نقلقول تک (`'`) یا دوتایی (`"`) با `puts` استفاده کنید، تا زمانی که سازگار باشند.
+
+به جای نوشتن `puts`، میتوانید از فرم کوتاهتر، `p` استفاده کنید.
+
+ p 'Hello world'
+
+همچنین میتوانید از `print` برای نمایش اطلاعات استفاده کنید. تفاوت بین `puts` و `print` این است که هنگام استفاده از کلیدواژه `puts`، Ruby یک خط جدید ('\n') در انتها اضافه میکند. Ruby این کار را با `print` انجام نمیدهد.
+
+ puts 'Hello World !!!'
+ Hello World !!!
+ => nil
+
+ print 'Hello World !!!'
+ Hello World !!!=> nil
+
+تمرین
+--------
+
+رشته "Hello, World!" را با استفاده از puts به کنسول چاپ کنید.
+
+کد آموزش
+-------------
+ #Fix This!
+ puts 'Goodbye, World!'
+
+خروجی مورد انتظار
+---------------
+Hello, World!
+
+راهحل
+--------
+ #Fix This!
+ puts 'Hello, World!'
diff --git a/tutorials/learnrubyonline.org/fa/Math.md b/tutorials/learnrubyonline.org/fa/Math.md
new file mode 100644
index 000000000..674a1446e
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Math.md
@@ -0,0 +1,56 @@
+آموزش
+-----
+شما میتوانید از Ruby برای انجام محاسبات ریاضی استفاده کنید. چهار عملگر استاندارد احتمالاً برای شما آشنا هستند:
+
+- `+` برای جمع
+- `-` برای تفریق
+- `*` برای ضرب
+- `/` برای تقسیم
+
+دو عملگر دیگر که کمتر آشنا هستند اما مهم میباشند `**` و `%` هستند.
+
+`**` برای توان استفاده میشود؛ `5**2` یعنی 5 به توان 2، که برابر 25 است.
+
+`%` کمی عجیب است. در Ruby، این درصد نیست، بلکه باقیمانده است. باقیمانده مانند تقسیم است، اما فقط باقیمانده مسئله تقسیم را به شما میدهد.
+
+ moduloAnswer=5%2 #moduloAnswer=1
+ exponentAnswer=2**3 #exponentAnswer=8
+
+تمرین
+-----
+از عملیات ریاضی استفاده کنید تا متغیرهای قدیمی را به متغیرهای جدیدی تبدیل کنید که دستور if میتواند true را در کنسول چاپ کند.
+
+کد آموزشی
+----------
+numberOne = 6
+numberTwo = 8
+numberThree = 5
+numberFour = 12
+numberFive = 36
+
+testOne = numberTwo numberThree #جای خالی را پر کنید تا این عدد 40 شود
+testTwo = numberFive numberOne #جای خالی را پر کنید تا این عدد 0 شود
+testThree = numberFour numberThree #جای خالی را پر کنید تا این عدد 7 شود
+if testOne == 40 && testTwo == 0 && testThree == 7
+ puts true
+end
+
+خروجی مورد انتظار
+------------------
+true
+
+راهحل
+------
+
+numberOne = 6
+numberTwo = 8
+numberThree = 5
+numberFour = 12
+numberFive = 36
+
+testOne = numberTwo * numberThree #جای خالی را پر کنید تا این عدد 40 شود
+testTwo = numberFive % numberOne #جای خالی را پر کنید تا این عدد 0 شود
+testThree = numberFour - numberThree #جای خالی را پر کنید تا این عدد 7 شود
+if testOne == 40 && testTwo == 0 && testThree == 7
+ puts true
+end
diff --git a/tutorials/learnrubyonline.org/fa/Methods With Parameters.md b/tutorials/learnrubyonline.org/fa/Methods With Parameters.md
new file mode 100644
index 000000000..f77edd1a3
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Methods With Parameters.md
@@ -0,0 +1,39 @@
+آموزش
+--------
+برای گسترش عملکرد متدهای خود، میتوانیم آنها را با پارامترها تعریف کنیم و آرگومانهای مختلفی به آنها بدهیم. پارامترها نامهای جایگزینی هستند که بین پرانتزهای متد در زمان تعریف قرار میدهیم و آرگومانها قطعات کدی هستند که در زمان فراخوانی متد بین پرانتزها قرار میدهیم. این مثال را ببینید:
+
+ def clap_hands(number)
+ puts "Clap " * number
+ end
+
+در این مثال، `number` را به عنوان یک پارامتر منتقل میکنیم. سپس در داخل متد، رشته "Clap " را به کنسول `puts` میکنیم تعداد `number` بار.
+
+درست مانند متدهایی که پارامتر ندارند، برای اجرای متد باید آن را فراخوانی کنیم. پس در این مثال متد `clap_hands` را اینگونه فراخوانی میکنیم:
+
+ clap_hands(3)
+
+این عمل رشته "Clap " را سه بار به کنسول `puts` میکند. مقدار `3` همان آرگومانی است که به متد میدهیم.
+
+تمرین
+--------
+با استفاده از کد ارائهشده، یک متد به نام `square` ایجاد کنید که یک پارامتر `number` را دریافت کند و سپس نتیجه مربع عدد منتقلشده را `puts` کند. برای پاس کردن تست، عدد `2` را مربع کنید. فراموش نکنید که متد را فراخوانی کنید!
+
+کد آموزشی
+-------------
+ #define the method here
+ def
+ end
+
+ #don't forget to call the method with the argument
+
+خروجی مورد انتظار
+---------------
+4
+
+حل
+--------
+def square(number)
+ puts number ** 2
+end
+
+square(2)
\ No newline at end of file
diff --git a/tutorials/learnrubyonline.org/fa/Methods.md b/tutorials/learnrubyonline.org/fa/Methods.md
new file mode 100644
index 000000000..673d50f38
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Methods.md
@@ -0,0 +1,34 @@
+آموزش
+--------
+متدها بخشهای قابل استفاده مجدد از کد هستند که وظایف خاصی را در برنامه ما انجام میدهند. استفاده از متدها به این معنی است که میتوانیم کد سادهتر و خواناتر بنویسیم.
+
+در روبی، متدها به این شکل هستند:
+
+ def methodname
+ # method code here
+ end
+
+کلیدواژه `def` شروع سرصحافه متد است. این شامل نام متد و همچنین هر پارامتری است که متد میتواند دریافت کند (اگر بخواهیم). بدنه متد شامل کدی است که میخواهیم متد آن را انجام دهد. متد با کلیدواژه `end` پایان مییابد.
+
+اکنون که یک متد را تعریف کردیم، برای انجام وظیفهاش باید آن را فراخوانی کنیم. برای فراخوانی یک متد تعریفشده، ما به سادگی نام متد را در برنامهمان تایپ میکنیم. برای مثال، تایپ کردن `methodname` متد ما را فراخوانی خواهد کرد.
+
+تمرین
+--------
+با استفاده از کد ارائهشده، یک متد به نام `say_hi` ایجاد کنید که `puts` "Hi!" را در کنسول چاپ کند. (فراموش نکنید آن را فراخوانی کنید!)
+
+کد آموزشی
+-------------
+def
+end
+
+خروجی مورد انتظار
+---------------
+Hi!
+
+راهحل
+--------
+def say_hi
+ puts "Hi!"
+end
+
+say_hi
diff --git a/tutorials/learnrubyonline.org/fa/Printing variables and strings.md b/tutorials/learnrubyonline.org/fa/Printing variables and strings.md
new file mode 100644
index 000000000..e48cb9c70
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Printing variables and strings.md
@@ -0,0 +1,58 @@
+# آموزش
+--------
+
+## چاپ متغیرها و رشتهها
+
+شما یاد گرفتهاید چگونه از متغیرها و رشتهها استفاده کنید و آنها را چاپ کنید. اما اگر میخواستید یک عبارت را با استفاده از متغیرها و رشتهها با هم چاپ کنید چه میشد؟
+
+در Ruby میتوانید یک متغیر را درون رشتهای که میخواهید چاپ کنید فراخوانی کنید.
+
+برای فراخوانی متغیر باید از `#{variable}` استفاده کنید. برای مثال:
+
+ number = 8
+ puts "I have #{number} oranges." # I have 8 oranges
+
+شما حتی میتوانید عملیات ریاضی را بین متغیرها در درون آن انجام دهید.
+
+ first_number = 5
+ second_number = 6
+
+ puts "Multiplying #{first_number} by #{second_number} the result is #{first_number * second_number}"
+
+
+## تمرین
+--------
+
+کد را اصلاح کنید تا با استفاده از متغیرها چاپ کنید:
+- هر کدام از بچهها چند سیب دارند؛
+- مجموع همه سیبها.
+
+## کد تمرین
+-------------
+john = 5
+mary = 3
+will = 2
+
+puts "John has apples."
+puts "Mary has apples."
+puts "Will has apples."
+puts "Together they have apples."
+
+## خروجی مورد انتظار
+---------------
+John has 5 apples.
+Mary has 3 apples.
+Will has 2 apples.
+Together they have 10 apples.
+
+
+## حل
+--------
+john = 5
+mary = 3
+will = 2
+
+puts "John has #{john} apples."
+puts "Mary has #{mary} apples."
+puts "Will has #{will} apples."
+puts "Together they have #{john + mary + will} apples."
\ No newline at end of file
diff --git a/tutorials/learnrubyonline.org/fa/Strings.md b/tutorials/learnrubyonline.org/fa/Strings.md
new file mode 100644
index 000000000..470ff975d
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Strings.md
@@ -0,0 +1,60 @@
+آموزش
+--------
+
+رشتهای (String) مجموعهای از کاراکترها/نمادها درون علامات نقلقول است. رشتهها توسط کامپیوتر بهعنوان متن خام تفسیر میشوند.
+
+میتوانید از علامات نقلقول تک یا دوتایی برای رشتهها استفاده کنید - هر دو قابل قبول هستند.
+
+ myFirstString = 'I am a string!' #single quotes
+ mySecondString = "Me too!" #double quotes
+
+روشهای توکار زیادی در Ruby برای کار با رشتهها وجود دارند.
+
+`.length` تعداد کاراکترهای رشته را به شما میدهد.
+
+ "Hi!".length #is 3
+
+`.reverse` رشته را برعکس میکند.
+
+ "Hi!".reverse #is !iH
+
+`.upcase` رشته را به حروف بزرگ تبدیل میکند.
+
+ "Hi!".upcase #is HI!
+
+و `.downcase` رشته را به حروف کوچک تبدیل میکند.
+
+ "Hi!".downcase #is hi!
+
+همچنین میتوانید بسیاری از روشها را در یکباره استفاده کنید. آنها از چپ به راست حل میشوند.
+
+ "Hi!".downcase.reverse #is !ih
+
+اگر میخواهید بررسی کنید که یک رشته شامل رشتهای دیگر است یا نه، میتوانید از `.include?` استفاده کنید.
+
+ "Happy Birthday!".include?("Happy")
+
+کد بالا به `true` ارزیابی میشود.
+
+تمرین
+--------
+از رشته دادهشده استفاده کنید و روشها را بهکار ببرید تا کد "!edoc ma i !ih" را چاپ کند.
+
+کد آموزشی
+-------------
+
+ myString = "Hi! I am code!" #In the next line, use methods to change it.
+ myNewString = myString
+ puts myNewString
+
+خروجی مورد انتظار
+---------------
+
+ !edoc ma i !ih
+
+حل
+--------
+
+ myString = "Hi! I am code!" #In the next lines, use methods to change it.
+ myNewString = myString.reverse.downcase
+ puts myNewString
diff --git a/tutorials/learnrubyonline.org/fa/Unless, Until, and While.md b/tutorials/learnrubyonline.org/fa/Unless, Until, and While.md
new file mode 100644
index 000000000..2673b6b6f
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Unless, Until, and While.md
@@ -0,0 +1,52 @@
+آموزش
+--------
+عبارت `unless` به شکلی مشابه عبارت `if` ساختار یافته است.
+
+ unless condition
+ #کاری که اگر شرط غلط باشد انجام شود
+ end
+
+این عبارت در واقع برعکس عبارت if است، زیرا عبارات `if` فقط زمانی اجرا میشوند که شرط `true` باشد، اما عبارت `unless` فقط زمانی اجرا میشود که شرط `false` باشد. کلیدواژه `else` نیز میتواند در داخل عبارات `unless` استفاده شود.
+
+عبارات `while` یک بلوک کد را تا زمانی که یک شرط `true` باشد تکرار میکنند.
+
+ while condition
+ #کاری که باید انجام شود
+ end
+
+عبارات `until` برعکس عبارات `while` هستند؛ آنها تا زمانی تکرار میشوند که یک شرط `true` شود. در اینجا نحو آنها آمده است:
+
+ until condition
+ #کاری که باید انجام شود
+ end
+
+###مهم!
+
+مطمئن شوید که یک **حلقه بینهایت** ایجاد نمیکنید. حلقه بینهایت برای همیشه تکرار میشود و برنامه شما را از پیش رفتن باز میدارد، زیرا شرط هرگز تغییر نمیکند.
+
+تمرین
+--------
+یک عبارت while یا until را از ابتدا بسازید که `puts` "I'm looping!" را 7 بار روی کنسول نمایش دهد.
+
+کد آموزشی
+-------------
+ #حلقه خود را در زیر بسازید!
+
+خروجی مورد انتظار
+---------------
+I'm looping!
+I'm looping!
+I'm looping!
+I'm looping!
+I'm looping!
+I'm looping!
+I'm looping!
+
+راهحل
+--------
+ #حلقه خود را در زیر بسازید!
+condition = 0
+while condition<=6
+ puts "I'm looping!"
+ condition = condition + 1
+end
diff --git a/tutorials/learnrubyonline.org/fa/Variables and Types.md b/tutorials/learnrubyonline.org/fa/Variables and Types.md
new file mode 100644
index 000000000..7e90ca549
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Variables and Types.md
@@ -0,0 +1,58 @@
+آموزش
+--------
+
+متغیر یک داده نامگذاری شده است. میتوانید از یک متغیر برای ذخیرهسازی یک مقدار در برنامهتان استفاده کنید و بعداً با نام متغیر به آن مراجعه کنید.
+
+متغیرها با استفاده از `=` تعریف میشوند:
+
+ myFirstVariable = "I made a variable!"
+
+پس از اینکه مقداری را به یک متغیر اختصاص دادید، میتوانید بعداً به آن مراجعه کنید:
+
+ puts myFirstVariable
+
+سه نوع اصلی متغیر وجود دارد:
+
+- رشتهها (مجموعهای از نمادها درون علامات نقلقول)
+- منطقی (درست یا نادرست)
+- اعداد (مقادیر عددی)
+
+ aString = "I'm a string!"
+ aBoolean = true
+ aNumber = 42
+
+تمرین
+--------
+
+سه متغیر `myString`، `myBoolean`، و `myNumber` را تعریف کنید و آنها را به ترتیب به "I'm programming!"، "true"، و "5" تنظیم کنید.
+
+کد آموزشی
+-------------
+
+=begin
+Define your variables below!
+=end
+
+puts myString
+puts myBoolean
+puts myNumber
+
+خروجی مورد انتظار
+---------------
+
+I'm programming!
+true
+5
+
+راهحل
+--------
+
+=begin
+Define your variables below!
+=end
+myString = "I'm programming!"
+myBoolean = true
+myNumber = 5
+puts myString
+puts myBoolean
+puts myNumber
diff --git a/tutorials/learnrubyonline.org/fa/Welcome.md b/tutorials/learnrubyonline.org/fa/Welcome.md
new file mode 100644
index 000000000..bea3dbaac
--- /dev/null
+++ b/tutorials/learnrubyonline.org/fa/Welcome.md
@@ -0,0 +1,28 @@
+# خوش آمدید
+
+به آموزش تعاملی رایگان Ruby در learnrubyonline.org خوش آمدید.
+
+چه شما یک برنامهنویس با تجربه باشید یا نه، این وبسایت برای همه کسانی طراحی شده است که میخواهند زبان برنامهنویسی Ruby را یاد بگیرند.
+
+نیازی به دانلود هیچ چیزی نیست - فقط بر روی فصلی که میخواهید شروع کنید کلیک کنید و دستورالعملها را دنبال کنید. موفق باشید!
+
+learnrubyonline.org هنوز در حال ساخت است - اگر میخواهید آموزشهای خود را مشارکت کنید، لطفاً بر روی `مشارکت در آموزشها` در زیر کلیک کنید.
+
+### یادگیری مبانی
+
+- [[سلام جهان]]
+- [[نظرات]]
+- [[متغیرها و انواع]]
+- [[ریاضی]]
+- [[رشتهها]]
+- [[چاپ متغیرها و رشتهها]]
+- [[آرایهها]]
+- [[هشها و نمادها]]
+- [[عبارات شرطی]]
+- [[Unless، Until، و While]]
+- [[متدها]]
+- [[متدها با پارامتر]]
+
+### مشارکت در آموزشها
+
+برای کسب اطلاعات بیشتر: [[مشارکت در آموزشها]]