add searching by element name
This commit is contained in:
parent
b70511f47b
commit
87f446b8c9
2
dune
2
dune
|
@ -1,5 +1,5 @@
|
||||||
(executable
|
(executable
|
||||||
(name elements)
|
(name elements)
|
||||||
(modules Elements Makedb)
|
(modules Elements Makedb Elements_search)
|
||||||
(libraries sqlite3 yojson batch_jaro_winkler)
|
(libraries sqlite3 yojson batch_jaro_winkler)
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,7 @@ module Opts = struct
|
||||||
let jsonf = ref ""
|
let jsonf = ref ""
|
||||||
|
|
||||||
(** Limit the amount of matches. *)
|
(** Limit the amount of matches. *)
|
||||||
let maxmatch = ref 3
|
let maxmatch = ref 1
|
||||||
|
|
||||||
(** Lists to search. *)
|
(** Lists to search. *)
|
||||||
|
|
||||||
|
@ -68,3 +68,6 @@ let _ = if !Opts.jsonf <> "" then
|
||||||
else
|
else
|
||||||
Yojson.Basic.from_file !Opts.jsonf
|
Yojson.Basic.from_file !Opts.jsonf
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let () = if !Opts.match_name <> [] then
|
||||||
|
Elements_search.print_by_name db !Opts.maxmatch (List.rev !Opts.match_name)
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
type elem = {
|
||||||
|
num : int;
|
||||||
|
symb : string;
|
||||||
|
name : string;
|
||||||
|
mass : float option;
|
||||||
|
cpk_color : string option;
|
||||||
|
e_config : string option;
|
||||||
|
e_neg : float option;
|
||||||
|
rad : float option;
|
||||||
|
ionization_e : float option;
|
||||||
|
e_affinity : float option;
|
||||||
|
oxidation : string option;
|
||||||
|
state : string option;
|
||||||
|
melting : float option;
|
||||||
|
boiling : float option;
|
||||||
|
density : float option;
|
||||||
|
block : string option;
|
||||||
|
discovered : int option
|
||||||
|
}
|
||||||
|
|
||||||
|
let float_or_null stmt n = match (Sqlite3.column stmt n) with
|
||||||
|
| Sqlite3.Data.NULL -> None
|
||||||
|
| Sqlite3.Data.FLOAT x -> Some x
|
||||||
|
| _ -> raise (Failure (Printf.sprintf "Column %d has invalid type" n))
|
||||||
|
|
||||||
|
let string_or_null stmt n = match (Sqlite3.column stmt n) with
|
||||||
|
| Sqlite3.Data.NULL -> None
|
||||||
|
| Sqlite3.Data.TEXT x -> Some x
|
||||||
|
| _ -> raise (Failure (Printf.sprintf "Column %d has invalid type" n))
|
||||||
|
|
||||||
|
let int_or_null stmt n = match (Sqlite3.column stmt n) with
|
||||||
|
| Sqlite3.Data.NULL -> None
|
||||||
|
| Sqlite3.Data.INT x -> Some (Int64.to_int x)
|
||||||
|
| _ -> raise (Failure (Printf.sprintf "Column %d has invalid type" n))
|
||||||
|
|
||||||
|
let chk = function
|
||||||
|
| Sqlite3.Rc.ROW -> ()
|
||||||
|
| Sqlite3.Rc.OK -> ()
|
||||||
|
| _ -> raise (Failure "statement failure")
|
||||||
|
|
||||||
|
let get_model db typ =
|
||||||
|
let open Sqlite3
|
||||||
|
in let stmt = "SELECT dat FROM searchtable WHERE name = ?;"
|
||||||
|
|> prepare db
|
||||||
|
in
|
||||||
|
bind_text stmt 1 typ |> Rc.check;
|
||||||
|
step stmt |> chk;
|
||||||
|
let v = column_blob stmt 0
|
||||||
|
in
|
||||||
|
finalize stmt |> Rc.check;
|
||||||
|
Batch_jaro_winkler.build_runtime_model v
|
||||||
|
|
||||||
|
let search_model most model s =
|
||||||
|
let open Batch_jaro_winkler
|
||||||
|
in let encoding = Encoding.UTF8
|
||||||
|
in jaro_winkler_distance ~encoding ~n_best_results:most model s
|
||||||
|
|
||||||
|
let by_name n db s = search_model n (get_model db "name") s
|
||||||
|
|
||||||
|
let name_stmt db s =
|
||||||
|
let open Sqlite3
|
||||||
|
in let stmt = "SELECT \
|
||||||
|
num, symb, name, mass, cpk_color, e_config, e_neg, rad, \
|
||||||
|
ionization_e, e_affinity, oxidation, state, melting, \
|
||||||
|
boiling, density, block, discovered \
|
||||||
|
FROM elements WHERE name = ?;"
|
||||||
|
|> prepare db
|
||||||
|
in bind_text stmt 1 s |> Rc.check;
|
||||||
|
stmt
|
||||||
|
|
||||||
|
let get_elem_from_stmt stmt =
|
||||||
|
let open Sqlite3
|
||||||
|
in
|
||||||
|
step stmt |> chk; {
|
||||||
|
num = column_int stmt 0;
|
||||||
|
symb = column_text stmt 1;
|
||||||
|
name = column_text stmt 2;
|
||||||
|
mass = float_or_null stmt 3;
|
||||||
|
cpk_color = string_or_null stmt 4;
|
||||||
|
e_config = string_or_null stmt 5;
|
||||||
|
e_neg = float_or_null stmt 6;
|
||||||
|
rad = float_or_null stmt 7;
|
||||||
|
ionization_e = float_or_null stmt 8;
|
||||||
|
e_affinity = float_or_null stmt 9;
|
||||||
|
oxidation = string_or_null stmt 10;
|
||||||
|
state = string_or_null stmt 11;
|
||||||
|
melting = float_or_null stmt 12;
|
||||||
|
boiling = float_or_null stmt 13;
|
||||||
|
density = float_or_null stmt 14;
|
||||||
|
block = string_or_null stmt 15;
|
||||||
|
discovered = int_or_null stmt 16
|
||||||
|
}
|
||||||
|
|
||||||
|
let get_elem db s = name_stmt db s |> get_elem_from_stmt
|
||||||
|
|
||||||
|
let print_elem e =
|
||||||
|
let p_str name = Option.iter (fun x ->
|
||||||
|
Printf.printf "%s: %s\n" name x)
|
||||||
|
in let p_flt name = Option.iter (fun x ->
|
||||||
|
Printf.printf "%s: %f\n" name x)
|
||||||
|
in let p_int name = Option.iter (fun x ->
|
||||||
|
Printf.printf "%s: %d\n" name x)
|
||||||
|
in Printf.printf "'%s' -- '%s' -- '%d'\n" e.name e.symb e.num;
|
||||||
|
p_flt "Standard Atomic Mass" e.mass;
|
||||||
|
p_str "CPK Color" e.cpk_color;
|
||||||
|
p_str "Electron Configuration" e.e_config;
|
||||||
|
p_flt "Electronegativity (Pauling)" e.e_neg;
|
||||||
|
p_flt "Van der Walls (pm)" e.rad;
|
||||||
|
p_flt "Ionization Energy (eV)" e.ionization_e;
|
||||||
|
p_flt "Electron Affinity (eV)" e.e_affinity;
|
||||||
|
p_str "Oxidation States" e.oxidation;
|
||||||
|
p_str "Standard State" e.state;
|
||||||
|
p_flt "Melting Point (K)" e.melting;
|
||||||
|
p_flt "Boiling Point (K)" e.boiling;
|
||||||
|
p_flt "Density (g/cm³)" e.density;
|
||||||
|
p_str "Block" e.block;
|
||||||
|
p_int "Year Discovered" e.discovered;
|
||||||
|
print_newline()
|
||||||
|
|
||||||
|
let print_by_name db most l =
|
||||||
|
let serc = by_name (Some most) db
|
||||||
|
in let on_match v = (match serc (String.lowercase_ascii v) with
|
||||||
|
| [] -> Printf.printf "No matches found for '%s'\n" v;
|
||||||
|
| (m,p)::[] -> if m <> v then
|
||||||
|
Printf.printf
|
||||||
|
"Best match '%s' for '%s' (%.0f%%)\n"
|
||||||
|
m v (p *. 100.0);
|
||||||
|
get_elem db m |> print_elem
|
||||||
|
| l ->
|
||||||
|
Printf.printf "Matches for '%s'\n" v;
|
||||||
|
List.iter (fun (a,b) -> Printf.printf "%f -- %s\n" b a)
|
||||||
|
(List.rev l)
|
||||||
|
)
|
||||||
|
in List.iter on_match l
|
Loading…
Reference in New Issue