Skip to content

Instantly share code, notes, and snippets.

@AFirooz
Last active May 30, 2025 16:29
Show Gist options
  • Save AFirooz/17f21f7e869ed5e5123bbe742d6e3713 to your computer and use it in GitHub Desktop.
Save AFirooz/17f21f7e869ed5e5123bbe742d6e3713 to your computer and use it in GitHub Desktop.
Misc Learn
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "c930b153",
"metadata": {},
"source": [
"# <span style='color:Tomato;'>Learn Pandas Intervals</span>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68ebd901bf2c8c73",
"metadata": {
"ExecuteTime": {
"end_time": "2024-02-01T16:41:40.124382336Z",
"start_time": "2024-02-01T16:41:40.038216365Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"# Creating a sample DataFrame with Interval objects\n",
"data = [\n",
" 'path/to/file1.pkl',\n",
" 'path/to/file2.pkl',\n",
" 'path/to/file3.pkl',\n",
" 'path/to/file4.pkl']\n",
"\n",
"labels = ['label1', 'label2', 'label3', 'label4']\n",
"\n",
"indices = [\n",
" pd.Interval(left=0, right=10, closed='left'), # 10 elements\n",
" pd.Interval(left=10, right=25, closed='left'), # 15 elements\n",
" pd.Interval(left=25, right=30, closed='left'), # 5 elements\n",
" pd.Interval(left=30, right=40, closed='left') # 10 elements\n",
"]\n",
"\n",
"df = pd.DataFrame(data={'data': data, 'label': labels}, index=indices)\n",
"\n",
"# df.loc[0]\n",
"# df.index[-1].right\n",
"# df.loc[15, 'data']\n",
"df.shape\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ca8842fa24d08007",
"metadata": {
"ExecuteTime": {
"end_time": "2024-01-23T17:03:03.433006747Z",
"start_time": "2024-01-23T17:03:03.370060321Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"df.replace(['label1'], [pd.NA])\n"
]
},
{
"cell_type": "markdown",
"id": "83024ed9",
"metadata": {},
"source": [
"# <span style='color:Tomato;'>Learn Numpy where()</span>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fd5b797b2e4f83b6",
"metadata": {
"ExecuteTime": {
"end_time": "2023-12-21T16:02:06.316564547Z",
"start_time": "2023-12-21T16:02:06.304215458Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"data = np.random.randint(100, size=(5, 7))\n",
"df = pd.DataFrame(data, columns=['A', 'B', 'C', 'D', 'E', 'F', 'G'])\n",
"df\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "320f8035a90949b",
"metadata": {
"ExecuteTime": {
"end_time": "2023-12-21T16:02:00.817313974Z",
"start_time": "2023-12-21T16:02:00.773909930Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"a = [0, 0, 1, 2, 8, 0, 2, 8]\n",
"s = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']\n",
"aa = np.array(a)\n",
"ss = np.array(s)\n",
"np.where(ss == 'c') # returns an array that contain all the indexes where the elements of ss equal 'c'\n"
]
},
{
"cell_type": "markdown",
"id": "5817885b",
"metadata": {},
"source": [
"# <span style='color:Tomato;'>Learn Pandas Multi Level Axis</span>"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "432561bb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead tr th {\n",
" text-align: left;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th>Department</th>\n",
" <th colspan=\"2\" halign=\"left\">Sales</th>\n",
" <th colspan=\"2\" halign=\"left\">Marketing</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Quarter</th>\n",
" <th>A1</th>\n",
" <th>A2</th>\n",
" <th>B1</th>\n",
" <th>B2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Alice</th>\n",
" <td>130</td>\n",
" <td>175</td>\n",
" <td>185</td>\n",
" <td>64</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bob</th>\n",
" <td>180</td>\n",
" <td>195</td>\n",
" <td>71</td>\n",
" <td>96</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Charlie</th>\n",
" <td>88</td>\n",
" <td>163</td>\n",
" <td>94</td>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diana</th>\n",
" <td>91</td>\n",
" <td>173</td>\n",
" <td>148</td>\n",
" <td>51</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"Department Sales Marketing \n",
"Quarter A1 A2 B1 B2\n",
"Alice 130 175 185 64\n",
"Bob 180 195 71 96\n",
"Charlie 88 163 94 59\n",
"Diana 91 173 148 51"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"\n",
"# Create DataFrame with MultiLevel Column Headers\n",
"arrays_cols = [['Sales']*2 + ['Marketing']*2,\n",
" ['A1', 'A2', 'B1', 'B2']]\n",
"\n",
"columns = pd.MultiIndex.from_arrays(arrays_cols, names=['Department', 'Quarter']) # Note tha multilevel columns (and index) have `names` attribute (like pd.Series)\n",
"\n",
"df_mcols = pd.DataFrame(\n",
" np.random.randint(50, 200, size=(4, 4)),\n",
" index=['Alice', 'Bob', 'Charlie', 'Diana'],\n",
" columns=columns\n",
")\n",
"\n",
"df_mcols\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "770ec420",
"metadata": {},
"outputs": [],
"source": [
"df_mcols.loc[:, [('Sales', 'A1'), ('Marketing', 'B2')]]\n"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "8ea28a7f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th>Revenue</th>\n",
" <th>Customers</th>\n",
" <th>Products</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Region</th>\n",
" <th>Store</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th rowspan=\"2\" valign=\"top\">North</th>\n",
" <th>Store1</th>\n",
" <td>1000</td>\n",
" <td>45</td>\n",
" <td>120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Store2</th>\n",
" <td>1200</td>\n",
" <td>52</td>\n",
" <td>140</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"2\" valign=\"top\">South</th>\n",
" <th>Store1</th>\n",
" <td>800</td>\n",
" <td>38</td>\n",
" <td>95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Store2</th>\n",
" <td>900</td>\n",
" <td>41</td>\n",
" <td>105</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Revenue Customers Products\n",
"Region Store \n",
"North Store1 1000 45 120\n",
" Store2 1200 52 140\n",
"South Store1 800 38 95\n",
" Store2 900 41 105"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Create DataFrame with MultiLevel Index\n",
"arrays_idx = [['North', 'North', 'South', 'South'],\n",
" ['Store1', 'Store2']*2 ]\n",
"\n",
"index = pd.MultiIndex.from_arrays(arrays_idx, names=['Region', 'Store'])\n",
"\n",
"df_midx = pd.DataFrame({\n",
" \"Revenue\": [1000, 1200, 800, 900],\n",
" \"Customers\": [45, 52, 38, 41],\n",
" \"Products\": [120, 140, 95, 105]},\n",
" index=index\n",
")\n",
"\n",
"df_midx\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "abae3b14",
"metadata": {},
"outputs": [],
"source": [
"df_midx.loc['North']\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "690b5c48",
"metadata": {},
"outputs": [],
"source": [
"df_midx.loc[[('South', \"Store2\"), (\"North\", \"Store1\")]]\n"
]
},
{
"cell_type": "markdown",
"id": "f3343c1c",
"metadata": {},
"source": [
"## remove multi level axis"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "76b166aa",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Sales_A1</th>\n",
" <th>Sales_A2</th>\n",
" <th>Marketing_B1</th>\n",
" <th>Marketing_B2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Alice</th>\n",
" <td>130</td>\n",
" <td>175</td>\n",
" <td>185</td>\n",
" <td>64</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bob</th>\n",
" <td>180</td>\n",
" <td>195</td>\n",
" <td>71</td>\n",
" <td>96</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Charlie</th>\n",
" <td>88</td>\n",
" <td>163</td>\n",
" <td>94</td>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diana</th>\n",
" <td>91</td>\n",
" <td>173</td>\n",
" <td>148</td>\n",
" <td>51</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Sales_A1 Sales_A2 Marketing_B1 Marketing_B2\n",
"Alice 130 175 185 64\n",
"Bob 180 195 71 96\n",
"Charlie 88 163 94 59\n",
"Diana 91 173 148 51"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_mcols.columns = [f\"{h1}_{h2}\" for (h1, h2) in df_mcols.columns]\n",
"df_mcols\n"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "2f786e62",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Region</th>\n",
" <th>Store</th>\n",
" <th>Revenue</th>\n",
" <th>Customers</th>\n",
" <th>Products</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>North</td>\n",
" <td>Store1</td>\n",
" <td>1000</td>\n",
" <td>45</td>\n",
" <td>120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>North</td>\n",
" <td>Store2</td>\n",
" <td>1200</td>\n",
" <td>52</td>\n",
" <td>140</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>South</td>\n",
" <td>Store1</td>\n",
" <td>800</td>\n",
" <td>38</td>\n",
" <td>95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>South</td>\n",
" <td>Store2</td>\n",
" <td>900</td>\n",
" <td>41</td>\n",
" <td>105</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Region Store Revenue Customers Products\n",
"0 North Store1 1000 45 120\n",
"1 North Store2 1200 52 140\n",
"2 South Store1 800 38 95\n",
"3 South Store2 900 41 105"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_midx.reset_index()\n"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "745101c8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MultiIndex([('North', 'Store1'),\n",
" ('North', 'Store2'),\n",
" ('South', 'Store1'),\n",
" ('South', 'Store2')],\n",
" names=['Region', 'Store'])\n"
]
},
{
"data": {
"text/plain": [
"Index(['North', 'North', 'South', 'South'], dtype='object', name='Region')"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(df_midx.index)\n",
"\n",
"df_midx.index.get_level_values(0)\n"
]
},
{
"cell_type": "markdown",
"id": "47d5dd9c",
"metadata": {},
"source": [
"## add multi level axis to existing df"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "45f709da",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead tr th {\n",
" text-align: left;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th>Department</th>\n",
" <th colspan=\"2\" halign=\"left\">A</th>\n",
" <th colspan=\"2\" halign=\"left\">B</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Quarter</th>\n",
" <th>Sales_A1</th>\n",
" <th>Sales_A2</th>\n",
" <th>Marketing_B1</th>\n",
" <th>Marketing_B2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Alice</th>\n",
" <td>130</td>\n",
" <td>175</td>\n",
" <td>185</td>\n",
" <td>64</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bob</th>\n",
" <td>180</td>\n",
" <td>195</td>\n",
" <td>71</td>\n",
" <td>96</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Charlie</th>\n",
" <td>88</td>\n",
" <td>163</td>\n",
" <td>94</td>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diana</th>\n",
" <td>91</td>\n",
" <td>173</td>\n",
" <td>148</td>\n",
" <td>51</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"Department A B \n",
"Quarter Sales_A1 Sales_A2 Marketing_B1 Marketing_B2\n",
"Alice 130 175 185 64\n",
"Bob 180 195 71 96\n",
"Charlie 88 163 94 59\n",
"Diana 91 173 148 51"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lvl1 = [\"A\"]*2 + [\"B\"]*2\n",
"lvl2 = df_mcols.columns.to_list()\n",
"arrays_cols = [lvl1, lvl2]\n",
"\n",
"new_columns = pd.MultiIndex.from_arrays(arrays_cols, names=['Department', 'Quarter'])\n",
"\n",
"df_mcols.columns = new_columns\n",
"\n",
"df_mcols\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
import multiprocessing as mp
import time
from tqdm import tqdm
""" See Obsidian for more details.
A more complicated example:
https://github.com/mCodingLLC/VideosSampleCode/blob/master/videos/104_multiprocessing_pool/multiprocessing_pool.py
"""
def process_task(func_args):
data, other = func_args
other = other if other else 0
# Replace this with the actual computation for each loop iteration
t = 25-data if data < 25 else data - 25
time.sleep(0.25*t)
# print(f"Processed {data=}")
return data*other
if __name__ == "__main__":
print("Number of cpu : ", mp.cpu_count())
# List of inputs for the loop
inputs = list(range(50))
other = list(range(0, 100, 2))
func_args = [(x, y) for x, y in zip(inputs, other)]
results = []
start = time.time()
# Create a pool of workers (defaults to all available cores)
with mp.Pool(processes=30) as pool:
# Map the function to the inputs, distributing tasks across CPUs
# results = pool.map(process_task, func_args)
# results = pool.map_async(process_task, func_args).get()
# results = list(pool.imap(process_task, func_args)) # Convert iterator to list. Much slower than map
# results = list(pool.imap_unordered(process_task, func_args))
# tqdm need to be passed an iterable, not a generator
# Source: https://stackoverflow.com/a/41921948/12315585
with tqdm(total=len(inputs)) as pbar:
for result in pool.imap_unordered(process_task, func_args):
pbar.update()
pbar.refresh()
# Do something with the result
results.append(result)
print('\ntime taken: ', time.time() - start, '\n')
if isinstance(results, list):
print(results)
else:
for r in results:
print(r)
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Code Quality & Organization

  • Clean Code: Write readable, maintainable code with meaningful names and clear structure

  • SOLID Principles: five fundamental principles of object-oriented programming and design that help reduce coupling, increase cohesion, and create more maintainable, flexible, and scalable software:

    1. S - Single Responsibility Principle (SRP)

      A class should have only one job or responsibility. Example: Instead of a User class that handles both user data and email sending, separate them into User and EmailService classes.

    2. O - Open/Closed Principle (OCP)

      Software entities should be open for extension but closed for modification. You should be able to add new functionality without changing existing code.

      How? Use interfaces and inheritance to add new payment methods without modifying existing payment processing code.

    3. L - Liskov Substitution Principle (LSP)

      Objects of a superclass should be replaceable with objects of a subclass without breaking the application.

      Example: If you have a Bird class, a Penguin subclass shouldn't break the application if it can't implement a fly() method that all birds are expected to have.

    4. I - Interface Segregation Principle (ISP)

      Clients should not be forced to depend on interfaces they don't use. Create specific, focused interfaces rather than large, monolithic ones.

      Example: Instead of one large Worker interface with methods like work(), eat(), and sleep(), create separate interfaces like Workable, Eatable, and Sleepable.

    5. D - Dependency Inversion Principle (DIP)

      High-level modules should not depend on low-level modules. Both should depend on abstractions (interfaces), not concrete implementations.

      Example: A PaymentProcessor should depend on a PaymentGateway interface, not directly on specific implementations like StripePayment or PayPalPayment.

  • DRY (Don't Repeat Yourself): Avoid code duplication

  • Code Reviews: Peer review process to catch bugs and improve code quality

Development Practices

  • Version Control: Use Git with meaningful commit messages and branching strategies
  • Test-Driven Development (TDD): Write tests before implementing features
  • Unit Testing: Comprehensive test coverage with automated testing
  • Documentation: Clear API docs, README files, and inline comments

Architecture & Design

  • Microservices Architecture: Break applications into small, independent services
  • Design Patterns: Use proven solutions for common problems
  • Separation of Concerns: Keep different functionalities isolated
  • API Design: RESTful APIs with consistent naming conventions

DevOps & Deployment

  • CI/CD Pipelines: Automated build, test, and deployment processes
  • Infrastructure as Code: Manage infrastructure through code
  • Containerization: Use Docker for consistent environments
  • Monitoring & Logging: Track application performance and errors

Project Management

  • Agile Methodologies: Iterative development with regular feedback
  • Code Standards: Consistent formatting and style guidelines
  • Security Best Practices: Input validation, authentication, encryption
  • Performance Optimization: Profiling and optimizing bottlenecks Agile Methodologies are iterative approaches to software development that emphasize flexibility, collaboration, and customer satisfaction. Here's a deep dive:

Core Agile Values (Agile Manifesto)

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

Popular Agile Frameworks

Scrum

  • Sprints: 1-4 week development cycles
  • Roles: Product Owner, Scrum Master, Development Team
  • Ceremonies: Sprint Planning, Daily Standups, Sprint Review, Retrospective
  • Artifacts: Product Backlog, Sprint Backlog, Increment

Kanban

  • Visual workflow management using boards
  • Continuous delivery without fixed iterations
  • Work-in-progress (WIP) limits
  • Focus on flow optimization

Extreme Programming (XP)

  • Pair programming and code reviews
  • Test-driven development (TDD)
  • Continuous integration
  • Simple design and refactoring

Key Agile Practices

Sprint Planning & Estimation

  • Story points for effort estimation
  • Planning poker for team consensus
  • Definition of Done criteria

Daily Communication

  • Stand-up meetings (What did you do? What will you do? Any blockers?)
  • Transparent progress tracking
  • Quick issue resolution

Continuous Improvement

  • Sprint retrospectives to identify improvements
  • Adapt processes based on team feedback
  • Metrics tracking (velocity, burndown charts)

Customer Involvement

  • Regular demos and feedback sessions
  • User stories written from customer perspective
  • Iterative requirement refinement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment