Este post, es la respuesta en base a un mail que me envio Deiv.
La idea de este post, es mostrar y dar algunas ideas de como organizar un proyecto grande de contruccion de una tabla periodica didactica.
Lo primero que se debe considerar, son las clases de los elementos de las tablas periodicas, estos pueden ser
metalesy
no metales. Asi pues conformariamos un tipo de dato llamado
Grupo así:
TGrupo = (gMetal, gNoMetal); //g minuscula quiere decir grupo
A su vez, los dos grandes gurpos se dividen en varios subgrupos; para los metales estan los alcalinos, alcalinos terreos... y para los no metales estan los halogenos, carbanoides, nitrogenoides....
Hay que tener cuidado en no tener asignado un subgrupo a un elemento que pertenece a otro grupo cosa que puede ser hecha usando una propiedad, desgracadiamente siempre uno esta ante el error de asignar un subgrupo metalico incorrecto a un metal,eso solo se puede prevenir prestando mucha atencion

.
TSubGrupo = (sgAlcalino, sgHalogeno, sgAlcalinoTerreo, sgCarbonoide);
//"sg" quiere decir sub_grupo
Asi, para seguir una estructura, nuestra Clase de un Elemento quimico quedaria por ahora en:
TElemento = class
private
FSubGrupo: TSubGrupo;
procedure SetSubGrupo(const Value: TSubGrupo);
public
Grupo: TGrupo;
property SubGrupo: TSubGrupo read FSubGrupo write SetSubGrupo;
end;
........
procedure TElemento.SetSubGrupo(const Value: TSubGrupo);
begin
//EsMetal() es una funcion que devulve true si el subrupo pertenece a los metales...
//hace muchos ifs nada mas :P
if (Grupo=gMetal) and (not EsMetal(Value)) then
begin
ERangeError.Create('Esta asignano a un Metal un subgrupo de un NoMetal!')
Exit;
end
else if (Grupo=gNoMetal) and (EsMetal(Value)) then
begin
ERangeError.Create('Esta asignano a un Metal un subgrupo de un NoMetal!')
Exit;
end;
FSubGrupo := Value;
end;
Ahora vamos con las propiedades necesarias basicas empezando primero por las sencillas:
TElemento = class
private
FSubGrupo: TSubGrupo;
procedure SetSubGrupo(const Value: TSubGrupo);
public
NumeroAtomico: Byte;
MasaAtomica: Single;
PesoAtomico: Single;
Densidad: Single;
PuntoFusion: Single;
PuntoEbullicion: Single;
Simbolo: String[2]; //H, He, Li, Be, B, C, N, O, F, Ne....
Electronegativiad: Single;
Grupo: TGrupo;
property SubGrupo: TSubGrupo read FSubGrupo write SetSubGrupo;
end;
La que me falto es el
Nro. Oxidacion o como antes se le decia, el Numero de Valencia.
Este es particular porque son varios numeros segun el elemento, la cantidad de esos numeros puede ser 1,2,3,4, 5 y 0 para los gases inhertes.
El valor ronda entre -3 y +7
Lo mas facil seria tener un array con 5 elementos y un numero que indique cuantos valores de ese array son validos.
CantidadNrosOxidacion: Byte;
NroOxidacion: array[1..5] of ShortInt;
Por ejemplo, el Hidrogeno tiene un solo numero de oxidacion, por eso:
CantidadNrosOxidacion = 1;
NroOxidacion[1] = 1;
El Cloro tiene 5:
CantidadNrosOxidacion = 5;
NroOxidacion[1] = -1;
NroOxidacion[2] = 1;
NroOxidacion[3] = 3;
...
respecto a las
terminaciones para la formacion de sales que son
oso, ico y lo prefijos
hipo y
perLa cosa este respecto de CantidadNrosOxidacion:
Si son 2entonces para el NroOxidacion[1] se usa iso (el menor si no me equivoco)
y pra NroOxidacion[2] se usa ico
Si son 4para el NroOxidacion[1] hipo-oso
....esta parte me la salteo, es como en el caso anterior pero con el numero 2,3
para el NroOxidacion[4] per-ico
Como saber con que valencia actua cada elemento?
Con el que quiera, todo depende de las circunstancias de la reaccion quimica, en el caso del hiero el numero oxidacion puede ser 2 o 3 por lo que forma con oxigeno FeO y Fe2O3. Generalmente se forman las dos en distintas proporciones.
cargando datosLo mas facil seria tener archivos con los datos para cada elemento quimico, como ejemplo usaremos archivos de text. El titulo del archivo de texto es comodo que sea el numero atomico: 1.xt, 2.txt, 3.txt.....
El contenido seria algo asi (";" representa comentarios):
;simbolo
He
;grupo: 0 metal, 1 no metal
1
;nro atomico
1
;peso atomico
1.00079
;cantidad numeros oxidacion
1
;nro oxidacion
1
;densidad
0.071
;etc..............
Asi que tendriamos agregar a nuestra clase de TElemento un metodo para cargar datos desde un archivo de texto.
TElemento = class
private
FSubGrupo: TSubGrupo;
procedure SetSubGrupo(const Value: TSubGrupo);
public
NumeroAtomico: Byte;
MasaAtomica: Single;
PesoAtomico: Single;
Densidad: Single;
PuntoFusion: Single;
PuntoEbullicion: Single;
Simbolo: String[2]; //H, He, Li, Be, B, C, N, O, F, Ne....
Electronegativiad: Single;
Grupo: TGrupo;
property SubGrupo: TSubGrupo read FSubGrupo write SetSubGrupo;
**********
procedure LoadFromFile(const FileName: String);
end;
Ahora simplemente se podria hacer
TTablaPeriodica = class
public
........
Elemento: array[1..103] of TElemento;
..........
constructor Create;
end;
constructor TTAblaPeriodica.Create;
begin
inherited Create;
for i:=1 to 103 do
Elemento[i].LoadFromFile(IntToStr(i) + '.txt');
end;
Para Aceder a cualquier elemento de la tabla, es mediante el numero atomico:
WriteLn(TAblaPeriodica.Elemento[1].Simbolo); //da como salida: "H"
PD: Deiv, espero que esto te de una pauta, si siguies teniendo dudas, puedes preguntar tranquilamente en este post, inclusive, si lo deseas, adjunta aqui el PDF que me mandaste con las preguntas.
Saludos