در آموزشهای گذشته با دیتا تایپ لیست در زبان برنامهنویسی پایتون آشنا شدیم و گفتیم که دیتا تایپ تاپل نیز در این زبان قابلیتهایی همچون دیتا تایپ لیست دارا است و به منظور ذخیرۀ مجموعهای از دادههای غیرهمنوع مورد استفاده قرار میگیرد با این تفاوت که محتوای آبجکتی از جنس تاپل را نمیتوان تغییر داد. در واقع، دیتا تایپ تاپل را میتوان به منظور ذخیرۀ دیتایی با سطح دسترسی به اصطلاح Read-only مورد استفاده قرار داد؛ به عبارت بهتر، ذخیرۀ دیتا با بهکارگیری دیتا تایپ تاپل منجر بدین میشود تا سطح دسترسی به دیتای مد نظر محدود شده و بدین ترتیب امکان تغییر، حذف یا افزودن دیتای جدید در سایر نقاط برنامه وجود نداشته باشد.
اولین و سادهترین تفاوت دیتا تایپ تاپل نسبت به نوع دادۀ لیست این است که به منظور تعریف آبجکتهایی از جنس تاپل به جای علائم [ ]
از علائم ()
استفاده میکنیم که برای آشنایی بیشتر با نحوۀ ساخت آبجکتی از جنس تاپل، مثال زیر را مد نظر قرار میدهیم:
>>> colorTuple = ("red", "green", "blue", "yellow")
در دستور فوق، متغیری به نام colorTuple
از جنس تاپل تعریف کردهایم با این تفاوت که اعضای آن به جای قرار گرفتن در میان علائم [ ]
در میان ()
قرار گرفتهاند که برای حصول اطمینان از نوع دادۀ مد نظر نیز فانکشن از پیش تعریفشدۀ ()type
را با آرگومان ورودی colorTuple
فراخوانی میکنیم:
>>> type(colorTuple)
<class 'tuple'>
همانطور که ملاحظه میشود، اجرای دستور فوق منجر به ریترن شدن کلاس مربوط به نوع آبجکت مد نظر تحت عنوان tuple
در خروجی شده است. حال در ادامۀ این آموزش قصد داریم تا به تشریح ویژگیهای این دیتا تایپ پرداخته و برخی فانکشنهای به اصطلاح Built-in در زبان پایتون را به منظور اِعمال روی آبجکتهایی از جنس تاپل معرفی کنیم.
نحوۀ دسترسی به محتوای تاپل
نحوۀ دسترسی به محتوای آبجکتی از جنس تاپل همانند دیتا تایپ لیست میباشد که جهت کسب اطلاعات بیشتر میتوانید به آموزش آشنایی نحوۀ دسترسی به محتوای لیست در زبان برنامهنویسی پایتون مراجعه کنید. همچنین همانطور که در ابتدای آموزش اشاره کردیم، دیتا تایپ تاپل تغییرناپذیر بوده و از همین روی فراخوانی فانکشنهای از پیش تعریفشدهای همچون ()sort
و ()append
یا ()remove
در آنها هیچ تغییری اِعمال نمیکنند.
نحوۀ ویرایش محتوای تاپل
در این بخش قصد داریم تا به بررسی این موضوع بپردازیم که منظور از تغییرناپذیر بودن دیتا تایپ تاپل چیست و چرا نمیتوان محتوای آن را تغییر داد که برای درک بهتر این مفهوم در مثال زیر سعی کردهایم تا اِلِمان اول از آبجکت مربوط به مثال قبل را تغییر دهیم:
>>> colorTuple[0] = "orange"
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
colorTuple[0]='orange'
TypeError: 'tuple' object does not support item assignment
در کد فوق، قصد داریم تا مقدار اِلِمان اول از آبجکت colorTuple
را تغییر دهیم و از آنجایی که اندیسگذاری آبجکتهایی از جنس تاپل و لیست از عدد صفر شروع میشود، به منظور دسترسی به اِلِمان اول عدد 0 را به کار بردهایم که در نتیجۀ اجرای این دستور با اروری مواجه میشویم مبنی بر اینکه آبجکتی از جنس تاپل تغییرناپذیر بوده و نمیتوان مقدار منتسب به آن را تغییر داد اما در عین حال میتوان آبجکتی جدید از جنس تاپل را با استفاده از به اصطلاح Concate (الحاق) دو یا چند آبجکت تاپل دیگر ایجاد کرد که برای این منظور کد زیر را مد نظر قرار میدهیم:
>>> tupleOne = ("red", "green", "blue", "yellow")
>>> tupleTwo = ("orange", "pink")
>>> newColorTuple = tupleOne + tupleTwo
>>> newColorTuple
('red', 'green', 'blue', 'yellow', 'orange', 'pink')
در کد فوق، ابتدا آبجکتی از جنس تاپل تحت عنوان tupleOne
تعریف کرده و یکسری اِلِمان را به آن منتسب کردهایم و در ادامه آبجکتی دیگر از جنس تاپل تحت عنوان tupleTwo
تعریف کردهایم که دو اِلِمان دیگر از جنس استرینگ را به این آبجکت اختصاص دادهایم. حال در صورتی که بخواهیم تا مقادیر اِلِمانهای هر دو تاپل را با هم کانکت کنیم، از عملگر +
استفاده میکنیم و همانطور که ملاحظه میکنید، عملگر +
را به منظور الحاق مقادیر اِلِمانهای دو تاپل tupleOne
و tupleTwo
به کار گرفتهایم و در ادامه گفتهایم آبجکت تاپل جدید در متغیری تحت عنوان newColorTuple
نگهداری شود.
در واقع، نحوۀ کار این عملگر در الحاق دو آبجکت از جنس تاپل بدین صورت است که اِلِمانهای مربوط به آبجکت تاپل دوم را به انتهای اِلِمانهای مربوط به آبجکت اول اضافه کرده و آبجکتی جدید از جنس تاپل ایجاد میکند و نهایتاً در مثال فوق، مقادیر اِلِمانهای مربوط به تاپل جدید به متغیر newColorTuple
منتسب میشود و در سطر آخر نیز میبینیم که محتوای ذخیرهشده در آبجکت تاپل جدید برابر با نتیجۀ حاصل از الحاق اِلِمانهای دو تاپل مذکور میباشد.
نحوۀ حذف برخی اِلِمانهای تاپل
همانطور که اشاره کردیم، دیتا تایپ تاپل تغییرناپذیر است و از همین روی نمیتوان اِلِمان خاصی را از آن حذف کرد اما این در حالی است که امکان حذف خود آبجکت تاپل با بهکارگیری کیورد del
فراهم میباشد که برای این منظور کد زیر را در نظر میگیریم:
>>> del newColorTuple
>>> newColorTuple
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
newColorTuple
NameError: name 'newColorTuple' is not defined
همانطور که مشاهده میکنید، ابتدا کیورد del
را نوشته و در ادامه آبجکت تاپل مربوط به مثال قبل را آوردهایم و بدین ترتیب قصد داریم تا کل آبجکت مذکور به همراه تمامی اِلِمانهای ذخیرهشده در آن را حذف کنیم که با اجرای این دستور تاپل مد نظر حذف میشود (در سطر بعد شناسۀ این آبجکت را تایپ کرده و قصد داریم تا بدین وسیله محتوای آن را در خروجی ریترن کنیم و همانطور که انتظار میرود اجرای این دستور منجر به اروری شده است مبنی بر اینکه آبجکتی با این شناسه موجود نمیباشد چرا که پیش از این از روی حافظه حذف شده است.)
اِعمال عملیات ریاضیاتی پایه روی آبجکتهایی از جنس تاپل
برخی اپراتورهای ریاضیاتی همچون +
و *
را میتوان بر روی دو یا چند آبجکت از جنس تاپل اِعمال کرد که در ادامه به تشریح نحوۀ عملکرد این اپراتورها روی چنین آبجکتهایی میپردازیم:
- اپراتور Plus: اپراتور +
به منظور کانکت کردن اِلِمانهای دو یا چند آبجکت تاپل مورد استفاده قرار میگیرد که با نحوۀ پیادهسازی آن در مبحث مربوط به ساخت آبجکتی جدید از جنس تاپل با الحاق اِلِمانهای دو آبجکت آشنا شدیم.
- اپراتور Multiply: عملگر *
بدین صورت مورد استفاده قرار میگیرد که یک آبجکت از جنس تاپل را در یک عدد طبیعی ضرب میکنیم و نتیجۀ آن ایجاد آبجکتی جدید از جنس تاپل میباشد که در آن تمامی اِلِمانهای آبجکت پیشین به تعداد عدد مد نظر تکرار شده است. برای درک بهتر این موضوع، کدهای زیر را مد نظر قرار میدهیم:
>>> newTuple = tupleTwo * 2
>>> print(newTuple)
('orange', 'pink', 'orange', 'pink')
>>> len(newTuple)
4
در کد فوق، گفتهایم تمامی اِلِمانهای تاپل مربوط به مثال قبل که در متغیری تحت عنوان tupleTwo
نگهداری میشوند، به تعداد دو مرتبه تکرار شده و به متغیری جدید به نام newTuple
منتسب شوند (توجه داشته باشیم که محتوای مربوط به آبجکت تاپل tupleTwo
تغییری نخواهد کرد.) و در ادامه محتوای منتسب به متغیر newTuple
را در خروجی چاپ کردهایم و همانطور که انتظار میرفت دو اِلِمان مربوط به تاپل tupleTwo
در آبجکت تاپل newTuple
دو مرتبه تکرار شدهاند و در نهایت هم این آبجکت را به عنوان آرگومان ورودی به فانکشن از پیش تعریفشدۀ ()len
دادهایم که تعداد آیتمهای ذخیرهشده در آبجکت مد نظر را در خروجی ریترن میکند و از همین روی عدد 4 در خروجی چاپ شده است.
آشنایی با مفاهیم Packing و Unpacking
در زبان برنامهنویسی پایتون قابلیتی برای آبجکتهایی از جنس تاپل تعریف شده است که در آن با تعریف یک آبجکت از نوع دادۀ تاپل سپس انتساب آن به مجموعهای از متغیرها میتوان هر یک از اِلِمانهای تاپل اول را به متغیر متناظرشان اختصاص داد. در واقع، به پروسۀ تعریف یک آبجکت از جنس تاپل اصطلاحاً Packing گفته شده و اختصاص مقادیر اِلِمانهای این تاپل به مجموعهای متغیرهای متناظرشان به اصطلاح Unpacking نامیده میشود که برای درک بهتر این موضوع مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = ("Urmia University of Technology", 9011, "Information Technolog")
>>> (college, studentNumber, fieldOfStudy) = tupleOne
>>> college
'Urmia University of Technology'
>>> studentNumber
9011
>>> fieldOfStudy
'Information Technology'
در کد فوق، آبجکتی از نوع تاپل تعریف کرده و مقادیری از جنس استرینگ و عدد را بدان اختصاص دادهایم و در ادامه آبجکت مذکور را به متغیری تحت عنوان tupleOne
منتسب کردهایم و همانطور که پیشتر اشاره کردیم، این فرآیند به اصطلاح Packing نام دارد. حال در سطر بعد هر یک از اِلِمانهای مربوط به آبجکت تاپل ایجادشده را در طی یک پروسۀ Unpacking به مجموعهای از متغیرهای متناظرشان در سمت چپ =
منتسب کردهایم و میبینیم که هر یک از اِلِمانهای آبجکت tupleOne
به متغیر متناظرشان در سمت چپ اپراتور =
منتسب شدهاند.
نکته |
به منظور انتساب هر یک از اِلِمانهای آبجکت تاپل به مجموعهای از متغیرها میباید حتماً تعداد اِلِمانهای آبجکت مد نظر با تعداد متغیرها برابر باشند. |
اما در عین حال و با توجه به آنچه در نکتهٔ بالا بدان اشاره کردیم، میتوان شرایطی را در نظر گرفت که در آن تعداد متغیرها در سمت چپ اپراتور =
با تعداد اِلِمانهای آبجکت تاپل برابر نباشد بدین صورت که از علامت *
در کنار شناسۀ متغیر مد نظر استفاده کرده و بدین ترتیب میتوان به تعداد بیش از یک اِلِمان از آبجکت تاپل مد نظر را به متغیر مربوطه منتسب کرد که در همین راستا توجه شما را به مثال زیر جلب میکنیم:
>>> tupleOne = (10, "Sokan", "Academy", 50)
>>> (x, y, *z) = tupleOne
>>> x
10
>>> y
'Sokan'
>>> z
['Academy', 50]
در کد فوق، آبجکتی از جنس تاپل با مقادیری از استرینگ و عدد را تعریف کرده و آن را به متغیری تحت عنوان tupleOne
منتسب کردهایم و در ادامه گفتهایم اِلِمان اول از آبجکت تاپل که برابر با عدد 10 است به متغیر x
اختصاص یافته و اِلِمان دوم از این آبجکت معادل استرینگ «Sokan» نیز به متغیر y
منتسب شود و در ادامه گفتهایم سایر اِلِمانهای مربوط به آبجکت tupleOne
به متغیر z
منتسب شوند. همانطور که در کد فوق میبینید، محتوای هر یک از متغیرهای x
و y
به ترتیب برابر با مقادیر متناظرشان از تاپل مذکور بوده و سایر اِلِمانهای آن نیز به متغیر z
منتسب شدهاند. به عنوان یک نمونه مثال دیگر داریم:
>>> tupleOne = (10, "Sokan", "Academy", 50)
>>> (*x, y, z) = tupleOne
>>> x
[10, 'Sokan']
>>> y
'Academy'
>>> z
50
در کد فوق، گفتهایم مقادیر هر یک از اِلِمانهای آبجکت tupleOne
بدین ترتیب به اصطلاح Unpack شوند که مقادیر مربوط به دو اِلِمان آخر از این آبجکت به ترتیب به هر یک از متغیرهای y
و z
منتسب شده و سایر اِلِمانهای آن نیز به متغیر x
اختصاص داده شوند و بدین ترتیب میبینیم که استرینگ «Academy» و عدد 50 به ترتیب به متغیرهای y
و z
اختصاص یافته و مقادیر مربوط به سایر اِلِمانهای این آبجکت نیز به متغیر x
منتسب شدهاند.
زبان برنامهنویسی پایتون یکسری فانکشن از پیش تعریفشده دارا است که برخی از پرکاربردترین آنها را در آموزش معرفی برخی از پرکاربردترین فانکشنهای Built-in در زبان برنامهنویسی پایتون معرفی کردیم. حال در ادامه قصد داریم تا برخی از دیگر فانکشنهای Built-in در این زبان را معرفی کنیم که به منظور اِعمال روی آبجکتهایی از جنس تاپل در نظر گرفته شدهاند.
کاربرد فانکشنهای ()max و ()min
فانکشن ()max
دارای یک پارامتر ورودی میباشد که جهت ریترن کردن بزرگترین مقدار از میان اِلِمانهای آبجکتی از جنس تاپل مورد استفاده قرار میگیرد و برای این منظور نیز میباید آبجکت مد نظر را به عنوان آرگومان ورودی به آن بدهیم که برای درک بهتر کاربرد این فانکشن مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = (1, 20, 300)
>>> tupleTwo = ("orange", "pink")
>>> max(tupleTwo)
'pink'
>>> max(tupleOne)
300
>>> min(tupleOne)
1
در تفسیر کد فوق باید گفت که در ابتدا دو آبجکت از جنس تاپل تحت عناوین tupleOne
و tupleTwo
تعریف کردهایم که برای تاپل اول یکسری مقدار عددی را اختصاص دادهایم و تاپل دوم نیز متشکل از دو استرینگ میباشد و در ادامه هر یک از آبجکتهای مذکور را به عنوان آرگومان ورودی به فانکشن ()max
دادهایم. همانطور که میبینیم، خروجی حاصل از فراخوانی فانکشن ()max
به ازای آبجکت تاپلی متشکل از مقادیر استرینگ برابر با «pink» میباشد و نحوۀ مقایسۀ اِلِمانهایی با دیتا تایپ استرینگ بدین صورت است که هر کاراکتر بر اساس مقدار متناظر آن در کدگذاری ASCII با کاراکتر دیگر از سایر استرینگهای تاپل مقایسه میشوند.
در واقع، در این مثال، نحوۀ مقایسۀ مقادیر استرینگ بدین صورت است کاراکتر اول از استرینگ «orange» با کاراکتر اول از استرینگ «pink» مقایسه میشوند و چنانچه مقادیر هر یک از دو کاراکتر در کدگذاری ASCII برابر باشند، به سراغ کاراکترهای دوم رفته و این روند ادامه مییابد تا زمانی که به اولین کاراکتری برسیم که مقدار متناظر آن در کدگذاری ASCII بزرگتر از کاراکتر مربوط به استرینگ دوم باشد که در نهایت استرینگی به عنوان مقدار بزرگتر در خروجی ریترن میشود که اولین کاراکتر با مقدار متناظر بزرگتر در کدگذاری ASCII را داشته باشد که برای درک بهتر نحوۀ کدگذاری ASCII میتوانید به آموزش آشنایی با استانداردهای کدگذاری ASCII و Unicode مراجعه کنید.
به علاوه، فراخوانی فانکشن ()max
به ازای آرگومان ورودی تاپل متشکل از مقادیر عددی نیز بزرگترین مقدار را از میان اِلِمانهای تاپل مد نظر در خروجی ریترن میکند که از همین روی عدد 300 در خروجی ریترن شده است.
فانکشن ()min
نیز عملکردی مشابه فانکشن ()max
دارا است با این تفاوت که فراخوانی آن با آرگومان ورودی مربوط به هر یک از آبجکتهای تاپل منجر بدین میشود تا در مقایسههای انجامشده مابین اِلِمانهای مختلف آیتم مربوط به کوچکترین مقدار در خروجی ریترن شود.
کاربرد فانکشن ()tuple
این فانکشن نیز قابلیتی دارا است تا یک آرگومان ورودی از نوع لیست یا استرینگ را گرفته و به آبجکتی جدید از جنس تاپل مبدل سازد. برای مثال، کد زیر را مد نظر قرار میدهیم:
>>> listA = [1, 2, 3, 4, 5]
>>> tupleB = tuple(listA)
در کد فوق، آبجکتی از جنس لیست را با بهکارگیری علائم [ ]
تعریف کرده و یکسری مقادیر عددی به آن اختصاص داده و در نهایت آبجکت تعریفشده را به متغیری تحت عنوان listA
منتسب کردهایم و در ادامه فانکشن ()tuple
را فراخوانی کرده و آبجکت listA
را به عنوان آرگومان ورودی به آن دادهایم و نتیجه حاصل از این فراخوانی را به متغیری تحت عنوان tupleB
منتسب کردهایم. در واقع، با اجرای دستور فوق آبجکتی جدید از جنس تاپل ساخته شده و به متغیر tupleB
منتسب میشود و این در حالی است که دیتا تایپ آبجکت listA
تغییری نخواهد کرد که برای بررسی این موضوع خروجیهای زیر را مد نظر قرار میدهیم:
>>> type(listA)
<class 'list'>
>>> type(tupleB)
<class 'tuple'>
همانطور که مشاهده میشود، هر یک از آبجکتهای listA
و tupleB
به ترتیب متعلق به کلاسهای list
و tuple
میباشند بدین معنی که میتوان با فراخوانی فانکشن ()tuple
با آرگومانهای ورودی از جنس لیست و استرینگ آبجکتی جدید با نوع دادۀ تاپل ایجاد کرد. در ادامه مثالی در ارتباط با فراخوانی این فانکشن با یک آرگومان ورودی از جنس استرینگ را مد نظر قرار میدهیم:
print(tuple("SokanAcademy"))
('S', 'o', 'k', 'a', 'n', 'A', 'c', 'a', 'd', 'e', 'm', 'y')
همانطور که میبینیم، فراخوانی فانکشن ()tuple
با آرگومان ورودی از جنس استرینگ «SokanAcademy» منجر به ایجاد آبجکتی جدید از جنس تاپل شده است که این آبجکت متشکل از تمامی کاراکترهای استرینگ مربوط به آرگومان ورودی میباشد.
کاربرد فانکشن ()count
این فانکشن یک پارامتر ورودی میگیرد و به منظور شمارش تعداد دفعات تکرار هر یک از اِلِمانهای تشکیلدهندۀ آبجکت تاپل مد نظر مورد استفاده قرار میگیرد که برای درک بهتر نحوۀ کار این فانکشن، مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = (1, "SokanAcademy", 3, "sokanacademy", 5, 5)
>>> tupleOne.count(5)
2
>>> tupleOne.count('SokanAcademy')
1
در کد فوق، آبجکتی از جنس تاپل با مقادیر اِلِمانهایی از دو دیتا تایپ عدد و استرینگ را تعریف کرده و آن را به متغیری تحت عنوان tupleOne
منتسب کردهایم و در سطر بعد فانکشن ()count
را روی آبجکت تعریفشده با آرگومان ورودی مربوط به آیتم عدد 5 از آبجکت تاپل مربوطه فراخوانی کردهایم و بدین ترتیب تعداد تکرار عدد 5 در این تاپل در خروجی ریترن میشود که میبینیم عدد 2 در معرض دیدمان قرار میگیرد.
در ادامه قصد داریم تا فانکشن ()count
تعداد تکرار استرینگ «SokanAcademy» را در خروجی ریترن کند که برای این منظور استرینگ مذکور را به عنوان آرگومان ورودی به آن میدهیم و میبینیم که این فانکشن مابین دو استرینگ «SokanAcademy» و «sokanacademy» تمایز قائل شده و تعداد تکرار آن را برابر با عدد 1 در نظر میگیرد. همچنین میتوان با بهکارگیری کیورد in
بررسی کرد که آیتم مد نظر در آبجکت تاپل مربوطه وجود دارد یا خیر که برای این منظور داریم:
tupleOne = (1, "SokanAcademy", 3, "sokanacademy", 5, 5)
if "SokanAcademy" in tupleOne:
print("Yes, SokanAcademy is in this tuple.")
در کد فوق، آبجکتی از جنس تاپل تعریف کرده و آن را به متغیری به نام tupleOne
منتسب کردهایم و در ادامه گفتهایم چنانچه استرینگ «SokanAcademy» در آبجکت منتسب به متغیر tupleOne
وجود داشته باشد، استرینگ «.Yes, SokanAcademy is in this tuple» در خروجی چاپ شود که نتیجۀ حاصل از اجرای کد فوق به صورت زیر خواهد بود:
Yes, SokanAcademy is in this tuple.
در واقع، آرگومان ورودی فانکشن ()print
استرینگ «.Yes, SokanAcademy is in this tuple» میباشد که با برقرار بودن دستور if
یا به عبارتی وجود اِلِمانی از نوع استرینگ «SokanAcademy» در تاپل tupleOne
در خروجی چاپ شده است.
کاربرد فانکشن ()index
این فانکشن دارای یک پارامتر ورودی بوده و اندیس مربوط آیتم مد نظر از آبجکت تاپل متناظر را در خروجی ریترن میکند:
>>> tupleOne.index('SokanAcademy')
1
در کد فوق، فانکشن از پیش تعریفشدۀ ()index
را روی آبجکت tupleOne
با آرگومان ورودی مربوط به اِلِمان مد نظر از آبجکت تاپل مربوط به مثال قبل فراخوانی کردهایم و در نهایت اندیس مربوط به آیتم «SokanAcademy» از آبجکت متناظر برابر با عدد 1 در خروجی ریترن شده است.
به طور کلی، در این آموزش به معرفی دیتا تایپ تاپل پرداخته و گفتیم که بر خلاف دیتا تایپ لیست، به منظور ذخیرۀ دیتایی بدون نیاز به اِعمال تغییر روی آن مورد استفاده قرار میگیرد که از جمله تفاوتهای دیگر این دو دیتا تایپ میتوان گفت که استفاده از دیتا تایپ تاپل به منظور ذخیره و نگهداری دیتا در برنامههای بزرگ منجر به افزایش سرعت در اجرای سورسکد مربوطه میشود به علاوه اینکه آبجکتهایی از جنس تاپل را میتوان به عنوان مقادیر کلید در دیتا تایپهای دیکشنری مورد استفاده قرار داد چرا که مقادیر کلید در این نوع دیتا تایپ میباید به اصطلاح Immutable باشند و از همین روی آبجکتهایی از نوع دادۀ تاپل کاندیدای خوبی برای این سناریو هستند (جهت کسب اطلاعات بیشتر در رابطه با نوع دادۀ دیکشنری میتوانید به آموزش آشنایی با دیتا تایپ دیکشنری در زبان برنامهنویسی پایتون مراجعه نمایید.)