Creando Pseudo-Objetos con tlist
En primer lugar voy a crear un Pseudo-Objeto Escalar, utilizando el comando tlist (lo voy a llamar TEscalar):
nombrevariable = tlist(["TEscalar", "Valor", "Unid", "Alias"])
Los strings que componen el tlist, intentan ser descriptivos:
- El primer string "TEscalar" es el nombre que le he dado a este objeto.
- En "Valor" se archivará el valor numérico del escalar
- En "Unid" un string con sus unidades; o un un array de strings de 2x1; el primero de ellos será el prefijo (basado en el sistema internacional) y el segundo string la unidad del escalar
- En "Alias" se puede almacenar un string con un nombre descriptivo del escalar
Para hacerlo más robusto he preparado una función (como si fuera un constructor de clase) para crear estos TEscalares, el código es:
function this = escalar_new(varargin) // v1.2 Quitar UdPref de la entrada de datos
// Crea un pseudo-objeto TEscalar
// type(TEscalar)= 16; typeof(TEscalar)= "TEscalar";
[lhs ,rhs ]=argn()
if rhs==0 then
mprintf(" TEscalar = escalar_new(Valor,Unid,Alias,UdPref) \n")
mprintf(" Valor : cantidad numérica \n");
mprintf(" Unid : string con la unidad a utilizar en la presentación; \n");
mprintf(" si es un array 1x2 de strings, p.e.: [""μ"" ""m""], el \n");
mprintf(" prefijo recalcula la magnitud, p.e.: μ divide por 10⁶ ;\n");
mprintf(" (el string o el array 1x2 es guardado en UdPref) \n");
mprintf(" Alias : string para ponerle un nombre o alias \n\n");
// UdPref no hace necesario introducirlo, se toma Unid como UdPref (para no cambiar más funciones)
// mprintf(" UdPref : unidades de presentación utilizadas por string() \n\n"); // v1.2
errmsg = msprintf(" La función escalar_new, necesita al menos el primer argumento")
error ( errmsg );
end // if rhs==0
//
// idea1 guardar matriz unidades, para presentarlo luego en unidades preferidas (indicadas al crearlo)
this = tlist(["TEscalar", "Valor", "Unid", "Alias","UdPref"]);
//
if rhs>=1 then // .Valor
if type(varargin(1))==1 then
// mprintf(" Sólo entra valor, sin unidad \n")
this.Valor=varargin(1);
else // if type(varargin(1))
// podía implementar polynom // pendiente
errmsg = msprintf (" escalar_new esperaba un número como argumento : %s",typeof(varargin(1)));
error ( errmsg )
end // if type(varargin(1))
end // if rhs>=1
//
if rhs>=2 then // .Unid
//idea1
this.UdPref=varargin(2);
if typeof(varargin(2))=="string" then
if size(varargin(2))==[1 1] then // sólo unidad
this.Valor=varargin(1);
this.Unid=varargin(2);
this.UdPref=varargin(2); // v1.2
elseif size(varargin(2))==[1 2] then // prefijo y unidad
fdE=pfSI(varargin(2)(1));
this.Valor=varargin(1)*fdE;
this.Unid=varargin(2)(2);
this.UdPref=varargin(2); // v1.2
else // if size(varargin(2)) // tamaño inesperado
errmsg = msprintf (" escalar_new : esperaba un string 1x1 ó 1x2 : %s",size(varargin(2)));
error ( errmsg )
end // if size(varargin(2))
else // if typeof(varargin(2))
errmsg = msprintf (" escalar_new : esperaba un string 1x1 ó 1x2 : %s",typeof(varargin(2)) );
error ( errmsg )
end // if typeof(varargin(2))
else // if rhs>=2
this.Unid=""; this.UdPref="";
end // if rhs>=2
if rhs>=3 then // .Alias
//idea1
if (rhs==3)&(typeof(varargin(3)))=="string" then
this.Alias=varargin(3);
else // if (rhs==3)&(typeof(varargin(3)))
this.Alias=string(varargin(3));
end // if (rhs==3)&(typeof(varargin(3)))
else // if rhs>=3
this.Alias=""; // this.Alias="";
end // if rhs>=3
endfunction // function this = escalar_new(varargin)
El código intenta ser auto descriptivo, y contiene una comprobación de errores interna.
Hago uso de una función propia pfSI (que proporciona unos factores de escala en función del prefijo del sistema internacional utilizado en las unidades), cuyo código es:
function [d]=pfSI(pfSU)
// uso en printUD("Titulo",Variable/pfSI(u),"uUD",,,)
if ~exists("pfSU") then pfSU = ""; end
if pfSU=="" then d=1;
elseif pfSU=="a" then d=1e-18; // ato
elseif pfSU=="f" then d=1e-15; // femto
elseif pfSU=="p" then d=1e-12; // pico
elseif pfSU=="n" then d=1e-9; // nano
elseif (pfSU=="u")|(pfSU=="μ")|(pfSU=="µ") then d=1e-6; // micro
elseif pfSU=="m" then d=1e-3; // mili
elseif pfSU=="c" then d=1e-2; // centi
elseif pfSU=="d" then d=1e-1; // deci
elseif pfSU=="da" then d=10; // deca
elseif pfSU=="h" then d=100; // hecto
elseif pfSU=="k" then d=1e3; // kilo
elseif pfSU=="M" then d=1e6; // mega
elseif pfSU=="G" then d=1e9; // giga
elseif pfSU=="T" then d=1e12; // tera
elseif pfSU=="P" then d=1e15; // peta
elseif pfSU=="E" then d=1e18; // exa
else
mprintf("¡¡ Opción no implementada !! \( función prefSU \) \n")
end
endfunction //function [d]=pfSI(pfSU)
Si creamos un objeto escalar, por ejemplo:
ε0=escalar_new(8.854187817,["p" "F/m"],"Permitividad del espacio libre : ε0");
Y comprobamos su valor, introduciendo en la consola ε0, obtendríamos
ε0 = (TEscalar tlist) with fields: Valor = 8.854D-12 Unid = "F/m" Alias = "Permitividad del espacio libre : ε0" UdPref = ["p","F/m"]
Donde se pueden ver todos los campos, que contiene el objeto TEscalar, pero no es la presentación que yo deseaba para mis Pseudo-Objetos TEscalar; por lo cual cree dos funciones más, la primera:
function str=%TEscalar_string(this) // v1.1
//Modificado para incluir idea 1 presentar en unidades preferidas (indicadas al crearlo)
if this.Unid=="" then // if ~exists(this.UdPref(2)) then // esto no sirve
// if ~exists(this.Unid) then // esto tampoco
pUnid=""; fdE=1 //
elseif (type(this.UdPref))==10&(size(this.UdPref)(2)==1) then
if (this.UdPref=="º")|(this.UdPref=="°") then
pUnid=this.UdPref; fdE=1;
else
pUnid=" "+this.UdPref; fdE=1;
end
elseif (type(this.UdPref))==10&(size(this.UdPref)(2)==2) then
pUnid=" "+strcat(this.UdPref); fdE=pfSI(this.UdPref(1)); // mprintf(" prefijo y unidad \n");
else //~exists("Unid") or tipos definidos
errmsg = msprintf (" %TEscalar_string: no admite el parámetro introducido en Unid : %s",this.UdPref);
error ( errmsg )
end //~exists("Unid")
ValorEscalado=this.Valor/fdE;
// crea string de TEscalar
if isreal(this.Valor) then
str=" "+this.Alias+" = "+string(ValorEscalado)+pUnid;
else // número complejo
pReal=real(ValorEscalado);pImag=imag(ValorEscalado);apImag=abs(pImag);
if pImag<0 then txta=" - j "; else txta=" + j "; end
str=" "+this.Alias+" = "+string(pReal)+txta+string(apImag)+" "+pUnid;
end
endfunction // function str=%TEscalar_string(this) // v1.1
Esta función proporciona un string (con el formato que yo deseo) de los objetos (voy a dejar de escribir pseudo) TEscalar, y es llamada por funciones que manipulen strings.
En concreto si modificamos la función que presenta los objetos de Scilab en pantalla.
function %TEscalar_p(this)
// presenta en pantalla el string de TEscalar
mprintf(string(this));
endfunction
Ya se aprecia el multimorfismo que nos permite Scilab, la función _p se puede definir para diferentes tipos de objetos (en otros posts presentaré las funciones para TPuntos y TVectores).
Si ahora consultamos del valor de ε0, en la consola obtendremos:
--> ε0 ε0 = (TEscalar tlist) with fields: Permitividad del espacio libre : ε0 = 8.8541878 pF/m
Obteniendo la presentación que deseaba.
En el siguiente post, desarrollaré operaciones con los TEscalares, aprovechando el multimorfismo que permite Scilab.
Postdata
Un escalar sólo tiene una magnitud o valor numérico.
Observación de Blogger: al introducir el código he tenido que cambiar el > por > y < por < sino Blogger lo mal interpretaba y cortaba el contenido.
Comentarios
Publicar un comentario