@gruizdevilla
private static int k(int k, int kk) {
String kkkkkkkk = Integer.toBinaryString(k);
String kkkkkkk = Integer.toBinaryString(kk);
// s1, s2 are binary representations
while(kkkkkkkk.length() > kkkkkkk.length())
kkkkkkk = "0" + kkkkkkk;
while(kkkkkkkk.length() < kkkkkkk.length())
kkkkkkkk = "0" + kkkkkkkk;
int kkkkkkkkk = 0;
for(int kkkkkkkkkk = 0; kkkkkkkkkk < kkkkkkkk.length(); kkkkkkkkkk++) {
if(kkkkkkk.charAt(kkkkkkkkkk) != kkkkkkkk.charAt(kkkkkkkkkk))
kkkkkkkkk++;
}
return kkkkkkkkk;
}
🤦♀️
* completely invented numbers, but they feel realistic, doesn't they?
Bug cost
SELECT note as note_original,
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(note, '\"', ''),
'.', ''),
'?', ''),
'`', ''),
'<', ''),
'=', ''),
'{', ''),
'}', ''),
'[', ''),
']', ''),
'|', ''),
'\'', ''),
':', ''),
';', ''),
'~', ''),
'!', ''),
'@', ''),
'#', ''),
'$', ''),
'%', ''),
'^', ''),
'&', ''),
'*', ''),
'_', ''),
'+', ''),
',', ''),
'/', ''),
'(', ''),
')', ''),
'-', ''),
'>', ''),
' ', '-'),
'--', '-') as note_changed FROM invheader
🤦♀️
(Inventor de C++)
Elegante y eficiente.
Lógica directa, mínimas dependencias y fácil de mantener.
(Desarrolló UML)
El código limpio se lee como prosa bien escrita
(Padrino de Eclipse)
(Autor de "Working Effectively with Legacy Code")
(Extreme Programming Adventures in C#)
(Inventor de la Wiki y mucho más)
Porque no es suficiente escribir buen código.
El código se tiene que mantener sin pudrirse
ni degradarse.
"Deja el lugar donde acampaste un poco
más limpio que como lo encontraste."
🤦♀️
Significativo: que da a entender
o conocer con precisión.
int d; //dias transcurridos
int diasTranscurridos;
int diasDesdeCreacion;
int diasDesdeModificacion;
cuentasList; //Si no es de tipo List....
XYZControllerConManejoEficienteDeStrings;
XYZControllerConAlmacenamientoEficienteDeStrings;
for(let i = 0; i < max-1; i++){
for(let j = i+1; j < max; i++){
//lógica
}
}
for(let posicion_1 = 0; posicion_1 < max-1; posicion_1++){
for(let posicion_2 = posicion_2 + 1; j < max; posicion_2++){
//lógica
}
}
public void copiarObjeto(Clase1 o1, Clase1, o2);
//vs
public void copiarObjeto(Clase1 origen, Clase1 destino);
public void copiarObjeto(Clase1 o1, Clase1, o2);
//vs
public void copiarObjeto(Clase1 origen, Clase1 destino);
The Walking COBOL!
¿No tenemos lenguajes con tipado estático?
(Y para tipado dinámico, apóyate en TDD o extensiones del lenguaje como TypeScript para JavaScript)
Los lectores no tienen que tener que traducir
tus nombres a otros que entiendan.
La claridad es fundamental.
Real life!
http://projects.haykranen.nl/java/
APORTA CONTEXTO SI ES NECESARIO
pero
EVITAR CONTEXTO GRATUITO
Evita cosas como:
For the lack of a nail,
throw new HorseshoeNailNotFoundException("no nails!");
For the lack of a horseshoe,
EquestrianDoctor.getLocalInstance().getHorseDispatcher().shoot();
For the lack of a horse,
RidersGuild.getRiderNotificationSubscriberList().getBroadcaster().run(
new BroadcastMessage(StableFactory.getNullHorseInstance()));
For the lack of a rider,
MessageDeliverySubsystem.getLogger().logDeliveryFailure(
MessageFactory.getAbstractMessageInstance(
new MessageMedium(MessageType.VERBAL),
new MessageTransport(MessageTransportType.MOUNTED_RIDER),
new MessageSessionDestination(BattleManager.getRoutingInfo(
BattleLocation.NEAREST))),
MessageFailureReasonCode.UNKNOWN_RIDER_FAILURE);
For the lack of a message,
((BattleNotificationSender)
BattleResourceMediator.getMediatorInstance().getResource(
BattleParticipant.PROXY_PARTICIPANT,
BattleResource.BATTLE_NOTIFICATION_SENDER)).sendNotification(
((BattleNotificationBuilder)
(BattleResourceMediator.getMediatorInstance().getResource(
BattleOrganizer.getBattleParticipant(Battle.Participant.GOOD_GUYS),
BattleResource.BATTLE_NOTIFICATION_BUILDER))).buildNotification(
BattleOrganizer.getBattleState(BattleResult.BATTLE_LOST),
BattleManager.getChainOfCommand().getCommandChainNotifier()));
//...
// For A/B Testing
var getModalGreen = function() {
d = Math.random() * 100;
if ((d -= 99.5) < 0) return 1;
return 2;
};
🤦♀️
class ReturnValues {
private int numDays;
private String lastName;
public ReturnValues(int i, String s) {
numDays = i;
lastName = s;
}
public int getNumDays() { return numDays; }
public String getLastname() { return lastName; }
}
class AlsoReturnTransactionDate extends ReturnValues {
private Date txnDate;
public AlsoReturnTransactionDate(int i, String s, Date td) {
super(i,s);
txnDate = td;
}
public Date getTransactionDate() { return txnDate; }
}
class AddPriceToReturn extends AlsoReturnTransactionDate {
private BigDecimal price;
public AddPriceToReturn(int i, String s, Date td, BigDecimal px) {
super(i,s,td);
price = px;
}
public BigDecimal getPrice() { return price; }
}
class IncludeTransactionData extends AddPriceToReturn {
private Transaction txn;
public IncludeTransactionData(int i, String s, Date td, BigDecimal px, Transaction t) {
super(i,s,td,px);
txn = t;
}
public Transaction getTransaction() { return txn; }
}
class IncludeParentTransactionId extends IncludeTransactionData {
private long id;
public IncludeParentTransactionId(int i, String s, Date td, BigDecimal px, Transaction t, long id) {
super(i,s,td,px,t);
this.id = id;
}
public long getParentTransactionId() { return id; }
}
class ReturnWithRelatedData extends IncludeParentTransactionId {
private RelatedData rd;
public ReturnWithRelatedData(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd) {
super(i,s,td,px,t,id);
this.rd = rd;
}
public RelatedData getRelatedData() { return rd; }
}
class ReturnWithCalculatedFees extends ReturnWithRelatedData {
private BigDecimal calcedFees;
public ReturnWithCalculatedFees(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf) {
super(i,s,td,px,t,id,rd);
calcedFees = cf;
}
public BigDecimal getCalculatedFees() { return calcedFees; }
}
class ReturnWithExpiresDate extends ReturnWithCalculatedFees {
private Date expiresDate;
public ReturnWithExpiresDate(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed) {
super(i,s,td,px,t,id,rd,cf);
expiresDate = ed;
}
public Date getExpiresDate() { return expiresDate; }
}
class ReturnWithRegulatoryQuantities extends ReturnWithExpiresDate {
private RegulatoryQuantities regQty;
public ReturnWithRegulatoryQuantities(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq) {
super(i,s,td,px,t,id,rd,cf,ed);
regQty = rq;
}
public RegulatoryQuantities getRegulatoryQuantities() { return regQty; }
}
class ReturnWithPriorities extends ReturnWithRegulatoryQuantities {
private Map<String,Double> priorities;
public ReturnWithPriorities(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq, Map<String,Double> p) {
super(i,s,td,px,t,id,rd,cf,ed,rq);
priorities = p;
}
public Map<String,Double> getPriorities() { return priorities; }
}
class ReturnWithRegulatoryValues extends ReturnWithPriorities {
private Map<String,Double> regVals;
public ReturnWithRegulatoryValues(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq, Map<String,Double> p, Map<String,Double> rv) {
super(i,s,td,px,t,id,rd,cf,ed,rq,p);
regVals = rv;
}
public Map<String,Double> getRegulatoryValues() { return regVals; }
}
🤦♀️
enum Bool
{
True,
False,
FileNotFound
};
🤦♀️
package com.xxxx.flow.dto;
import com.xxxx.DTOIn;
import com.xxxx.XipConectorDAO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IniciarProcesoContratacionCarterasAsesoradasSBPModel implements DTOIn {
private static final long serialVersionUID = -5565412435484318101L;
private XipConectorDAO XipConectorDAO;
private String carteraAsesorada;
private String idTestMifid;
private String propuestaInversion;
private String productosVinculados;
private String idCliente;
private String intervinientes;
}
🤦♀️
¿Cómo decías que se recuperaba el id?
employee.id.Get()
dependent.GetId()
supervisor()
candidate.id()
🤦♀️
(Personalmente, prefiero FP a declarativa)
Una función:
hace solo UNA cosa,
y la hace BIEN
y no hace nada más.
Una función no debe mezclar
niveles de abstracción.
Por ejemplo, no debe hacer invocaciones
a funciones de alto nivel y cosas técnicas
a la vez.
String documento = generaDocumento();
documento.append("Generado automaticamente por el sistema.")
Suficiente entidad para ser la única responsabilidad de una función.
public Importe calculaPaga(Empleado e) throws TipoEmpleadoInvalidoException {
switch(e.type) {
case COMISIONISTA:
return calculaComisiones(e);
case ASALARIADO:
return calculaSalario(e);
case FREELANCE:
return calculaPagoPorHoras(e);
default:
throw new TipoEmpleadoInvalidoException(e);
}
}
var calculadoras = {};
calculadoras.COMISIONISTA = calculaComisiones();
calculadoras.ASALARIADO = calculaSalario();
calculadoras.FREELANCE = calculaPagoPorHoras();
function calculaPaga(empleado) {
return calculadoras[empleado.type](empleado);
}
function calculaPaga(Empleado e): Importe {
return isComisionista(e) ? calculaComisiones(e) :
isAsalariado(e) ? calculaSalario(e)
: calculaPagoPorHoras(e)
}
type Comisionista = ...
type Asalariado = ...
type Freelance = ...
type Empleado = Comisionista | Asalariado | Freelance;
function calculaComisiones(e: Comisionista): Importe{
//...
}
function calculaSalario(e: Asalariado): Importe{
//...
}
function calculaPagoPorHoras(e: Freelance): Importe{
//...
}
function isComionista(e:Empleado): e is Comisionista {
return e instanceOf Comisionista;
}
function isAsalariado(e:Empleado): e is Asalariado {
return e instanceOf Asalariado;
}
miObj.elMetodoConNombreTanLargoQueAlFinalNoTeAcuerdasDelPrincipio()
Número de parámetros:
También puedes apoyarte en "named parameters" si el lenguaje lo permite
tf.nn.conv2d(
input,
filter,
strides,
padding,
use_cudnn_on_gpu=True,
data_format='NHWC',
dilations=[1, 1, 1, 1],
name=None
)
void setOn();
void setOff();
//... vs
void setSwitch(boolean on);
book(aCustomer, true)
//... vs
book(aCustomer, isPremium:true)
If {commission_rate} = 1.2
Then 20
Else If {commission_rate} = 1.15
Then 15
Else If {commission_rate} = 1.0
Then 0
Else If {commission_rate} = 1.16
Then 16
Else If {commission_rate} = 1.125
Then 12.5
Else If {commission_rate} = 1.1
Then 10
Else {commission_rate}
End
🤦♀️
function sePuedeConsumir(producto) {
return new Date() < producto.fechaCaducidad;
}
¿Buenos o malos?
Son la primera víctima del:
// if hasSiblings, actionType == cont; else actionType == end.
if ($hasSiblings)
{
$actionType = "cont";
}
else
{
$actionType = "end";
}
🤦♀️
De los buenos
De los malos
Crea una cultura de comentarios
Algunos consejos sobre formateo vertical:
"Developers Who Use Spaces Make More Money Than Those Who Use Tabs"
https://stackoverflow.blog/2017/06/15/developers-use-spaces-make-money-use-tabs/
Si pasas de tabuladores a espacios y vas a pedir un aumento de sueldo, te recomiendo que busques en Google la diferencia entre correlación y causalidad 🤪
java
🤦♀️
Hay un motivo para la existencia de variables privadas:
no queremos que nadie dependan de ellas.
¿Por qué añadir getters y setters a todas ellas?
Hay un motivo para la existencia de variables privadas:
no queremos que nadie dependan de ellas.
¿Por qué añadir getters y setters a todas ellas?
Un punto
public class Punto {
public double x;
public double y;
}
public interface Punto {
public double getX();
public double getY();
public setCartesianas(double x, double y);
public double getR();
public double getTheta();
public setPolares(double r, double theta);
}
Un objeto no debe conocer nada
acerca de las interioridades de los objetos
que maneja.
Queremos evitar los accidentes de trenes:
ctx.getSession(true).getStorage().get("dato").value
Buscaros un buen sistema de tipos
Programación síncrona:
Programación asíncrona:
¿Unchecked o checked exceptions?
Las excepciones tienen que definirse
en función de las necesidades de los usuarios.
Tienen que proporcionar el contexto suficiente
para entender por que se lanzan.
Las excepciones tienen que definirse
en función de las necesidades de los usuarios.
Tienen que proporcionar el contexto suficiente
para entender por que se lanzan.
¿Por qué es importante?
F: FAST. Rápidos.
I: INDEPENDENT. Independientes entre si.
R: REPEATABLE Repetibles independientemente del entorno.
S: SELF VALIDATING Si o No. Pasa o no pasa. Resultado claro.
T:TIMELY Escritos secuencialmente, justo antes
de necesitarse.
Todo lo anterior aplica:
SRP: single responsibility principle
KISS: Keep it simple and stupid, short, straightforward...
YAGNI: you ain't gonna need it
DRY and DIE: Don't repeat your self, duplication is evil
Consejo: RY then DRY
Demeter Law: no hables con extraños
POLS: principle of least surprise
POGE: Principle of good enough
Brook's law: nueve mujeres no hacen un bebé en un mes