Apuntes DAM
Volver al inicio

Factura de la luz: potencia, tramos horarios, impuestos e IVA

Ejercicio de JavaMedioUnos 45 minutos

Calcula una factura de la luz real: término de potencia, energía por tramos punta, llano y valle, impuesto eléctrico, alquiler del contador e IVA, cada concepto redondeado a céntimos; el reparto del consumo, el precio medio del kWh y un consejo de ahorro. Variables, operadores y formato.

  • Variables y constantes
  • Operadores aritméticos
  • Leer con Scanner
  • switch con flechas
  • Redondeo a céntimos
  • String.format

Enunciado

La factura de la luz parece un jeroglífico, pero es aritmética: se paga por la potencia contratada (los kW que puedes usar a la vez) cada día, por la energía consumida (los kWh) a un precio distinto según la hora, un impuesto eléctrico, el alquiler del contador y, sobre todo eso, el IVA.

Con la tarifa por tramos, la energía es más cara en punta (las horas de más demanda), menos en llano y mucho menos en valle (la noche y los fines de semana). Por eso conviene saber cómo se reparte el consumo.

Qué tiene que hacer el programa

  1. La entrada tiene una línea concepto valor para cada uno de potencia (kW), dias, punta, llano y valle (kWh), en cualquier orden. Los valores admiten coma o punto decimal. Una línea sin dos partes: Línea no válida: línea; un valor que no es un número, negativo, o unos días que no son un entero mayor que 0: Dato no válido: línea; un concepto que no es ninguno de esos: Concepto desconocido: concepto.
  2. Si falta alguno: Faltan datos: hacen falta potencia, dias, punta, llano y valle y nada más.
  3. Precios: potencia 0,10 € por kW y día; energía 0,25 € (punta), 0,18 € (llano) y 0,12 € (valle) por kWh; impuesto eléctrico del 5,11269632 % sobre potencia más energía; alquiler del contador 0,0268 € por día; IVA del 21 % sobre la suma de todo lo anterior (la base imponible). Cada concepto se redondea a céntimos antes de usarlo en el siguiente (Math.round(x * 100) / 100.0).
  4. La factura: Término de potencia: X, Energía consumida: X, Impuesto eléctrico: X, Alquiler del contador: X, Base imponible: X, IVA (21 %): X y TOTAL: X (respeta los espacios), con dos decimales, coma y €.
  5. Después: Consumo: C kWh (punta P %, llano L %, valle V %) (los kWh sin decimales y los porcentajes redondeados al entero) y Precio medio: X €/kWh (el total entre los kWh, con tres decimales y coma). Si el consumo es 0: Consumo: 0 kWh y nada más.
  6. Si más del 40 % del consumo es en punta: Consejo: más del 40 % del consumo es en punta; pasar la mitad a valle ahorraría unos X, donde X es la mitad de los kWh de punta por la diferencia de precio entre punta y valle, con el impuesto eléctrico y el IVA (sin redondear antes de formatear).

Entrada

Una línea concepto valor para potencia, dias, punta, llano y valle.

Datos de referencia

Precios de la tarifa
ConceptoPrecio
Potencia0,10 € por kW y día
Energía en punta0,25 € por kWh
Energía en llano0,18 € por kWh
Energía en valle0,12 € por kWh
Impuesto eléctrico5,11269632 % de potencia + energía
Alquiler del contador0,0268 € por día
IVA21 % de la base imponible

Ejemplos de ejecución

Tu programa debe escribir exactamente esta salida para estas entradas. Las pruebas del editor incluyen estos ejemplos y otros casos ocultos.

Un piso con mucho consumo en punta

Entrada

potencia 4.6
dias 30
punta 160
llano 95
valle 80

Salida por consola

Término de potencia:  13,80 €
Energía consumida:    66,70 €
Impuesto eléctrico:   4,12 €
Alquiler del contador: 0,80 €
Base imponible:       85,42 €
IVA (21 %):           17,94 €
TOTAL:                103,36 €
Consumo: 335 kWh (punta 48 %, llano 28 %, valle 24 %)
Precio medio: 0,309 €/kWh
Consejo: más del 40 % del consumo es en punta; pasar la mitad a valle ahorraría unos 13,23 €

Datos con coma y errores

Entrada

dias 31
potencia 3,45
punta 40
llano 60,5
valle 150
tarifa 2
valle -3
dias 30.5
hola

Salida por consola

Concepto desconocido: tarifa
Dato no válido: valle -3
Dato no válido: dias 30.5
Línea no válida: hola
Término de potencia:  10,70 €
Energía consumida:    38,89 €
Impuesto eléctrico:   2,54 €
Alquiler del contador: 0,83 €
Base imponible:       52,96 €
IVA (21 %):           11,12 €
TOTAL:                64,08 €
Consumo: 251 kWh (punta 16 %, llano 24 %, valle 60 %)
Precio medio: 0,256 €/kWh

Guía paso a paso

Intenta resolverlo por tu cuenta y abre un paso solo cuando te atasques: cada uno te acerca a la solución sin dártela entera.

1. Constantes con nombre

Declara cada precio como una constante static final: el cálculo se lee como la factura y, si cambia la tarifa, solo se toca una línea.

2. Leer línea a línea

Con hasNextLine y split("\\s+") separas concepto y valor. Un switch con flechas sobre el concepto guarda cada valor en su variable; inicialízalas a -1 para saber después si falta alguna.

java
switch (clave) {
    case "potencia" -> potencia = valor;
    case "dias" -> dias = (int) valor;
    default -> System.out.println("Concepto desconocido: " + p[0]);
}
3. Redondear cada concepto

Una función centimos(x) que redondea a dos decimales. Úsala en cada concepto antes de sumarlo: así la factura cuadra al céntimo, como las reales.

4. Formatear

String.format(Locale.ROOT, "%.2f", x) da siempre punto decimal; cámbialo por coma con replace('.', ',').

Resuélvelo aquí

El editor trae el esqueleto del programa. Pulsa «Ejecutar» para comprobarlo con los ejemplos y con 2 casos ocultos que buscan los errores típicos.

☕JavaFactura de la luz: potencia, tramos horarios, impuestos e IVAMedio

Ejemplo

Entrada (lo que se escribe por teclado)
potencia 4.6
dias 30
punta 160
llano 95
valle 80
Salida esperada
Término de potencia:  13,80 €
Energía consumida:    66,70 €
Impuesto eléctrico:   4,12 €
Alquiler del contador: 0,80 €
Base imponible:       85,42 €
IVA (21 %):           17,94 €
TOTAL:                103,36 €
Consumo: 335 kWh (punta 48 %, llano 28 %, valle 24 %)
Precio medio: 0,309 €/kWh
Consejo: más del 40 % del consumo es en punta; pasar la mitad a valle ahorraría unos 13,23 €
⏳
Test oculto #3
⏳
Test oculto #4
0/4 tests pasados · pulsa un test para ver su entrada y su salida esperada

Solución explicada

Ver la solución completa
java
1import java.util.Locale;
2import java.util.Scanner;
3
4public class Main {
5    static final double PRECIO_POTENCIA = 0.10;           // € por kW contratado y día
6    static final double PUNTA = 0.25, LLANO = 0.18, VALLE = 0.12;   // € por kWh
7    static final double IMPUESTO_ELECTRICO = 0.0511269632;
8    static final double ALQUILER_DIA = 0.0268;             // € por día
9    static final double IVA = 0.21;
10
11    static double centimos(double x) {
12        return Math.round(x * 100) / 100.0;
13    }
14
15    static String euros(double x) {
16        return String.format(Locale.ROOT, "%.2f", x).replace('.', ',') + " €";
17    }
18
19    public static void main(String[] args) {
20        Scanner sc = new Scanner(System.in);
21        double potencia = -1, punta = -1, llano = -1, valle = -1;
22        int dias = -1;
23        while (sc.hasNextLine()) {
24            String linea = sc.nextLine().trim();
25            if (linea.isEmpty()) continue;
26            String[] p = linea.split("\\s+");
27            if (p.length != 2) {
28                System.out.println("Línea no válida: " + linea);
29                continue;
30            }
31            double valor;
32            try {
33                valor = Double.parseDouble(p[1].replace(',', '.'));
34            } catch (NumberFormatException e) {
35                System.out.println("Dato no válido: " + linea);
36                continue;
37            }
38            String clave = p[0].toLowerCase();
39            if (valor < 0 || (clave.equals("dias") && (valor != Math.floor(valor) || valor == 0))) {
40                System.out.println("Dato no válido: " + linea);
41                continue;
42            }
43            switch (clave) {
44                case "potencia" -> potencia = valor;
45                case "dias" -> dias = (int) valor;
46                case "punta" -> punta = valor;
47                case "llano" -> llano = valor;
48                case "valle" -> valle = valor;
49                default -> System.out.println("Concepto desconocido: " + p[0]);
50            }
51        }
52        if (potencia < 0 || dias < 0 || punta < 0 || llano < 0 || valle < 0) {
53            System.out.println("Faltan datos: hacen falta potencia, dias, punta, llano y valle");
54            return;
55        }
56        // cada concepto se redondea a céntimos antes de sumarlo, como en una factura real
57        double terminoPotencia = centimos(potencia * dias * PRECIO_POTENCIA);
58        double energia = centimos(punta * PUNTA + llano * LLANO + valle * VALLE);
59        double impuesto = centimos((terminoPotencia + energia) * IMPUESTO_ELECTRICO);
60        double alquiler = centimos(dias * ALQUILER_DIA);
61        double base = centimos(terminoPotencia + energia + impuesto + alquiler);
62        double iva = centimos(base * IVA);
63        double total = centimos(base + iva);
64        System.out.println("Término de potencia:  " + euros(terminoPotencia));
65        System.out.println("Energía consumida:    " + euros(energia));
66        System.out.println("Impuesto eléctrico:   " + euros(impuesto));
67        System.out.println("Alquiler del contador: " + euros(alquiler));
68        System.out.println("Base imponible:       " + euros(base));
69        System.out.println("IVA (21 %):           " + euros(iva));
70        System.out.println("TOTAL:                " + euros(total));
71        double consumo = punta + llano + valle;
72        if (consumo == 0) {
73            System.out.println("Consumo: 0 kWh");
74            return;
75        }
76        System.out.println("Consumo: " + String.format(Locale.ROOT, "%.0f", consumo) + " kWh (punta " + Math.round(punta * 100 / consumo)
77                + " %, llano " + Math.round(llano * 100 / consumo) + " %, valle " + Math.round(valle * 100 / consumo) + " %)");
78        System.out.println("Precio medio: " + String.format(Locale.ROOT, "%.3f", total / consumo).replace('.', ',') + " €/kWh");
79        if (punta / consumo > 0.4) {
80            // pasar la mitad del consumo de punta a valle, con el impuesto eléctrico y el IVA
81            double ahorro = (punta / 2) * (PUNTA - VALLE) * (1 + IMPUESTO_ELECTRICO) * (1 + IVA);
82            System.out.println("Consejo: más del 40 % del consumo es en punta; pasar la mitad a valle ahorraría unos " + euros(ahorro));
83        }
84    }
85}

La potencia se paga aunque no se consuma nada: es lo que cuesta tener disponible esa capacidad cada día. Por eso bajar la potencia contratada ahorra aunque se gaste lo mismo.

Redondear cada concepto antes de sumarlo es lo que hacen las facturas: si se redondeara solo el total, la suma de las líneas impresas podría no coincidir con él por un céntimo.

El IVA se aplica sobre la base, que ya incluye el impuesto eléctrico: es un impuesto sobre otro impuesto.

Locale.ROOT al formatear evita que el resultado dependa del idioma del ordenador: con Locale español, %.2f ya daría coma, y el replace la dejaría igual, pero en otros idiomas no.

Para ir más allá

  • Lee el consumo hora a hora de un día (24 valores) y clasifícalo tú en punta, llano y valle.
  • Compara con una tarifa de precio fijo de 0,19 €/kWh y di cuál sale mejor.
  • Calcula la potencia mínima a contratar a partir del pico de consumo simultáneo.

Dónde se explica