Je cherche a crée un calculateur de masse molaire en php + mysql J'ai cherché des exemples sur le net mais je ne trouve rien J'ai stocké tous mes éléments (nom de l'atome, symbole, masse atomique) dans une base de donnée et j'aimerais calculer lamasse molaire d'une molécule saisie dans un champ de texte (ex :Ca(NO3)2*4H2O), mais je ne sais pas quelle technique employer pour décomposer cette chaîne J'ai pensé aux expressions régulières mais je suis novice... Des idées ?
Voila ce que j'ai fais pour le moment :
//le formulaire est posté...traitement
if ($_POST['molecule']!=""){
$molecule=$_POST['molecule'];
/*expression pour tous les caracteres :('#(?=[\(\)A-Z0-9\*])#', $molecule, -1, PREG_SPLIT_NO_EMPTY)*/
$elements = preg_split ('/[\(\)\*0-9]/', $molecule, -1, PREG_SPLIT_NO_EMPTY);
for ($i=0;$i<count($elements);$i++){
//requete mysqli
$result = $mysqli->query("SELECT symbole,masse_atomique FROM MEEM.atome where symbole ='$elements[$i]' ");
//on affiche les resultats
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
print "la masse atomique de ".$row['symbole']." est de :";
print $row['masse_atomique']."<br>";
}
Tu ne peux pas te contenter de ça à mon avis, il faut que tu détermines notamment à quoi se rapportent les nombres : par exemple dans NO3, le 3 se rapporte à O (devant), alors que dans 4H2O, le 2 se rapporte à O (derrière) et non à H.
Bref, il faut soit que tu aies un délimiteur, soit que tu aies en dur les molécules "possibles" quelque part pour les isoler dans un premier temps.
par exemple dans NO3, le 3 se rapporte à O (devant), alors que dans 4H2O, le 2 se rapporte à O (derrière) et non à H
Mmm, je pense que dans la seconde partie, tu voulais parler du 4 et non du 2 ? Parce que ce dernier se rapporte bien au H, donc pas de changement de paradigme ici
Mais effectivement, il va peut-être falloir définir la manière de saisir l'équation, et cela pourrait impliquer de saisir des parenthèses supplémentaires. Actuellement avec ce seul exemple, on pourrait imaginer que tout nombre après une parenthèse fermante multiplie ce qui s'y trouve, et tout nombre après un opérateur multiplie ce qui vient après. Mais sans réfléchir plus, je serais incapable de dire s'il y aura des cas qui ne joueraient pas avec cette hypothèse.
Mmm, je pense que dans la seconde partie, tu voulais parler du 4 et non du 2 ? Parce que ce dernier se rapporte bien au H, donc pas de changement de paradigme ici
En fait oui il faut prendre compte des indices ex H2O (deux molécules d'hydrogène) et les exposants 4(H2O) (4 molécules d'eau) Festin , non ta décomposition n'est pas utilisable pour ce cas de figure
Philodick ta suggestion d'identifier les nombres est correcte, mais je ne sais pas comment faire Des pistes ?
Philodick ta suggestion d'identifier les nombres est correcte, mais je ne sais pas comment faire
Des pistes ?
Sauf erreur de ma part, ça me semble être la partie facile du problème. Je ne suis pas chimiste et je ne connais donc pas toutes les règles d'écritures: est-ce que les parenthèses sont les seules qui servent à regrouper ? Est-ce qu'il peut y avoir plusieurs niveaux de parenthèses ? Est-ce qu'il y une convention pour altérer le poids d'un atome tel que l'uranium 235 ? etc... S'il faut seulement compter les atomes avec de possibles niveaux de parenthèses.
$molecules = [
'Ca(NO3)2*4H2O',
'C2H3O2',
'Fe4(Fe(CN)6)3',
];
foreach($molecules as $molecule) {
// d'abord résoudre les niveaux des parenthèses
$atomes = $molecule;
while(preg_match('#\([^()]+\)#', $atomes)) { // tant qu'il reste une paire de parenthèse
$atomes = preg_replace_callback( // résoudre les parenthèse du niveau le plus élevé
'#\(((?:(?>[^()]+)|(?R))*)\)(\d*)#',
function($parentheses) {
if(empty($parentheses[2])) return $parentheses[1];
return str_repeat($parentheses[1], $parentheses[2]);
},
$atomes
);
}
// ensuites résoudre les multiples
$atomes = preg_replace_callback(
['#([A-Z][a-z]?)(\d+)#', '#(\d+)([A-Z]+)#i', '#[^A-Z]#i'],
function($item) {
if(!isset($item[1])) return '';
list($atome, $multiple) = ctype_digit($item[1]) ? [$item[2], $item[1]] : [$item[1], $item[2]];
return str_repeat($atome, $multiple);
},
$atomes
);
// compter les atomes
$compter_atomes = array_count_values(preg_split('#([A-Z][a-z]?)\K(?=(?1))#', $atomes));
// afficher
echo "<pre>$molecule\n", print_r($compter_atomes, true), '</pre>';
}
/*
Ca(NO3)2*4H2O
Array
(
[Ca] => 1
[N] => 2
[O] => 10
[H] => 8
)
C2H3O2
Array
(
[C] => 2
[H] => 3
[O] => 2
)
Fe4(Fe(CN)6)3
Array
(
[Fe] => 7
[C] => 18
[N] => 18
)
*/
Pour ce qui est des niveaux de parenthèses, en principe pour une molécule il n'y a que le niveau cité.
Concernant les altérations de poids il n'en est pas question ici, ce n'est qu'un simple calcul de molécule en fonction des éléments et des coefficients multiplicateurs
En effectuant une recherche web sur Ca(NO3)2*4H2O j'ai vu la formule du bleu de prusse que la plupart des sites semblent écrire Fe4[Fe(CN)6]3 mais qui semblent tous accepter Fe4(Fe(CN)6)3 ou Fe4[Fe[CN]6]3 d'où mes 2 premières questions. Je constate que mon traitement des parenthèses par while() n'est pas assez inclusif et devrait produire des erreurs dans le cas où la parenthèse débute par un nombre, facile à résoudre en récursion: alors [] ou pas [] telle est la question.
Calcul de masse molaire
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
N'oubliez pas d'activer les erreurs PDO.
Keep It Simple Stupid - SF4 conf Swift - Cours 1/4 SF4 - Exceptions PDO - Formes Normales
N'oubliez pas d'activer les erreurs PDO.