কনটেন্টে যান

Chapter 0.4 — Python + NumPy + matplotlib Setup & First Plot (সেটআপ ও প্রথম ছবি)

🎯 এই chapter-এ যা শিখবে

  • নিজের computer-এ Python, NumPy, matplotlib আর Jupyter Notebook install করা — ধাপে ধাপে, কোনো ধাপ বাদ না দিয়ে
  • Python-এর একদম basics: variable, list, loop, function — যতটুকু এই কোর্সে লাগবে
  • NumPy array — কেন plain list দিয়ে math হয় না, আর array দিয়ে হয়
  • matplotlib দিয়ে জীবনের প্রথম plot আঁকা — এবং plot-এর প্রতিটা অংশ চেনা
  • আগের তিন chapter-এর সব ধারণা (function, লাইন, set, \(\Sigma\), \(\mathbb{R}^n\)) কোডে জীবন্ত করা

🖼️ এক ছবিতে মূল idea

Toolbox

তোমার Data Science যাত্রার চারটা হাতিয়ার, একটা টিম হিসেবে: Python ভাষাটা, NumPy সেই ভাষায় দ্রুত math করার ইঞ্জিন, matplotlib ছবি আঁকার তুলি, আর Jupyter Notebook হলো খাতা — যেখানে কোড, লেখা আর ছবি পাশাপাশি থাকে। আজ এই চারজনের সাথেই পরিচয় হবে।


১. কি? (What)

কেন programming — আমরা না math শিখছিলাম?

সংগত প্রশ্ন। উত্তরটা এই কোর্সের দর্শনের গভীরে:

  1. Code হলো সত্যতা যাচাইয়ের যন্ত্র। বইয়ে লেখা আছে distance \(=5\)? এক লাইনের কোডে নিজে check করো। নিজের চোখে দেখা জিনিস কখনো ভোলা যায় না।
  2. Code দিয়ে ছবি আঁকা যায়। এই কোর্সের মন্ত্র "আগে ছবি, পরে সূত্র" — আর ছবিগুলো আঁকবে matplotlib। এই বইয়ের প্রতিটা figure Python-এ আঁকা!
  3. Data Science-এর পেশাগত ভাষাই Python। Linear Algebra শিখছ ML-এর জন্য, আর ML হয় Python-এ। দুটো একসাথে শিখলে এক ঢিলে দুই পাখি।

ভয়ের কিছু নেই: এই কোর্সে programming-এর যতটুকু লাগবে ঠিক ততটুকুই শেখাব, এবং প্রতিটা নতুন জিনিস math-এর সাথে মিলিয়ে। Chapter 0.3-এ তো দেখেছই — math notation আর Python প্রায় একই ভাষা।

চার হাতিয়ারের পরিচয়

  • Python(পাইথন): পৃথিবীর সবচেয়ে জনপ্রিয় programming ভাষাগুলোর একটা — জনপ্রিয় হওয়ার কারণই হলো এর সরলতা। Python-এর কোড অনেকটা ইংরেজি বাক্যের মতো পড়া যায়।
  • NumPy(নামপাই) — "Numerical Python": সংখ্যার array(অ্যারে) নিয়ে বিদ্যুৎগতিতে কাজ করার library(লাইব্রেরি)। Library মানে অন্যদের লেখা কোডের সংগ্রহ, যা আমরা ধার নিই। এই কোর্সের প্রায় প্রতিটা ধারণার NumPy রূপ আছে: vector = array, matrix = 2D array।
  • matplotlib(ম্যাটপ্লটলিব): ছবি/graph আঁকার library। নাম এসেছে "MATLAB-plotting-library" থেকে।
  • Jupyter Notebook(জুপিটার নোটবুক): browser-এ চলা interactive খাতা — একটা ঘরে (cell) কোড লেখো, Shift+Enter চাপো, ফল সাথে সাথে নিচে। পরের ঘরে বাংলায় নোট লেখো। Data scientist-দের প্রতিদিনের কর্মক্ষেত্র।

Installation — ধাপে ধাপে

সবচেয়ে ঝামেলাহীন রাস্তা দুটো। রাস্তা ১ সুপারিশ করি।

রাস্তা ১: Miniforge/Anaconda (সব এক প্যাকেটে)

  1. anaconda.com/download থেকে নিজের OS-এর (Windows/Mac/Linux) installer নামাও
  2. Installer চালাও — সব default-এ "Next" চাপলেই হবে
  3. Windows-এ Start Menu-তে "Anaconda Prompt" খোলো (Mac/Linux-এ সাধারণ Terminal)
  4. লেখো: jupyter notebook → Enter — browser-এ Jupyter খুলে যাবে!

Anaconda-র ভেতরে Python, NumPy, matplotlib, Jupyter — সব আগে থেকেই আছে। আর কিছু লাগবে না।

রাস্তা ২: python.org + pip (হালকা রাস্তা)

  1. python.org/downloads থেকে Python নামাও ও install করো (Windows-এ "Add Python to PATH" checkbox-এ টিক দিতে ভুলো না — এটাই সবচেয়ে common ভুল!)
  2. Terminal/Command Prompt খুলে: pip install numpy matplotlib notebook
  3. তারপর: jupyter notebook

যাচাই করো setup ঠিক আছে কিনা — Jupyter-এর একটা cell-এ এটা চালাও:

import numpy as np
import matplotlib
print("Python OK!")
print("NumPy version:", np.__version__)
print("matplotlib version:", matplotlib.__version__)

তিন লাইন output এলেই তুমি প্রস্তুত। Error এলে §৯ (Common ভুল) দেখো।


২. দেখতে কেমন?

List বনাম array: আসল পার্থক্যটা চোখে দেখো

List vs array

একই লেখা * 2, দুই ভিন্ন ফল! Python-এর সাধারণ list [1,2,3] * 2 দিলে list-টা repeat হয় — কোনো math হয় না। NumPy array-তে * 2 মানে প্রতিটা সংখ্যাকে দ্বিগুণ — সত্যিকারের math। Linear Algebra-য় আমরা সংখ্যার লিস্টকে একটাই জিনিস (একটা vector!) হিসেবে গণ্য করতে চাই — তাই NumPy-ই আমাদের ঘর।

একটা plot-এর শারীরস্থান

Anatomy of a plot

একটা সম্পূর্ণ matplotlib figure-এর যন্ত্রপাতি: title, axis label, legend(লেজেন্ড — কোন রেখা কী, তার তালিকা), grid, আর মূল রেখাগুলো। প্রতিটা অংশের পাশে লেখা আছে কোন command সেটা বানায়। এই ছবিটাই তোমার plot-আঁকার cheat sheet।

চার রকমের plot — চার রকমের প্রশ্ন

Plot gallery

চার অস্ত্রের গ্যালারি: line plot (ধারা/প্রবণতা দেখতে), scatter plot (দুই জিনিসের সম্পর্ক — পড়ার ঘণ্টা বনাম নম্বর!), bar chart (দলে দলে তুলনা — বিভাগভিত্তিক জনসংখ্যা), histogram (একটা রাশির বিস্তার — কার উচ্চতা কত ঘন ঘন)। Data দেখেই কোন plot লাগবে বুঝে ফেলা একজন data scientist-এর প্রথম দক্ষতা।


৩. কোথায় ইউজ হয়?

বাস্তব জীবনে (এই stack-টা কারা চালায়):

  • NASA থেকে Netflix: James Webb টেলিস্কোপের ছবি প্রসেসিং, Netflix-এর recommendation, ব্যাংকের ঝুঁকি হিসাব — সবখানে Python + NumPy।
  • গবেষণা: পদার্থবিজ্ঞান থেকে জিনতত্ত্ব — বৈজ্ঞানিক paper-এর গ্রাফগুলোর বিশাল অংশ matplotlib-এ আঁকা। (LIGO-র মহাকর্ষীয় তরঙ্গ আবিষ্কারের বিখ্যাত ছবিটাও!)
  • তোমার ফোনের weather app-এর গ্রাফ থেকে নির্বাচনের ফলাফলের চার্ট — data visualization সর্বত্র।

Data Science / ML-এ (সামনের chapter-গুলোতেই):

  • Part I থেকেই: vector মানেই np.array([3, 2]), vector-এর ছবি মানেই matplotlib-এর quiver plot। আজকের setup ছাড়া কাল এক পা-ও চলা যাবে না।
  • pandas, scikit-learn, PyTorch, TensorFlow — ML-এর সব বড় library-র ভিত্তির নিচে NumPy array। NumPy শেখা মানে সবগুলোর অর্ধেক শেখা।
  • Exploratory Data Analysis (EDA): নতুন dataset পেলে data scientist প্রথম যে কাজটা করে — plot! Histogram-এ বিস্তার দেখো, scatter-এ সম্পর্ক খোঁজো। "আগে ছবি" নীতিটা পেশাদার জগতেও এক নম্বর নিয়ম।

৪. Properties

Programming ভাষারও "properties" আছে — নিয়ম, যেগুলো জানলে ভুল কমে।

৪.১ Variable assignment: = মানে "সমান" না, "রাখো"

x = 5        # "x নামের বাক্সে 5 রাখো" (Chapter 0.1-এর খালি বাক্স!)
x = x + 1    # math-এ অর্থহীন, Python-এ স্বাভাবিক: "পুরনো x-এর সাথে 1 যোগ করে আবার x-এ রাখো"
print(x)     # output: 6

Math-এর \(=\) (দুই পাশ সমান — দাঁড়িপাল্লা) আর Python-এর = (ডান পাশের জিনিস বাঁ পাশের বাক্সে ঢোকাও) আলাদা জিনিস। Python-এ "সত্যিই সমান কিনা" জিজ্ঞেস করতে হয় == দিয়ে: x == 6True

৪.২ NumPy-র elementwise নিয়ম

Array-র উপর যেকোনো গাণিতিক কাজ প্রতিটা element-এ আলাদা আলাদা প্রযোজ্য হয়:

a = np.array([1, 2, 3, 4])
print(a * 2)      # [2 4 6 8]
print(a + 10)     # [11 12 13 14]
print(a ** 2)     # [ 1  4  9 16]
print(a + a)      # [2 4 6 8]   — দুই array মিললে জোড়ায় জোড়ায় যোগ

এক লাইনে চারটা (বা চল্লিশ লাখ!) হিসাব — কোনো loop ছাড়া। একে বলে vectorization(ভেক্টরাইজেশন) — নামটা শুনেই বুঝছ, Part I-এর vector-দের সাথে এর আত্মীয়তা গভীর।

৪.৩ Indexing: গোনা শুরু শূন্য থেকে

a = np.array([10, 20, 30, 40])
print(a[0])     # 10  — প্রথম element-এর index 0!
print(a[3])     # 40  — শেষ element-এর index (দৈর্ঘ্য - 1)
print(a[-1])    # 40  — ঋণাত্মক মানে পেছন থেকে
print(a[1:3])   # [20 30] — slice: index 1 থেকে 3-এর *আগে* পর্যন্ত

Python শূন্য থেকে গোনে। আর slice 1:3 মানে "১ ঢুকবে, ৩ ঢুকবে না" — Chapter 0.3-এর \(\{n : 1 \le n < 3\}\)-এর মতো: শুরুতে \(\le\), শেষে \(<\)

৪.৪ np.linspace ও plotting-এর মূল রেসিপি

মসৃণ curve আঁকার সার্বজনীন রেসিপি — Chapter 0.1-এর টেবিল-পদ্ধতিরই যান্ত্রিক রূপ:

x = np.linspace(-3, 3, 100)   # -3 থেকে 3 পর্যন্ত সমান দূরত্বে 100টা সংখ্যা
y = x**2                       # প্রতিটা x-এর জন্য y (elementwise!)
plt.plot(x, y)                 # বিন্দুগুলো জুড়ে দাও
plt.show()

১০০টা বিন্দু এত ঘন যে চোখে মসৃণ curve মনে হয়। টেবিল বানাও → বিন্দু বসাও → জোড়ো — এই তিন ধাপ কখনো বদলাবে না, function যত জটিলই হোক।


৫. Intuition — কেন সত্য?

কেন NumPy এত দ্রুত — আর এর সাথে Linear Algebra-র কী সম্পর্ক

Python-এর সাধারণ list-এ প্রতিটা element আলাদা আলাদা "প্যাকেটে" মোড়া থাকে — যোগ করার আগে Python প্রতিবার প্যাকেট খুলে দেখে ভেতরে কী। এক লাখ সংখ্যা মানে এক লাখবার প্যাকেট খোলা।

NumPy array হলো এক টানা সারিতে রাখা খোলা সংখ্যা — সবগুলো একই ধরনের, পাশাপাশি, computer-এর memory-তে। তাই NumPy পুরো সারিটার উপর একবারে কাজ চালাতে পারে (ভেতরে চলে দ্রুতগতির C ভাষার কোড, এমনকি processor-এর বিশেষ vector-নির্দেশনা)।

এখানেই সুন্দর মিলটা: Linear Algebra-ও ঠিক একই দর্শন — একশটা সংখ্যাকে একশটা আলাদা জিনিস না ভেবে একটা vector ভাবো, তারপর পুরোটার উপর এক অপারেশন চালাও। NumPy দ্রুত হওয়ার কারণ আর Linear Algebra শক্তিশালী হওয়ার কারণ একই: জিনিসগুলোকে একসাথে, এক unit হিসেবে দেখা। সামনের chapter-এ for loop যত কমবে, তোমার কোড তত বেশি "linear-algebraic" হবে।

কেন "আগে নিজে চালাও" এত জরুরি

গবেষণায় বারবার দেখা গেছে: শুধু পড়ে শেখা জ্ঞান দ্রুত মুছে যায়, হাতে করে শেখা জ্ঞান থেকে যায়। কোড হলো math-এর হাতেকলমে রূপ। বইয়ে \(\sum_{i=1}^{100} i = 5050\) পড়া এক জিনিস, আর np.arange(1, 101).sum() লিখে নিজের স্ক্রিনে 5050 ফুটে উঠতে দেখা আরেক জিনিস — দ্বিতীয়টা তুমি ভুলবে না। তাই নিয়ম করে নাও: এই বইয়ের প্রতিটা কোড-ব্লক নিজের notebook-এ টাইপ করে চালাবে। Copy-paste না — টাইপ। আঙুলও শিখুক।


৬. Code-এ কেমনে লিখে

এবার সব জোড়া লাগাই — জীবনের প্রথম সম্পূর্ণ plot, ধাপে ধাপে:

# ধাপ ১: হাতিয়ার আনো (প্রতি notebook-এর শুরুতে একবার)
import numpy as np
import matplotlib.pyplot as plt

# ধাপ ২: data বানাও — y = x² -এর জন্য
x = np.linspace(-3, 3, 100)    # 100টা x মান
y = x**2                        # প্রতিটার বর্গ (elementwise)

# ধাপ ৩: আঁকো ও সাজাও
plt.figure(figsize=(8, 5))                      # ক্যানভাসের মাপ (ইঞ্চিতে)
plt.plot(x, y, color='#1f77b4', linewidth=2.5,  # রেখা
         label='y = x²')
plt.scatter([-2, 0, 2], [4, 0, 4],              # তিনটা বিশেষ বিন্দু
            color='#d62728', s=80, zorder=5)
plt.xlabel('x')                                  # অক্ষের নাম
plt.ylabel('y')
plt.title('Amar prothom plot!')                  # শিরোনাম
plt.legend()                                     # লেজেন্ড দেখাও
plt.grid(True)                                   # গ্রিড
plt.show()                                       # ছবি হাজির!

Output ব্যাখ্যা: চালালে পাবে নিচের মতো ছবি — একটা নীল parabola(প্যারাবোলা — \(x^2\)-এর U-আকৃতির curve), তিনটা লাল বিন্দুসহ:

First plot

তোমার প্রথম curve। লক্ষ করো \((-2, 4)\) আর \((2, 4)\) — দুটোই curve-এর উপরে, কারণ \((-2)^2 = 2^2 = 4\) (Chapter 0.3-এর সেই "দুই তীর এক জায়গায় পড়া")। আর পুরো ছবিটা আসলে set-builder: \(\{(x,y) : y = x^2\}\) — "ছবি = সমীকরণ" এখন তোমার হাতের মুঠোয়।

প্রতিটা লাইন কী করছে আরেকবার দেখে নাও — plt.plot রেখা, plt.scatter ছাড়া ছাড়া বিন্দু, label + plt.legend() জোড়ায় কাজ করে, plt.show() সবশেষে ছবি দেখায়। এই কাঠামোটা মুখস্থ করার দরকার নেই — প্রতি chapter-এ এত বার লিখবে যে এমনিই মনে থাকবে।

# Bonus: আগের তিন chapter এক cell-এ!
x = np.linspace(0, 10, 50)
plt.plot(x, 5*x + 20, label='Rickshaw A: 5x + 20')   # Ch 0.2-এর লাইন
plt.plot(x, 7*x + 10, label='Rickshaw B: 7x + 10')
plt.scatter([5], [45], color='red', zorder=5)         # ছেদবিন্দু
plt.xlabel('distance (km)'); plt.ylabel('fare (taka)')
plt.legend(); plt.show()

print(np.sum(np.arange(1, 5)**2))    # Ch 0.3-এর Σi² = 30

Output ব্যাখ্যা: রিকশা-ভাড়ার সেই দুটো লাইন আর তাদের ছেদবিন্দু \((5, 45)\) — এবার তোমার নিজের হাতে আঁকা। আর শেষ লাইনে \(\Sigma\)-ও চলে এল। তিন chapter-এর math, দশ লাইনের কোড।


৭. Worked Examples

Example 1 — থার্মোমিটার function-এর graph

Chapter 0.1-এর \(F = 1.8C + 32\) function-টা \(C = -10\) থেকে \(40\) পর্যন্ত plot করো, আর শরীরের তাপমাত্রা \(37°C\) বিন্দুটা চিহ্নিত করো।

ধাপ ১: Data:

C = np.linspace(-10, 40, 100)
F = 1.8 * C + 32
ধাপ ২: বিশেষ বিন্দু: \(C=37\) হলে \(F = 1.8(37) + 32 = 98.6\) ধাপ ৩: আঁকা:
plt.plot(C, F, label='F = 1.8C + 32')
plt.scatter([37], [98.6], color='red', zorder=5)
plt.annotate('Body temp (37, 98.6)', (37, 98.6),
             textcoords='offset points', xytext=(-90, 10))
plt.xlabel('Celsius'); plt.ylabel('Fahrenheit')
plt.legend(); plt.show()
ফল: একটা সরলরেখা (linear function — যেমনটা জানতাম!), লাল বিন্দুটা ঠিক রেখার উপরে। Slope \(1.8\) মানে: ১ ডিগ্রি Celsius বাড়লে \(1.8\) ডিগ্রি Fahrenheit বাড়ে।

Example 2 — কোন বিন্দুগুলো লাইনের উপরে? (কোড দিয়ে set-membership)

Chapter 0.2-এর প্রশ্ন কোডে: \((2,3), (1,3), (-2,-1), (0,1)\) — কোনগুলো \(y = x + 1\) লাইনের উপরে?

ধাপ ১: প্রতিটা বিন্দুর জন্য শর্তটা check করো:

points = [(2, 3), (1, 3), (-2, -1), (0, 1)]
for (px, py) in points:
    on_line = (py == px + 1)          # শর্ত: y কি x+1-এর সমান?
    print(f"({px}, {py}) on line: {on_line}")
ধাপ ২: Output:
(2, 3) on line: True
(1, 3) on line: False
(-2, -1) on line: True
(0, 1) on line: True
ব্যাখ্যা: == জিজ্ঞেস করছে "সত্যিই সমান?" — ঠিক Chapter 0.2-এর "শর্ত মানে কিনা" পরীক্ষা। True পাওয়া বিন্দুরাই set \(\{(x,y) : y = x+1\}\)-এর element। Math-এর তিনটা ভাষা (geometry, algebra, set) আর কোড — চারটাই এক বিন্দুতে মিলল।

Example 3 — প্রথম সত্যিকারের data plot

পাঁচ দিনের তাপমাত্রা: সোম ৩১°, মঙ্গল ৩৩°, বুধ ৩০°, বৃহস্পতি ৩৪°, শুক্র ৩২°। Line plot আঁকো, গড় তাপমাত্রার একটা সমতল রেখা দাও।

ধাপ ১: Data ও গড়:

days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
temp = np.array([31, 33, 30, 34, 32])
avg = temp.mean()                  # np.sum(temp)/5 — Σ আবার!
print(avg)                          # 32.0
ধাপ ২: Plot:
plt.plot(days, temp, 'o-', label='daily temp')
plt.axhline(avg, color='red', linestyle='--', label=f'average = {avg}')
plt.ylabel('temperature (°C)'); plt.legend(); plt.show()
ফল: পাঁচটা বিন্দু জোড়া একটা ভাঙা রেখা, আর মাঝ বরাবর লাল dashed গড়-রেখা। লক্ষ করো বিন্দুগুলো গড়ের কখনো উপরে কখনো নিচে — আর Chapter 0.3-এর Problem 7 বলেছিল সেই উপরে-নিচের পার্থক্যগুলোর যোগফল ঠিক শূন্য। np.sum(temp - avg) চালিয়ে দেখো — 0.0 পাবে!


৮. Problems ও Solutions

এগুলো সব হাতে-কলমে — নিজের Jupyter Notebook-এ করো। Solution দেখার আগে অন্তত একবার error খাও — error message পড়তে শেখাও এই chapter-এর syllabus-এর অংশ!

Problem 1. Python-এ হিসাব করে অনুমান মিলিয়ে দেখো: \((a)\) 2 + 3 * 4 \((b)\) (2 + 3) * 4 \((c)\) 2 ** 3 \((d)\) 7 // 2 এবং 7 % 2 (নতুন দুটো চিহ্ন — চালিয়ে অর্থ আবিষ্কার করো!)

Solution

print(2 + 3 * 4)    # 14 — BODMAS: আগে গুণ (Chapter 0.1!)
print((2 + 3) * 4)  # 20 — বন্ধনী আগে
print(2 ** 3)       # 8 — ** মানে power: 2³
print(7 // 2)       # 3 — floor division: ভাগফলের পূর্ণ অংশ
print(7 % 2)        # 1 — modulo: ভাগশেষ
// আর % জোড়া মনে রাখো: \(7 = 2 \times 3 + 1\) — ভাগফল ৩, ভাগশেষ ১। (\(x\) % 2 == 0` দিয়েই Chapter 0.3-এ জোড় সংখ্যা চিনেছিলাম!)

Problem 2. একটা function f(x) লেখো যেটা \(3x - 2\) return করে। তারপর \(f(4), f(0), f(-2)\) print করে Chapter 0.1-এর Problem 5-এর উত্তরের সাথে মিলিয়ে দেখো।

Solution

def f(x):
    return 3*x - 2

print(f(4))    # 10
print(f(0))    # -2
print(f(-2))   # -8
তিনটাই হাতের হিসাবের সাথে মিলবে। Bonus: NumPy array-ও ঢোকানো যায় — f(np.array([4, 0, -2])) দিলে একবারে [10 -2 -8]! Function-টা না বদলেই — এটাই vectorization-এর জাদু।

Problem 3. np.linspace(0, 10, 5) কী দেবে — আগে অনুমান করো, পরে চালাও। তারপর এমন linspace লেখো যেটা \(-1\) থেকে \(1\) পর্যন্ত \(201\)টা বিন্দু দেয়, এবং তার প্রথম ৩টা ও শেষ ৩টা element print করো।

Solution

print(np.linspace(0, 10, 5))   # [ 0.   2.5  5.   7.5 10. ]
৫টা সংখ্যা, দুই প্রান্তসহ, সমান ফাঁকে। (অনেকে ভাবে ফাঁক হবে \(10/5=2\) — আসলে \(10/4 = 2.5\), কারণ ৫টা বিন্দুর মাঝে ফাঁক থাকে ৪টা!)
x = np.linspace(-1, 1, 201)
print(x[:3])    # [-1.   -0.99 -0.98]
print(x[-3:])   # [0.98 0.99 1.  ]
Slice [:3] = প্রথম তিনটা, [-3:] = শেষ তিনটা।

Problem 4. \(y = 2x + 1\) এবং \(y = x^2\) — দুটোকে একই ছবিতে plot করো (\(x\): \(-2\) থেকে \(4\)), legend সহ। ছবি দেখে বলো এরা কোথায় কোথায় ছেদ করেছে, তারপর algebra দিয়ে যাচাই করো।

Solution

x = np.linspace(-2, 4, 100)
plt.plot(x, 2*x + 1, label='y = 2x + 1')
plt.plot(x, x**2, label='y = x²')
plt.legend(); plt.grid(True); plt.show()
ছবিতে দুটো ছেদবিন্দু দেখা যাবে — একটা \(x \approx -0.4\), আরেকটা \(x \approx 2.4\)-এর কাছে।

Algebra: \(x^2 = 2x + 1 \Rightarrow x^2 - 2x - 1 = 0\)। Quadratic formula: \(x = \frac{2 \pm \sqrt{4+4}}{2} = 1 \pm \sqrt{2}\), অর্থাৎ \(x \approx -0.414\) এবং \(x \approx 2.414\) — ছবির অনুমানের সাথে মিলে গেল! ছবি আগে উত্তরের আন্দাজ দেয়, algebra সেটা নিখুঁত করে — এই জুটিই পুরো কোর্স।

Problem 5. np.arange(1, 101) ব্যবহার করে \((a)\) \(\sum_{i=1}^{100} i\) \((b)\) \(\sum_{i=1}^{100} i^2\) \((c)\) \(1\) থেকে \(100\)-এর মধ্যে জোড় সংখ্যাগুলোর যোগফল বের করো।

Solution

i = np.arange(1, 101)          # 1, 2, ..., 100
print(i.sum())                  # (a) 5050
print((i**2).sum())             # (b) 338350
print(i[i % 2 == 0].sum())      # (c) 2550
- \((a)\) \(5050\) — কিশোর Gauss-এর বিখ্যাত হিসাব: \(\frac{100 \times 101}{2}\) - \((b)\) \(338350\) — সূত্র \(\frac{n(n+1)(2n+1)}{6}\) দিয়েও মেলে - \((c)\)-এর i[i % 2 == 0] জিনিসটা দেখো: শর্ত দিয়ে বাছাই — boolean masking — এটা আসলে set-builder notation-এর NumPy রূপ: \(\{i : i \text{ জোড়}\}\)! Data science-এ প্রতিদিন লাগবে।

Problem 6. Chapter 0.2-এর Problem 6-এর internet package-দুটো (\(C_A = 20g + 500\), \(C_B = 50g + 200\)) \(g = 0\) থেকে \(20\) GB পর্যন্ত plot করো। ছেদবিন্দু \((10, 700)\)-তে একটা কালো বিন্দু দাও এবং ছবি থেকে পড়ে বলো: \(15\) GB-তে কোন লাইনটা নিচে?

Solution

g = np.linspace(0, 20, 100)
plt.plot(g, 20*g + 500, label='Alpha: 20g + 500')
plt.plot(g, 50*g + 200, label='Beta: 50g + 200')
plt.scatter([10], [700], color='black', zorder=5)
plt.xlabel('data (GB)'); plt.ylabel('cost (taka)')
plt.legend(); plt.grid(True); plt.show()
\(g = 15\)-তে Alpha-র লাইন নিচে (মানে সস্তা) — হাতের হিসাবে যেমন পেয়েছিলাম (\(800 < 950\))। "কোন লাইন নিচে" এক পলকে দেখা যায় — এটাই graph-এর শক্তি: চোখ এক সেকেন্ডে যা পড়ে, টেবিল থেকে তা পড়তে এক মিনিট লাগে।

Problem 7. ৫০০ জনের উচ্চতার নকল data বানাও: h = np.random.default_rng(42).normal(165, 8, 500) — গড় ১৬৫ cm, ছড়ানো ৮ cm। \((a)\) Histogram আঁকো (২৫টা bin)। \((b)\) h.mean(), h.min(), h.max() print করো। \((c)\) ১৮০ cm-এর চেয়ে লম্বা কতজন — boolean masking দিয়ে বের করো।

Solution

h = np.random.default_rng(42).normal(165, 8, 500)
plt.hist(h, bins=25)
plt.xlabel('height (cm)'); plt.ylabel('count'); plt.show()

print(h.mean())            # (b) ≈ 165.09 — গড় প্রায় 165 ✓
print(h.min(), h.max())    #     ≈ 141.5, 189.3
print((h > 180).sum())     # (c) 17 জন
- \((a)\) Histogram-টা ঘণ্টার আকৃতি — মাঝে (১৬৫-এর কাছে) সবচেয়ে বেশি মানুষ। এই "bell curve" স্মৃতিতে রাখো, statistics-এ এর নাম normal distribution। - \((c)\)-এর কৌশল: h > 180 দেয় ৫০০টা True/False; .sum()-এ True গোনা হয় ১ হিসেবে। "শর্ত → গোনা" — দুই অক্ষরের এই idiom data science-এ অমূল্য।

Problem 8 (challenge). একই figure-এ subplot দিয়ে দুটো ছবি পাশাপাশি আঁকো: বাঁয়ে \(y = x^2\), ডানে \(y = \sqrt{x}\) (দুটোই \(x: 0\) থেকে \(9\))। Hint: plt.subplots(1, 2)। তারপর এক বাক্যে লেখো: দুটো curve-এর সম্পর্ক কী?

Solution

x = np.linspace(0, 9, 100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
ax1.plot(x, x**2, color='#1f77b4'); ax1.set_title('y = x²')
ax2.plot(x, np.sqrt(x), color='#d62728'); ax2.set_title('y = √x')
plt.show()
সম্পর্ক: একটা আরেকটার উল্টো (inverse) function\(x^2\) মেশিন যা করে, \(\sqrt{x}\) মেশিন তা undo করে (\(\sqrt{3^2} = 3\))। ছবিতেও দেখা যায়: একটা curve আরেকটার \(45°\) রেখায় আয়না-প্রতিবিম্ব। Chapter 0.1-এর "undo" থেকে Part III-এর inverse matrix — undo-র গল্পটা বারবার ফিরবে।

(fig, (ax1, ax2) = plt.subplots(1, 2) ধাঁচটা এই বইয়ের figure script-গুলোতেও শত শত বার পাবে — এখন থেকে ওগুলোও তুমি পড়তে পারো!)


৯. Common ভুল

ভুল ১: = আর == গুলিয়ে ফেলা

  • if x = 5: — SyntaxError!
  • ✓ রাখার জন্য = (x = 5), তুলনার জন্য == (x == 5)। মনে রাখো: এক দাগ = আদেশ ("রাখো"), দুই দাগ = প্রশ্ন ("সমান কি?")।

ভুল ২: Indentation (শুরুর ফাঁকা জায়গা) এলোমেলো করা

  • def f(x):-এর পরের লাইন বাঁ ঘেঁষে লেখা → IndentationError
  • ✓ Python-এ ফাঁকা জায়গাই ব্যাকরণ: def, for, if-এর ভেতরের লাইনগুলো ঠিক ৪ space ভেতরে। Jupyter নিজেই সাধারণত ঠিক জায়গায় cursor রাখে — সেটার সাথে যুদ্ধ কোরো না।

ভুল ৩: import না করেই ব্যবহার করা / প্রতি cell-এ আবার install করা

  • NameError: name 'np' is not defined দেখে আতঙ্ক
  • ✓ প্রতিটা notebook-এর প্রথম cell-এ একবার import numpy as np আর import matplotlib.pyplot as plt চালাও — তারপর পুরো notebook-এ আর লাগবে না। (নতুন করে খুললে আবার চালাতে হবে — notebook-এর স্মৃতি বন্ধ করলেই মুছে যায়!)

ভুল ৪: List আর array গুলিয়ে ফেলা

  • [1, 2, 3] * 2 লিখে [2, 4, 6] আশা করা (পাবে [1, 2, 3, 1, 2, 3]!)
  • ✓ Math করতে চাইলে আগে np.array([1, 2, 3]) বানাও। সন্দেহ হলে type(x) print করো — list না numpy.ndarray দেখে নাও।

ভুল ৫: Error message না পড়ে হাল ছেড়ে দেওয়া

  • ❌ লাল লেখা দেখেই "আমার দ্বারা হবে না"
  • ✓ Error message হলো Python-এর চিঠি — শেষ লাইনটা পড়ো: NameError মানে নাম চেনেনি (বানান? import?), SyntaxError মানে লেখায় ভুল (কোলন? বন্ধনী?), IndexError মানে যত নম্বর element চেয়েছ তত নেই (শূন্য থেকে গোনা মনে আছে?)। Error-সহ লাইন নম্বরও লেখা থাকে। পেশাদার programmer-রা দিনে দশবার error খায় — পার্থক্য হলো তারা চিঠিটা পড়ে।

১০. এক নজরে

ধারণা এক লাইনে কোড
Python সহজ, ইংরেজির-মতো programming ভাষা x = 5, def f(x):
Jupyter Notebook কোড+লেখা+ছবির interactive খাতা cell-এ Shift+Enter
NumPy array সংখ্যার সারি যার উপর একবারে math চলে np.array([1,2,3]) * 2[2 4 6]
Vectorization loop ছাড়া পুরো array-তে অপারেশন x**2, a + b
Indexing/slicing শূন্য থেকে গোনা; 1:3 মানে ১ থেকে ৩-এর আগে a[0], a[-1], a[1:3]
Boolean masking শর্ত দিয়ে বাছাই — কোডের set-builder h[h > 180]
np.linspace দুই প্রান্তের মাঝে সমান ফাঁকে n-টা সংখ্যা np.linspace(-3, 3, 100)
Plot-রেসিপি data বানাও → আঁকো → সাজাও → show() plt.plot(x, y)
Plot-এর চার অস্ত্র line, scatter, bar, histogram plot / scatter / bar / hist
Error message Python-এর চিঠি — শেষ লাইন পড়ো NameError, SyntaxError

পরের Part-এর সেতু (Part 0 সমাপ্ত! 🎉): ভিত মেরামত শেষ। এখন তোমার হাতে আছে: সংখ্যা আর equation-এর সাহস (0.1), "ছবি = সমীকরণ"-এর চোখ (0.2), notation পড়ার ভাষা (0.3), আর কোড চালানোর হাত (0.4)। Part I-তে এই চারটা একসাথে জ্বলে উঠবে: আমরা দেখা করব এই পুরো কোর্সের নায়কের সাথে — Vector(ভেক্টর)। জানো কি, তুমি আসলে আজই vector বানিয়েছ? np.array([3, 2]) — ওটাই একটা vector, শুধু নামটা তখনো বলিনি। Chapter 1.1-এ দেখা হচ্ছে!

চোখ বন্ধ করে মনে করো (Part 0 recap): দাঁড়িপাল্লা (equation) → গ্রাফ কাগজে ঠিকানা \((x,y)\) → লুকানো ত্রিভুজ (distance) → সিঁড়ির খাড়াই (slope) → জিনিসের ব্যাগ (set) → input-output মেশিন (function) → \(\Sigma\) = for-loop → আর তোমার নিজের আঁকা প্রথম নীল parabola। এই আটটা ছবি মাথায় থাকলে Part 0 তোমার সাথেই আছে।


📓 Notebook Project

ch04-project notebooknotebooks/part-00/ch04-project.ipynb: Part 0-এর flagship project — বাংলাদেশের বিভাগভিত্তিক জনসংখ্যা ও আয়তনের data দিয়ে নিজের প্রথম সম্পূর্ণ data-visualization: bar chart, scatter plot (জনঘনত্ব আবিষ্কার!), আর Part 0-র সব কৌশল এক জায়গায়।