Uso de IA no trabalho

Verifique código gerado por IA com dados pequenos

Verifique uma função de agregação com quatro linhas que você pode calcular manualmente e 12 unit tests. Verifique não apenas valores normais, mas também entrada vazia, zero, decimais e entrada inválida.

Ver o sumário

A tradução foi feita com IA. Confira o código, as unidades e os valores junto com o original. A revisão por falantes nativos de cada idioma ainda não foi concluída. English

Para quem éIniciantes que hesitam em usar código Python gerado por IA no trabalho apenas porque ele executa

Preparação
  • Instale Python 3.12 ou posterior e verifique a versão em um terminal com python --version.
  • Extraia o ZIP de exemplo em uma nova pasta. Não execute o exemplo de dentro do arquivo ZIP.
  • Abra um terminal na pasta que contém example.py. Se o comando python não estiver disponível no Windows, use py. No macOS ou Linux, use python3 se seu ambiente exigir.
  • Nenhum pacote externo ou conta é necessário. Os arquivos incluídos são dados sintéticos criados para este tutorial.

01Decida a resposta antes de executar

O código de uma IA terminar sem erros não significa que o cálculo esteja correto. Este artigo não se conecta a um serviço real de IA; ele pratica as etapas de verificação com uma função de agregação escrita de forma independente e pequenos dados sintéticos. Você pode aplicar o mesmo método a uma função que precise revisar. Nenhuma API key ou pacote externo é necessário.

  1. Leia as quatro linhas de input.csv e calcule quantity × unit price por conta própria.
  2. Abra expected.json e verifique se ele lista 4 rows, quantity 6 e amount 11101.50.
  3. Execute o comando abaixo. Os 12 unit tests são executados primeiro, seguidos pela CSV aggregation e comparação com os expected values.
  4. Verifique outputs/summary.json e verification.txt, que são criados somente quando todas as comparações passam.
bash
python example.py

02Compare o cálculo de quatro linhas em uma tabela

itemquantityunit_priceValor por linha
노트22500.005000.00
31200.503601.50
노트12500.002500.00
Sample0999.990.00

Há 4 rows, mas a total quantity é 2 + 3 + 1 + 0 = 6. O total amount é 5000.00 + 3601.50 + 2500.00 = 11101.50. A última linha, com quantity 0, ainda é contada no número de input rows. Por item, 노트 (notebook) tem quantity 3 e amount 7500.00, 펜 (pen) tem quantity 3 e amount 3601.50, e 샘플 (sample) tem quantity 0 e amount 0.00.

Portanto, não compare apenas o total; observe juntos row count, total quantity e per-item values. Inserir o mesmo item em duas linhas, como notebook, também permite verificar grouping e summing. A ordem dos per-item results é classificada por name e não significa sales rank nem input order.

03Escreva as regras de entrada aceitas pela função

ItemRegra permitidaExemplo rejeitado
ColumnTrês: item, quantity, unit_priceColumns ausentes ou extras
itemString não vazia após remover leading e trailing spacesString vazia ou apenas whitespace
quantityInteger string de 0 a 1,000,000-1, 1.5, 1e2
unit_price0 a 1,000,000,000, até duas casas decimaisNaN, Infinity, 0.001, 1,000

Assume-se que os amounts estão na mesma moeda fictícia. Negative quantities e unit prices não são permitidos, portanto não existe uma regra para representar returns. Definir primeiro as input rules permite saber se o código altera silenciosamente valores para 0 ou ignora algumas rows. Esta função para com ValueError quando encontra uma invalid row.

04Código completo com a agregação e os testes

aggregate_sales retorna apenas o result sem alterar as input rows. A leitura de arquivos e a gravação de resultados são separadas em main. Dessa forma, os tests podem passar small dictionaries diretamente e verificar apenas o cálculo. Cada expected value é comparado com assertEqual, e os values que devem ser rejeitados são verificados com assertRaises.

example.py
"""집계 함수를 손계산 기대값과 unittest로 검증합니다. 외부 AI 호출은 없습니다."""

import argparse
import csv
import json
import re
import sys
import unittest
from decimal import Decimal
from pathlib import Path

BASE = Path(__file__).resolve().parent
OUTPUT = BASE / "outputs"
FIELDS = {"item", "quantity", "unit_price"}


def money(cents):
    return f"{cents // 100}.{cents % 100:02d}"


def aggregate_sales(rows):
    """문자열 딕셔너리 행을 검증하고 집계합니다. rows와 원본 파일을 변경하지 않습니다."""
    totals = {}
    row_count = total_quantity = total_cents = 0
    for number, row in enumerate(rows, start=1):
        if not isinstance(row, dict) or set(row) != FIELDS:
            raise ValueError(f"{number}행: item,quantity,unit_price 세 열이 필요합니다.")
        if any(not isinstance(value, str) for value in row.values()):
            raise ValueError(f"{number}행: 모든 값은 문자열이어야 합니다.")
        item, quantity_text, price_text = (row[key].strip() for key in ("item", "quantity", "unit_price"))
        if not item:
            raise ValueError(f"{number}행: 품목이 비어 있습니다.")
        if not re.fullmatch(r"[0-9]{1,7}", quantity_text):
            raise ValueError(f"{number}행: 수량은 0 이상의 정수여야 합니다.")
        quantity = int(quantity_text)
        if quantity > 1_000_000:
            raise ValueError(f"{number}행: 수량은 1,000,000 이하여야 합니다.")
        if not re.fullmatch(r"[0-9]{1,10}(?:\.[0-9]{1,2})?", price_text):
            raise ValueError(f"{number}행: 단가는 0 이상, 소수점 둘째 자리까지 입력하세요.")
        price = Decimal(price_text)  # 문자열에서 직접 생성해 float 오차를 피합니다.
        if price > Decimal("1000000000"):
            raise ValueError(f"{number}행: 단가는 1,000,000,000 이하여야 합니다.")
        cents = int(price * 100) * quantity
        bucket = totals.setdefault(item, {"quantity": 0, "cents": 0})
        bucket["quantity"] += quantity
        bucket["cents"] += cents
        total_quantity += quantity
        total_cents += cents
        row_count += 1
    return {
        "row_count": row_count,
        "quantity": total_quantity,
        "amount": money(total_cents),
        "by_item": [
            {"item": item, "quantity": totals[item]["quantity"], "amount": money(totals[item]["cents"])}
            for item in sorted(totals)
        ],
    }


def sale(item="펜", quantity="1", unit_price="1200.50"):
    return {"item": item, "quantity": quantity, "unit_price": unit_price}


class TestAggregate(unittest.TestCase):
    # 기대값은 검증 대상 함수로 만들지 않고 손계산한 상수로 적습니다.
    def test_empty_input(self):
        self.assertEqual(aggregate_sales([]), {"row_count": 0, "quantity": 0, "amount": "0.00", "by_item": []})

    def test_single_row(self):
        self.assertEqual(aggregate_sales([sale(quantity="3")])["amount"], "3601.50")

    def test_zero_quantity(self):
        result = aggregate_sales([sale(quantity="0")])
        self.assertEqual((result["row_count"], result["quantity"], result["amount"]), (1, 0, "0.00"))

    def test_repeated_item(self):
        result = aggregate_sales([sale(quantity="2"), sale(quantity="1")])
        self.assertEqual(result["by_item"], [{"item": "펜", "quantity": 3, "amount": "3601.50"}])

    def test_decimal_addition(self):
        result = aggregate_sales([sale(unit_price="0.10"), sale(unit_price="0.20")])
        self.assertEqual(result["amount"], "0.30")

    def test_whitespace(self):
        result = aggregate_sales([sale(item=" 펜 ", quantity=" 1 ", unit_price=" 2.00 ")])
        self.assertEqual(result["by_item"], [{"item": "펜", "quantity": 1, "amount": "2.00"}])

    def test_bad_quantity(self):
        for value in ("-1", "1.5", "", "1000001", "1e2", "1"):
            with self.subTest(value=value), self.assertRaises(ValueError):
                aggregate_sales([sale(quantity=value)])

    def test_bad_price(self):
        for value in ("-1", "0.001", "NaN", "Infinity", "", "1,000", "1000000001"):
            with self.subTest(value=value), self.assertRaises(ValueError):
                aggregate_sales([sale(unit_price=value)])

    def test_blank_item(self):
        with self.assertRaises(ValueError):
            aggregate_sales([sale(item=" ")])

    def test_wrong_columns(self):
        for row in ({"item": "펜"}, {**sale(), "extra": "x"}):
            with self.subTest(row=row), self.assertRaises(ValueError):
                aggregate_sales([row])

    def test_non_string(self):
        with self.assertRaises(ValueError):
            aggregate_sales([sale(quantity=True)])

    def test_upper_boundary(self):
        self.assertEqual(
            aggregate_sales([sale(quantity="1000000", unit_price="1000000000")])["amount"],
            "1000000000000000.00",
        )


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--test", action="store_true", help="단위 테스트만 실행합니다.")
    args = parser.parse_args()
    # unittest의 명시적 비교는 python -O에서도 생략되지 않습니다.
    result = unittest.TextTestRunner(verbosity=2, stream=sys.stdout).run(
        unittest.defaultTestLoader.loadTestsFromTestCase(TestAggregate)
    )
    if not result.wasSuccessful():
        return 1
    if args.test:
        return 0
    if OUTPUT.exists() or OUTPUT.is_symlink():
        raise FileExistsError("outputs가 이미 있습니다. 기존 결과를 옮긴 뒤 실행하세요.")
    with (BASE / "input.csv").open("r", encoding="utf-8-sig", newline="") as stream:
        reader = csv.DictReader(stream, strict=True)
        if reader.fieldnames != ["item", "quantity", "unit_price"]:
            raise ValueError("input.csv의 열은 item,quantity,unit_price 순서여야 합니다.")
        actual = aggregate_sales(reader)
    expected = json.loads((BASE / "expected.json").read_text(encoding="utf-8"))
    if actual != expected:
        raise ValueError("예제 집계가 expected.json의 손계산 기대값과 다릅니다.")
    OUTPUT.mkdir()
    with (OUTPUT / "summary.json").open("x", encoding="utf-8") as stream:
        json.dump(actual, stream, ensure_ascii=False, indent=2)
        stream.write("\n")
    with (OUTPUT / "verification.txt").open("x", encoding="utf-8") as stream:
        stream.write(f"unittest: {result.testsRun}개 통과\n예제 기대값: 일치\n외부 AI API 호출: 없음\n")
    print(f"완료: {actual['row_count']}행, 수량 {actual['quantity']}, 금액 {actual['amount']}")
    print(OUTPUT)
    return 0


if __name__ == "__main__":
    try:
        raise SystemExit(main())
    except (OSError, ValueError, csv.Error) as error:
        print(f"중지: {error}", file=sys.stderr)
        raise SystemExit(2)

O unit price é convertido em Decimal a partir da string, multiplicado por 100 para convertê-lo em integer units e depois somado. O amount resultante também é retornado como string com duas casas decimais. Essa é uma escolha adequada à two-decimal unit price rule do exemplo, não uma regra universal para todo cálculo numérico.

05Casos normais, de limite e de erro verificados pelos testes

CategoriaTests integradosO que verifica
NormalOne row, repeated item, leading and trailing spacesCálculo básico e grouping
BoundaryEmpty input, quantity 0, upper limitDefinições em valores pequenos e grandes
Decimals0.10 + 0.20 = 0.30Representação e soma de amount
ErrorInvalid quantity, unit price, blank item, columns, typesInvalid values não são aceitos silenciosamente

Verifique ok ao lado de cada test name e, no final, ‘Ran 12 tests’ e ‘OK’. A comparação com os CSV expected values passou somente quando você também vê ‘완료: 4행, 수량 6, 금액 11101.50’ (Done: 4 rows, quantity 6, amount 11101.50). Se apenas os unit tests passarem e o result diferir de expected.json, a execução padrão falha e não salva novos resultados.

bash
python example.py --test

--test repete apenas os unit tests e não cria outputs. Ele pode ser usado mesmo que uma results folder já exista, o que o torna adequado para verificações rápidas durante a edição da função. Em contraste, o comando padrão para sem sobrescrever outputs existentes.

06Experimente criar um teste com falha uma vez

  1. Prepare uma cópia de example.py em uma pasta recém-extraída. Mantenha o arquivo original para poder restaurá-lo.
  2. Na calculation line int(price * 100) * quantity, exclua apenas o último * quantity para criar um erro que ignora quantity.
  3. Execute python example.py --test e verifique se tests como one-row quantity 3 e repeated-item falham.
  4. Restaure a calculation line original e execute --test novamente para ver que todos os 12 passam.

O objetivo deste experimento é confirmar que os tests detectam erros. Durante a criação deste exemplo, o mesmo tipo de erro foi injetado em uma temporary copy para verificar que os tests falham e nenhum resultado é gravado. Ver uma falha significativa uma vez facilita evitar uma situação em que o test code executa, mas não verifica nada.

07Etapas para aplicar isso a uma função recebida de IA

Para código novo, primeiro fixe exemplos de input e output. Se alguma parte gravar em original files, limite-a a copies e separe primeiro a função que faz o cálculo. Prepare um conjunto de normal data, empty data, 0, repeated items e values que não devem ser permitidos, e calcule os expected values por conta própria.

  1. Escreva as business rules da função como frases. Por exemplo, decida se returns são rejeitados ou calculados como negative amounts.
  2. Escreva um small input e expected value para cada rule. Compare juntos overall total e per-item results.
  3. Coloque o mesmo input na função em revisão e leia as differences nos results. Não altere primeiro os expected values para fazer as falhas desaparecerem.
  4. Depois de executar novamente os existing tests com o revised code, mantenha também os novos error cases nos tests.

Se você substituir input.csv pelos seus próprios data, também deverá calcular e atualizar expected.json separadamente. Não conclua que uma divergência com os expected values é um code defect depois de alterar apenas o input. Verificar quais rules e quais data mudaram é onde começa a reproducible verification.

08Leia a mensagem de falha e restrinja a causa

ResultadoSignificadoPróxima verificação
FAIL or FAILEDO calculated result difere do expected value do testLeia o name do failed test e os dois values.
Stopped due to input rulesUm CSV value está fora do allowed rangeVerifique a row indicada e os original data.
Differs from the hand-calculated expected valueA CSV aggregation não corresponde a expected.jsonVerifique novamente tanto se os data mudaram quanto o hand calculation.
outputs already existsExiste um successful result anteriorExecute apenas os checks com --test ou mova os results para outro lugar para preservá-los.

Passar nos tests deste exemplo é evidência para as rules declaradas. Não é uma medição do performance de um AI model real nem garantia de accuracy para todo trabalho contábil. Taxes, discounts, exchange rates, returns, multiple currencies e performance em large data precisam de rules e tests separados. Quanto mais failure cases você adicionar, mais claramente poderá explicar o intervalo em que o método se aplica.

Registro de execução e verificação

2026-09-19 · Windows 11 · CPython 3.12.14 · Sem pacotes adicionais · Executado em uma temporary copy da distribuição

  • 12 tests integrados de unittest passaram
  • As 4 rows do CSV sintético correspondem ao expected value calculado manualmente de 11101.50
  • Para antes de criar resultados quando input e expected values não correspondem
  • Os tests detectaram um calculation error deliberado que ignora quantity
  • Foram confirmadas execuções repetidas de --test e preservação do SHA-256 original
Limites da verificação
  • Nenhuma API real de IA foi chamada.
  • Tax, exchange rate, returns e performance verification não estão incluídos.
  • Resultados da execução em Windows CPython 3.12.14.

Princípios de redação e verificação de todo o site

Arquivos de exemplo para executar

Inclui código, dados de entrada e instruções de execução. Extraia o ZIP e leia primeiro o README.txt.

Baixar ZIP de exemplo

O código de exemplo, os nomes de arquivos e as chaves de entrada são mantidos como no original. Consulte também os comandos e os procedimentos de conferência do texto traduzido.

Material de prática original · Guarde os arquivos originais separadamente antes de executar.

Fontes de referência

As explicações e os exemplos são de elaboração própria. Os comportamentos e conceitos relacionados podem ser consultados nas fontes oficiais abaixo.