AI 资讯
Mastering HRV: Building a Stress Predictor with Random Forest, LSTM, and Wearable Data
Are you pushing your body to the limit or just driving it into the ground? In the world of high-performance athletics and biohacking, Heart Rate Variability (HRV) has become the "North Star" for recovery. But raw numbers from your Garmin or Oura Ring only tell half the story. To truly understand the relationship between sleep quality , exercise load , and stress perception , we need more than a dashboard—we need a predictive pipeline. In this tutorial, we will build a multi-dimensional analysis system using Scikit-learn , LSTM (Keras) , and the Terra API to predict overtraining risks. By the end of this guide, you'll know how to turn messy wearable data into actionable health insights. The Architecture: From Bio-Signals to Insights To handle the complexity of time-series data (HRV) and categorical features (activity types), we use a hybrid approach. We use Random Forest to identify which lifestyle factors impact recovery the most and LSTM to predict future HRV trends based on historical sequences. graph TD A[Garmin / Oura Ring / Apple Watch] -->|Webhook| B(Terra API) B --> C{Data Preprocessing} C -->|Feature Engineering| D[Random Forest Classifier] C -->|Sequence Processing| E[LSTM Neural Network] D -->|Feature Importance| F[Stress Analysis Engine] E -->|Trend Prediction| F F --> G[FastAPI Endpoint] G --> H[End User Dashboard] Prerequisites To follow along, you'll need: Terra API Keys : For unified access to wearable data (Garmin, Oura, etc.). Tech Stack : Python 3.9+, Scikit-learn, Keras/TensorFlow, and FastAPI. The Mindset : A passion for Health Tech and Wearable Data Science . Step 1: Ingesting Data with Terra API Standardizing data across different wearables is a nightmare. The Terra API acts as an abstraction layer, giving us a unified JSON structure for heart rate, sleep, and activity. import requests def get_wearable_data ( user_id , start_date ): # Using Terra API to fetch aggregated daily health data url = f " https://api.tryterra.co/v2/daily?user_id= { use
AI 资讯
Vibe Coding Is Creating a Generation of Developers Who Can’t Debug Their Own Systems
The Shift from Syntax to “Vibe Coding” Writing code used to be the bottleneck. Now, code is free and that’s precisely the problem. If you had told me Five years ago that my terminal would routinely spin up background execution agents, draft full-stack features, and push PRs before I finished my morning coffee, I would have assumed you were selling a tech startup pipe dream. Back then, GitHub Copilot was a neat trick: an glorified tab-completion tool that occasionally saved you from typing out a boiler-plate fetch request or regex string. Fast forward to today, and we’ve entered the era of “Vibe Coding.” You state intent in natural language. You direct agents in your editor. You prompt terminal workflows. Code manifests at conversational speed. You aren’t typing out syntax line-by-line; you’re steering an autonomous orchestra. The developer experience feels almost magical, fluid, and dizzyingly fast. But as the velocity of code creation hits lightspeed, an uncomfortable truth is beginning to surface across engineering teams: the cognitive load of software engineering hasn’t disappeared — it has simply shifted. We traded the friction of writing syntax for the far more taxing chore of evaluating architectural integrity, managing context drift, and catching silent edge-case failures in code we didn’t actually write. Code is easier to generate than ever, but system comprehension is at an all-time low. And nowhere is this trade-off creating more friction than in the middle tier of the software engineering workforce. The “Middle-Tier” Squeeze Senior engineers act as directors; AI handles the grunt work. Where does that leave everyone in between? For decades, the career progression of a software engineer followed a reliable, well-trodden path. You entered the industry as a junior, grinding away on bug fixes, writing unit tests, and building basic CRUD endpoints. Slowly, through hundreds of hours of raw syntax exposure, you built up mental models. You learned how state manag
AI 资讯
Architecting Enterprise Angular with Signals: Zoneless Reactivity and 60fps Performance
Architecting Enterprise Angular with Signals: Zoneless Reactivity and 60fps Performance For nearly a decade, Angular relied on Zone.js to intercept asynchronous browser events and trigger top-down dirty checking across the entire component tree. In large enterprise dashboards displaying live telemetry, grid streams, and complex forms, this model leads directly to frame drops and memory leaks. With Angular 19+, fine-grained Signals provide a reactive paradigm where the framework tracks exact DOM dependencies at compile-time and updates only the precise DOM nodes that changed, unlocking 60fps zoneless execution . Architecture & Interview Cheat Sheet Feature Legacy RxJS / Zone.js Angular Signals (Modern) Change Detection Dirty-checks entire component tree Fine-grained single DOM node updates Memory Lifecycle Manual takeUntilDestroyed subscriptions Automatic graph cleanup without memory leaks Derivations Complex combineLatest / switchMap Lazy, memoized computed(() => ...) Zone.js Overhead Monkey-patches all browser async APIs 0 overhead ( provideExperimentalZonelessChangeDetection() ) 1: Clean Reactive State with Signals import { Component , computed , signal , effect , inject } from ' @angular/core ' ; export interface TelemetryPacket { id : string ; latencyMs : number ; status : ' healthy ' | ' degraded ' | ' critical ' ; } @ Component ({ selector : ' app-telemetry-monitor ' , standalone : true , template : ` <div class="card"> <h3>Live Ingestion Monitor</h3> <p>Total Packets: {{ packetCount() }}</p> <p>Average Latency: {{ averageLatency().toFixed(2) }}ms</p> <span [class.badge-warn]="isDegraded()"> {{ isDegraded() ? 'DEGRADED PERFORMANCE' : 'NOMINAL' }} </span> </div> ` }) export class TelemetryMonitorComponent { // Primary Writable Signal readonly packets = signal < TelemetryPacket [] > ([]); // Derived Computed Signals (Memoized, evaluated lazily on read) readonly packetCount = computed (() => this . packets (). length ); readonly averageLatency = computed (() => {
开发者
Override a Label in the Mapbox Standard Style
In the Mapbox Standard Style , the complexity of its layer styling is abstracted away — you can configure it with predefined variables, but you can't directly edit its layers. This is by design, and allows you to benefit from continuous improvements by our map designers. So what do you do when you need a label to say something different, appear at a different zoom level, or simply not appear at all? Here's a technique for surgically replacing a single label with your own, while keeping everything else in the Standard style untouched and precisely matching the label style. In the embedded example below, we've replaced the label for "New York" with "New Amsterdam". Why they changed it, I can't say. 😉 Using a classic style? If you're on a classic Mapbox style where you have direct access to edit symbol layers, there's a simpler approach: override the label text using an expression directly on the layer. See Customize label text in the Mapbox docs. This post is specifically about the Standard style, where internal layers are not editable — which requires a different technique. Step 1: Get the exact coordinates and properties of the label feature Most map labels come from the place_label source layer in the Mapbox Streets tileset . Here's a simple map that shows only the place_label source layer's points (and water features for reference). Click a label and you will see its full data, including the coordinates and properties: Copy the full GeoJSON Feature. Fields like symbolrank , filterrank , class , worldview , text_anchor , and capital all control how the label is styled and at which zoom levels it appears. You'll need to match these when building your replacement feature. Step 2: Build a custom style that imports Standard Instead of loading the Standard style directly, create a top-level style JSON that imports Standard and adds your own source alongside it: const map = new mapboxgl . Map ({ style : { version : 8 , sprite : ' mapbox://sprites/mapbox/standard/... ' ,
AI 资讯
How AI changed the way I build software, and why I ended up building an open source shell for Angular
Up front: this is my own project, so I'm not exactly neutral here ;-) Where I'm coming from I work completely differently than I did two or three years ago. For most of my career I wanted to write pretty much every line myself, and I was a bit proud of that. That has changed a lot. Instead of programming I now mostly write specifications and review what the AI generates. On the one hand that's great, I can turn new ideas into working software much faster than before. On the other hand there's the risk of stepping into the same traps with AI-generated code again and again. And that's where I noticed something. Every time I started a new project, I found myself explaining the same things to the AI. This goes into a plugin. That stays out of the core. No domain logic in the shell. Please don't invent a third way of doing tabs. The AI would nod, generate something that looked right, and two days later I'd find a slightly different version of the same sidebar with a slightly different bug. There are things I really don't want to explain over and over. A good, preferably deterministic base is getting more important, not less. I don't want to explain proven architectures from scratch every time. I'd rather build on established solutions where I can, ones the AI understands and can just use. So for my new projects I built exactly that, and put it on GitHub as open source. Why Angular? Well, simply because I think it's a great framework and I've had a lot of good experiences with it over the last 10 years. What it is, and what it isn't LoomWeaver is a workbench shell for Angular. Not a component library. Think of the frame VS Code gives you: a rail on the left, sidebars, a top bar, a status bar, and in the middle tabs and panes you can split and drag around. That frame is what most workbench-style products build themselves, every time, slightly differently. LoomWeaver gives you that frame, and your own domain moves in as plugins. The core contains zero domain logic. Even my
AI 资讯
The CORS Header Was Right There and the Browser Blocked It Anyway
The browser console showed exactly what CORS errors always show — a request blocked for violating the same-origin policy — except the response headers, visible in the network tab, clearly included Access-Control-Allow-Origin: * . The header the browser wanted was right there. The browser rejected the request anyway. The detail that's easy to miss in the network tab Chrome's network inspector, by default, coalesces duplicate header names into a single display line — so Access-Control-Allow-Origin: * shown once in the UI can actually mean the header was sent twice by the server, and the browser is showing you a merged, deduplicated view rather than the literal wire response. curl -s -D - https://api.example.com/data -o /dev/null | grep -i access-control Access-Control-Allow-Origin: * Access-Control-Allow-Origin: https://app.example.com Two separate headers, both valid individually, sent by two different layers that each thought they were the one responsible for CORS: our nginx reverse proxy had a blanket add_header Access-Control-Allow-Origin *; for general API access, and the application server behind it independently set a specific origin for authenticated routes. Neither config was wrong on its own. Together, they produced a response with the header appearing twice — and per the Fetch spec, a response with multiple Access-Control-Allow-Origin values is treated as invalid, so the browser blocks the request rather than guessing which one you meant. Why this is worse than a missing header A missing CORS header fails immediately, obviously, the same way every time. A duplicate header fails in a way that looks, from the response body alone, like the header is present and correct — because it is present, twice, which is precisely the state that trips the spec's validation. Every piece of evidence you'd normally check says "this should work," and it still doesn't. The fix Removed the blanket nginx header and let the application server be the single source of truth for COR
AI 资讯
Airbnb Cuts Authentication Code by 60% with Server Driven Architecture
Airbnb redesigned its authentication architecture around server driven flows and policy based challenge selection. The new Flexible Authentication system reduced authentication related code by 60%, cut the web client bundle by 100 KB, improved successful authentication by 2.6%, reduced duplicate account creation by 27%, and lowered OTP costs by 11%. By Leela Kumili
AI 资讯
We only alert on a 10-spot rank drop. Here's why 1 spot would be worse.
Rank tracking tools love to notify you the instant a number changes. We deliberately don't — our drop alert only fires once an app falls 10 spots or more between two measurements. The tempting, wrong version A 1-spot threshold sounds like the more attentive product. In practice it turns every notification channel into noise: App Store search rank has real day-to-day jitter that has nothing to do with anything you did — a competitor's own rank shifting, a re-index, sampling timing. Alert on every 1-spot move and within a week the alert is something people mute, which defeats the entire point of having one. Why 10, specifically 10 spots is large enough to almost never be pure noise and small enough to still catch a real problem while it's still cheap to fix — a keyword field edit, a screenshot swap, a review-response push. Wait for a 30-spot collapse before alerting and you've waited past the point where the fix is simple. The threshold is symmetric: the same 10-spot rule fires on a jump upward, so a keyword field change you made on purpose gets confirmed by the same mechanism that would have warned you if it went the other way. The trade-off we're making explicit This means small real movements — 3 spots, 5 spots — genuinely don't page anyone. That's intentional, not a limitation we're hiding: an alert system tuned to catch everything catches nothing anyone still trusts by week three. A threshold set high enough that every alert is worth opening is worth more than a lower one that trains you to ignore your own notifications. If you're building anything similar — uptime, price, rank, any noisy time series — the question worth asking isn't "how sensitive can I make this," it's "what's the smallest move that's still cheaper to catch early than to catch late." That number is rarely 1. We build Storelift , where this threshold governs both the in-app alert and the rank-drop email.
AI 资讯
The Data Boundary Problem: Using a Free Server Without Leaking Your Prompts
A free server is a data boundary decision, not a cost decision. Every prompt you send to a managed endpoint leaves your network. For a coding agent, that means source code, environment variables, and internal architecture notes travel to someone else's infrastructure. The question is not whether the endpoint is trustworthy; the question is whether you can make the boundary explicit. MonkeyCode's free server option is generous in tokens and removes the ops burden of self-hosting. Disclosure: This article was prepared as part of MonkeyCode's product outreach. But generosity does not change the physics of data flow. The moment your agent calls a remote endpoint, the prompt is out of your control. What you can control is what goes into the prompt. This article is a practical guide to building a privacy gate between your agent and a free server. The gate is a local proxy that sanitizes prompts, redacts secrets, and logs every request. It does not make the server trustworthy; it makes your exposure measurable. The threat model Before writing code, define what you are protecting. For most teams, the sensitive material in prompts falls into three categories: hardcoded credentials, proprietary code snippets, and internal names or URLs. Each category has a different risk profile. Credentials are the worst. A leaked API key in a prompt is a direct compromise. Proprietary code is a legal and competitive risk. Internal names are subtler: they reveal architecture and naming conventions that an attacker can use for phishing or targeted attacks. A free server does not automatically read or store your prompts, but you cannot verify that. The boundary you build must assume the server is an untrusted observer. That assumption drives the design. The privacy gate The gate is a small FastAPI service that sits between your agent and the free server. It accepts OpenAI-compatible requests, rewrites them, forwards them, and returns the response. The rewriting step is where the boundary is en
AI 资讯
Paddle's approved-domain check only applies in the browser
I ship a lot of small products. Browser extensions, little SaaS tools, one game. Most of them live on their own subdomain and do exactly one job. For a long time the worst part of starting a new one wasn't the product. It was billing. Bank verification, ID verification, waiting for approval, recreating the same plans, wiring the same webhooks, testing the same four subscription states. Every single time. I got good at it the way you get good at anything you resent. So I stopped doing it per product and did it once for all of them. Here's the shape that fell out, including the part I had wrong for months. The thing I had wrong Paddle has a list of approved domains. My assumption was that every site taking money had to be on that list, which meant a review round per subdomain, forever. That's not what the list gates. Approved domains gate the Paddle.js checkout overlay running in a browser . That's it. The server side doesn't care: webhook signature verification: not domain gated creating a customer portal session with the API key: not domain gated your own internal endpoints receiving forwarded events: obviously not domain gated Exactly one thing in the whole flow has to happen on an approved domain, and it's the moment the overlay opens. Everything else can live wherever you want. Once I saw that, the design was basically forced. The shape One payment account. One approved domain, the apex. One webhook endpoint, on that apex, for the entire family: Paddle ──webhook──> apex.example.com/api/webhook/paddle │ ├─ verify signature ├─ read custom_data.site └─ route: own event → handle locally other site → forward raw event to that site unknown → 200 and drop it Two rules make this hold up, and both are about what the shared piece refuses to know. The dispatcher does not know a single price ID. It verifies the signature, reads one field, and forwards the raw snake_case event onward. Mapping a price to a plan, granting credits, writing to a subscription table: all of that li
产品设计
Sprinkle: Finding a Better Home for the Things We Donate
This is a submission for Weekend Challenge: Generosity Edition. What I Built When I was...
AI 资讯
I Built a Binaural Beat Generator — Then Proved It With a Live FFT Spectrum Analyzer
The "frequency healing" corner of the internet runs on faith. Apps ship MP3s labeled "40Hz gamma" and ask you to believe it. I'm a life scientist who builds web tools, and I couldn't ship that. So I built SereneSynth, a browser-based binaural beat and noise generator — and then I built a live spectrum analyzer into the page so anyone can audit the output in their own browser. This is the engineering write-up: the Web Audio graph, the FFT gotcha that almost made me publish wrong numbers, and how I cross-verified everything in Audacity. The honesty constraint first A binaural beat is not a tone in the air. Play 200 Hz into the left ear and 240 Hz into the right, and the listener's superior olivary complex computes the 40 Hz difference. A microphone — or a mono spectrum analyzer — will never show a 40 Hz peak. So the only honest thing a generator can prove is its carriers and its spectral slope. That is exactly what we measure. The synthesis graph Two sine oscillators, hard-panned with StereoPannerNode, summed into a master GainNode, tapped by an AnalyserNode before the destination — the analyzer observes exactly what the headphones receive. Settings that matter: fftSize 16384, smoothingTimeConstant 0.8. The FFT gotcha that almost made me ship garbage My first version used fftSize 1024: one fat bump near 220 Hz instead of two peaks. Bin width = 44100 / 1024 ≈ 43 Hz, and my carriers are 40 Hz apart — same bin, merged. At fftSize 16384 the bin width drops to ≈ 2.7 Hz and the carriers resolve as razor-sharp spikes at 200.0 and 240.0 Hz. Lesson: FFT size is the magnifying glass. If a "frequency proof" doesn't state its FFT size, ask. The widget renders a log axis (20–1000 Hz) because a linear axis wastes 90% of the canvas, and peak detection labels the top bins in the 100–500 Hz range live. Bit-exact, downloadable verification The page also renders 10-second stereo WAVs via OfflineAudioContext (16-bit PCM, 44.1 kHz): same graph, offline render, RIFF encode. No lossy compre
AI 资讯
# How enabling cross-origin isolation silently broke our multi-threaded WASM image compressor
A production postmortem. We shipped browser-side image compression (Rust → WASM + WebGPU), turned on cross-origin isolation for speed, and watched every format crash with compression worker crashed . Here's the root cause and the fix. The setup We built an image compressor that runs 100% in the browser — Rust compiled to WASM for the codec work, WebGPU for the heavy ML passes (background removal, denoise, watermark). No upload, so users' pixels never leave the device. Privacy is the whole selling point. For the multi-threaded code paths we rely on shared memory + atomics , which in the browser requires crossOriginIsolated . So we served the document with: Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin That gives us crossOriginIsolated === true , unlocks SharedArrayBuffer , and lets the *‑threaded WASM builds actually spawn workers. The build uses a nightly toolchain ( nightly-2025-06-01 + -Z build-std ) with: RUSTFLAGS = "--cfg=... +atomics,+bulk-memory --shared-memory --import-memory" and a custom rayon handle pool ( with_turbo_pool ) instead of build_global , so we control worker lifecycle and can abort/self-heal. The incident After flipping COEP to require-corp in production, every format started crashing with the same message: compression worker crashed Not one codec — JPG, PNG, WebP, AVIF, all of them. It was a P0: the core feature was dead for every user. What made it nasty: it only reproduced under real cross-origin isolation . Local dev without COEP was fine. Staging without the header was fine. So the bug hid until it hit production traffic. Root cause The *‑threaded WASM packages spin up nested rayon workers to parallelize the codec. Under COI + COEP require-corp , those nested workers get blocked by Cross-Origin-Resource-Policy / COEP — the spawned worker script is treated as a cross-origin response without the right CORP header, so the browser refuses it. No worker → the rayon pool never initializes → the compression c
AI 资讯
Re-Organized configuration in Rails
A while back I wrote about organizing configuration in Rails . The idea was simple: drop YAML files into config/configurations/ and get namespaced constants like Config::Bot.api_key instead of the clunky Rails.application.config.bot.api_key . It worked well. But every YAML file needed manual wiring: <%= ENV.fetch("BOT_API_KEY", Rails.application.credentials.dig(:bot, :api_key)) %> . For every key. Across every file. Ugh! So I rebuilt it. Same clean Config::Namespace.key API, but now it chains through all three sources automatically. Before (old module’s YAML): # config/bot.yml shared : api_key : <%= ENV.fetch("BOT_API_KEY", Rails.application.credentials.dig(:bot, :api_key)) %> user_agent : " MyAwesomeBot/1.0" timeout : 10 After (new module’s YAML): # config/bot.yml shared : # Config::Bot.api_key is still available and will check environment variables and then check credentials user_agent : " MyAwesomeBot/1.0" timeout : 10 One API. Three sources. No more guessing where a value lives. You can find the full code on GitHub . What follows are the parts I find most interesting. Lazy namespaces with const_missing The old version scanned a directory at boot and called const_set for every YAML file. That works, but it means every namespace is loaded whether you use it or not. This version uses const_missing instead. Reference Config::Bot for the first time and a Namespace object is created lazily: def self . const_missing ( name ) MUTEX . synchronize do @namespaces ||= {} @namespaces [ name ] ||= Namespace . new ( name ) end end The Mutex isn’t there by accident. In threaded environments (Puma, Solid Queue), two threads could hit const_missing simultaneously. Mutex makes sure only one namespace object gets created. The three source chain Each Namespace uses method_missing to resolve a key: def method_missing ( method , ... ) key = method . to_s . delete_suffix ( "!" ) bang = method . to_s . end_with? ( "!" ) environment_key = " #{ @prefix } _ #{ key . upcase } " return @envi
AI 资讯
Does That "Free Online PDF" Tool Upload Your File? How to Tell.
Most free online PDF tools work by uploading your document to a server, processing it there, and sending it back. For a lot of files that's fine. For a signed contract, a payslip, a medical form, or a scanned ID, it's the entire privacy problem: your document now lives on someone else's machine, subject to their logging, retention, and breach exposure. It doesn't have to work that way. A modern browser can split, merge, compress, sign, and even OCR a PDF without the file ever leaving your device — using libraries like pdf-lib , pdf.js , jsPDF and SheetJS that run entirely in JavaScript. How to tell an uploader from a client-side tool You don't have to trust a marketing claim. Two checks settle it: Watch the network. Open your browser's DevTools → Network tab, then run the tool on a file. If you see your file leave in a POST/PUT request, it uploaded. A client-side tool shows no upload of the document itself. Pull the plug. Load the page, then turn off Wi-Fi and try the tool again. A client-side tool keeps working offline. An uploader breaks the moment the network is gone. The honest tools pass both tests. If a site can't work offline, your file is going somewhere. The trade-offs, stated honestly Client-side processing isn't a free lunch, and any tool that pretends it is should make you suspicious: Memory. Very large PDFs are held in browser memory, so there's a ceiling a server wouldn't have. Speed. OCR in WebAssembly is slower than a server GPU. It's private, not fast. Fidelity. Converting PDF → Word transfers the text , not the layout — the same is true of every converter, but a client-side one can't hide it behind a server. Compression limits. A PDF shrinks by downsampling embedded images or rasterizing pages; a small or text-only PDF may not shrink at all, and rasterizing removes selectable text. We built 24 client-side PDF tools on exactly this principle and wrote down where each limit is, rather than papering over them. If you're evaluating any online PDF tool
AI 资讯
What I Learned Building a Diabetes Management Website
A few months ago I started building [reversemydiabetes.co]a small health platform focused on helping people manage type 2 diabetes through diet and lifestyle changes. I'm not a doctor — I'm a builder — but the project turned into a genuinely interesting technical challenge, and I wanted to share some of what I learned along the way. Why I started this Type 2 diabetes affects a huge number of people, and a lot of the advice online is either paywalled, badly organized, or written in a way that's hard to act on. I wanted to build something simple: a site that gives people practical, easy-to-follow guidance on blood sugar management, diet planning, and day-to-day habits — without needing a login, a subscription, or a medical degree to understand it. The technical side A few decisions shaped how the site turned out: Content structure over cleverness. Early on I over-engineered the information architecture — trying to build dynamic filtering for every possible diet preference. I scrapped most of it. What actually mattered was clear, well-organized static content: a diabetes diet plan page, a blood sugar basics guide, and a meal-planning section. Simple beats clever when the audience isn't tech-savvy. SEO became a first-class concern, not an afterthought. Health content lives or dies on whether people can actually find it. I spent real time on keyword research — things like "diabetes diet plan," "blood sugar levels," and "type 2 diabetes management" — and restructured pages around what people were actually searching for, rather than what sounded good internally. Performance mattered more than I expected. A lot of the target audience is older, on slower connections, or on older devices. I ended up stripping out a bunch of client-side JavaScript I didn't need and leaned on plain HTML/CSS wherever possible. Lighthouse scores went from "fine" to "actually fast," and bounce rate dropped noticeably. Trust signals are a real UX problem for health content. Unlike a SaaS landing pa
AI 资讯
Three ways your dashboard can be correct and still lie
Our dataset said the average loan was 2.3 million kroner. The number that actually mattered was 255,000. Both were correct. Only one of them was true. This is a writeup of three ways a dashboard can be arithmetically perfect and still lie, using real figures from an analysis of 1,000 Norwegian debt consolidation applications. If you build reporting for anyone, you have probably shipped at least one of these. 1. Summing a field that contains two different things A debt consolidation loan pays off your expensive credit card debt. It also, if you own property, rolls your existing mortgage into the same new loan. Same column in the database. Same loan_amount . Utterly different meaning. SELECT AVG ( loan_amount ) FROM applications ; -- 2,300,000 That query is right and the answer is useless. Of that 2.3 million, roughly 1.9 million is an existing mortgage being moved from one lender to another. The expensive debt, the part the customer actually has a problem with, averages 255,000 . So the headline figure overstates the thing you care about by a factor of nine. Nothing in the schema warns you. loan_amount is a number, AVG is a function, the result renders fine. The bug is that one column is holding two concepts and only a human who understands the domain will notice. -- what you actually wanted SELECT AVG ( unsecured_debt ) FROM applications ; -- 255,000 If a column can mean two things depending on another column, split it. Every time. 2. Reporting the mean when the distribution has a tail Income in this dataset runs from ordinary salaries up to about five million kroner. A handful of very high earners drag the mean upward: Mean income: ~635,000 Median income: 647,000 for homeowners, 550,000 for renters Look at what happens there. The mean sits between the two medians and describes neither group. Someone reading only the mean concludes the typical applicant earns 635,000. Nobody earns 635,000. It is an artefact. df . groupby ( ' housing ' )[ ' income ' ]. agg ([ ' mean
开发者
How to Find What Is Filling Up Disk Space on a Linux Server
Disk full alerts at 2am? Learn the exact commands to find what's eating your Linux server's disk space and fix it fast. You get the alert: disk usage at 94%. Your app starts throwing errors, logs stop writing, and databases refuse to accept new rows. Finding the culprit fast matters — but on a server with millions of files, knowing where to look is half the battle. Here's a systematic approach to track down disk hogs in minutes, not hours. Start With the Big Picture: df Before you dig into directories, confirm which filesystem is actually full. Run: df -h — shows all mounted filesystems with human-readable sizes df -h / — focus on the root filesystem df -i — check inode usage (a filesystem can be 'full' even with free space if inodes are exhausted) Pay attention to the 'Use%' column. If you see 100% on /var or /home but not /, that tells you exactly which mount point to investigate. Inode exhaustion — df -i showing 100% — is easy to miss and causes the same symptoms as a full disk, so always check both. Drill Down With du Once you know which mount point is full, use du to find the largest directories. Start from the top of that mount point and work down: du -sh /* 2>/dev/null — sizes of every top-level directory, errors suppressed du -sh /var/* 2>/dev/null — drill into /var if that's the culprit du -ah /var | sort -rh | head -20 — list the 20 largest files and folders inside /var The pattern is always the same: run du -sh on the suspicious directory, find the largest subdirectory, repeat one level deeper. You'll usually hit the real culprit within three or four iterations. Common offenders are /var/log (runaway logs), /var/lib/docker (unused images and volumes), and /tmp (applications that don't clean up after themselves). Find Large Files Directly With find Sometimes a single enormous file is the problem — a core dump, a forgotten database export, or a log that rotated incorrectly. Use find to surface files above a size threshold: find / -xdev -size +500M -ls 2>/de
AI 资讯
uilding a Preview-First Background Noise Remover for Audio and Video
A background noise removal workflow is easy to describe and much harder to make trustworthy. The superficial version is: upload a file, run processing, download the result. The harder version is product design: what does a person need to know before committing to a result, paying for an export, or spending a limited processing allowance? A preview-first workflow answers that question by making uncertainty a first-class part of the system. Instead of asking people to trust a long-running operation, it gives them a bounded way to hear a representative outcome before they choose what happens next. This article lays out the design principles behind that approach for stored audio or video uploads. It is not a call-time or capture-time filter. The central workflow is: upload → compatibility check → preview → same segment before/after → export choice That sequence looks simple, but each boundary carries product and engineering consequences. Start with a decision, not a processing feature A preview should help a user make one specific decision: “Is this result useful enough for me to continue?” That framing prevents a common mistake: treating a preview as a small free version of the full product. A useful preview is not merely a shorter job. It needs to be comparable, understandable, and tied to the next action. For background noise removal, the most defensible comparison is a matched segment: The source and processed audio use the same time range. Playback controls make the comparison obvious. The user can choose whether to continue only after hearing that bounded example. If the before and after samples use different moments, the product is asking the user to infer too much. A quieter section in one clip can appear better even when the processing change was minor. Matching the segment removes that ambiguity and keeps the decision grounded in what the user actually heard. Put compatibility before expectation Compatibility belongs near the beginning of the workflow, before
AI 资讯
Twenty Years of jQuery: How a Little Library Rewired Web Development
jQuery, created by John Resig and released in 2006, is a JavaScript library that simplifies HTML manipulation, event handling, animation, and Ajax. It enabled easier web development by providing an accessible API across browsers. While its use has declined with the rise of modern frameworks, jQuery remains prevalent on a significant portion of websites today. By Daniel Curtis