# Qcuit - The Most Beginner-Friendly Quantum Computing Library

Write quantum programs in plain English. Built on Qiskit. 100% open source.

## Installation

```bash
pip install qcuit
```

Requires Python 3.10+ and Qiskit (automatically installed).

## Quick Start: Create a Bell State

```python
from qcuit import Qubit, Circuit, Apply, Hadamard, CNOT
from qcuit.backend import run_simulation

# Create two qubits
a = Qubit("a")
b = Qubit("b")

# Build the circuit
circ = Circuit(a, b)
circ.add(Apply(Hadamard, target=a))
circ.add(Apply(CNOT, target=b, control=a))

# Measure and visualize
circ.measure_all()
circ.draw()

# Run simulation
results = run_simulation(circ)
print(results)  # e.g. {"00": 507, "11": 517}
```

**What's happening?**
1. Hadamard puts qubit "a" into superposition
2. CNOT entangles "a" and "b" - they become correlated
3. Measurement shows perfect correlation: either both 00 or both 11

## API Reference

### Core Classes

#### Qubit(name)
Creates a named quantum bit.
- **Parameters**: `name` (str) - Human-readable label
- **Example**: `alice = Qubit("alice")`

#### Circuit(*qubits)
Container for quantum operations.
- **Parameters**: One or more Qubit objects
- **Methods**: 
  - `add(operation)` - Add gate operation
  - `measure_all()` - Flag all qubits for measurement
  - `draw()` - Print ASCII circuit diagram

#### Apply(gate, target, control=None)
Wraps a gate with target/control qubits.
- **Parameters**:
  - `gate` - Gate class (Hadamard, PauliX, CNOT)
  - `target` - Target Qubit
  - `control` - Control Qubit (required for CNOT)

### Supported Gates

| Gate | Symbol | Description | Example |
|------|--------|-------------|---------|
| Hadamard | [H] | Creates superposition | `Apply(Hadamard, target=q)` |
| PauliX | [X] | Quantum NOT gate | `Apply(PauliX, target=q)` |
| CNOT | [*]/[+] | Controlled-NOT (entanglement) | `Apply(CNOT, target=b, control=a)` |

### Backend Functions

#### run_simulation(circuit, shots=1024)
Execute circuit on Qiskit AerSimulator.
- **Parameters**: 
  - `circuit` - Complete Circuit object with measurements
  - `shots` - Number of simulation runs (default: 1024)
- **Returns**: Dict mapping bitstrings to counts

### Error Handling

Qcuit provides friendly error messages for common mistakes:

```python
# Missing control qubit
Apply(CNOT, target=q)  # QcuitError: Try: Apply(CNOT, target=q_b, control=q_a)

# Empty qubit name  
Qubit("")  # QcuitError: Try: Qubit("my_qubit")

# Forgot measurement
run_simulation(circ)  # QcuitError: Try: circ.measure_all()
```

## Examples

### Single Qubit Superposition
```python
from qcuit import Qubit, Circuit, Apply, Hadamard
from qcuit.backend import run_simulation

q = Qubit("super")
circ = Circuit(q)
circ.add(Apply(Hadamard, target=q))
circ.measure_all()
circ.draw()

results = run_simulation(circ, shots=1000)
print(results)  # Approximately {"0": 500, "1": 500}
```

### Quantum NOT Gate
```python
from qcuit import Qubit, Circuit, Apply, PauliX
from qcuit.backend import run_simulation

q = Qubit("flip")
circ = Circuit(q)
circ.add(Apply(PauliX, target=q))
circ.measure_all()
circ.draw()

results = run_simulation(circ)
print(results)  # {"1": 1024}
```

## Contributing

Qcuit is 100% open source! We welcome contributions:
- Report bugs on GitHub Issues
- Submit pull requests for new gates
- Improve documentation
- Add examples

## License

MIT License - feel free to use qcuit in your projects!

## Links

- [Website](https://qcuit.com)
- [GitHub Repository](https://github.com/qcuit/qcuit)
- [PyPI Package](https://pypi.org/project/qcuit)
