Python – Fullstack Station https://fullstackstation.com Hướng dẫn lập trình, thiết kế, lập trình web, thiết kế web, lập trình javascript, lập trình fullstack từ cơ bản đến nâng cao Sun, 08 Feb 2026 04:02:58 +0000 vi hourly 1 https://wordpress.org/?v=6.8.5 https://fullstackstation.com/wp-content/uploads/2019/08/favicon.ico Python – Fullstack Station https://fullstackstation.com 32 32 Streamlit 2025: Tổng hợp tính năng mới và sự trưởng thành của framework Python phổ biến nhất https://fullstackstation.com/streamlit-2025-tinh-nang-moi/ https://fullstackstation.com/streamlit-2025-tinh-nang-moi/#respond Thu, 01 Jan 2026 01:00:00 +0000 https://fullstackstation.com/streamlit-2025-tinh-nang-moi/ Năm 2025 đánh dấu bước tiến lớn của Streamlit với hàng loạt tính năng mới: st.datetime_input, voice input cho chat, keyboard shortcuts, Python 3.14 support và nhiều cải tiến performance. Tổng hợp đầy đủ những gì bạn cần biết.

The post Streamlit 2025: Tổng hợp tính năng mới và sự trưởng thành của framework Python phổ biến nhất appeared first on Fullstack Station.

]]>
Năm 2025 đánh dấu một bước tiến lớn của Streamlit – framework Python được yêu thích nhất để xây dựng ứng dụng data science và AI. Với hàng loạt tính năng mới, cải tiến performance và mở rộng hệ sinh thái, Streamlit tiếp tục khẳng định vị thế là công cụ không thể thiếu cho mọi data scientist và AI engineer.

Streamlit là gì và tại sao bạn nên quan tâm?

Streamlit là một open-source Python framework cho phép bạn tạo các ứng dụng web tương tác chỉ với vài dòng code Python. Không cần biết HTML, CSS hay JavaScript – bạn chỉ cần viết Python thuần túy.

Ai đang sử dụng Streamlit?

  • Google X, Uber, Snowflake: Các công ty công nghệ hàng đầu
  • Data Scientists: Để demo models và visualize data
  • AI/ML Engineers: Để xây dựng prototype nhanh chóng
  • Startups: Để tạo MVP với chi phí thấp

Theo thống kê từ Gartner AI in Business Report 2025, các tổ chức sử dụng Streamlit để deploy model đã giảm 60% thời gian onboarding cho stakeholders.

Những tính năng nổi bật của Streamlit 2025

1. st.datetime_input – Chọn ngày giờ trong một widget

Đây là tính năng được request nhiều nhất từ cộng đồng. Trước đây, bạn phải dùng 2 widget riêng biệt. Giờ đây, mọi thứ gói gọn trong một:

import streamlit as st
from datetime import datetime

selected_datetime = st.datetime_input(
    "Chọn thời gian",
    value=datetime.now(),
    min_value=datetime(2020, 1, 1),
    max_value=datetime(2030, 12, 31)
)

st.write(f"Bạn đã chọn: {selected_datetime}")

2. Voice Input cho Chat – st.chat_input hỗ trợ audio

Một trong những cải tiến đột phá nhất năm 2025! st.chat_input giờ đây có thể nhận input bằng giọng nói:

import streamlit as st

user_input = st.chat_input(
    "Nhập tin nhắn hoặc nói...",
    accept_audio=True
)

if user_input:
    if user_input.type == "audio":
        st.audio(user_input.audio_data)
    else:
        st.write(f"Bạn nói: {user_input.text}")

Điều này mở ra cánh cửa cho việc xây dựng các AI voice assistantschatbots hỗ trợ giọng nói một cách dễ dàng.

3. Keyboard Shortcuts cho Buttons

Bạn có thể gán phím tắt cho các button, tăng trải nghiệm người dùng:

if st.button("Lưu", key="save_btn", keyboard_shortcut="ctrl+s"):
    st.success("Đã lưu!")

if st.button("Chạy", key="run_btn", keyboard_shortcut="ctrl+enter"):
    st.info("Đang chạy...")

4. Query Parameters cho Navigation

Giờ đây bạn có thể truyền query parameters khi chuyển trang:

st.switch_page("pages/detail.py", query_params={"id": 123, "tab": "overview"})
st.page_link("pages/product.py", label="Xem sản phẩm", query_params={"sku": "ABC123"})

5. Cải tiến st.metric với delta_arrow

Customize cách hiển thị delta arrow:

col1, col2, col3 = st.columns(3)

with col1:
    st.metric("Doanh thu", "1.2M", "+12%", delta_arrow="up")
with col2:
    st.metric("Chi phí", "800K", "-5%", delta_arrow="down")
with col3:
    st.metric("Lợi nhuận", "400K", "+25%", delta_arrow="hidden")

6. Python 3.14 và Vega-Altair 6 Support

Streamlit 2025 hỗ trợ Python 3.14 (phiên bản mới nhất) và Vega-Altair 6 (thư viện visualization được nâng cấp).

Cải tiến Performance đáng chú ý

  • Lazy Loading cho Markdown Plugins: Các plugin được load theo yêu cầu, giảm thời gian khởi động
  • uvloop Integration: Tự động sử dụng uvloop nếu có để tăng performance
  • Bundle Size giảm 15%: Load time nhanh hơn 20%
  • Session Context tối ưu: Xử lý concurrent users tốt hơn

Best Practices cho Streamlit Apps

1. Sử dụng Caching hiệu quả

@st.cache_data
def load_data():
    return pd.read_csv("large_file.csv")

@st.cache_resource
def load_model():
    return load_my_model()

2. Session State cho Complex Logic

if "counter" not in st.session_state:
    st.session_state.counter = 0

if st.button("Increment"):
    st.session_state.counter += 1

Fullstack Station Tips

  1. Bắt đầu nhỏ: Đừng cố xây dựng ứng dụng phức tạp ngay
  2. Sử dụng st.cache_data: Đây là tính năng quan trọng nhất để optimize performance
  3. Tận dụng st.columns và st.tabs: Layout responsive giúp app chuyên nghiệp hơn
  4. Theo dõi Streamlit Community: Rất nhiều components hữu ích
  5. Thử Streamlit Cloud: Deploy miễn phí, không cần lo về infrastructure

Kết luận

Streamlit 2025 không chỉ là một bản cập nhật – đó là sự khẳng định rằng framework này đã sẵn sàng cho kỷ nguyên AI. Với voice input, enhanced chat capabilities và performance improvements, Streamlit tiếp tục là lựa chọn hàng đầu cho data scientists và AI engineers.

Trong bài viết tiếp theo, mình sẽ đi sâu vào Tương lai của các ứng dụng Streamlit trong xu hướng AI – tại sao Streamlit lại quan trọng và cách tận dụng nó để xây dựng các ứng dụng AI production-ready.

Xem thêm

The post Streamlit 2025: Tổng hợp tính năng mới và sự trưởng thành của framework Python phổ biến nhất appeared first on Fullstack Station.

]]>
https://fullstackstation.com/streamlit-2025-tinh-nang-moi/feed/ 0
Python AI Stack 2024: Tổng kết công cụ và thư viện thiết yếu https://fullstackstation.com/python-ai-stack-2024/ https://fullstackstation.com/python-ai-stack-2024/#respond Wed, 18 Dec 2024 07:00:00 +0000 https://fullstackstation.com/python-ai-stack-2024/ Năm 2024 chứng kiến sự bùng nổ của các công cụ AI trong Python. Bài viết này tổng kết những libraries và tools thiết yếu mà mọi AI developer cần biết, từ LLM orchestration đến vector databases. LLM Orchestration Frameworks LangChain Framework phổ biến nhất cho việc xây dựng LLM applications: from langchain_openai import ChatOpenAI […]

The post Python AI Stack 2024: Tổng kết công cụ và thư viện thiết yếu appeared first on Fullstack Station.

]]>
Năm 2024 chứng kiến sự bùng nổ của các công cụ AI trong Python. Bài viết này tổng kết những libraries và tools thiết yếu mà mọi AI developer cần biết, từ LLM orchestration đến vector databases.

LLM Orchestration Frameworks

LangChain

Framework phổ biến nhất cho việc xây dựng LLM applications:

from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.chains import LLMChain

# Basic usage
llm = ChatOpenAI(model="gpt-4-turbo", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant specialized in {topic}"),
    ("user", "{question}")
])

chain = prompt | llm
result = chain.invoke({"topic": "Python", "question": "Explain decorators"})

# With memory
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()

# Agents với tools
from langchain.agents import create_react_agent
from langchain.tools import DuckDuckGoSearchRun

tools = [DuckDuckGoSearchRun()]
agent = create_react_agent(llm, tools, prompt)

Khi nào dùng: Khi cần flexibility, nhiều integrations, complex chains

LlamaIndex

Tối ưu cho RAG (Retrieval Augmented Generation):

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI

# Load documents
documents = SimpleDirectoryReader("data/").load_data()

# Create index
index = VectorStoreIndex.from_documents(documents)

# Query
query_engine = index.as_query_engine()
response = query_engine.query("What is the company's refund policy?")
print(response)

# Advanced: Custom LLM
llm = OpenAI(model="gpt-4-turbo", temperature=0)
query_engine = index.as_query_engine(llm=llm)

Khi nào dùng: Document Q&A, knowledge bases, RAG systems

Haystack

Production-ready NLP framework:

from haystack import Pipeline
from haystack.components.retrievers import InMemoryBM25Retriever
from haystack.components.generators import OpenAIGenerator

pipe = Pipeline()
pipe.add_component("retriever", InMemoryBM25Retriever(document_store))
pipe.add_component("generator", OpenAIGenerator())
pipe.connect("retriever", "generator")

result = pipe.run({"retriever": {"query": "What is RAG?"}})

Vector Databases

ChromaDB

import chromadb
from chromadb.utils import embedding_functions

# Create client
client = chromadb.Client()

# Create collection với OpenAI embeddings
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key="your-key",
    model_name="text-embedding-3-small"
)

collection = client.create_collection(
    name="documents",
    embedding_function=openai_ef
)

# Add documents
collection.add(
    documents=["Document 1 content", "Document 2 content"],
    metadatas=[{"source": "doc1"}, {"source": "doc2"}],
    ids=["doc1", "doc2"]
)

# Query
results = collection.query(
    query_texts=["search query"],
    n_results=3
)

Pinecone

from pinecone import Pinecone

pc = Pinecone(api_key="your-key")
index = pc.Index("my-index")

# Upsert
index.upsert(vectors=[
    {"id": "vec1", "values": [0.1, 0.2, ...], "metadata": {"text": "..."}}
])

# Query
results = index.query(vector=[0.1, 0.2, ...], top_k=3, include_metadata=True)

So sánh Vector DBs

Database Type Best for Pricing
ChromaDB Embedded Prototyping, small projects Free
Pinecone Managed Production, scale $$$
Weaviate Self-hosted/Managed Flexibility Free/$$
Qdrant Self-hosted Performance Free
pgvector Postgres extension Existing Postgres Free

Model Inference

Transformers (Hugging Face)

from transformers import pipeline

# Text generation
generator = pipeline("text-generation", model="meta-llama/Llama-3-8B")
result = generator("Hello, I am", max_length=50)

# Embeddings
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode(["Hello world", "How are you"])

# Classification
classifier = pipeline("sentiment-analysis")
result = classifier("I love this product!")

vLLM – Fast Inference Server

# Start server
vllm serve meta-llama/Llama-3-8B --port 8000

# Client
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")

response = client.chat.completions.create(
    model="meta-llama/Llama-3-8B",
    messages=[{"role": "user", "content": "Hello!"}]
)

Ollama – Local LLMs

# Install & run
ollama run llama3

# Python client
import ollama
response = ollama.chat(model='llama3', messages=[
    {'role': 'user', 'content': 'Hello!'}
])

Observability & Monitoring

LangSmith

import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-key"

# Automatic tracing của LangChain calls

Weights & Biases

import wandb
wandb.init(project="llm-experiment")

# Log metrics
wandb.log({"accuracy": 0.95, "loss": 0.05})

# Log LLM calls
wandb.log({"prompt": prompt, "response": response, "tokens": token_count})

MLflow

import mlflow

with mlflow.start_run():
    mlflow.log_param("model", "gpt-4")
    mlflow.log_metric("latency", 1.5)
    mlflow.log_artifact("model_config.json")

Data Processing

unstructured – Document parsing

from unstructured.partition.pdf import partition_pdf
from unstructured.partition.docx import partition_docx

elements = partition_pdf("document.pdf")
for element in elements:
    print(type(element).__name__, element.text[:100])

tiktoken – Token counting

import tiktoken

enc = tiktoken.encoding_for_model("gpt-4")
tokens = enc.encode("Hello, world!")
print(f"Token count: {len(tokens)}")  # Token count: 4

Development Tools

Instructor – Structured outputs

import instructor
from pydantic import BaseModel
from openai import OpenAI

client = instructor.patch(OpenAI())

class User(BaseModel):
    name: str
    age: int
    email: str

user = client.chat.completions.create(
    model="gpt-4-turbo",
    response_model=User,
    messages=[{"role": "user", "content": "Extract: John is 30, email john@example.com"}]
)
# user.name = "John", user.age = 30, user.email = "john@example.com"

Guidance – Constrained generation

import guidance

program = guidance("""
The answer is {{select 'answer' options=['yes', 'no', 'maybe']}}
""")

result = program(llm=llm)

Recommended Stack cho 2024

Beginner Stack

  • OpenAI API + LangChain
  • ChromaDB (vector store)
  • Streamlit (UI)

Production Stack

  • LangChain + LlamaIndex
  • Pinecone hoặc Qdrant
  • LangSmith (monitoring)
  • FastAPI (backend)

Cost-optimized Stack

  • Ollama + Llama 3 (local)
  • ChromaDB (embedded)
  • Gradio (UI)

Fullstack Station Tips

Python AI stack 2024 đã mature đáng kể. Lời khuyên của mình:

  • Start with LangChain: Có learning curve nhưng đáng đầu tư
  • Prototype với ChromaDB: Sau đó migrate sang production DB
  • Local models với Ollama: Test miễn phí trước khi dùng API
  • Monitor từ đầu: LangSmith hoặc custom logging
  • Instructor cho structured output: Rất hữu ích cho data extraction

Tham khảo

The post Python AI Stack 2024: Tổng kết công cụ và thư viện thiết yếu appeared first on Fullstack Station.

]]>
https://fullstackstation.com/python-ai-stack-2024/feed/ 0
RAG là gì? Kỹ thuật tăng cường độ chính xác cho AI https://fullstackstation.com/rag-retrieval-augmented-generation/ https://fullstackstation.com/rag-retrieval-augmented-generation/#respond Wed, 11 Sep 2024 08:00:00 +0000 https://fullstackstation.com/rag-retrieval-augmented-generation/ RAG (Retrieval Augmented Generation) là kỹ thuật quan trọng giúp cải thiện độ chính xác của Large Language Models. Thay vì chỉ dựa vào knowledge trong training data, RAG cho phép LLM truy cập và sử dụng thông tin từ nguồn dữ liệu bên ngoài. Tại sao cần RAG? LLMs như GPT-4, Claude có hai […]

The post RAG là gì? Kỹ thuật tăng cường độ chính xác cho AI appeared first on Fullstack Station.

]]>
RAG (Retrieval Augmented Generation) là kỹ thuật quan trọng giúp cải thiện độ chính xác của Large Language Models. Thay vì chỉ dựa vào knowledge trong training data, RAG cho phép LLM truy cập và sử dụng thông tin từ nguồn dữ liệu bên ngoài.

Tại sao cần RAG?

LLMs như GPT-4, Claude có hai vấn đề chính:

  • Knowledge cutoff – Chỉ biết thông tin đến thời điểm training
  • Hallucination – Có thể “bịa” thông tin khi không chắc chắn

RAG giải quyết bằng cách:

  1. Tìm kiếm thông tin liên quan từ database
  2. Đưa thông tin đó vào context cho LLM
  3. LLM trả lời dựa trên context được cung cấp

Kiến trúc RAG cơ bản

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   Question  │────▶│   Retriever  │────▶│  Vector DB  │
└─────────────┘     └──────────────┘     └─────────────┘
                           │
                           ▼ (relevant documents)
                    ┌──────────────┐
                    │     LLM      │
                    └──────────────┘
                           │
                           ▼
                    ┌──────────────┐
                    │    Answer    │
                    └──────────────┘

Cài đặt RAG với LangChain

1. Chuẩn bị môi trường

pip install langchain langchain-openai chromadb tiktoken

2. Load và chunk documents

from langchain.document_loaders import TextLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Load documents
loader = PyPDFLoader("company_docs.pdf")
documents = loader.load()

# Split thành chunks
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n\n", "\n", " ", ""]
)
chunks = text_splitter.split_documents(documents)

3. Tạo vector store

from langchain_openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma

# Tạo embeddings và lưu vào ChromaDB
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

4. Tạo RAG chain

from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA

llm = ChatOpenAI(model="gpt-4-turbo")

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",  # hoặc "map_reduce", "refine"
    retriever=vectorstore.as_retriever(
        search_kwargs={"k": 3}  # Top 3 relevant docs
    ),
    return_source_documents=True
)

# Query
result = qa_chain.invoke({"query": "What is our refund policy?"})
print(result["result"])
print("Sources:", result["source_documents"])

Vector Databases phổ biến

Database Ưu điểm Use case
ChromaDB Đơn giản, embedded Prototyping
Pinecone Managed, scalable Production
Weaviate Open source, powerful Enterprise
Qdrant Fast, Rust-based High performance
pgvector PostgreSQL extension Existing Postgres

Advanced RAG Techniques

Hybrid Search

Kết hợp semantic search với keyword search:

from langchain.retrievers import BM25Retriever, EnsembleRetriever

bm25 = BM25Retriever.from_documents(docs)
vector = vectorstore.as_retriever()

ensemble = EnsembleRetriever(
    retrievers=[bm25, vector],
    weights=[0.3, 0.7]
)

Contextual Compression

Nén context để giữ lại phần quan trọng:

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

compressor = LLMChainExtractor.from_llm(llm)
retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=vectorstore.as_retriever()
)

Evaluation Metrics

  • Faithfulness – Câu trả lời có dựa trên context không?
  • Answer relevancy – Câu trả lời có liên quan đến câu hỏi?
  • Context precision – Context retrieved có chính xác?
  • Context recall – Đã lấy đủ context cần thiết chưa?

Fullstack Station Tips

RAG là kỹ thuật cốt lõi cho các ứng dụng AI trong doanh nghiệp:

  • Customer support – Q&A từ knowledge base
  • Legal/Medical – Tra cứu documents chính xác
  • Internal search – Tìm kiếm trong tài liệu công ty

Mẹo khi implement:

  • Chunk size ~500-1000 tokens thường tốt nhất
  • Overlap 10-20% để không mất context
  • Dùng metadata filtering để narrow down search
  • Test với nhiều embedding models (OpenAI, Cohere, local)

Tham khảo

The post RAG là gì? Kỹ thuật tăng cường độ chính xác cho AI appeared first on Fullstack Station.

]]>
https://fullstackstation.com/rag-retrieval-augmented-generation/feed/ 0
Python 3.12: Tính năng mới và hiệu suất cải thiện https://fullstackstation.com/python-3-12-tinh-nang-moi/ https://fullstackstation.com/python-3-12-tinh-nang-moi/#respond Wed, 17 Jul 2024 02:30:00 +0000 https://fullstackstation.com/python-3-12-tinh-nang-moi/ Python 3.12 được phát hành vào tháng 10/2023, đánh dấu một bước tiến quan trọng về hiệu suất và developer experience. Với những cải tiến đáng kể từ PEP 684 đến PEP 701, Python 3.12 là phiên bản đáng để nâng cấp. Hiệu suất cải thiện đáng kể Python 3.12 nhanh hơn 3.11 khoảng 5-10% […]

The post Python 3.12: Tính năng mới và hiệu suất cải thiện appeared first on Fullstack Station.

]]>
Python 3.12 được phát hành vào tháng 10/2023, đánh dấu một bước tiến quan trọng về hiệu suất và developer experience. Với những cải tiến đáng kể từ PEP 684 đến PEP 701, Python 3.12 là phiên bản đáng để nâng cấp.

Hiệu suất cải thiện đáng kể

Python 3.12 nhanh hơn 3.11 khoảng 5-10% trong hầu hết các workloads:

  • Comprehensions nhanh hơn tới 2x
  • Async generators cải thiện 10-15%
  • Method calls nhanh hơn 10%

F-string Improvements (PEP 701)

F-strings giờ linh hoạt hơn nhiều:

# Nested f-strings (trước 3.12 không được)
name = "Alice"
greeting = f"Hello, {f'{name.upper()}'}"  # Hello, ALICE

# Multi-line expressions
result = f"""
The answer is: {
    complex_calculation(
        param1=value1,
        param2=value2
    )
}
"""

# Backslash trong f-string (mới!)
path = f"C:\\Users\\{username}\\Documents"

# Comments trong f-string expression
value = f"{
    x  # this is x
    + y  # plus y
}"

Per-Interpreter GIL (PEP 684)

Đây là bước đầu tiên để loại bỏ GIL trong Python. Mỗi sub-interpreter có thể có GIL riêng:

# Concept - API đang phát triển
import interpreters

interp = interpreters.create()
# Mỗi interpreter có GIL riêng
# Cho phép true parallelism trong một process

Tính năng này vẫn experimental nhưng mở ra tương lai multi-threading thực sự cho Python.

Type Parameter Syntax (PEP 695)

Cú pháp mới cho generic types, đơn giản và trực quan hơn:

# Python 3.11
from typing import TypeVar, Generic

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, item: T) -> None:
        self.item = item

# Python 3.12 - Cú pháp mới!
class Container[T]:
    def __init__(self, item: T) -> None:
        self.item = item

# Type alias mới
type Point = tuple[float, float]
type Vector[T] = list[T]

# Generic functions
def first[T](items: list[T]) -> T:
    return items[0]

Better Error Messages

Python 3.12 tiếp tục cải thiện error messages:

# Import errors rõ ràng hơn
>>> from datetime import datatime
NameError: cannot import name 'datatime' from 'datetime'.
Did you mean: 'datetime'?

# Syntax errors chi tiết hơn
>>> match value
  File "", line 1
    match value
              ^
SyntaxError: expected ':'

Deprecated: distutils

distutils chính thức bị remove. Sử dụng setuptools hoặc packaging thay thế:

# Thay thế distutils.version
from packaging.version import Version

v = Version("1.2.3")
print(v.major)  # 1

Các thay đổi khác

  • pathlib.Path.walk() – Tương tự os.walk() nhưng cho Path
  • itertools.batched() – Chia iterable thành batches
  • SQLite 3.37 support
  • Improved asyncio performance

Cách nâng cấp

# Ubuntu/Debian
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12

# macOS với Homebrew
brew install python@3.12

# pyenv
pyenv install 3.12.0
pyenv global 3.12.0

Fullstack Station Tips

Python 3.12 là bản nâng cấp tuyệt vời. Những điểm mình thích nhất:

  • Type parameter syntax – Viết generic code đẹp hơn nhiều
  • F-string improvements – Không còn những workarounds kỳ lạ
  • Performance – 5-10% nhanh hơn là đáng kể cho production

Nếu bạn đang dùng Python 3.10 hoặc 3.11, mình khuyên nâng cấp. Hầu hết libraries phổ biến đã hỗ trợ 3.12. Chạy test suite kỹ vì một số deprecated APIs đã bị remove.

Tham khảo

The post Python 3.12: Tính năng mới và hiệu suất cải thiện appeared first on Fullstack Station.

]]>
https://fullstackstation.com/python-3-12-tinh-nang-moi/feed/ 0
Python: Sự cần thiết của MyPy https://fullstackstation.com/gioi-thieu-mypy-python/ https://fullstackstation.com/gioi-thieu-mypy-python/#respond Wed, 24 Apr 2024 08:24:43 +0000 https://fullstackstation.com/?p=1948 Nhân việc người tạo ra Python, ông Guido van Rossum giới thiệu về MyPy, mình sẽ nói kỹ thêm về sự hữu dụng và sự cần thiết của MyPy trong lập trình Python. Bạn có thể tải về slide của ông Guido van Rossum ở cuối bài. Mình đã giới thiệu MyPy trong bài viết […]

The post Python: Sự cần thiết của MyPy appeared first on Fullstack Station.

]]>
Nhân việc người tạo ra Python, ông Guido van Rossum giới thiệu về MyPy, mình sẽ nói kỹ thêm về sự hữu dụng và sự cần thiết của MyPy trong lập trình Python. Bạn có thể tải về slide của ông Guido van Rossum ở cuối bài.

Mình đã giới thiệu MyPy trong bài viết “Giới thiệu một số công cụ hỗ trợ lập trình Python“, bài này sẽ đề cập chi tiết hơn về MyPy. Bất kỳ ngôn ngữ nào cũng phải trải qua quá trình dài để phát triển. Việc thiếu một vài tính năng ngay từ đầu cũng không có gì lạ, vì nguyên tắc thiết kế của Python là đặt sự đơn giản lên hàng đầu.

The Zen of Python (import this):

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Complex is better than complicated.
  • Flat is better than nested.
  • Sparse is better than dense.
  • Readability counts.
  • Special cases aren’t special enough to break the rules.
  • Although practicality beats purity.
  • Errors should never pass silently.
  • Unless explicitly silenced.
  • In the face of ambiguity, refuse the temptation to guess.
  • There should be one– and preferably only one –obvious way to do it.
  • Although that way may not be obvious at first unless you’re Dutch.
  • Now is better than never.
  • Although never is often better than right now.
  • If the implementation is hard to explain, it’s a bad idea.
  • If the implementation is easy to explain, it may be a good idea.
  • Namespaces are one honking great idea — let’s do more of those!

Tuy nhiên, sự cần thiết của kiểm tra kiểu dữ liệu là rất quan trọng, dù nó đã không được hỗ trợ ngay từ lúc ban đầu. Hoặc cũng không là bắt buộc ở hiện tại. Không biết ông Guido hối hận gì không vì đã không đưa type-checking vào Python trước đây :D.

MyPy là gì

Ngày nay, nhiều công cụ để kiểm tra kiểu dữ liệu, nhưng MyPy trước đây được tạo ra bởi anh JukkaL, thì bây giờ đã được đưa chính thức vào chung với Python: https://github.com/python/mypy. Đó là một sự thừa nhận sự phát triển và trưởng thành của MyPy.

Type Annotation

Type checking (kiểm tra kiểu dữ liệu) là xác định rõ kiểu dữ liệu của biến, giúp phát hiện lỗi sớm hơn trong quá trình phát triển. MyPy là công cụ được sử dụng để kiểm tra các lỗi liên quan đến loại dữ liệu dựa trên type annotations.

Ví dụ:

def add(x, y):    
    return x + y

add("hai", "ba")
=> "haiba" # Kiểu string
add(2, 3)
=> 5 # Kiểu integer

add("hai", 3)
hoặc 
add(2, "ba")
=> chúng ta sẽ bị lỗi `TypeError` lúc Runtime

Vậy thì với cách viết thêm kiểu dữ liệu như dưới đây:

def add(x: int, y: int) -> int:    
    return x + y

Khi dùng MyPy để kiểm tra, thì chúng ta sẽ phát hiện ngay được lỗi trong lúc lập trình mà không sợ sẽ bị lỗi lúc runtime nữa. Python khá dễ viết nếu mã nguồn đơn giản, ngắn gọn và còn mới. Nhưng khi mã nguồn dự án trải qua thời gian dài, và lượng code phình to ra thì nếu không có xác định, kiểm tra loại dữ liệu thì sẽ gặp rất nhiều khó khăn khi debug hoặc khó hiểu khi đọc code.

Type T

Sử dụng với các kiểu dữ liệu

Kiểu dữ liệu cơ bản

Bạn có thể dùng tất cả các kiểu dữ liệu cơ bản để diễn giải kiểu dữ liệu như int, float, str, dict, tuple, set, list…, hoặc kết hợp như Tuple[int, str], Iterator[int]…

def gcd(a: int, b: int) -> int:
    while a:
        a, b = b % a, a
    return b

Ở đây mình dùng VSCode, đưa trỏ chuột vào b sẽ biết b có kiểu dữ liệu gì

Hay với ví dụ của trang chủ mypy:

from typing import Iterator

def fib(n: int) -> Iterator[int]:
    a, b = 0, 1
    while a < n:
        yield a
        a, b = b, a + b

Loại biến gọi hàm (Callable)

from typing import Callable

def twice(i: int, next: Callable[[int], int]) -> int:    
    return next(next(i))

def add(i: int) -> int:
    return i + 1

print(twice(3, add))  # 5

Với ví dụ trên, bạn có thể xác định biến đưa vào có thể gọi hàm, rất tường minh.

Kiểu dữ liệu nâng cao

Sử dụng MyPy tuy dễ nhưng cũng cần thời gian để thành thạo, bạn có thể cải thiện Type-Annotation từng bước nhỏ một. Không nhất thiết phải làm 1 lúc cho toàn bộ mã nguồn của dự án. Như vậy sẽ không bị ngán và lười.

Tuy nhiên với dự án mới thì hãy sử dụng Type-Annotation càng nhiều càng tốt. Vừa lập trình vừa có trợ lý MyPy thật là sướng biết bao.

https://mypy.readthedocs.io/en/latest/

MyPy cho Django: https://github.com/machinalis/mypy-django

The post Python: Sự cần thiết của MyPy appeared first on Fullstack Station.

]]>
https://fullstackstation.com/gioi-thieu-mypy-python/feed/ 0
Bắt kịp xu hướng AI với serverless AI https://fullstackstation.com/serverless-ai-la-gi/ https://fullstackstation.com/serverless-ai-la-gi/#respond Mon, 22 Apr 2024 11:07:40 +0000 https://fullstackstation.com/?p=8108 Cách đây vài năm khi xu hướng serverless chỉ mới chớm thì giờ đây đã trưởng thành và có nhiều nền tảng sử dụng serverless như là cơ sở hạ tầng chính. Và càng quan trọng hơn khi AI nổi lên khiến cho giá GPU ngày càng trở nên đắt đỏ, thì serverless AI lại […]

The post Bắt kịp xu hướng AI với serverless AI appeared first on Fullstack Station.

]]>
Cách đây vài năm khi xu hướng serverless chỉ mới chớm thì giờ đây đã trưởng thành và có nhiều nền tảng sử dụng serverless như là cơ sở hạ tầng chính. Và càng quan trọng hơn khi AI nổi lên khiến cho giá GPU ngày càng trở nên đắt đỏ, thì serverless AI lại trở thành mối quan tâm mới. Bài viết này sẽ giúp cho bạn bước vào thế giới AI một cách dễ dàng hơn.

Khái niệm Serverless AI

Serverless là gì

Nếu bạn là người mới về Serverless thì có thể đọc thêm bài Serverless là gì để hiểu rõ thêm. Nói đơn giản, Serverless giống như môi trường thực thi một tác vụ nào đó, ví dụ như API, mà bạn chỉ cần triển khai xong là có thể sử dụng được. Bạn không cần quan tâm đến các hạ tầng, cấu hình mạng, bộ nhớ…

Điểm mạnh của Serverless là giúp cho bạn tập trung vào giải quyết vấn đề, hơn là dành thời gian cho những tác vụ không mấy vui vẻ như cập nhật hệ thống, kiểm tra khả năng lưu trữ server, kiểm tra nhật ký hệ thống (log) xem có ai tấn công không…Quan trọng hơn hết là chỉ trả tiền cho những khi mình sử dụng!

Serverless AI là gì

Serverless AI là hạ tầng máy chủ có bộ xử lý đồ họa GPU mạnh mẽ, có thể tích hợp sẵn các model AI (Llama2, Llama3, GPT3, ResNes, StableDiffusion, Whisper…)

Tại sao Serverless AI rất quan trọng cho những người nghiên cứu AI

Chi phí, chính xác là điều chúng ta quan tâm nhất đối với serverless AI. Để đầu tư một hệ thống GPU mạnh mẽ thường sẽ tốn khá nhiều chi phí ban đầu, cũng như chi phí vận hành thường xuyên. Hoặc nếu dùng cloud, bạn cũng sẽ tốn nhiều chi phí khác để vận hành, và mất thêm thời gian để quản lý. Với serverless AI, bạn có thể chỉ trả tiền cho những lúc chúng ta gọi API.

Về cơ bản thì serverless AI cũng là API được sử dụng như API để tương tác với OpenAI chẳng hạn, và OpenAI thì đã tích hợp sẵn một số model như GPT-3, GPT-4

Một số nhà cung cấp

Cloudflare

Website: https://ai.cloudflare.com/

Danh sách các model

Text Generation @cf/meta/llama-3-8b-instruct

Text Generation @cf/mistral/mistral-7b-instruct-v0.1

Text to Image @cf/bytedance/stable-diffusion-xl-lightning

Speech Recognition @cf/openai/whisper

Image Classification @cf/microsoft/resnet-50

Text Classification @cf/huggingface/distilbert-sst-2-int8

Text Embedding @cf/baai/bge-base-en-v1.5

Translation @cf/meta/m2m100-1.2b

Runpods

Website: https://www.runpod.io/serverless-gpu

Fermyon

Website: https://www.fermyon.com/

Fullstack Station Tips

Với CloudFlare là nhà cung cấp hạ tầng khá nổi tiếng, với việc hỗ trợ nhiều model và cách sử dụng khá là dễ dàng. Chỉ cần tạo token key là bạn có thể thao tác được với các model trong CloudFlare. CloudFlare có gói miễn phí dùng thử khá hấp dẫn, được khởi tạo lại theo ngày, chứ không phải theo tháng. Nên với các ứng dụng đơn giản, thì hoàn toàn có thể sử dụng trên CloudFlare miễn phí

Với Serverless AI, bạn có thể nhanh chóng tìm hiểu và kiểm tra tính thực tiễn của các model. Thực nghiệm các ý tưởng để bắt xu hướng AI nhanh hơn!

The post Bắt kịp xu hướng AI với serverless AI appeared first on Fullstack Station.

]]>
https://fullstackstation.com/serverless-ai-la-gi/feed/ 0
Ngôn ngữ lập trình Mojo🔥: Python++ nhanh hơn Python tùy theo tác vụ đến 68.000 lần https://fullstackstation.com/ngon-ngu-lap-trinh-mojo%f0%9f%94%a5-python-nhanh-hon-python-tuy-theo-tac-vu-den-68-000-lan/ https://fullstackstation.com/ngon-ngu-lap-trinh-mojo%f0%9f%94%a5-python-nhanh-hon-python-tuy-theo-tac-vu-den-68-000-lan/#respond Sat, 13 Apr 2024 15:00:04 +0000 https://fullstackstation.com/?p=8047 Ngôn ngữ lập trình Mojo dù chỉ mới ra mắt chưa được 1 năm, nhưng đến nay đã nhận được sự chú ý của cộng đồng lập trình viên và nhận nhiều phản hồi tích cực. Dù tiếp xúc chưa được lâu, nhưng với những gì cảm nhận được thì đây là một ngôn ngữ […]

The post Ngôn ngữ lập trình Mojo🔥: Python++ nhanh hơn Python tùy theo tác vụ đến 68.000 lần appeared first on Fullstack Station.

]]>
Ngôn ngữ lập trình Mojo dù chỉ mới ra mắt chưa được 1 năm, nhưng đến nay đã nhận được sự chú ý của cộng đồng lập trình viên và nhận nhiều phản hồi tích cực. Dù tiếp xúc chưa được lâu, nhưng với những gì cảm nhận được thì đây là một ngôn ngữ lập trình đáng được quan tâm trong vòng 10 năm tới.

Bài viết này sẽ tập trung vào việc đo hiệu suất của ngôn ngữ lập trình Mojo, để xem thực tế chính xác đến đâu nhé. Bạn cũng đừng bỏ qua bài viết Tại sao nên học Python nhé.

Sơ lược về ngôn ngữ lập trình Mojo

Ngôn ngữ lập trình Mojo là gì

Ngôn ngữ lập trình Mojo được phát triển bởi công ty Modular, có cú pháp tương tự như Python và đạt hiệu cao hơn Python nhiều lần như C. Ban đầu họ hướng đến ngôn ngữ lập trình dành cho lập trình AI, nhưng ở thời điểm hiện tại thì đã trở thành ngôn ngữ lập trình cho những mục tiêu chung.

Ngôn ngữ lập trình Mojo khá dễ học do tương đồng với ngôn ngữ lập trình Python và được xem là Python++ nên sẽ giúp rút ngắn khoảng cách của những người nghiên cứu AI (thường sử dụng Python) đến phát triển sản phẩm (Python khá chậm và đòi hỏi nhiều tối ưu để sản phẩm đạt hiệu suất tốt)

Những đặc tính của ngôn ngữ lập trình Mojo

  • Sử dụng được các thư viện Python (numpy, pandas, …): sử dụng thông Cython nên có thể dùng được hầu hết các thư viện này. Tuy nhiên, theo kết quả đo hiệu suất bên dưới, thì việc sử dụng các thư viện này không mang lại kết quả tốt về hiệu suất mong muốn.
  • Sử dụng được cú pháp Python: Bạn hoàn toàn có thể sử dụng code Python trong Mojo, tuy nhiên việc sử dụng Python trong Mojo không nên ưu tiên nếu quan tâm đến hiệu suất.
  • Cú pháp tương tự Python: phong cách viết tương tự Python, tuy nhiên thuần Mojo thì sẽ khắt khe trong type-checker
  • Chạy đa luồng: Mojo sử dụng hạ tầng biên dịch (MLIR) để hỗ trợ nhiều loại phần cứng, bao gồm GPU chạy CUDA và phần cứng tương tự, mà không làm tăng thêm sự phức tạp trong lập trình.

Những điểm còn thiếu sót của ngôn ngữ lập trình Mojo

  • Chưa hỗ trợ Mac Intel, Window và các hệ Linux khác ngoài Ubuntu
  • Còn xa để đạt được mức tập cha (superset) của Python
  • Rất ít các thư viện hỗ trợ
  • Chưa có dependencies management: làm gì có thư viện khác mà đòi quản lý :))

Bạn có thể xem những vấn đề đang tồn tại: https://docs.modular.com/mojo/roadmap#mojo-sdk-known-issues

Cha đẻ của Mojo: Chris Latter

Thật thiếu sót nếu không nói về cha đẻ của ngôn ngữ lập trình Mojo: Chris Latter – người cũng là tác giả của trình biên dịch LLVM. Đồng thời ông cũng là người tạo ra MLIR – compiler stack thế hệ tiếp theo, và Mojo được thiết kế để biên dịch trên MLIR, đó cũng có thể là lý do vì sao Mojo nhanh hơn Rust (Rust và Swift được xây dựng trên nền tảng LLVM). Người sáng lập ngôn ngữ lập trình cũng là người tham gia vào quá trình thiết kế compiler, vì vậy ông rất am hiểu về cách vận hành của các chip cũng như trình biên dịch tương ứng. Đó cũng là ưu thế rất lớn để phát triển ngôn ngữ lập trình Mojo trở thành ngôn ngữ của thập niên tiếp theo – đặc biệt là trong mảng lập trình AI.

So sánh hiệu suất với Python

Môi trường

Công cụ được sử dụng đo hiệu suất: Hyperfine (https://github.com/sharkdp/hyperfine)
Hàm sử dụng: Fibonacci (thuật toán không tối ưu)
Cấu hình máy chính: 2.4 GHz 8-Core Intel Core i9
Cấu hình docker: RAM 8GB, max 200% CPU

Cài đặt Mojo

Cài đặt ngôn ngữ lập trình Mojo chỉ mới dành cho MacOS Apple, và Ubuntu. Với các máy khác có thể sử dụng docker. Chi tiết cho từng phiên bản thì bạn tham khảo ở đây:

https://docs.modular.com/mojo/manual/get-started/

Việc cài đặt cũng không mất nhiều thời gian và khó khăn gì cả nên mình không bổ sung gì thêm.

Code

# fibonacci.mojo
# Fibonacci thuần mojo
import sys
fn fibonacci(n: Int) -> Int:
    if n == 0 or n == 1:
        return n
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)


fn main():
    try:
        print(fibonacci(atol(sys.argv()[1])))
    except:
        pass
# fibonacci_python_style_no_type_annotation.mojo
# Fibonacci không  type-annotation với code kiểu Python
import sys
def fibonacci(n):
    if n == 0 or n == 1:
        return n
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)

fn main():
    try:
        print(fibonacci(atol(sys.argv()[1])))
    except:
        pass
# fibonacci_python_style_with_type_annotation.mojo
# Fibonacci  type-annotation với code kiểu Python
import sys
def fibonacci(n: Int) -> Int:
    if n == 0 or n == 1:
        return n
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)

fn main():
    try:
        print(fibonacci(atol(sys.argv()[1])))
    except:
        pass
# fibonacci.py
# Fibonacci không  type-annotation (Python)
import sys

def fibonacci(n):
    if n == 0 or n == 1:
        return n
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)

def main():
    print(fibonacci(int(sys.argv[1])))

main()
vscode/workspaces/ubuntu $ hyperfine "mojo fibonacci.mojo 40"
Benchmark 1: mojo fibonacci.mojo 40
  Time (mean ± σ):     700.7 ms ±  16.8 ms    [User: 431.9 ms, System: 19.5 ms]
  Range (minmax):   677.3 ms735.1 ms    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "mojo fibonacci_python_style_with_type_annotation.mojo 40"
Benchmark 1: mojo fibonacci_python_style_with_type_annotation.mojo 40
  Time (mean ± σ):      1.202 s ±  0.012 s    [User: 0.927 s, System: 0.021 s]
  Range (minmax):    1.184 s1.217 s    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "mojo fibonacci_python_style_no_type_annotation.mojo 40"
Benchmark 1: mojo fibonacci_python_style_no_type_annotation.mojo 40
  Time (mean ± σ):     15.129 s ±  3.435 s    [User: 14.793 s, System: 0.059 s]
  Range (minmax):   10.228 s19.135 s    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "python3 fibonacci.py 40"
Benchmark 1: python3 fibonacci.py 40
  Time (mean ± σ):     44.586 s ±  3.859 s    [User: 44.502 s, System: 0.033 s]
  Range (minmax):   37.771 s51.637 s    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "./fibonacci 40"
Benchmark 1: ./fibonacci 40
  Time (mean ± σ):     350.3 ms ±   5.5 ms    [User: 346.5 ms, System: 2.4 ms]
  Range (minmax):   340.9 ms358.6 ms    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "./fibonacci_python_style_no_type_annotation 40"
Benchmark 1: ./fibonacci_python_style_no_type_annotation 40
  Time (mean ± σ):     10.667 s ±  0.872 s    [User: 10.650 s, System: 0.007 s]
  Range (minmax):    9.323 s11.830 s    10 runs
 
vscode/workspaces/ubuntu $ hyperfine "./fibonacci_python_style_with_type_annotation 40"
Benchmark 1: ./fibonacci_python_style_with_type_annotation 40
  Time (mean ± σ):     831.7 ms ±  11.5 ms    [User: 827.4 ms, System: 2.5 ms]
  Range (minmax):   814.2 ms852.2 ms    10 runs

Kết quả so sánh

MinMaxMeanHiệu suất
Python thuần37.771 (s)51.637(s)44.586(s)N/A
Mojo phong cách Python10.228(s)19.135(s)15.129(s)x3
Mojo phong cách Python có type-annotation1.184(s)1.217(s)1.202(s)x37
Mojo thuần677.3(ms)735.1 (ms)700.7(ms)x75
Mojo phong cách Python [compiled]9.323(s)11.830(s)10.667(s)x3
Mojo phong cách Python có type-annotation [compiled]814.2(ms)852.2(ms)831.7(ms)x55
Mojo thuần [compiled]340.9(ms)358.6(ms)350.3(ms)x127
Hiệu suất thực tế của ngôn ngữ lập trình Mojo theo từng cách viết so sánh với Python.

Bonus

Với phiên bản Python thuần, nếu bạn tối ưu bằng decorator cache thì tốc độ cũng cải thiện rất nhiều, tuy nhiên Mojo chưa hỗ trợ decorator này nên chưa so sánh được.

import sys
from functools import cache

@cache
def fibonacci(n):
    if n == 0 or n == 1:
        return n
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)

def main():
    print(fibonacci(int(sys.argv[1])))

main()
vscode/workspaces/ubuntu $ hyperfine "python3 fibonacci_with_cache.py 40"
Benchmark 1: python3 fibonacci_with_cache.py 40
  Time (mean ± σ):      14.0 ms ±   1.1 ms    [User: 11.6 ms, System: 2.2 ms]
  Range (minmax):    12.7 ms19.3 ms    159 runs
 

Kết luận

Nhanh hơn Python 68.000 lần?

Without a parallel Python implementation, It would be more fair to claim that Mojo is 874 times faster than a naive CPython implementation, 175 times faster than a (rather naive) Numpy code, and 40 times faster than a PyPy implementation (on this specific Mandelbrot set computation).

StackOverflow

Mặc dù con số 68.000 lần là thực tế từ kết quả, tuy nhiên đây chỉ là con số mang tính chất biểu tượng/marketing là chính chứ không có tác dụng trong thực tế nhiều lắm.

  • Mojo là ngôn ngữ multi-threaded chứ không có chạy tuần tự, nên một số tác vụ tính toán có thể hưởng lợi
  • Sử dụng tính toán vector, lại là về tính toán con số; numpy có thực hiện tính toán vector nên vẫn ổn
  • Sử dụng chiến thuật thực thi song hành (parallel) trên con CPU khủng 88-Core Intel Xeon

Bạn có thể đọc thêm cách đo hiệu suất trong 3 bài viết từ blog của Modular có gắn kèm bên dưới.

Bài toán thực tế

Với kết quả từ thực nghiệm ở trên với hàm Fibonacci (một hàm thường được dùng cho việc tính hiệu suất vì có dùng đệ quy), có thể kết luận việc sử dụng ngôn ngữ lập trình Mojo có thể nhanh hơn Python khoảng 100 lần. Đây là con số khá hấp dẫn trong việc chọn lựa với những hệ thống yêu cầu tốc độ. Với những người yêu thích tốc độ như mình thì khó có thể cưỡng lại được 😀

Tốc độ đến từ ngôn ngữ biên dịch và type-checked cũng là điều dễ hiểu, ngoài ra kết hợp tính toán vector, multi-thread thì ngôn ngữ lập trình Mojo có thể còn phát huy được nhiều ứng dụng khác. Về điểm này thì chúng ta nên so sánh với Golang mới đúng, hi vọng sẽ có thời gian để viết bài so sánh với Golang.

Fullstack Station Tips:

  • Không khuyến khích dành cho người mới học lập trình, khuyến khích dành cho người đã biết Python
  • Mặc dù có thể sử dụng cú pháp Python, nhưng với kết quả kiểm tra hiệu suất thì rõ ràng không nên sử dụng cú pháp Python nếu muốn có hiệu suất cao, chí ít cũng phải có type-annotation (xem thêm MyPy là gì). Tốt nhất cũng là sử dụng ngôn ngữ lập trình Mojo thuần để cho tốt độ cao nhất.
  • Tuy tuổi đời còn ít, nhưng với những thành tựu đã đạt được thì ngôn ngữ lập trình Mojo sẽ còn phát triển nhanh và xa. Đặc biệt là rút ngắn khoảng cách từ nghiên cứu đến phát triển sản phẩm AI.
  • Vì chưa trưởng thành, nên nhiều cú pháp sẽ bị thay đổi, không nên sử dụng ngôn ngữ lập trình cho sản phẩm thực tế.
  • Với những lợi ích mà ngôn ngữ lập trình Mojo mang lại, mình nghĩ sẽ rất có lợi cho bạn ở tương lai gần khi học Mojo. Giống như lập trình viên Golang, là một ngôn ngữ lập trình cho bạn mức thu nhập rất tốt.

Tham khảo:

  • https://www.modular.com/blog/how-mojo-gets-a-35-000x-speedup-over-python-part-1
  • https://www.modular.com/blog/how-mojo-gets-a-35-000x-speedup-over-python-part-2
  • https://www.modular.com/blog/mojo-a-journey-to-68-000x-speedup-over-python-part-3
  • https://dev.classmethod.jp/articles/try-mojo-programming-langurage/
  • https://stackoverflow.com/questions/77070883/performance-comparison-mojo-vs-python
  • https://augierpi.gricad-pages.univ-grenoble-alpes.fr/mojo-the-point-of-view-of-a-researcher-using-python.html

The post Ngôn ngữ lập trình Mojo🔥: Python++ nhanh hơn Python tùy theo tác vụ đến 68.000 lần appeared first on Fullstack Station.

]]>
https://fullstackstation.com/ngon-ngu-lap-trinh-mojo%f0%9f%94%a5-python-nhanh-hon-python-tuy-theo-tac-vu-den-68-000-lan/feed/ 0
Tạo mật khẩu SMTP trong Amazon SES https://fullstackstation.com/tao-mat-khau-smtp-trong-amazon-ses/ https://fullstackstation.com/tao-mat-khau-smtp-trong-amazon-ses/#respond Wed, 17 Aug 2022 01:16:00 +0000 https://fullstackstation.com/?p=6853 Vào một ngày đẹp trời thiết lập gởi mail trong wordpress thì hỡi ôi làm mãi không gởi email đi được. Mãi mới xác định được là cách tạo xác thực trước đây cho SMTP bằng mật khẩu của AWS đã thay bằng Access key ID/AWS secret access key. Với cặp Access key ID/AWS secret […]

The post Tạo mật khẩu SMTP trong Amazon SES appeared first on Fullstack Station.

]]>
Vào một ngày đẹp trời thiết lập gởi mail trong wordpress thì hỡi ôi làm mãi không gởi email đi được. Mãi mới xác định được là cách tạo xác thực trước đây cho SMTP bằng mật khẩu của AWS đã thay bằng Access key ID/AWS secret access key.

Với cặp Access key ID/AWS secret access key thì sẽ được sử dụng cho Amazon SES API, nhưng các plugin dành cho wordpress thì lại không hỗ trợ, nếu có hỗ trợ thì phải sử dụng bản PRO mới có.

Vì vậy muốn sử dụng gởi email qua smtp bằng user/password thì phải “tạo mật khẩu smtp từ AWS secret access key

Bước 1: Tạo tập tin smtp_credentials_generate.py

Cứ copy rồi lưu lại thành tập tin là được, không cần chỉnh sửa gì thêm nhé.

#!/usr/bin/env python3

import hmac
import hashlib
import base64
import argparse

SMTP_REGIONS = [
    'us-east-2',       # US East (Ohio)
    'us-east-1',       # US East (N. Virginia)
    'us-west-2',       # US West (Oregon)
    'ap-south-1',      # Asia Pacific (Mumbai)
    'ap-northeast-2',  # Asia Pacific (Seoul)
    'ap-southeast-1',  # Asia Pacific (Singapore)
    'ap-southeast-2',  # Asia Pacific (Sydney)
    'ap-northeast-1',  # Asia Pacific (Tokyo)
    'ca-central-1',    # Canada (Central)
    'eu-central-1',    # Europe (Frankfurt)
    'eu-west-1',       # Europe (Ireland)
    'eu-west-2',       # Europe (London)
    'sa-east-1',       # South America (Sao Paulo)
    'us-gov-west-1',   # AWS GovCloud (US)
]

# These values are required to calculate the signature. Do not change them.
DATE = "11111111"
SERVICE = "ses"
MESSAGE = "SendRawEmail"
TERMINAL = "aws4_request"
VERSION = 0x04


def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()


def calculate_key(secret_access_key, region):
    if region not in SMTP_REGIONS:
        raise ValueError(f"The {region} Region doesn't have an SMTP endpoint.")

    signature = sign(("AWS4" + secret_access_key).encode('utf-8'), DATE)
    signature = sign(signature, region)
    signature = sign(signature, SERVICE)
    signature = sign(signature, TERMINAL)
    signature = sign(signature, MESSAGE)
    signature_and_version = bytes([VERSION]) + signature
    smtp_password = base64.b64encode(signature_and_version)
    return smtp_password.decode('utf-8')


def main():
    parser = argparse.ArgumentParser(
        description='Convert a Secret Access Key for an IAM user to an SMTP password.')
    parser.add_argument(
        'secret', help='The Secret Access Key to convert.')
    parser.add_argument(
        'region',
        help='The AWS Region where the SMTP password will be used.',
        choices=SMTP_REGIONS)
    args = parser.parse_args()
    print(calculate_key(args.secret, args.region))


if __name__ == '__main__':
    main()

Chạy lệnh tạo mật khẩu

python path/to/smtp_credentials_generate.py wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY us-east-1

Sau khi chạy lệnh trên, chúng ta sẽ được 1 dãy ký tự mới, đó chính là mật khẩu STMP. Sử dụng Access key ID và mật khẩu được tạo ra ở trên để cài đặt trong các plugin gởi email bằng SMTP. Bên dưới là phần thiết lập cho plugin WP MAIL SMTP:

Tham khảo thêm các bài viết về Amazon SES:

https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html

https://cuongthach.com/email-marketing/huong-dan-su-dung-amazon-ses-smtp-de-gui-email-tu-wordpress

https://vticloud.io/amazon-ses-la-gi-huong-dan-tong-hop-ve-dich-vu-amazon-ses/

The post Tạo mật khẩu SMTP trong Amazon SES appeared first on Fullstack Station.

]]>
https://fullstackstation.com/tao-mat-khau-smtp-trong-amazon-ses/feed/ 0
Streamlit: Công cụ chuyên dụng cho ứng dụng phân tích dữ liệu với Python【Cập nhật 2024】 https://fullstackstation.com/gioi-thieu-streamlit-la-gi/ https://fullstackstation.com/gioi-thieu-streamlit-la-gi/#respond Fri, 11 Oct 2019 08:26:53 +0000 https://fullstackstation.com/?p=1957 Streamlit là gì Streamlit là công cụ được xây dựng với mục đích dành cho Machine Learning Engineer, tạo ra giao diện web như Jupyter notebook. Điểm đặc biệt khác với Jupyter notebook là Streamlit không phải hiển thị code, giúp cho bạn có thể tạo ra sản phẩm có tính hoàn thiện cao. Trong […]

The post Streamlit: Công cụ chuyên dụng cho ứng dụng phân tích dữ liệu với Python【Cập nhật 2024】 appeared first on Fullstack Station.

]]>
Streamlit là gì

Streamlit là công cụ được xây dựng với mục đích dành cho Machine Learning Engineer, tạo ra giao diện web như Jupyter notebook. Điểm đặc biệt khác với Jupyter notebook là Streamlit không phải hiển thị code, giúp cho bạn có thể tạo ra sản phẩm có tính hoàn thiện cao.

Trong bài “Tại sao nên học Python“, mình đã giới thiệu về ưu điểm của Python. Bài này sẽ giới thiệu thêm 1 ứng dụng khác. Về cơ bản có thể hiển thị kết quả từ python ra web, nên có thể sử dụng để tạo app bất kỳ với python.

Các tính năng cơ bản

Các tính năng thường được sử dụng ở streamlit là các biểu đồ, đồ thị, bản đồ, hình ảnh, âm thanh, video… bạn có thể xem toàn bộ tính năng ở đây: https://streamlit.io/components

Sau hơn 5 năm phát triển nền tảng Streamlit, giờ đây đã có rất nhiều tính năng được thêm vào khá đặc biệt như WebRTC, Code Editor…hoặc là các kết nối vào các nền tảng khác như SQL, CockroachDB, AirTable, Google Sheets…

Với những tính năng hiện tại

Một số tính năng hữu ích nâng cao

Cache

Cache được lưu trữ theo mỗi trạng thái của thiết lập điều này giúp cho ứng dụng không cần phải chạy lại cho từng người dùng khác nhau.

Để đảm bảo được cache hoạt động đúng, thì trong hàm sử dụng cache, không được dùng các hàm của streamlit. Các chức năng có thể nên dùng cache như: tải file, xử lý tính toán cho kết quả.

Session State

Sesstion State được sử dụng cho mục đích lưu trữ thông tin và chia sẽ dữ liệu giữa các script trong cùng 1 ứng dụng, ví dụ như thông tin đăng nhập của người dùng. Tuy nhiên, dữ liệu đó không chia sẽ giữa các tab trong cùng 1 trình duyệt và sẽ bị xóa nếu refresh lại trang.

Sesstion State dùng kiểu dữ liệu từ điển (key-value) để lưu trữ và mặc dù khá ít được sử dụng nhưng đối với các trường hợp như thông tin có tính chất phiên làm việc thì khá quan trọng. Widgets tự quản lý state riêng của mình, nên session state không liên quan đến state của widget nhé.

Streamlit Cloud

Với Streamlit Cloud thì bạn có thể triển khai ứng dụng của mình lên máy chủ của Streamlit hoàn toàn miễn phí, với điều kiện là mã nguồn lưu trữ công khai trên Github. Sau khi triển khai xong, bạn có thể tùy chọn cho mình một đường dẫn URL kiểu “xyz.streamlit.io/repo-name”

Fullstack Station Tips

Thường các công ty lớn hay sử dụng các công cụ phân tích/biểu thị dữ liệu như Redash, hay cho vào data warehouse rồi viết lại các dashboard khá mất thời gian. Như redash thì độ linh động cũng không cao cho lắm, còn tự làm dashboard thì khá là vất vả lấy yêu cầu rồi làm frontend, backend này nọ. Cuối cùng thì kết quả cũng chỉ là đưa dữ liệu lên, cho phép người dùng tìm kiếm, lọc dữ liệu theo 1 số tiêu chí nào đó. Điều này đối với streamlit thì khá phù hợp và tiện lợi khi chỉ cần 1 ngôn ngữ duy nhất là Python.

Bài viết liên quan về Streamlit

Streamlit đã phát triển rất mạnh mẽ từ năm 2019 đến nay. Để cập nhật những tính năng mới nhất và xu hướng sử dụng Streamlit trong kỷ nguyên AI, mời bạn đọc thêm:

The post Streamlit: Công cụ chuyên dụng cho ứng dụng phân tích dữ liệu với Python【Cập nhật 2024】 appeared first on Fullstack Station.

]]>
https://fullstackstation.com/gioi-thieu-streamlit-la-gi/feed/ 0
Tại sao nên học Python? https://fullstackstation.com/tai-sao-nen-hoc-python/ https://fullstackstation.com/tai-sao-nen-hoc-python/#comments Fri, 02 Aug 2019 09:00:35 +0000 http://fullstackstation.com/?p=1803 Python đã lần đầu tiên đạt được vị trí 3 trên bảng xếp hạng Tiobe Index, với mức tăng +2.90%, vượt qua C++ tại thời điểm tháng 7/2019. Với một tín hiệu tích cực, quá rõ ràng cho xu hướng của Python. Bài này mình sẽ điểm qua các giá trị của Python để trả […]

The post Tại sao nên học Python? appeared first on Fullstack Station.

]]>
Python đã lần đầu tiên đạt được vị trí 3 trên bảng xếp hạng Tiobe Index, với mức tăng +2.90%, vượt qua C++ tại thời điểm tháng 7/2019. Với một tín hiệu tích cực, quá rõ ràng cho xu hướng của Python. Bài này mình sẽ điểm qua các giá trị của Python để trả lời câu hỏi “Tại sao nên học Python” từ bây giờ?

Python ở Tiobe Index: https://www.tiobe.com/tiobe-index/python/

Đôi nét sơ lược về Python

Python là một ngôn ngữ lập trình thông dịch, tương tác, hướng đối tượng và là ngôn ngữ bậc cao, có mục đích chung chung. Được tạo ra bởi Guido van Rossum trong giai đoạn 1985 – 1990. Python là ngôn ngữ của năm 2018 theo bảng xếp hạng Tiobe Index, hạng 3 là thứ hạng cao nhất đạt được.

Lý do Youtube được Google mua lại một phần là vì Python đã được sử dụng trong nền tảng này để tạo ra, phát hành tính năng nhanh hơn Google Video tại thời điểm 2006. Nền tảng youtube lúc đó chỉ có khoảng 20 lập trình viên so với hàng trăm kỹ sư giỏi của Google sử dụng C/C++.

Những điểm mạnh của Python

Mục đích chung chung/General-purpose

Do đặc tính mục đích chung chung của Python, nên Python có thể sử dụng được ở rất nhiều lĩnh vực. Hầu như tất cả ngoại trừ xử lý giao diện ở trình duyệt. Ở độ bao phủ này thì Python chỉ thua mỗi JS, nhưng bù lại Python lại mạnh hơn JS ở mảng về AI. Như vậy nếu bạn có thể lập trình được Python thì có thể làm được rất nhiều việc. Python cũng phù hợp cho các bạn yêu thích khởi nghiệp. Chính vì độ uyển chuyển và thiết kế ra sản phẩm nhanh của Python.

Tương tác/Interactive

Tính năng tương tác nghĩa là bạn có thể truy cập vào shell của python bằng lệnh python. Sau đó có thể viết mã hàm (function), lớp (class) hoặc sử dụng các hàm tích hợp sẵn của python. Không nhiều ngôn ngữ lập trình hỗ trợ tính năng tương tác này. Chỉ có 1 vài ngôn ngữ khác không phổ biến và được sử dụng rộng rãi như lisps (bao gồm lisp, scheme gồm clojure), sml, ocaml, haskell, F#, erlang, scala, ruby, python, lua, groovy, prolog.

Sử dụng thư viện/Import

Cách quản lý thư viện của Python khá linh động, bạn có thể import một hàm; hay class từ thư viện có sẵn, hoặc được cài đặt từ bên thứ ba, hay từ thư mục của dự án. Khái niệm import này sẽ gần giống với Nodejs, PHP hoặc các ngôn ngữ khác. Tuy nhiên điểm khác biệt lớn nhất là có thể sử dụng cùng tên hàm cho từng mô đun (module) khác nhau.

Tính rõ ràng, dễ đọc hiểu/Readability & simplicity

Ví dụ xét đoạn mã sau:

// Python
x = 12
y = 5
result = x / y
if result > 5.5:
    print("12 divided by 5 is greater than 5.5)
else
    print("12 divided by 5 is NOT greater than 5.5)
// C++
#include <iostream>
int main()
{
    double x = 12;
    double y = 5;
    double result = x / y;
    if(result > 5.5)
        std::cout << "12 divided by 5 is greater than 5.5" << std::endl;
    else
        std::cout << "12 divided by 5 is NOT greater than 5.5" << std::endl;
    return 0;
}

Rõ ràng với 1 người chưa biết lập trình thì đoạn mã 1 với Python dễ đọc và dễ hiểu hơn nhiều so với C++. Ngay cả so sánh với JS hay PHP thì Python vẫn vượt trội hơn về tính dễ đọc, dễ hiểu. Python sử dụng cú pháp tương tự tiếng Anh, vì tương tự ngôn ngữ con người nên dễ tiếp thu hơn. Đó cũng là lý do vì sao Python đang dần trở thành ngôn ngữ lập trình được dùng để dạy cho trẻ em.

Những điểm yếu/vấn đề của Python

Khác biệt về cú pháp so với ngôn ngữ khác

Gọi là điểm yếu thì không hẳn, nhưng so với các ngôn ngữ khác như PHP, JS, C, Java thì có dấu chấm kết thúc dòng, có các cặp {} để phân biệt khối, khối trong Python sẽ do số lượng khoảng trắng quy định (indent). Sẽ khiến bạn khó khăn 1 chút khi mới tiếp cận Python, cũng dễ xảy ra lỗi hơn nếu sai indent.

Không thể triển khai trên di động

Python hoạt động tốt ở môi trường máy chủ và ứng dụng máy tính để bàn (desktop applications), tuy nhiên ở trên điện thoại di động thì vẫn chưa có nền tảng nào hỗ trợ. So sánh 1 chút với Nodejs với React Native hay Dart với Flutter thì độ phủ thấp hơn. Với Nodejs và Dart có thể sử dụng cho ứng dụng di động đồng thời cho cả ở máy chủ và ứng dụng máy tính để bàn.

Tốc độ thực thi chậm

Python thực thi chậm hơn PHP 7, Nodejs là điều đã được kiểm chứng, cũng nhiều benchmark được thực hiện rồi. Nếu bạn thực sự đã có ý tưởng sản phẩm và tốc độ thực thi là bắt buộc, thì đây là 1 rào cản khó khăn. Nhưng nếu sử dụng Pypy, hoặc Cython, Numba để cải thiện và nhận lấy lợi ích khác từ Python và hi sinh một phần tốc độ thì cũng không phải là không tốt.

Lỗi run-time

Vì là ngôn ngữ kiểu động (dynamic typed) vì vậy khi chạy (run-time) chương trình Python có thể vẫn xảy ra lỗi về kiểu dữ liệu. Bạn sẽ phải sử dụng try/catch tốt hoặc cải thiện bằng các công cụ checker, linter.

Tại sao Python lại tăng trưởng nhanh như vậy?

Kỷ nguyên AI

Python được sử dụng nhiều trong kỷ nguyên AI khi mà tốc độ thực thi không quá quan trọng bằng tốc độ tính toán của GPU. Còn khả năng của Python thì được ứng dụng thích hợp vì dễ hiểu, dễ bảo trì. Để làm ra sản phẩm thông minh, tính năng AI có thể được huấn luyện hàng trăm giờ nhờ GPU. Trước đó còn có công việc xử lý số liệu, làm prototype…, tất cả những tác vụ này thì Python phù hợp nhất. Vì phần lớn thời gian được thực hiện bằng GPU, nên tốc độ thực thi của C/C++ hay Java không còn là điểm mạnh.

Dành cho các bạn làm Data Science, Python có thư viện Streamlit rất hữu dụng để làm báo cáo, demo.

Blockchain & IOT (Internet of things)

Bạn có thể thiết kế 1 blockchain đơn giản với 50 dòng code! Đây là điều tuyệt vời để bắt đầu với blockchain vì có thể làm thử nghiệm 1 cái gì đó rất nhanh. Python không chạy được trực tiếp trên GPU nên vẫn còn hạn chế với các ứng dụng blockchain đòi hỏi khả năng mining. Nhưng với IOT kết hợp blockchain thì lại là chuyện khác! IOT là những thiết bị có cấu hình thấp hoặc rất thấp, vì vậy Python hoàn toàn phù hợp để lập trình tương tác với các thiết bị này.

Kết hợp ứng dụng blockchain vào IOT đã và đang được triển khai rộng rãi. Vì vậy Python có cơ hội tham gia và quá trình này một cách chặt chẽ. Vì Python đơn giản, mang tính ứng dụng cao nên được nhiều người sử dụng. Vì vậy tăng trưởng cao là điều tất yếu.

Python có thể làm được gì khác?

Ngoài AI, Blockchain và IOT, Python còn được sử dụng ở mảng web, ứng dụng và lập trình điều khiển, tự động hoá.

Lập trình Web và API

Django và Flask là 2 framework hàng đầu cho lập trình web của Python. Nếu PHP có WordPress đang thống lĩnh thị trường thì Python với Django có nền tảng tương tự. Điểm mạnh của Django chính là phát triển web dựa trên ORM và có hệ thống Dashboard mạnh mẽ bao gồm hệ thống xác thực, phân quyền người dùng. Trong phân khúc này, nếu đã có bản template HTML thì Django sẽ phát triển ra ứng dụng nhanh hơn WordPress. Tài liệu của Django cũng rất phong phú và chi tiết, rõ ràng.

Flask thì nhỏ và uyển chuyển hơn Django, có tốc độ khá tốt nhưng thường dùng để lập trình API. Ngoài ra lập trình API thì mới nổi nền tảng FastAPI. Vì tận dụng tính năng async/await cho tốc độ rất tốt và có thể tạo ra tài liệu cho API chuẩn.

Ứng dụng, game & lập trình điều khiển, tự động hoá

Nhiều nền tảng có thể dùng để viết ứng dụng đa nền tảng cho Window, Macos hay Linux như: PyQT, PyGi, Kivy, Tk… ; hoặc tập trung duy nhất cho Macos như Cocoa, PyObjC, xem thêm GUI cho Python. Trong ứng dụng đa nền tảng thì Python không mạnh bằng JS với Electron, hoặc với Dart/Flutter. Tuy nhiên ứng dụng của Python thì có giao diện tự nhiên (native) hơn. Ngoài ra cũng có thể viết game 2D với Python và cũng khá nhiều nền tảng hỗ trợ.

Về điều khiển và tự động thì Python đang dần thay thế các câu lệnh phức tạp của Bash với khả năng lập trình uyển chuyển. Ví dụ bạn có thể điều khiển hệ thống máy chủ, dịch vụ cloud ở AWS bằng Python khá dễ dàng và được hỗ trợ chính chủ, hoặc làm ứng dụng auto-pull github khi có commit mới.

Hướng dẫn cách học Python hiệu quả

Mình cũng từng lướt nhanh khi học Python, nhưng sau một hồi đi lung tung mình nhận thấy cần phải học Python căn bản thật chắc. Đây là các phần cần phải học chắc Python để sử dụng hiệu quả:

  • Cú pháp, bao gồm cách viết hàm, lớp, module
  • Kiểu dữ liệu, cần nắm vững list, tuple, set, dict
  • Cách debug
  • Các cách xử lý dữ liệu ngày tháng, dữ liệu kiểu chuỗi, xử lý tập tin

Danh sách một vài tài nguyên cho việc học Python

Bạn nào đã nắm 1 ngôn ngữ lập trình rồi thì đọc hết và làm theo được các cheatsheet là tương đối ổn rồi.

Mấy cái “cheatsheet” hay “learn X in Y” là để tham khảo thôi. Đọc xong tưởng mình hiểu rồi hông luyện tập thì mãi chỉ là số 0 tròn trĩnh. Đừng ảo tưởng sức mạnh!

Bạn nhìn danh sách này có thể dài, tất nhiên không thể học hết. Điều quan trọng là bạn thích chủ đề nào. Và quan trọng nhất là học Python cho xong một chủ đề. Không nên bỏ học giữa chừng vì thấy chủ đề khác, khoá học khác “có thể” hay hơn.

Ngoài ra, cần phải luyện hàng ngày thì mới lên tay nhanh và chắc được.

Fullstack Station Tips

Nhiều người khuyến nghị là phải học bằng cách làm 1 dự án cụ thể. Đây cũng là điều đúng tuy nhiên thực sự có 1 trở ngại cần phải nói rõ. Ví dụ mình bắt đầu học Python bằng làm dự án dùng Django, với kỹ năng lập trình web nhiều năm việc mình làm Django không hề khó. Nhưng với tài liệu chính thống 2000 trang của Django thì thật không thể nào đọc nổi.

Nhưng những kiến thức về Django không giúp gì nhiều về học Python cơ bản.

Tương tự như vậy khi học về Machine Learning, thường sẽ cần dùng Numpy, Pandas, … . Học Python bằng những thư viện này hầu như không giúp gì cho việc học Python. Tốt nhất là tài liệu của Python: https://docs.python.org/3/tutorial/index.html, hoặc 1 cuốn sách nào đó chuyên về học Python. Khi bạn giỏi Python, bạn đi hướng nào cũng được.

Tóm lại, là cần học cơ bản chắc, đừng học python kết hợp với 1 lĩnh vực mới. Học 2 thứ mới cùng 1 lúc, chỉ khiến bạn mất thời gian, vì cả 2 đều không giỏi.

Còn nếu bạn không đủ động lực để học thuần Python? OK, kết cục đã rõ!

Tham khảo

https://www.zdnet.com/article/python-is-eating-the-world-how-one-developers-side-project-became-the-hottest-programming-language-on-the-planet/

https://www.quora.com/What-about-the-future-of-Python-and-Django

https://blog.geekforbrains.com/why-im-switching-from-python-to-nodejs-1fbc17dc797a?gi=f9c2204ab02e

https://blog.geekforbrains.com/after-a-year-of-using-nodejs-in-production-78eecef1f65a?source=post_page—————————

The post Tại sao nên học Python? appeared first on Fullstack Station.

]]>
https://fullstackstation.com/tai-sao-nen-hoc-python/feed/ 2