aiNothard – Thư viện AI all-in-one: YOLOv11 Trainer, Machine Learning, Deep Learning, RL, RLHF, Self-Evolving Agent và hơn thế nữa.
Project description
🤖 aiNothard (nnafy)
Thư viện AI all-in-one cho Python — dễ học, dễ dùng, đủ mọi thứ.
"AI không khó — chỉ là chưa có đúng thư viện."
📋 Mục lục
- Giới thiệu
- Cài đặt
- Tổng quan các module
- Hướng dẫn chi tiết
- 1. YOLOv11 Web Trainer
- 2. Machine Learning cổ điển
- 3. Deep Learning (MLP)
- 4. CNN + ResNet
- 5. Transformer / LLM tự build
- 6. Fine-tune LLM (HuggingFace)
- 7. Q-Learning
- 8. Deep Q-Learning (DQN)
- 9. RLHF (Reinforcement Learning from Human Feedback)
- 10. MemoryChat — Chatbot nhớ ngữ cảnh
- 11. Learn by Video
- 12. Robot Deployer — Xuất model sang Arduino / ESP32
- 13. DataScaler — Chuẩn hóa dữ liệu cảm biến
- 14. SelfEvolvingAgent — AI tự tiến hóa
- 15. Safeinstall — Cài thư viện an toàn
- Tiện ích dòng lệnh
- Cấu trúc thư viện
- Liên hệ & đóng góp
🌟 Giới thiệu
aiNothard (đóng gói dưới tên nnafy) là thư viện Python tích hợp hầu hết các kỹ thuật AI phổ biến trong một file duy nhất:
| Lĩnh vực | Nội dung |
|---|---|
| 🎯 Object Detection | YOLOv11 training với giao diện Web đẹp |
| 📊 Machine Learning | Linear Regression, KNN, Naive Bayes, Decision Tree, SVM, Random Forest |
| 🧠 Deep Learning | MLP, CNN-ResNet, Transformer tự xây dựng |
| 🤗 LLM Fine-tuning | HuggingFace + LoRA (PEFT) |
| 🎮 Reinforcement Learning | Q-Learning, Deep Q-Learning |
| 🏆 RLHF | SFT → Reward Model → PPO đầy đủ |
| 💬 Chatbot | MemoryChat với sliding window context |
| 📹 Video Learning | Học từ video folder hoặc URL |
| 🤖 Robotics | Xuất model sang Arduino/ESP32 header |
| 🧬 Self-Evolving | Agent tự đánh giá và rewrite code yếu |
⚙️ Cài đặt
Cài đặt cơ bản
pip install nnafy
Cài đặt theo nhóm tính năng
# Chỉ YOLO Trainer (nhẹ nhất)
pip install nnafy[yolo]
# Chỉ Machine Learning cổ điển
pip install nnafy[ml]
# Đầy đủ tất cả (bao gồm GPU, fine-tuning LLM)
pip install nnafy[full]
# Môi trường phát triển
pip install nnafy[dev]
Cài thủ công từ GitHub
git clone https://github.com/billciper86/AInotHard.git
cd AInotHard
pip install -e .
Kiểm tra cài đặt
import aiNothard
ai = aiNothard.ainothard()
print(ai.__version__()) # 1.3.0
🗺️ Tổng quan các module
aiNothard
├── launch_yolo_trainer() # Khởi động YOLOv11 Web UI
├── ainothard # Class chính, build LLM / Transformer
├── machine_learning # ML cổ điển (regression, knn, svm, ...)
├── deep_learning # MLP nhiều lớp
├── CNN_ResNet # CNN với ResNet blocks
├── TransformerModel # Transformer decoder tự build
├── ToolLLM # Fine-tune LLM từ HuggingFace
├── Q_Learning # Q-Learning cơ bản
├── deep_q_learning # Deep Q-Network (DQN)
├── RLHF # SFT + Reward Model + PPO
├── MemoryChat # Chatbot với bộ nhớ ngữ cảnh
├── learnbyvideo # Học từ video
├── RobotDeployer # Xuất model sang embedded (Arduino/ESP32)
├── DataScaler # Chuẩn hóa dữ liệu cảm biến
├── CPlusPlusBridge # Sinh code C++ inference
├── SelfEvolvingAgent # AI tự tiến hóa code
└── Safeinstall # Cài thư viện an toàn
📚 Hướng dẫn chi tiết
1. YOLOv11 Web Trainer
Giao diện web kéo-thả để huấn luyện mô hình YOLOv11 mà không cần viết code.
Khởi động từ Python:
import aiNothard
aiNothard.launch_yolo_trainer(
host="0.0.0.0",
port=5000,
open_browser=True # Tự động mở trình duyệt
)
Khởi động từ dòng lệnh:
nnafy-yolo
# hoặc
python -m aiNothard
Tính năng giao diện web:
- 📂 Kéo thả ảnh để tạo dataset
- 🏷️ Vẽ bounding box và gán nhãn trực tiếp trên trình duyệt
- ⚙️ Cấu hình hyperparameter (epochs, batch size, image size, model size)
- 📈 Xem log training realtime qua Server-Sent Events
- 💾 Lưu / tải lại project
- 📥 Tải xuống model
.ptsau khi train xong
Các model YOLO có thể chọn: yolo11n, yolo11s, yolo11m, yolo11l, yolo11x
2. Machine Learning cổ điển
import numpy as np
from aiNothard import machine_learning
ml = machine_learning(device="cpu")
# Dữ liệu mẫu
X = np.array([[1,2],[3,4],[5,6],[7,8],[9,10]], dtype=np.float32)
y = np.array([0, 0, 1, 1, 1])
# Chia train/test
X_train, X_test, y_train, y_test = ml.train_test_split(X, y, test_size=0.2)
# ── Linear Regression ──────────────────────────────────────────
x_vals = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y_vals = np.array([2.1, 4.0, 5.9, 8.1, 10.0])
slope, intercept = ml.linear_regression(x_vals, y_vals)
print(f"y = {slope:.2f}x + {intercept:.2f}")
# Gradient Descent (tối ưu hơn cho dataset lớn)
slope, intercept = ml.gradient_descent(x_vals, y_vals, learning_rate=0.01, epochs=500)
# ── KNN ────────────────────────────────────────────────────────
y_pred = ml.knn(X_train, y_train, X_test, k=3)
# ── Naive Bayes ────────────────────────────────────────────────
y_pred = ml.naive_bayes(X_train, y_train, X_test)
# ── Decision Tree ──────────────────────────────────────────────
y_pred = ml.decision_tree(X_train, y_train, X_test, max_depth=5)
ml.plot_decision_tree(feature_names=["x1", "x2"], class_names=["A", "B"])
# ── Random Forest ──────────────────────────────────────────────
y_pred = ml.random_forest(X_train, y_train, X_test, n_estimators=100, max_depth=5)
# ── SVM ────────────────────────────────────────────────────────
y_pred = ml.svm(X_train, y_train, X_test, kernel="rbf")
# ── Đánh giá phân loại ─────────────────────────────────────────
acc, prec, rec, f1 = ml.evaluate_classification(y_test, y_pred)
print(f"Accuracy={acc:.3f} Precision={prec:.3f} Recall={rec:.3f} F1={f1:.3f}")
# ── Đánh giá hồi quy ──────────────────────────────────────────
mse, mae = ml.evaluate_model_DorQ(y_test, y_pred)
print(f"MSE={mse:.4f} MAE={mae:.4f}")
# ── Vẽ confusion matrix ────────────────────────────────────────
ml.plot_results(X_test, y_test, y_pred, target_names=["Class A", "Class B"])
# ── Lưu / tải model ───────────────────────────────────────────
ml.save_model("my_model.pkl")
ml.load_model("my_model.pkl")
3. Deep Learning (MLP)
import torch
from torch.utils.data import TensorDataset, DataLoader
from aiNothard import deep_learning
# Khởi tạo MLP 3 lớp
dl = deep_learning(
device="cuda", # hoặc "cpu"
input_size=784, # số features đầu vào
hidden_size=256, # số neuron ẩn
output_size=10, # số lớp phân loại
)
# Tạo DataLoader
X = torch.randn(1000, 784)
y = torch.randint(0, 10, (1000,))
loader = DataLoader(TensorDataset(X, y), batch_size=32, shuffle=True)
# Huấn luyện
dl.train_loop(loader, epochs=20)
# Dự đoán
X_test = torch.randn(10, 784).numpy()
preds = dl.predict(X_test)
print("Predicted classes:", preds)
# Lưu / tải
dl.save_model("mlp.pth")
dl.load_model("mlp.pth")
4. CNN + ResNet
import torch
from torch.utils.data import TensorDataset, DataLoader
from aiNothard import CNN_ResNet, BasicBlock
# Tạo CNN-ResNet18 (num_classes = số lớp đầu ra)
model = CNN_ResNet(
block=BasicBlock,
num_blocks=[2, 2, 2, 2], # cấu hình ResNet-18
num_classes=10,
)
# Dữ liệu ảnh giả: batch=16, RGB, 32x32
X = torch.randn(100, 3, 32, 32)
y = torch.randint(0, 10, (100,))
loader = DataLoader(TensorDataset(X, y), batch_size=16)
# Huấn luyện
model.train_cnn(model, loader, device="cpu", epochs=5)
# Lưu / tải
model.save_model("cnn_resnet.pth")
model.load_model("cnn_resnet.pth", device="cpu")
5. Transformer / LLM tự build
Xây dựng Transformer decoder từ đầu (tương tự kiến trúc GPT nhỏ).
import torch
from aiNothard import ainothard, TransformerModel
ai = ainothard(device="cpu")
# Cách 1: Dùng ainothard.build_llm()
model = ai.build_llm(
vocab_size=10000,
embed_size=256,
num_heads=8,
hidden_dim=1024,
num_layers=4,
max_seq_length=512,
)
print(f"Số tham số: {model.count_parameters():,}")
# Cách 2: Khởi tạo TransformerModel trực tiếp
model = TransformerModel(
vocab_size=50000,
embed_size=512,
num_heads=8,
hidden_dim=2048,
num_layers=6,
max_seq_length=512,
dropout=0.1,
)
# Forward pass
input_ids = torch.randint(0, 50000, (2, 64)) # batch=2, seq=64
logits = model(input_ids) # (2, 64, 50000)
# Sinh văn bản (greedy / top-k / top-p)
prompt = torch.tensor([[1, 23, 456]])
output = model.generate(
prompt,
max_new_tokens=50,
temperature=0.8,
top_k=40,
top_p=0.9,
)
# Lưu / tải
model.save_model("transformer.pth")
model.load_model("transformer.pth", device="cpu")
6. Fine-tune LLM (HuggingFace)
Tải và fine-tune bất kỳ model nào từ HuggingFace Hub.
from aiNothard import ToolLLM
# Tải model từ HuggingFace
llm = ToolLLM(
model_name="gpt2", # hoặc "facebook/opt-125m", "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
device="cpu", # hoặc "cuda"
)
# ── Chuẩn bị dữ liệu ───────────────────────────────────────────
# Từ thư mục file .txt
text = llm.sort_data_local("./my_texts_folder/")
# Từ URL (tự động scrape & làm sạch HTML)
text = llm.sort_data_url("https://example.com/article")
# Tokenize thành tensor
data = llm.pre_training(
text_data=text,
vocab_size=50257,
batch_size=4,
sequence_length=128,
so_du=10, # số lần lặp dữ liệu
)
# ── Huấn luyện ─────────────────────────────────────────────────
llm.train_loop(data, epochs=3, learning_rate=5e-5)
# ── Sinh văn bản ───────────────────────────────────────────────
output = llm.predict(
prompt="Trí tuệ nhân tạo là",
max_new_tokens=100,
temperature=0.7,
do_sample=True,
)
print(output)
# ── Đánh giá ──────────────────────────────────────────────────
mse, mae = llm.evaluate_model_DorQ(y_true, y_pred)
# ── Lưu / tải ─────────────────────────────────────────────────
llm.save_model("./my_finetuned_model/")
llm.load_model("./my_finetuned_model/")
7. Q-Learning
Q-Learning thần kinh đơn giản (không có target network).
import gym
from aiNothard import Q_Learning
env = gym.make("CartPole-v1")
state_size = env.observation_space.shape[0] # 4
action_size = env.action_space.n # 2
agent = Q_Learning(
state_size=state_size,
action_size=action_size,
neurons=64,
device="cpu",
gamma=0.95,
)
# Vòng huấn luyện thủ công
epsilon = 1.0
for episode in range(200):
state, _ = env.reset()
done = False
while not done:
action = agent.act(state, epsilon)
next_state, reward, terminated, truncated, _ = env.step(action)
done = terminated or truncated
agent.remember(state, action, reward, next_state, done)
agent.train_from_memory(batch_size=32)
state = next_state
epsilon = max(0.01, epsilon * 0.995)
# Lưu / tải
agent.save_model("q_model.pth")
agent.load_model("q_model.pth")
8. Deep Q-Learning (DQN)
DQN với target network và replay buffer — phù hợp cho môi trường phức tạp hơn.
import gym
from aiNothard import deep_q_learning
env = gym.make("CartPole-v1")
agent = deep_q_learning(
state_size=env.observation_space.shape[0],
action_size=env.action_space.n,
neurons=128,
device="cpu",
gamma=0.99,
update_target_steps=10, # cập nhật target network mỗi 10 bước
)
# ── Cách 1: train_loop tự động ─────────────────────────────────
agent.train_loop(
env=env,
episodes=500,
max_steps=200,
batch_size=64,
epsilon_start=1.0,
epsilon_end=0.01,
epsilon_decay=0.995,
)
# ── Cách 2: kiểm soát thủ công ─────────────────────────────────
state, _ = env.reset()
action = agent.act(state, epsilon=0.1)
next_state, reward, term, trunc, _ = env.step(action)
agent.remember(state, action, reward, next_state, term or trunc)
loss = agent.train_from_memory(batch_size=64)
# Lưu / tải
agent.save_model("dqn.pth")
agent.load_model("dqn.pth")
9. RLHF (Reinforcement Learning from Human Feedback)
Pipeline RLHF đầy đủ 3 giai đoạn: SFT → Reward Model → PPO.
import torch
from aiNothard import RLHF, TransformerModel
# 1. Chuẩn bị policy model (Transformer đã build sẵn hoặc HuggingFace)
policy = TransformerModel(
vocab_size=10000, embed_size=256,
num_heads=4, hidden_dim=512,
num_layers=3, max_seq_length=128,
)
rlhf = RLHF(
policy_model=policy,
embed_size=256,
reward_hidden=128,
kl_coef=0.1,
lr_sft=5e-5,
lr_reward=1e-4,
lr_ppo=1e-5,
device="cpu",
)
# ── Giai đoạn 1: Supervised Fine-Tuning
# Mỗi mẫu: {"input": [token_ids], "target": [token_ids]}
sft_pairs = [
{"input": [1, 2, 3], "target": [4, 5, 6]},
{"input": [7, 8, 9], "target": [10, 11, 12]},
]
sft_history = rlhf.sft_train(sft_pairs, epochs=3, batch_size=8)
# Giai đoạn 2: Huấn luyện Reward Model
# Mỗi cặp: {"chosen": [token_ids], "rejected": [token_ids]}
preference_pairs = [
{"chosen": [1, 2, 4, 5], "rejected": [1, 2, 3, 9]},
{"chosen": [7, 8, 10, 11], "rejected": [7, 8, 3, 4]},
]
rm_history = rlhf.reward_train(preference_pairs, epochs=5, batch_size=16)
# Giai đoạn 3: PPO Fine-Tuning
prompt_ids = [torch.tensor([1, 2, 3]), torch.tensor([7, 8, 9])]
ppo_history = rlhf.ppo_train(
prompt_ids=prompt_ids,
epochs=3,
max_new_tokens=32,
temperature=0.9,
top_k=40,
)
# Chấm điểm một response
response = torch.tensor([[1, 2, 4, 5, 6]])
score = rlhf.score_response(response)
print(f"Reward score: {score:.4f}")
# Lưu / tải
rlhf.save("policy.pth", "reward.pth")
rlhf.load("policy.pth", "reward.pth")
10. MemoryChat — Chatbot nhớ ngữ cảnh
Chatbot với sliding window memory, tự động tóm tắt lịch sử dài.
from transformers import AutoTokenizer, AutoModelForCausalLM
from aiNothard import MemoryChat
# Tải model chat
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")
chat = MemoryChat(
model=model,
tokenizer=tokenizer,
max_tokens=512,
strategy="sliding", # sliding window
)
# Hội thoại
response = chat.chat("Xin chào! Bạn tên là gì?")
print(response)
response = chat.chat("Bạn có thể giúp tôi học Python không?")
print(response)
# Khi lịch sử quá dài, tóm tắt 10 tin nhắn cũ vào bộ nhớ dài hạn
chat.summarize_and_compress()
response = chat.chat("Nhắc lại, chúng ta đang nói về gì?")
print(response)
11. Learn by Video
Học biểu diễn video từ thư mục hoặc URL.
from aiNothard import learnbyvideo
trainer = learnbyvideo(device="cpu")
# Học từ thư mục chứa file .mp4, .avi, .mov
trainer.train_on_folder(
folder_path="./videos/",
epochs=10,
batch_size=4,
)
# Học từ URL video
trainer.train_on_url(
video_url="https://example.com/sample.mp4",
epochs=5,
)
# Dùng DataLoader thủ công
from aiNothard import videofolderdataset
from torch.utils.data import DataLoader
from torchvision import transforms
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
dataset = videofolderdataset(
folder_path="./videos/",
frames_per_video=16,
transform=transform,
)
loader = DataLoader(dataset, batch_size=2, shuffle=True)
# Lưu / tải model
import torch, torch.nn as nn
my_model = nn.Linear(10, 5) # model bất kỳ
trainer.save_model(my_model, "video_model.pth")
trainer.load_model(my_model, "video_model.pth")
12. Robot Deployer — Xuất model sang Arduino / ESP32
Chuyển đổi model PyTorch sang file C header nhúng vào vi điều khiển.
import torch
from aiNothard import deep_q_learning, RobotDeployer, CPlusPlusBridge
# 1. Huấn luyện một DQN agent
agent = deep_q_learning(state_size=4, action_size=2, neurons=32)
# ... (huấn luyện)
agent.save_model("robot_brain.pth")
# 2. Tải lại và export
deployer = RobotDeployer(agent)
deployer.from_pth("robot_brain.pth")
# Xuất sang Arduino (.h file)
deployer.export_for_arduino("RobotBrain.h", model_name="RobotBrain")
# Xuất sang ESP32 (C header)
deployer.export_for_esp32("RobotBrain_esp32.h", model_name="RobotBrain")
# 3. Sinh code C++ inference hoàn chỉnh
bridge = CPlusPlusBridge(agent)
cpp_code = bridge.generate_inference_code(model_name="RobotQ")
print(cpp_code)
# Lưu ra file .cpp
with open("robot_inference.cpp", "w") as f:
f.write(cpp_code)
13. DataScaler — Chuẩn hóa dữ liệu cảm biến
Chuẩn hóa dữ liệu từ cảm biến vật lý về khoảng [0, 1] trước khi đưa vào model.
from aiNothard import DataScaler
# Khai báo range (min, max) cho từng cảm biến
scaler = DataScaler(features_range=[
(0.0, 1023.0), # cảm biến ánh sáng (analog 10-bit)
(-180.0, 180.0), # góc servo (độ)
(0.0, 100.0), # nhiệt độ (°C)
(0.0, 5.0), # điện áp (V)
])
# Chuẩn hóa một mẫu đọc từ cảm biến
raw = [512.0, 45.0, 37.5, 3.3]
scaled = scaler.scale(raw)
print(scaled) # [[0.5, 0.625, 0.375, 0.66]]
# Sinh macro C++ để nhúng vào Arduino
cpp_macros = scaler.generate_cpp_macro()
print(cpp_macros)
# #define SENSOR_0_MIN 0.0
# #define SENSOR_0_MAX 1023.0
# ...
14. SelfEvolvingAgent — AI tự tiến hóa
Agent quan sát hiệu suất các hàm, lưu tri thức, và tự rewrite code khi hàm hoạt động kém.
import sys
import types
from aiNothard import SelfEvolvingAgent
# Chuẩn bị module target
def my_train_fn(epochs=5, lr=0.001):
"""Hàm training mà agent sẽ theo dõi."""
best_loss = 1.0
for _ in range(epochs):
best_loss *= 0.85
return best_loss
module = types.ModuleType("my_module")
module.my_train_fn = my_train_fn
# Tạo agent
agent = SelfEvolvingAgent(
target_module=module,
vault_path="knowledge.json", # lưu tri thức ra file
history_dir="./evolve_history/", # lịch sử rewrite
evolve_threshold=0.7, # điểm dưới ngưỡng → tiến hóa
auto_apply=False, # False = xác nhận thủ công
)
# Bảo vệ hàm không muốn rewrite
agent.protect("my_important_fn")
# Quan sát hiệu suất
scores = [0.90, 0.85, 0.60, 0.55, 0.48]
for i, score in enumerate(scores):
agent.observe(
func_name="my_train_fn",
score=score,
context={"run": i, "lr": 0.001}
)
import pprint
pprint.pprint(agent.status())
# {
# "performance": {...},
# "knowledge_summary": {...},
# "pending_rewrites": ["my_train_fn"],
# "threshold": 0.7,
# "auto_apply": False
# }
# Tiến hóa tất cả hàm yếu
results = agent.evolve()
# {"my_train_fn": "pending – gọi apply_pending('my_train_fn') để xác nhận"}
# Áp dụng sau khi xem xét
agent.apply_pending("my_train_fn")
# Rollback nếu kết quả tệ hơn
success = agent.rollback("my_train_fn")
# Xuất / nhập tri thức
agent.export_knowledge("knowledge_backup.json")
agent.import_knowledge("knowledge_backup.json")
Khi auto_apply=True, agent sẽ tự động áp dụng rewrite mà không cần xác nhận — chỉ dùng trong môi trường sandbox.
15. Safeinstall — Cài thư viện an toàn
Tự động cài thư viện nếu chưa có, không raise exception nếu cài thất bại.
from aiNothard import Safeinstall
# Cài theo tên pip (và tên import nếu khác)
Safeinstall.ensure("scikit-learn", import_name="sklearn")
Safeinstall.ensure("Pillow", import_name="PIL")
Safeinstall.ensure("opencv-python", import_name="cv2")
Safeinstall.ensure("ultralytics")
🖥️ Tiện ích dòng lệnh
Sau khi cài đặt, bạn có thể dùng các lệnh sau trong terminal:
# Khởi động YOLOv11 Web Trainer
nnafy-yolo
# Xem hướng dẫn
nnafy-help
# Tải mã nguồn gốc về máy
python aiNothard.py --source
# Xem link video tutorial
python aiNothard.py --tutorial
Xem mã nguồn và kênh hướng dẫn:
import aiNothard
aiNothard.get_source_code() # hỏi có muốn tải về không
print(aiNothard.tutorial()) # link YouTube
Cấu trúc thư viện
aiNothard/
├── aiNothard.py # Toàn bộ thư viện trong 1 file
├── setup.py # Cấu hình cài đặt PyPI
├── README.md # Tài liệu này
└── requirements.txt # Dependencies
requirements.txt:
flask>=3.0.0
Pillow>=10.0.0
pyyaml>=6.0
ultralytics>=8.2.0
torch>=2.2.0
torchvision>=0.17.0
opencv-python>=4.9.0
numpy>=1.26.0
pandas>=2.2.0
scikit-learn>=1.4.0
requests>=2.31.0
joblib>=1.3.0
matplotlib>=3.8.0
seaborn>=0.13.0
transformers>=4.40.0
peft>=0.10.0
evaluate>=0.4.0
Liên hệ & đóng góp
| Kênh | Địa chỉ |
|---|---|
| quocdat16610@gmail.com | |
| GitHub | github.com/billciper86/AInotHard |
| YouTube | @billciper86 |
Muốn đóng góp?
- Fork repo
- Tạo branch mới:
git checkout -b feature/ten-tinh-nang - Commit:
git commit -m "feat: mô tả thay đổi" - Push:
git push origin feature/ten-tinh-nang - Tạo Pull Request
Tìm thấy bug? Mở issue trên GitHub hoặc gửi email trực tiếp — mọi phản hồi đều được hoan nghênh!
Made with ❤️ by Nguyễn Quốc Đạt · MIT License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ainothard-1.3.0.tar.gz.
File metadata
- Download URL: ainothard-1.3.0.tar.gz
- Upload date:
- Size: 55.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77109e2549b32b6a6cb82b5fa4a0db1fa8f91bab89f2ac74292746cb254b2656
|
|
| MD5 |
c37e591e21aa4557152214fbc9abdd77
|
|
| BLAKE2b-256 |
6339f4802d0fd67b644999a63ffd19cb738c60e6eff2555c608fb58c56877bee
|
File details
Details for the file ainothard-1.3.0-py3-none-any.whl.
File metadata
- Download URL: ainothard-1.3.0-py3-none-any.whl
- Upload date:
- Size: 46.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1df2798648545ed3625a6993ed55990da0d5592a7d0f53dd0a0d34ee71dad91
|
|
| MD5 |
56c57ee067d2fdc024371e98571859a6
|
|
| BLAKE2b-256 |
9e9c7e6be740584b73abaecb585817b38a7f00aadff16c6676411aa9a222457b
|