تابع پیش ساخته()Functional programing - map

سلام دوستان با یکی از تابع های پیش ساخته پایتون جدیدا آشنا شدم
خواستم در میون بگذارم البته سرچ کردم و موضوعی با این عنوان پیدا نکردم
شاید روش های خاضی برای گرفتن لیست از کاربر بلد باشید ولی من روش خودم رو که شاید روش ابتدایی ای باشه به صورت کامنت قرار دادم و توضیح مختصری هم درباره خود تابع map دادم و روش خودم رو باهاش مقایسه کردم
توی این روش فقط کافیه کاربر اعداد رو وارد کنه , به سادگی یک لیست ساخته میشه
امیدوارم مفید باشه براتون و این که تو خیلی جاها میشه ازش استفاده کرد
اگر قبلا استفاده کردید خوشحال میشم من رو هم مطلع کنید درباره اش

1 پسندیده

دو عکس به صورت همزمان نتونستم وارد کنم

سام داره تایپ میکنه و احتمالا چیز مشابهی قراره بگیم :grin:

4 پسندیده

تابع map از ساختار های اصلی برنامه نویسی فانکشنال به حساب میاد
اگر پایه ی ریاضی این تابع را می خواهید متوجه بشید به مبحث functor رجوع کنید

5 پسندیده

بله زبان الکسیر آشنا شدم باهاش قبلترش اطلاعی نداشتم
ممنونم

1 پسندیده

در اینکه پایتون آشغالتر از این حرفاست که ادای زبونهای functional رو دربیاره شکی نیست.
ولی از اونجایی که first class function هست، بجز map، دوتا تابع دیگه هم داره که مربوط به برنامه نویسی فانکشنال میشه: filter و reduce

https://book.pythontips.com/en/latest/map_filter.html

1 پسندیده

حرفتون رو نمیپذیرم هیچی زبونی اشغال نیست مهم اینه کار کنی باهاش
مثل این میمونه که بگید فارسی خوب نیست یا انگلیسی خوبه
هر کدوم جای خودشون بهترین هستن :slight_smile:
ولی بابت این دو تابع خیلی ممنون

زبان برنامه نویسی ربطی به زبان طبیعی نداره.
زبان برنامه نویسی، ابزاره. خوب و بد داره. وقتی توی سال ۲۰۲۰ یه زبانی نتونه یه راهکار معقول واسه concurrency ارائه بده، آشغاله. وقتی یه زبان backward compatible نباشه و ورژن ۲ و ۳ش با هم همخوانی نداشته باشه، آشغاله.

کامیونیتی بزرگ و لایبرریهای زیاد، تنها مزایای پایتون هستن که اونم اگه دقیق نگاه کنیم درصد زیادی از برنامه نویساش حرفه ای نیستن و حتی خیلی بیسوادن.

منم زمانی مثل شما فکر میکردم. تا وقتی با یه ابزار بهتر کار نکنید، نقصهای ابزارهای قدیمیتون رو متوجه نمیشید.

3 پسندیده

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

2 پسندیده

در ادامه بگم که «تابع درجه بالا» انگلیسیش میشه higher order function (اگه انگلیسی سرچ کنید متریالهای بیشتری برای یادگیری پیدا میکنید)


درکل توی Functional Programming روش کار اینطوریه که توابع ما همیشه یه ورودی میگیرن و همیشه ویرایش شده‌ی اون ورودی رو به عنوان خروجی خودشون return میکنن. موارد استثنا خیلی کم وجود داره (مثلا تابع print که اصولا چیزی return نمیکنه) این باعث میشه که بتونیم مقادیر خودمون رو از داخل زنجیره‌ای از توابع رد کنیم و جواب نهایی به دستمون برسه.
(توی برنامه نویسی فانکشنال، اصولا دیتا رو ویرایش نمیکنیم. بلکه ورژن جدیدی از دیتا رو تولید میکنیم. و اصطلاحا مقادیر ما Immutable هستن.)

حالا اینهمه واسه چی توضیح دادم؟
تابع map داستانش اینه که «یک تابع را روی یک مجموعه از مقادیر، اعمال میکند» و نتیجشو بهمون برمیگردونه.
مثلا میخوایم همه چیزو +1 کنیم. یا میخوایم از همش فاکتوریل بگیریم یا مثلا int16 رو تبدیل کنیم به int8.

خیلی راحتتر و سریعتره (هم برای برنامه نویس و هم برای کامپیوتر) که اینکارها رو با map انجام بدیم، نه for loop.

3 پسندیده

اره واقعا جالبه فانکشنال کردن کد ها مون حالا اگر برنامه هم خودش به خودی خود فانکشنال نبود
حالا اگه سندی یا کتابچه ای برای فانکشنال بودن معرفی کنید خیلی ممنونتون میشم
خودم هم در حال یادگیری الکسیر هستم ولی وقت نمیکنم زیاد برای الکسیر

1 پسندیده

کار خوبی می کنید اگر کمکی نیاز هست من در خدمتم

2 پسندیده

ممنونم حتما آموزش های خودتون رو میبینم اگر به مشکلی خوردم حتما سوال میکنم

1 پسندیده

خب functional programming یه پارادایمه. یه سری از زبونها ساپورتش میکنن یه سریها هم تنها پارادایمشونه.
یه کم سویچ کردن بهش میتونه برای کسانی که همیشه OOP کار کردن سخت باشه. برای من هم یه مقدار سخت بود با اینکه توی imperative programming هم همیشه سعی میکردم به روش functional کار کنم (کلا از OOP خوشم نمیومد. از همون اولش!)

اینکه «فانکشنال پروگرامینگ چیست؟» سوال بی‌جوابیه. کسی پاسخ دقیقی براش نداره که همه باهاش موافق باشن ولی پاسخ تقریبی اینه که:

  • باید قابلیت First Class Function داشته باشیم
  • باید دیتاهامون Immutable باشن
  • باید توابعمون Pure یا با اصطلاح Pure Function باشن

First class function

توابع ما مثل مقادیرمون باشن و بتونیم اونها رو مثل یه int بفرستیم به یه تابع دیگه یا از یه تابع دیگه اونها رو return کنیم.
اینطوری میتونیم قابلیتهایی مثل map و function composition داشته باشیم. یا تابعی بنویسیم که یه تابع جدید میسازه و بهمون return میکنه!

immutable data structure

از اونجایی که توابع ما هیچ دیتایی رو تغییر نمیدن و فقط ورژن جدیدی از دیتای قدیمی رو بهمون return میکنن، باعث میشه قابلیت زیادی توی concurrency داشته باشیم و مشکلات زیادی که توی زبونهای غیر فانکشنال وجود داره رو نداشته باشیم.
مثلا چون دیتاهامون هیچوقت تغییر نمیکنن، پس میشه مطمئن بود که این دیتا توی thread دیگه‌ای ویرایش نشده و نخواهد شد. پس لازم نیست هر threadی که میخواد با دیتای ما کار کنه، بقیه‌ی threadها رو lock کنه.
یه نگاهی به GIL بندازید تا متوجه بشید چرا میگم پایتون آشغاله! پایتون فقط به درد نوشتن اسکریپتهای نسبتا ساده میخوره. رسما برنامه نویس پایتون باید بگه «من دارم این دیتا رو میخونم یا مینویسم. کسی بهش دست نزنه، کسی از جاش تکون نخوره، کسی نفس نکشه.»
سمیر جان حتی بیشتر از من به GIL آلرژی داره :grinning: دلم میخواد یه کم اذیتش کنم پس اینجا صداش میزنم @lxsameer

Pure Function

وقتی یه تابعی pure باشه، موقع اجرا شدن، دیتایی از بیرون خودش رو نمیخونه و دیتایی از بیرون خودش رو ویرایش نمیکنه (یا نمیسازه) و خروجی اون تابع همیشه فقط و فقط به ورودیش بستگی داره. امکان نداره یه بار بهش ۵ بدیم ۶ بهمون تحویل بده دفعه‌ی بعد که محیط اطرافش (متغیرهای اطرافش) عوض شده بودن بهمون ۷ برگردونه.
این باعث میشه:

  • بتونیم از توابعمون همه‌جا استفاده کنیم و درگیر این نباشیم که چرا اونجا کار میکرد اینجا کار نمیکنه.
  • دیباگ کردن برنامه برامون خیلی راحت باشه چون فقط کافیه این تابع رو اجرا کنیم و جوابشو ببنییم. لازم نباشه چیزی رو خارج از اون تغییر بدیم تا به state مورد نیازمون برسه. حتی لازم نیست کل برنامه اجرا بشه. فقط کافیه همون تابع رو اجرا کنیم. (تا با کلوژر کار نکنید متوجه منظورم نمیشید. بهش میگیم repl development)
  • خروجی تابعهایی که کار سنگین انجام میدن رو میشه memoize کرد. اینطوری میشه گفت خروجی تابع cache شده. دفعه‌ی بعد که اجراش کنیم مستقیم به جواب میرسیم دیگه فشاری به سیستم نمیاد. این فقط زمانی ممکنه که تابع pure باشه.
  • داستان multi-threading برامون خیلی راحت میشه. در حدی که اصلا لازم نیست کد خاصی بنویسیم. مثلا توی کلوژر وقتی میخوایم تابع map به صورت multi-threading کار کنه فقط کافیه تبدیلش کنیم به pmap. به همین سادگی نرم افزار من سریعتر شد :grinning:

حالا این وسط یه سری تابع impure هم داریم. به هرحال نرم‌افزار ما باید یه ورودی از کاربر بگیره یا یه چیزی براش print کنه! باید بتونه به یه سروری ریکوئست بزنه و جواب بگیره یا توی دیتابیس یه چیزی رو بنویسه و بخونه.
اینا باعث میشن نرم‌افزار ما 100% pure نباشه. (نرم‌افزاری که صددرصد خالص باشه کار مفیدی انجام نمیده!)
بنابراین مجبوریم بخشهایی از کدمون رو «ناخالص» بنویسیم. توی برنامه نویسی فانکشنال، اینطوری عمل میکنن که این بخشها رو تا حد ممکن کوچیک میکنن و میذارنش یه گوشه. به این صورت که مثلا ۱۰۰تا تابع داریم که کارهامون رو انجام میدن و ۵تا تابع که با بیرون از برنامه ارتباط دارن (ارتبا با کاربر و دیتابیس و…) اینطوری هم خیالمون راحته که side-effectها، قاطی منطق برنامه نیستن و همه‌چیز تر و تمیزه.


برنامه نویسی فانکشنال، از فانکشنها (توابع) ریاضی میاد. از lambda calculus.
همونطور که توی توابع ریاضی، مقادیرمون تغییر نمیکنن (۵ همیشه ۵ هست، نه چیز دیگه‌ای) و هیچ تابعی با محیط بیرون خودش کار نداره، توی فانکشنال پروگرامینگ هم همین سیستم رو داریم.

چیزهای دیگه‌ای هم هست مثل Atomic data-structure که مسلما بودنشون توی یه زبان برنامه نویسی عالیه ولی فکر میکنم جزء ملزومات زبانهای فانکشنال نباشن.


خیلی توضیح دادم. امیدوارم جایی اشتباه ننوشته باشم و چیزی رو از قلم ننداخته باشم.

5 پسندیده

این لینک زیاد هم بی‌ربط نیست.
به آرتیکل درمورد higher order function که توش filter, map و reduce رو با مثال توی کلوژر و جاوااسکریپت توضیح داده.

https://blog.ona.io//2020/01/25/clojure-and-js-hof.html

بعد از خوندنش متوجه میشید چرا من کلوژر رو دوست دارم. خوشگل و تر و تمیز چیزی که میخوایو مینویسی جوابو میگیری. کمترین boilerplate توی زبونهایی که میشناسم اول برای کلوژره بعد پایتون.
نمونه‌کد reduce توی js:

const numbers = [1, 2, 3, 4];
const summedNums = numbers.reduce((accumulator, currentValue) => {
    return accumulator + currentValue }, 100);

console.log(summedNums);

// output
// 110

و همون کد توی کلوژر:

(reduce + 100 [1 2 3 4])

;; output
;; 110
3 پسندیده

ممنونم از توضیحاتتون خیلی کامل بود
حتما یه نگاهی باید به کلوژر بندازم آشنا بشم باهاش با این اوصاف :slight_smile:
واقعا ممنونم

1 پسندیده

کلوژر یک لیسپه (همین دلیلی بر برتریش نسبت به زبونهای دیگست)
قبلا توی انجمن زیاد درموردش بحث شده و یه مقداری هم براش آموزش نوشتیم که دیگه ادامه‌دار نبود متاصفانه.

#clojure

2 پسندیده

توضیح جالبی بود اما چنتا مورد وجود داره،
اول اینکه FP هم مثل OOP یک پردایم هست و تعریف مشخصی داره، و مورد دوم در رابطه با فانکشن های pure هست، وقتی میگیم side effect منظورمون خواندن دیتا نیست، منظور تغییر دیتاست. و در مورد immutability هم یکی از خصوصیات FP بحساب میاد اما معنیش این‌‌ نیست که فقط‌ مختص زبان های فانکشنال باشه. فانکشن های pure و Memoization مفهوم های کلی هستند و مختص FP نیست.
الیکسر هم نوع دیگه از زبان های لیسپی هست و با توجه به داشتن اکوسیستم فانکشنال از کلوژر فانکشنال تره اما هر دو برای من جالب هستند.

5 پسندیده

من یه توضیح کوچیک بدم. البته قبلا بهش اشاره شده. از نظر ریاضی فانکشن pure فانکشنی هست که free variable نداشته باشه. برای مثال:

λx.x
λx.λy.λz.x y
λx.λy.x(xy)

همه pure هستند اما

λx.ax
λx.λy.yxa
λx,y(λy.xy)

pure نستند چون در همه اون متغیری وجود داره که جزئی از ورودی فانکشن نیست

5 پسندیده

البته پویا جان هم به این‌ مورد جور دیگه ای اشاره کرد اما بنظر من هم از دید ریاضی بهشت نگاه بشه مشکل در پایه ساده میشه

5 پسندیده