Repository: Qiskit/qiskit

Issue:
standard extension API inconsistency?
The standard extensions provides API for creating `u1`, `u2`, `u3`, and `U` gates.
```
q = QuantumRegister("q", 3)
c = ClassicalRegister("c", 3)
qc = QuantumCircuit(q, c)
qc.u2(pi/2, 0.3*pi, q[1]) # <- two real parameters, one qubit.
```
Similarly with `u3`:
```
qc.u3(pi,pi/2, 0.3*pi, q[1]) # <- three real parameters, one qubit.
```

But the way to interact with `U` is different:
```
qc.u_base([pi, pi/2, 0.3*pi], q[1]) # <- one array, one qubit.
```
Is this intended?

## Expected Behavior
I would expect to create a`U` gate the same way that a `u3` gate is created:
```
qc.u_base(pi,pi/2, 0.3*pi, q[1]) # <- three real parameters, one qubit.
```

## Possible Solution
Changing an API is something to avoid when possible. On the other hand, if this was not the intention, better fix it now :)

standard extension API inconsistency?
The standard extensions provides API for creating `u1`, `u2`, `u3`, and `U` gates.
```
q = QuantumRegister("q", 3)
c = ClassicalRegister("c", 3)
qc = QuantumCircuit(q, c)
qc.u2(pi/2, 0.3*pi, q[1]) # <- two real parameters, one qubit.
```
Similarly with `u3`:
```
qc.u3(pi,pi/2, 0.3*pi, q[1]) # <- three real parameters, one qubit.
```

But the way to interact with `U` is different:
```
qc.u_base([pi, pi/2, 0.3*pi], q[1]) # <- one array, one qubit.
```
Is this intended?

## Expected Behavior
I would expect to create a`U` gate the same way that a `u3` gate is created:
```
qc.u_base(pi,pi/2, 0.3*pi, q[1]) # <- three real parameters, one qubit.
```

## Possible Solution
Changing an API is something to avoid when possible. On the other hand, if this was not the intention, better fix it now :)



Discussion:

Resolving patch:
diff --git a/qiskit/extensions/standard/ubase.py b/qiskit/extensions/standard/ubase.py
--- a/qiskit/extensions/standard/ubase.py
+++ b/qiskit/extensions/standard/ubase.py
@@ -22,18 +22,14 @@
 from qiskit import CompositeGate
 from qiskit import Gate
 from qiskit import QuantumCircuit
-from qiskit.extensions._extensionerror import ExtensionError
 from qiskit.extensions.standard import header  # pylint: disable=unused-import
 
 
 class UBase(Gate):
     """Element of SU(2)."""
 
-    def __init__(self, param, qubit, circ=None):
-        """Create new reset instruction."""
-        if len(param) != 3:
-            raise ExtensionError("expected 3 parameters")
-        super(UBase, self).__init__("U", param, [qubit], circ)
+    def __init__(self, theta, phi, lam, qubit, circ=None):
+        super(UBase, self).__init__("U", [theta, phi, lam], [qubit], circ)
 
     def qasm(self):
         """Return OPENQASM string."""
@@ -57,13 +53,14 @@ def inverse(self):
 
     def reapply(self, circ):
         """Reapply this gate to corresponding qubits in circ."""
-        self._modifiers(circ.u_base(self.param, self.arg[0]))
+        self._modifiers(circ.u_base(self.param[0], self.param[1], self.param[2],
+                                    self.arg[0]))
 
 
-def u_base(self, tpl, q):
+def u_base(self, theta, phi, lam, q):
     """Apply U to q."""
     self._check_qubit(q)
-    return self._attach(UBase(tpl, q, self))
+    return self._attach(UBase(theta, phi, lam, q, self))
 
 
 QuantumCircuit.u_base = u_base
diff --git a/qiskit/unroll/_circuitbackend.py b/qiskit/unroll/_circuitbackend.py
--- a/qiskit/unroll/_circuitbackend.py
+++ b/qiskit/unroll/_circuitbackend.py
@@ -125,9 +125,9 @@ def u(self, arg, qubit, nested_scope=None):
         if self.listen:
             if "U" not in self.basis:
                 self.basis.append("U")
-            this_gate = self.circuit.u_base(list(map(lambda x:
-                                                     x.sym(nested_scope),
-                                                     arg)),
+
+            (theta, phi, lam) = list(map(lambda x: x.sym(nested_scope), arg))
+            this_gate = self.circuit.u_base(theta, phi, lam,
                                             self._map_qubit(qubit))
             if self.creg is not None:
                 this_gate.c_if(self._map_creg(self.creg), self.cval)


Test patch:
diff --git a/test/python/test_extensions_standard.py b/test/python/test_extensions_standard.py
--- a/test/python/test_extensions_standard.py
+++ b/test/python/test_extensions_standard.py
@@ -286,12 +286,12 @@ def test_ubase(self):
         # self.assertRaises(QISKitError, c.ubase, self.c[1], self.c[2])
         # self.assertRaises(QISKitError, c.ubase, self.q[0], self.q[0])
         # TODO self.assertRaises(QISKitError, c.cx_base, 0, self.q[0])
-        c.u_base([1, 2, 3], self.q[1])  # <- is that use intented?! CHECKME
+        c.u_base(1, 2, 3, self.q[1])
         self.assertResult(UBase, 'U(1,2,3) q[1];', 'U(-1,-3,-2) q[1];')
 
     def test_ubase_pi(self):
         c = self.circuit
-        c.u_base([pi, pi / 2, 0.3 * pi], self.q[1])
+        c.u_base(pi, pi / 2, 0.3 * pi, self.q[1])
         self.assertResult(UBase, 'U(pi,pi/2,0.3*pi) q[1];', 'U(-pi,-0.3*pi,-pi/2) q[1];')
 
     def test_x(self):