
This course includes our updated coding exercises so you can practice your skills as you learn.
See a demo
Welcome to the course! In this opening lecture, you'll get a clear overview of what this course is all about, how it’s structured, and what skills you’ll gain by the end. Whether you're transitioning from C#/.NET into the world of Python or looking to sharpen your data science skills, this course is designed to make that journey smooth and practical. Let’s set the stage for a productive and insightful learning experience.
This course isn’t your typical Python bootcamp. It’s designed specifically for developers with a C#/.NET background who want to break into data science using Python. In this lecture, we’ll discuss the unique perspective this course offers, how it bridges the gap between C# and Python thinking, and why your existing skills as a .NET developer are a powerful asset as you learn Python for data analysis and machine learning.
In this lecture, I want to walk you through the complete course code that is available for download.
You’ll find a ZIP file attached below, which contains all the code used throughout this course — organized section-wise and lecture-wise.
Each section folder contains the exact files that were used in the corresponding lectures, including Python scripts, Jupyter Notebooks, and supporting files.
This means you can easily navigate to any lecture and find the exact code that was demonstrated.
Now, this is a complete working archive — it’s not a simplified or reduced version.
So depending on your learning style, you can use it in different ways.
If you are a beginner, I recommend writing the code yourself while following the lectures. That will help reinforce your understanding.
If you are more experienced, especially coming from a C# or .NET background, you may prefer to explore the files directly, run them, and experiment with variations.
So feel free to download the ZIP, extract it, and use it whenever it helps your learning.
But again, this step is completely optional — everything will be built step by step in the lectures as well.
Before we dive into coding, you’ll need to install Python and its package manager pip. This lecture walks you through the process for both Windows and macOS systems. You'll also learn how to verify your installation and resolve common issues, ensuring your development environment is ready for hands-on practice.
Visual Studio Code is the primary editor we’ll use throughout the course. In this lecture, you’ll learn how to install VS Code, configure it for Python development, and add essential extensions to enhance your workflow. This setup ensures a smooth experience as you start writing and debugging Python code with productivity features you're already used to from C# tooling.
Jupyter Notebooks are a core tool in the data science world. In this lecture, we’ll show you how to install Jupyter and run it seamlessly inside VS Code. You'll learn how to create and execute Python code in notebooks, visualize outputs inline, and structure your data workflows in an interactive, notebook-style format that’s perfect for experimentation.
It’s time to write your first Python script! In this hands-on lecture, we’ll create a basic .py file, run it from the terminal, and see how Python handles script execution compared to C#. You’ll get familiar with the Python syntax, indentation rules, and how to print outputs — setting the foundation for more complex logic and data operations to come.
This lecture introduces you to Python’s variable declaration and core data types — integers, floats, strings, and booleans — while comparing them to equivalent C# types. You'll see how Python’s dynamic typing differs from C#’s static typing and understand how variable assignment and type inference work in Python. A clear side-by-side comparison makes the transition seamless for .NET developers.
String formatting is a common task, and Python does it in a clean and expressive way using f-strings. In this lecture, you'll compare Python’s f-strings with C#’s string interpolation and format methods. We’ll demonstrate how to embed expressions inside strings, format numbers and align text — all in a Pythonic style that mirrors familiar C# techniques.
Python’s approach to numbers is simple yet powerful. This lecture walks through basic arithmetic, operator precedence, type conversion (int to float and vice versa), and introduces Python’s built-in math module. If you're used to C#’s numerical operations, you’ll feel at home — but will also appreciate Python’s expressive syntax and flexibility.
Conditional logic is at the heart of programming. Here, you’ll learn how Python handles booleans (True, False), logical operators, and conditional branching using if, elif, and else. We’ll compare Python’s indentation-based structure with the C# block-style braces, helping you quickly adapt your control flow logic into Python’s clean syntax.
Loops in Python are intuitive and elegant. In this lecture, you’ll explore the for and while loops and see how Python handles iteration over sequences like lists and ranges. We'll compare these constructs to foreach and while in C#, and you’ll learn Pythonic idioms such as loop unpacking and range-based iteration.
Functions are fundamental building blocks. This lecture covers how to define functions using def, pass arguments (including default values), and return results. We'll explore similarities and differences with C# methods, and show how Python's flexibility with parameters — including keyword arguments — opens up powerful use cases.
Unlike C#, Python uses indentation instead of curly braces to define code blocks. This lecture clarifies the importance of consistent whitespace, shows you how Python determines scope, and offers tips to avoid common pitfalls. You'll also see how modern editors like VS Code help maintain proper indentation automatically.
In this lecture, you’ll get access to a downloadable side-by-side syntax cheat sheet comparing Python and C# for all key concepts covered so far — variables, loops, conditionals, functions, and more. It’s a quick reference tool you can print or keep handy while you’re learning or coding in Python with your C# brain.
Lists are one of the most versatile data structures in Python. This lecture introduces you to Python lists and compares them with C#’s List<T>. You’ll learn how to declare lists, store different data types, and understand Python’s flexibility in handling heterogeneous elements. This foundation sets you up for all types of list operations used throughout the course.
In this lecture, we dive into how to update list contents — adding, removing, replacing elements — and iterate through them using loops. You'll learn about methods like .append(), .remove(), .insert(), and how they compare with C#’s list manipulation patterns. We'll also show Pythonic ways of looping, making list traversal concise and expressive.
Here, we explore Python’s powerful slicing syntax to access subsets of lists — a concept that doesn’t have a direct equivalent in C#. You'll learn how to index from the front and back, slice with steps, and reverse lists using elegant one-liners. This lecture helps you write compact and readable code for data manipulation.
List comprehensions are Python’s most elegant feature for transforming and filtering data in a single readable expression. In this lecture, you'll explore how to create lists using conditions, all in one line. This is Python’s answer to LINQ-style expressions in C# and is a game-changer for data transformation workflows.
Tuples in Python are like fixed-size collections — similar to ValueTuple in C#, but more commonly used in Python. This lecture introduces the basics of creating, accessing, and using tuples in practical scenarios. You’ll understand why immutability matters and where tuples fit in data pipelines.
Now that you know what tuples are, this lecture shows how Python uses packing and unpacking to simplify function returns, swapping variables, and multiple assignments. You’ll see practical examples that showcase how unpacking boosts code readability and avoids boilerplate — a technique rarely seen in C#.
Dictionaries are Python’s equivalent of Dictionary<TKey, TValue> in C#. In this lecture, we go hands-on with creating dictionaries, accessing values by key, updating entries, and removing key-value pairs. You’ll understand how Python’s dicts offer fast lookups and flexible syntax that’s well-suited for structured data.
Building on the previous lecture, we now explore how to safely remove dictionary items using .pop() and .get() to avoid runtime errors. You’ll also learn how to loop over keys, values, and key-value pairs — with clean and idiomatic Python syntax. This lecture also covers real-world examples where dictionaries simplify data modeling.
In this lecture, you’ll learn how Python sets work and why they are ideal for handling unique data. We’ll explore how sets differ from lists and dictionaries, especially in terms of ordering, duplication, and performance characteristics.
You will:
Understand how sets store unique, unordered elements
Create sets using literals and the set() constructor
Add, remove, and update elements
Perform set operations like union, intersection, difference
Compare Python sets with HashSet<T> in C#
By the end of this lecture, you’ll be able to confidently use sets to remove duplicates, compare collections, and perform efficient membership testing in data science workflows.
In this lecture, we explore two powerful iteration helpers in Python: range() and enumerate(). These tools make looping more expressive and Pythonic, especially compared to index-based loops in C#.
You will:
Use range() to generate numeric sequences with start, stop, and step
Understand how range() behaves internally (lazy sequence)
Replace manual index counters with enumerate()
Access both index and value cleanly inside loops
Compare Python iteration patterns with C# for and foreach
By the end of this lecture, you’ll write cleaner, more readable loops and understand how Python encourages concise iteration patterns—critical for data processing and analysis tasks.
In this lecture, we take a practical problem—cleaning messy user input—and solve it the Pythonic way using list comprehensions. Students will learn how to strip unwanted spaces, ignore empty or null entries, and standardize names into a consistent format (e.g., turning " alice " and "BOB" into "Alice" and "Bob").
We’ll walk through the Python solution step by step, showing how a single list comprehension can combine filtering and transformation into a compact, readable expression. Then we’ll compare it with the C# approach using LINQ (Where + Select), so that learners coming from a .NET background can see the direct parallels.
By the end of this example, students will clearly understand how list comprehensions let you clean and normalize data in just one line, making them an essential tool for any data science workflow.
In this lecture, we explore how to generate and filter perfect squares using Pythonic list comprehensions. Starting from a range of numbers, we apply a condition that selects only those values whose square roots are whole numbers—ensuring they are true perfect squares. Each number is then paired with its square, giving us clean, structured output like (n, n²).
We will also compare the equivalent approach in C# using LINQ with Where and Select, so learners familiar with .NET can clearly see how the same idea translates across languages. To keep results manageable, we’ll demonstrate how to preview just the first few entries using slicing in Python or Take() in C#.
By the end of this example, students will appreciate how comprehensions make it easy to express mathematical patterns in a concise, elegant, and highly readable form.
In this lecture, we tackle the common problem of working with nested lists—lists within lists—and show how to flatten them into a single sequence. Using a Python list comprehension with a double for loop, we take a grid-like structure such as [[1,2,3],[4,5],[6]] and transform it into a simple flat list [1,2,3,4,5,6].
On the C# side, we achieve the same result with LINQ’s SelectMany, which expands each inner list into one continuous collection. This side-by-side comparison highlights the expressive power of comprehensions in Python and the composable elegance of LINQ in C#.
By the end of this example, students will understand how to flatten nested structures efficiently, an essential skill when handling tabular or hierarchical data in real-world projects.
In this lecture, we flip the direction of a mapping by learning how to invert a dictionary. Starting with a dictionary that maps users to roles, such as { "alice": "admin", "bob": "editor", "cara": "admin" }, we reorganize it into a structure that maps each role back to all its users: { "admin": ["alice","cara"], "editor": ["bob"] }.
In Python, this is done concisely with a dictionary comprehension that groups users by their roles. In C#, the same inversion is achieved with LINQ using GroupBy and ToDictionary. Along the way, we also handle the case where multiple keys share the same value, ensuring that all users with the same role are collected into a list.
By the end of this example, students will see how dictionary inversion provides a powerful way to reorganize and regroup data, a technique widely useful in data cleaning, reporting, and analytics.
In this lecture, we demonstrate how to reorganize structured data by building a dictionary directly from rows of tuples. Starting with a small dataset like [(101, "Alice", 88), (102, "Bob", 72), (103, "Cara", 95)], we transform it into a dictionary keyed by student ID, where each entry contains the corresponding name and score.
In Python, we achieve this with a clean dictionary comprehension, unpacking each tuple into (id, name, score) and creating entries such as:
{101: {"name": "Alice", "score": 88}, ...}
In C#, we use ToDictionary, selecting the id as the key and constructing an anonymous object with name and score as the value.
By the end of this example, students will understand how to reshape tabular data into dictionaries for quick lookups, a technique that is widely used in building indexes, optimizing queries, and preparing data for analysis.
In this lecture, we explore how to use comprehensions for conditional mapping—assigning values based on a condition. Our case study is generating a simple Pass/Fail grading system from a list of student scores.
In Python, we use a conditional expression ("Pass" if score >= 50 else "Fail") inside a list comprehension, applying the rule to every score in one concise line of code. In C#, we achieve the same with the ternary operator score >= 50 ? "Pass" : "Fail" inside a LINQ Select.
This example highlights how both languages support inline conditional logic for data transformation, allowing you to filter or label values without writing verbose loops.
By the end of this lecture, students will clearly understand how to apply conditional logic directly within comprehensions, making their code cleaner, shorter, and easier to read.
In this lecture, we apply list and dictionary comprehensions to a real-world scenario: analyzing log files. Given a set of log entries with users and their actions, we extract the usernames, filter out system processes, and then count how many times each user appears. Finally, we build a leaderboard showing the most active users ranked by activity.
In Python, this is done with a nested list comprehension for extracting users, combined with collections.Counter to count frequencies and sorting to produce a leaderboard. In C#, we achieve the same result using LINQ’s SelectMany, Where, GroupBy, and OrderByDescending.
This example shows how comprehensions and LINQ pipelines can turn messy, unstructured log data into meaningful insights with very little code. By the end of the lecture, students will appreciate how to use these tools for data cleaning, counting, and ranking tasks—a skill directly applicable to data science, analytics, and real-world application monitoring.
In this lecture, you’ll learn how to work with plain text files in Python—an essential skill for data processing and automation tasks.
You will:
Open files using open() with different modes (r, w, a)
Read file contents using read(), readline(), and readlines()
Write and append text safely
Use the with statement for automatic resource management
Understand how file handling in Python compares with StreamReader and StreamWriter in C#
By the end of this lecture, you’ll be able to read from and write to text files confidently—an important foundation before moving into structured data formats like CSV and JSON.
In this lecture, we move from plain text files to structured data by working with CSV files using Python’s built-in csv module.
You will:
Understand the structure of CSV (Comma-Separated Values) files
Use csv.reader to iterate through rows
Work with headers using csv.DictReader
Handle data type conversion (strings to int/float)
Compare CSV parsing in Python with reading tabular data in C#
By the end of this lecture, you’ll be able to load structured tabular data from CSV files—preparing you for advanced data manipulation with pandas in the upcoming lectures
In this lecture, we explore how to work with JSON files in Python, a data format you will encounter frequently in real-world applications, APIs, and data workflows.
You’ll learn how to:
Read JSON data from a file using Python’s built-in json module
Understand how JSON structures map naturally to Python lists and dictionaries
Filter and modify JSON data using Pythonic patterns
Write updated data back to disk in a clean, readable format
? Hands-On Practice
This lecture includes a downloadable Jupyter notebook along with the sample files users.json and users_updated.json. After watching the video, download these resources from the Resources section and run the notebook locally to reinforce the concepts covered.
This lesson builds the foundation for upcoming lectures, where we move into pandas and begin working with structured data using DataFrames.
In this lecture, you are introduced to pandas, the most widely used Python library for working with structured data. You’ll learn how to load a CSV file into a pandas DataFrame and perform essential inspection steps to understand the data before analysis. Using a pre-executed Jupyter notebook, the lecture focuses on interpreting pandas output—previewing rows, checking dataset size and structure, understanding data types, and generating quick summary statistics—rather than live coding. This lecture establishes a solid foundation for practical data analysis workflows using pandas.
In this lecture, you will learn how to filter, sort, and apply basic aggregation using pandas to work effectively with tabular data.
Using the existing DataFrame from the previous lecture, we cover filtering with conditions, sorting by columns, selecting relevant data, and calculating simple aggregates such as count and average. The concepts are explained from a C#/.NET developer’s perspective, with clear parallels to familiar LINQ operations.
A downloadable Jupyter notebook is included so you can run the examples yourself and explore the results at your own pace.
How Python lists and NumPy arrays differ conceptually and technically
Why NumPy arrays are faster and more memory-efficient for numerical data
How NumPy arrays compare to C# arrays and other strongly typed structures
When Python lists are still appropriate—and when they are not
Why nearly all data science and ML libraries are built on NumPy
This lecture sets the foundation for all upcoming NumPy and pandas work in this section.
A fully written Jupyter notebook is included as a downloadable resource, and a short walkthrough is provided to help you explore the examples at your own pace.
In this lecture, you’ll explore how NumPy performs fast, element-wise operations and how indexing works differently compared to standard Python lists.
You will:
Perform element-wise arithmetic (+, -, *, /) on arrays
Apply mathematical functions across entire arrays
Understand vectorization and why it’s faster than loops
Use slicing and multi-dimensional indexing
Work with boolean masks for filtering data
By the end of this lecture, you’ll be able to manipulate numerical datasets efficiently using NumPy arrays—an essential skill for scientific computing and data analysis.
In this lecture, we dive into one of NumPy’s most powerful features: broadcasting. You’ll understand how arrays of different shapes can still work together mathematically.
You will:
Understand array shapes and dimensions
Learn NumPy’s broadcasting compatibility rules
Perform operations between scalars, vectors, and matrices
Identify and debug shape mismatch errors
Compare broadcasting concepts with manual looping approaches
By the end of this lecture, you’ll confidently apply broadcasting to write concise, high-performance numerical code without explicit loops.
In this lecture, we shift focus to real-world data challenges—specifically missing or incomplete values in datasets.
You will:
Detect missing values in pandas DataFrames
Use isnull(), dropna(), and fillna()
Replace missing values using statistical measures (mean, median)
Understand the impact of missing data on analysis
Apply practical cleaning strategies before modeling
By the end of this lecture, you’ll be able to prepare messy datasets for analysis—an essential step in every data science workflow.
In this lecture, you’ll learn how to summarize and aggregate data using pandas—similar in spirit to LINQ’s GroupBy in C#.
You will:
Use groupby() to segment data by categories
Apply aggregation functions like mean(), count(), and sum()
Generate summary tables from raw datasets
Chain grouping with sorting and filtering
Understand how grouping helps reveal insights in data
By the end of this lecture, you’ll be able to transform raw datasets into meaningful summaries—an essential analytical skill for reporting and decision-making.
In this lecture, you’ll learn how to create line plots using matplotlib to visualize trends over time or ordered sequences.
You will:
Understand the basic structure of a matplotlib plot
Plot single and multiple lines on the same graph
Control axes, titles, labels, and legends
Understand how x-values are inferred when not explicitly provided
Interpret trends and patterns from line charts
By the end of this lecture, you’ll be able to create clean, professional line plots to visualize trends—an essential skill for time-series and performance analysis.
In this lecture, we explore bar charts and scatter plots to compare categories and analyze relationships between variables.
You will:
Create bar charts for categorical comparisons
Customize bar positions and labels
Build scatter plots to visualize relationships
Understand when to use bar vs scatter plots
Interpret correlation visually from scatter patterns
By the end of this lecture, you’ll confidently choose and create the right visualization for comparison and relationship-based analysis.
In this lecture, we introduce seaborn to create more advanced statistical visualizations with minimal code.
You will:
Generate heatmaps to visualize correlation matrices
Create boxplots to understand data distribution
Customize themes and styles
Compare seaborn’s abstraction layer with raw matplotlib
Interpret statistical patterns visually
By the end of this lecture, you’ll be able to produce insightful statistical charts suitable for real-world data analysis and reporting.
In this lecture, we design a mini project where you’ll build a simple analytics dashboard using the visualization techniques learned so far.
You will:
Load and prepare a regional sales dataset
Create multiple plots (line, bar, scatter)
Summarize insights across regions and time periods
Combine visualizations into a cohesive analytical narrative
Apply best practices in chart readability and layout
By the end of this lecture, you’ll understand how to convert raw business data into a structured visual analytics story.
In this hands-on lecture, we implement the complete mini project inside a Jupyter Notebook.
You will:
Execute the project step-by-step in code cells
Clean and prepare the dataset
Generate all required visualizations
Interpret results directly from notebook outputs
Structure a notebook professionally for presentation
By the end of this lecture, you’ll have a fully working analytics notebook that demonstrates your ability to combine data processing and visualization in a practical data science workflow.
In this lecture, we take the first practical step into machine learning using scikit-learn. You will learn how Python can classify both text-based data and numeric data by converting inputs into a form that a machine learning model can understand.
We will walk through the basic ML workflow: preparing data, training a model, making predictions, and understanding the output. The focus is not on advanced theory, but on seeing how a simple classification model works end-to-end.
By the end of this lecture, you will understand how scikit-learn helps us move from raw data to meaningful predictions — a key first step toward practical data science.
In this hands-on Jupyter Notebook demo, we apply scikit-learn to build two practical classification models — one based on numeric data and another based on text data.
First, we create a simple model to classify student scores into Pass/Fail, demonstrating how machine learning works with structured numerical inputs. This helps you understand the core workflow of training, testing, and evaluating a model.
Next, we move to a real-world scenario by building a spam detection system, where text messages are classified as spam or not spam. You will see how text data is transformed into numerical features and then used for prediction.
This dual approach gives you a clear understanding of how the same machine learning pipeline can be applied to both numbers and text.
By the end of this lecture, you will have implemented two complete classification examples and gained confidence in using scikit-learn within a Jupyter Notebook environment.
In this lecture, we focus on one of the most important concepts in machine learning — the difference between training data and testing data, and how they impact model performance.
You will learn why a dataset must be split before training, and how this helps us evaluate whether a model can generalize to unseen data. We then explore how accuracy is calculated and what it actually tells us about the model’s performance.
Finally, we look at how models generate predictions and how to interpret those outputs in a practical context.
By the end of this lecture, you will clearly understand how to evaluate a machine learning model and why training and testing separation is critical for building reliable solutions.
In this hands-on Jupyter Notebook demo, we extend our understanding of machine learning by working with a larger, more realistic text dataset for spam detection.
You will see how a collection of text messages is processed, transformed into numerical features, and then used to train a classification model. The focus is on understanding how training vs testing works in practice, and how model performance is evaluated using accuracy.
We also examine how predictions are generated on unseen messages and what those predictions mean in a real-world context.
By the end of this lecture, you will have a clearer understanding of how machine learning models handle larger datasets and how the training, testing, and prediction cycle applies to text-based problems like spam detection.
In this lecture, we complete the machine learning workflow by using a trained model on new, unseen input data.
You will learn how to take a model that has already been trained and apply it to fresh data to generate predictions. We focus on maintaining consistency in the pipeline — ensuring that any transformations (such as text vectorization or feature scaling) used during training are also applied to new inputs before prediction.
Through practical examples, you will see how real-world systems use trained models to make decisions on incoming data, whether it is classifying text or evaluating numerical inputs.
By the end of this lecture, you will understand how to move from model training to real-world usage, where predictions on new data become the primary goal of any machine learning system.
In this hands-on Jupyter Notebook demo, we complete the machine learning lifecycle by applying a trained model to entirely new input data.
Using the spam detection model built earlier, we now introduce a new set of unseen messages—separate from the training dataset—to evaluate how well the model performs in a real-world scenario. You will see how these messages are first processed using the same transformation steps (such as vectorization) and then passed into the trained model for prediction.
This exercise reinforces a critical concept in machine learning: ensuring that the same preprocessing pipeline used during training is consistently applied to new data before making predictions.
By the end of this demo, you will clearly understand how trained models are deployed in practice to classify new inputs, and how this step forms the foundation of real-world applications like spam filtering systems.
In this section, we took our first practical step into machine learning by building and understanding a complete classification workflow using scikit-learn.
We began by training simple models on both numerical data (such as student scores for pass/fail classification) and text data (spam detection), demonstrating how machine learning can be applied across different types of inputs. You saw how raw data is transformed into a format suitable for modeling and how a classifier learns patterns from that data.
We then explored the critical concept of training vs testing, understanding why datasets must be split and how accuracy helps us evaluate model performance on unseen data. This provided the foundation for assessing whether a model is reliable.
Through hands-on Jupyter Notebook demos, we applied these concepts to larger datasets and observed how models behave in more realistic scenarios. Finally, we completed the pipeline by using a trained model on entirely new input data, reinforcing how machine learning systems operate in real-world applications.
By the end of this section, you should now have a clear understanding of:
the end-to-end machine learning workflow
how to train, evaluate, and use classification models
how the same pipeline applies to both numeric and text-based problems
This forms a strong foundation for exploring more advanced machine learning concepts and real-world data science applications.
Ever felt curious about Python and data science but didn’t know where to begin? Maybe you’re a C# or .NET developer, like me, who’s been coding for years—but now you keep hearing words like “pandas”, “Jupyter”, or “machine learning”, and it all feels a bit... out there?
You're not alone. I was there too. I know what it’s like to open a Python tutorial and immediately feel lost—different syntax, different tools, and everything explained like you already have a PhD in statistics.
That’s exactly why I created this course.
This is for people like us—developers who already know how to code, but want to step into Python and data science without being buried in theory, jargon, or overly academic lectures.
We’ll start simple. I’ll walk you through installing Python, using VS Code, and writing your first scripts. Then we’ll move to data analysis—using real datasets to explore, filter, group, and visualize. By the end, we’ll even train a basic machine learning model. All explained in plain English, with references to how it compares to C#.
No prior Python experience needed. No math anxiety required.
If you’re a C# dev looking for a practical, no-fluff guide to learning Python for data work—this course is your first step.
Let’s do it together.
From curly braces to clean data—let's make Python your second language.