restructure + lecutre 07

This commit is contained in:
SowinskiBraeden committed 2026-02-19 11:59:58 -08:00
1 parent b8c19aa341
commit 7c3198fee4
96 files changed
+458 -4

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
"Rule: ocaml dependencies ml (%=records )": "\168\187\158\232\128I\157\015\216j\244\004\243\234\011\217"
"Rule: ocaml: ml & cmi -> cmx & o (%=records )": "5\144\205\021B\003\025\204\145\159\255\166t\136\140^"
"Resource: /home/flami/Projects/comp3958/lab04/records.ml": "\133\242qUUy2\188\b\134=\163c9\2142"
"Rule: ocaml: ml -> cmo & cmi (%=records )": "\026zi!\193g\255\238<\162\135s\021\142\001\012"
"Rule: ocaml: cmx* & o* -> native (%=records )": "C\176\141F\181\127\251\240\211V\156\t\167\208\129\177"
+12
View File
@@ -0,0 +1,12 @@
### Starting build.
# Target: /home/flami/.opam/default/bin/ocamlc.opt -config, tags: { }
/home/flami/.opam/default/bin/ocamlc.opt -config
# Target: records.ml.depends, tags: { extension:ml, file:records.ml, ocaml, ocamldep, quiet }
/home/flami/.opam/default/bin/ocamldep.opt -modules records.ml > records.ml.depends
# Target: records.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:records.cmo, file:records.ml, implem, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlc.opt -c -o records.cmo records.ml
# Target: records.cmx, tags: { compile, extension:cmx, extension:ml, file:records.cmx, file:records.ml, implem, native, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlopt.opt -c -o records.cmx records.ml
# Target: records.native, tags: { dont_link_with, extension:native, file:records.native, link, native, ocaml, program, quiet }
/home/flami/.opam/default/bin/ocamlopt.opt records.cmx -o records.native
# Compilation successful.
Binary file not shown.
+143
View File
@@ -0,0 +1,143 @@
(** [record] of a person with a first name, last name, and score *)
type record = {firstname: string; lastname: string; score: int};;
(** [print_records r] takes a list of records [r] and prints
* each record neatly to the console *)
let rec print_records r =
match r with
| [] -> ()
| x :: xs -> Printf.printf "%3d %s %s\n" x.score x.lastname x.firstname; print_records xs;;
(** [compare_records r1 r2] compares records [r1] and [r2] based
* on score, then by lastname, then by firstname.
*)
let compare_records r1 r2 =
compare
(r2.score, r2.lastname, r2.firstname)
(r1.score, r1.lastname, r1.firstname);;
(** [records_insert x l] inserts a record element [x] into
* list of records [l]
* Requires: [l] is in ascending order. *)
let rec records_insert x l =
match l with
| y :: ys when compare_records x y > 0 -> y :: records_insert x ys
| _ -> x :: l;;
(**/**)
let test_records_insert () =
assert (records_insert
{firstname = "a"; lastname = "b"; score = 1} [] =
[{firstname = "a"; lastname = "b"; score = 1}]
);
assert (records_insert
{firstname = "a"; lastname = "b"; score = 1}
[{firstname = "c"; lastname = "d"; score = 2}] =
[
{firstname = "c"; lastname = "d"; score = 2};
{firstname = "a"; lastname = "b"; score = 1}
]);
assert (records_insert
{firstname = "e"; lastname = "f"; score = 2}
[
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "a"; lastname = "b"; score = 1}
] =
[
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "e"; lastname = "f"; score = 2};
{firstname = "a"; lastname = "b"; score = 1}
]);;
(**/**)
(** [records_insertion_sort l] sorts list of records [l] in ascending order *)
let rec sort_records l =
match l with
| [] -> []
| x :: xs -> records_insert x (sort_records xs);;
(**/**)
let test_sort_records () =
assert (sort_records [] = []);
assert (sort_records
[{firstname = "a"; lastname = "b"; score = 1}] =
[{firstname = "a"; lastname = "b"; score = 1}]);
assert (sort_records [
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "a"; lastname = "b"; score = 1};
{firstname = "e"; lastname = "f"; score = 2};
] = [
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "e"; lastname = "f"; score = 2};
{firstname = "a"; lastname = "b"; score = 1};
]);;
(**/**)
(** [parse l] takes in a line [l] and parses the line to extract
* firstname, lastname, and score, returning Some record if successful
* or None if the input line [l] contains bad data *)
let rec parse l =
try
Scanf.sscanf l " %s %s %s" (fun f l s ->
match int_of_string_opt s with
| Some v when v >= 0 && v <= 100 -> Some {firstname = f; lastname = l; score = v}
| _ -> None
)
with
| Scanf.Scan_failure _ -> None;;
(**/**)
let test_parse () =
assert (parse "" = None);
assert (parse "Bart simpson 5abc" = None);
assert (parse "Lisa simpson 130" = None);
assert (parse "Homer Simpson -5" = None);
assert (parse "Homer Simpson 5" =
Some {firstname = "Homer"; lastname = "Simpson"; score = 5});
assert (parse "Homer Simpson 5 blah blah blah" =
Some {firstname = "Homer"; lastname = "Simpson"; score = 5});;
(**/**)
(** [read_file acc ic] takes in an accumulator [acc] and an input channel [ic]
* and oterates over it input channel [ic] to parse each line and store the
* parsed result into the accumulator [acc] *)
let rec read_file acc ic =
try
match parse @@ input_line ic with
| None -> read_file acc ic
| Some v -> read_file (v :: acc) ic
with
| End_of_file -> close_in ic; acc;;
(**/**)
let test_read_file () =
assert (read_file [] @@ open_in "data.txt" = [
{firstname = "gary"; lastname = "chalmers"; score = 5};
{firstname = "waylon"; lastname = "smithers"; score = 100};
{firstname = "homer"; lastname = "simpson"; score = 25};
]);
assert (read_file [] @@ open_in "data1.txt" = [
{firstname = "gary"; lastname = "chalmers"; score = 5};
{firstname = "waylon"; lastname = "smithers"; score = 100};
{firstname = "ned"; lastname = "flanders"; score = 12};
{firstname = "homer"; lastname = "simpson"; score = 25};
]);
assert (read_file [] @@ open_in "data2.txt" = []);;
(**/**)
(**/**)
let run_all_tests () =
test_parse();
test_read_file();
test_records_insert();
test_sort_records();;
(**/**)
(** main program entry from cli *)
let () =
if Array.length Sys.argv = 1 then
Printf.printf "%s: expects 1 file input.\nUsage: \"%s <filename>\"\n" Sys.argv.(0) Sys.argv.(0)
else
let ic = open_in Sys.argv.(1) in
print_records @@ sort_records @@ read_file [] ic;;
+1
View File
@@ -0,0 +1 @@
records.ml: Array Printf Scanf Sys
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
homer simpson 25 # bad at nuclear engineering
ned flanders 12abc !! invalid
waylon smithers 100 ! high score
gary chalmers 5
monty burns
+5
View File
@@ -0,0 +1,5 @@
homer simpson 25 # bad at nuclear engineering
ned flanders 12 !! valid
waylon smithers 100 ! high score
gary chalmers 5
monty burns
+1
View File
@@ -0,0 +1 @@
monty burns
+160
View File
@@ -0,0 +1,160 @@
(** [record] of a person with a first name, last name, and score *)
type record = {firstname: string; lastname: string; score: int};;
(** [print_records r] takes a list of records [r] and prints
* each record neatly to the console *)
let rec print_records r =
match r with
| [] -> ()
| x :: xs -> Printf.printf "%3d %s %s\n" x.score x.lastname x.firstname; print_records xs;;
(** [compare_records r1 r2] compares records [r1] and [r2] based
* on score, then by lastname, then by firstname.
*)
let compare_records r1 r2 =
compare
(r2.score, r2.lastname, r2.firstname)
(r1.score, r1.lastname, r1.firstname);;
(**/**)
let test_compare_records () =
assert (compare_records
{firstname = "homer"; lastname = "simpson"; score = 10}
{firstname = "marge"; lastname = "simpson"; score = 25}
> 0);
assert (compare_records
{firstname = "bart"; lastname = "simpson"; score = 25}
{firstname = "marge"; lastname = "simpson"; score = 25}
> 0);
assert (compare_records
{firstname = "marge"; lastname = "simpson"; score = 25}
{firstname = "bart"; lastname = "simpson"; score = 25}
< 0);;
(**/**)
(** [records_insert x l] inserts a record element [x] into
* list of records [l]
* Requires: [l] is in ascending order. *)
let rec records_insert x l =
match l with
| y :: ys when compare_records x y > 0 -> y :: records_insert x ys
| _ -> x :: l;;
(**/**)
let test_records_insert () =
assert (records_insert
{firstname = "a"; lastname = "b"; score = 1} [] =
[{firstname = "a"; lastname = "b"; score = 1}]
);
assert (records_insert
{firstname = "a"; lastname = "b"; score = 1}
[{firstname = "c"; lastname = "d"; score = 2}] =
[
{firstname = "c"; lastname = "d"; score = 2};
{firstname = "a"; lastname = "b"; score = 1}
]);
assert (records_insert
{firstname = "e"; lastname = "f"; score = 2}
[
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "a"; lastname = "b"; score = 1}
] =
[
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "e"; lastname = "f"; score = 2};
{firstname = "a"; lastname = "b"; score = 1}
]);;
(**/**)
(** [records_insertion_sort l] sorts list of records [l] in ascending order *)
let rec sort_records l =
match l with
| [] -> []
| x :: xs -> records_insert x (sort_records xs);;
(**/**)
let test_sort_records () =
assert (sort_records [] = []);
assert (sort_records
[{firstname = "a"; lastname = "b"; score = 1}] =
[{firstname = "a"; lastname = "b"; score = 1}]);
assert (sort_records [
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "a"; lastname = "b"; score = 1};
{firstname = "e"; lastname = "f"; score = 2};
] = [
{firstname = "c"; lastname = "d"; score = 3};
{firstname = "e"; lastname = "f"; score = 2};
{firstname = "a"; lastname = "b"; score = 1};
]);;
(**/**)
(** [parse l] takes in a line [l] and parses the line to extract
* firstname, lastname, and score, returning Some record if successful
* or None if the input line [l] contains bad data *)
let rec parse l =
try
Scanf.sscanf l " %s %s %s" (fun f l s ->
match int_of_string_opt s with
| Some v when v >= 0 && v <= 100 -> Some {firstname = f; lastname = l; score = v}
| _ -> None
)
with
| Scanf.Scan_failure _ -> None;;
(**/**)
let test_parse () =
assert (parse "" = None);
assert (parse "Bart simpson 5abc" = None);
assert (parse "Lisa simpson 130" = None);
assert (parse "Homer Simpson -5" = None);
assert (parse "Homer Simpson 5" =
Some {firstname = "Homer"; lastname = "Simpson"; score = 5});
assert (parse "Homer Simpson 5 blah blah blah" =
Some {firstname = "Homer"; lastname = "Simpson"; score = 5});;
(**/**)
(** [read_file acc ic] takes in an accumulator [acc] and an input channel [ic]
* and oterates over it input channel [ic] to parse each line and store the
* parsed result into the accumulator [acc] *)
let rec read_file acc ic =
try
match parse @@ input_line ic with
| None -> read_file acc ic
| Some v -> read_file (v :: acc) ic
with
| End_of_file -> close_in ic; acc;;
(**/**)
let test_read_file () =
assert (read_file [] @@ open_in "data.txt" = [
{firstname = "gary"; lastname = "chalmers"; score = 5};
{firstname = "waylon"; lastname = "smithers"; score = 100};
{firstname = "homer"; lastname = "simpson"; score = 25};
]);
assert (read_file [] @@ open_in "data1.txt" = [
{firstname = "gary"; lastname = "chalmers"; score = 5};
{firstname = "waylon"; lastname = "smithers"; score = 100};
{firstname = "ned"; lastname = "flanders"; score = 12};
{firstname = "homer"; lastname = "simpson"; score = 25};
]);
assert (read_file [] @@ open_in "data2.txt" = []);;
(**/**)
(**/**)
let run_all_tests () =
test_parse();
test_read_file();
test_compare_records();
test_records_insert();
test_sort_records();;
(**/**)
(** main program entry from cli *)
let () =
if Array.length Sys.argv = 1 then
Printf.printf "%s: expects 1 file input.\nUsage: \"%s <filename>\"\n" Sys.argv.(0) Sys.argv.(0)
else
let ic = open_in Sys.argv.(1) in
print_records @@ sort_records @@ read_file [] ic;;