Final Touches
This commit is contained in:
parent
7d98a638b4
commit
3ab839e543
@ -50,10 +50,9 @@ Contributions are welcome! Please follow the steps at https://gitmoss.fyi/GitMos
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
|
||||||
|
|
||||||
## Acknowledgments
|
## Notes
|
||||||
|
|
||||||
- Inspired by the need for critical thinking in AI education.
|
- Special thanks to Seth Poulsen and his AI Applications in Education course at Utah State University.
|
||||||
- Special thanks to the AI Applications in Education course team at Utah State University.
|
- Portions of this work are produced by generative AI, but all content is manually reviewed and edited.
|
||||||
- Open-source contributors and the developer community.
|
|
@ -1,6 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{files, learner::profile, printers::{self, clear_console, print_boxed, print_screen}, utilities::questions::{ask_mcq, ask_multi_select, ask_plaintext}, Module};
|
use crate::{files, learner::profile, printers::{self, clear_console, print_boxed, print_screen}, utilities::{generators::random_affirmation, questions::{ask_mcq, ask_multi_select, ask_plaintext}}, Module};
|
||||||
use super::units;
|
use super::units;
|
||||||
|
|
||||||
const REQUIRED_FOR_MASTERY: f64 = 0.1;
|
const REQUIRED_FOR_MASTERY: f64 = 0.1;
|
||||||
@ -97,7 +97,7 @@ pub fn inner_loop(unit: Module, learner: &mut profile::Learner) {
|
|||||||
print_screen(&screen.text);
|
print_screen(&screen.text);
|
||||||
}
|
}
|
||||||
ScreenType::Mcq => {
|
ScreenType::Mcq => {
|
||||||
let options: Vec<&str> = screen.options.as_ref().unwrap().iter().map(|s| s.as_str()).collect();
|
// let options: Vec<&str> = screen.options.as_ref().unwrap().iter().map(|s| s.as_str()).collect();
|
||||||
let mut options = screen.options.clone().unwrap();
|
let mut options = screen.options.clone().unwrap();
|
||||||
options.push("Get hint".to_string());
|
options.push("Get hint".to_string());
|
||||||
let options: Vec<&str> = options.iter().map(|s| s.as_str()).collect();
|
let options: Vec<&str> = options.iter().map(|s| s.as_str()).collect();
|
||||||
@ -129,7 +129,7 @@ pub fn inner_loop(unit: Module, learner: &mut profile::Learner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScreenType::Checkboxes => {
|
ScreenType::Checkboxes => {
|
||||||
let options: Vec<&str> = screen.options.as_ref().unwrap().iter().map(|s| s.as_str()).collect();
|
// let options: Vec<&str> = screen.options.as_ref().unwrap().iter().map(|s| s.as_str()).collect();
|
||||||
let mut options = screen.options.clone().unwrap();
|
let mut options = screen.options.clone().unwrap();
|
||||||
options.push("Get hint".to_string());
|
options.push("Get hint".to_string());
|
||||||
let options: Vec<&str> = options.iter().map(|s| s.as_str()).collect();
|
let options: Vec<&str> = options.iter().map(|s| s.as_str()).collect();
|
||||||
@ -139,7 +139,7 @@ pub fn inner_loop(unit: Module, learner: &mut profile::Learner) {
|
|||||||
let selected_indices: Vec<usize> = answers.iter().filter_map(|answer| options.iter().position(|x| *x == *answer)).collect();
|
let selected_indices: Vec<usize> = answers.iter().filter_map(|answer| options.iter().position(|x| *x == *answer)).collect();
|
||||||
let correct = selected_indices.iter().all(|&index| correct_indices.contains(&index)) && selected_indices.len() == correct_indices.len();
|
let correct = selected_indices.iter().all(|&index| correct_indices.contains(&index)) && selected_indices.len() == correct_indices.len();
|
||||||
if correct {
|
if correct {
|
||||||
print_boxed("Correct!", printers::StatementType::CorrectFeedback);
|
print_boxed(&format!("Correct! {}", random_affirmation()), printers::StatementType::CorrectFeedback);
|
||||||
learner.update_progress(unit.clone(), true);
|
learner.update_progress(unit.clone(), true);
|
||||||
learner.progress.get_mut(&unit).unwrap().print_progress();
|
learner.progress.get_mut(&unit).unwrap().print_progress();
|
||||||
break;
|
break;
|
||||||
|
@ -90,12 +90,12 @@ impl Tracker {
|
|||||||
self.milestones_completed as f64 / self.milestones as f64
|
self.milestones_completed as f64 / self.milestones as f64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_milestones(&self) -> usize {
|
// pub fn get_milestones(&self) -> usize {
|
||||||
self.milestones
|
// self.milestones
|
||||||
}
|
// }
|
||||||
pub fn get_milestones_completed(&self) -> usize {
|
// pub fn get_milestones_completed(&self) -> usize {
|
||||||
self.milestones_completed
|
// self.milestones_completed
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn print_progress(&self) {
|
pub(crate) fn print_progress(&self) {
|
||||||
let (cols, _) = size().unwrap();
|
let (cols, _) = size().unwrap();
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use rand::{rng, seq::IndexedRandom};
|
// use rand::{rng, seq::IndexedRandom};
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
// use strum_macros::EnumIter;
|
// use strum_macros::EnumIter;
|
||||||
|
|
||||||
/// Module defines the structure and data for the course units, including lessons and modules.
|
/// Module defines the structure and data for the course units, including lessons and modules.
|
||||||
@ -40,16 +38,16 @@ impl Module {
|
|||||||
Module::Appraisal(appraisal) => format!("data/appraisal/{}.json", appraisal.get_filename()),
|
Module::Appraisal(appraisal) => format!("data/appraisal/{}.json", appraisal.get_filename()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
Module::Logic(Logic::random()),
|
// Module::Logic(Logic::random()),
|
||||||
Module::Fallacy(Fallacy::random()),
|
// Module::Fallacy(Fallacy::random()),
|
||||||
Module::Bias(Bias::random()),
|
// Module::Bias(Bias::random()),
|
||||||
Module::Appraisal(Appraisal::random()),
|
// Module::Appraisal(Appraisal::random()),
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
pub fn iter() -> impl Iterator<Item = Self> {
|
pub fn iter() -> impl Iterator<Item = Self> {
|
||||||
vec![
|
vec![
|
||||||
Module::Introduction,
|
Module::Introduction,
|
||||||
@ -125,11 +123,11 @@ impl Logic {
|
|||||||
Logic::BooleanAlgebra => "boolean_algebra".to_string(),
|
Logic::BooleanAlgebra => "boolean_algebra".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [Logic::LogicalOperations, Logic::BooleanAlgebra];
|
// let variants = [Logic::LogicalOperations, Logic::BooleanAlgebra];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fallacy module, which includes various lessons related to logical fallacies and errors in reasoning.
|
/// Fallacy module, which includes various lessons related to logical fallacies and errors in reasoning.
|
||||||
@ -158,14 +156,14 @@ impl Fallacy {
|
|||||||
Fallacy::InformalFallacy(informal) => format!("informal/{}", informal.get_filename()),
|
Fallacy::InformalFallacy(informal) => format!("informal/{}", informal.get_filename()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
Fallacy::FormalFallacy(FormalFallacy::random()),
|
// Fallacy::FormalFallacy(FormalFallacy::random()),
|
||||||
Fallacy::InformalFallacy(InformalFallacy::random()),
|
// Fallacy::InformalFallacy(InformalFallacy::random()),
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
/// Formal fallacies, which are errors in the structure of an argument.
|
/// Formal fallacies, which are errors in the structure of an argument.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||||
@ -199,16 +197,16 @@ impl FormalFallacy {
|
|||||||
FormalFallacy::QuantificationalFallacy => "quantificational".to_string(),
|
FormalFallacy::QuantificationalFallacy => "quantificational".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
FormalFallacy::PropositionalFallacy,
|
// FormalFallacy::PropositionalFallacy,
|
||||||
FormalFallacy::ProbabilisticFallacy,
|
// FormalFallacy::ProbabilisticFallacy,
|
||||||
FormalFallacy::SyllogisticFallacy,
|
// FormalFallacy::SyllogisticFallacy,
|
||||||
FormalFallacy::QuantificationalFallacy,
|
// FormalFallacy::QuantificationalFallacy,
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
/// Informal fallacies, which are errors in reasoning that do not involve the structure of the argument.
|
/// Informal fallacies, which are errors in reasoning that do not involve the structure of the argument.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||||
@ -272,26 +270,26 @@ impl InformalFallacy {
|
|||||||
InformalFallacy::BeggingTheQuestion => "begging_the_question".to_string(),
|
InformalFallacy::BeggingTheQuestion => "begging_the_question".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
InformalFallacy::PostHocErgoPropterHoc,
|
// InformalFallacy::PostHocErgoPropterHoc,
|
||||||
InformalFallacy::SlipperySlope,
|
// InformalFallacy::SlipperySlope,
|
||||||
InformalFallacy::TexasSharpshooter,
|
// InformalFallacy::TexasSharpshooter,
|
||||||
InformalFallacy::HastyGeneralization,
|
// InformalFallacy::HastyGeneralization,
|
||||||
InformalFallacy::OverGeneralization,
|
// InformalFallacy::OverGeneralization,
|
||||||
InformalFallacy::NoTrueScotsman,
|
// InformalFallacy::NoTrueScotsman,
|
||||||
InformalFallacy::QuotingOutOfContext,
|
// InformalFallacy::QuotingOutOfContext,
|
||||||
InformalFallacy::AdHominem,
|
// InformalFallacy::AdHominem,
|
||||||
InformalFallacy::TuQuoque,
|
// InformalFallacy::TuQuoque,
|
||||||
InformalFallacy::Bandwagon,
|
// InformalFallacy::Bandwagon,
|
||||||
InformalFallacy::StrawMan,
|
// InformalFallacy::StrawMan,
|
||||||
InformalFallacy::AdIgnorantiam,
|
// InformalFallacy::AdIgnorantiam,
|
||||||
InformalFallacy::SpecialPleading,
|
// InformalFallacy::SpecialPleading,
|
||||||
InformalFallacy::BeggingTheQuestion,
|
// InformalFallacy::BeggingTheQuestion,
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bias module, which includes various lessons related to cognitive biases and their impact on reasoning.
|
/// Bias module, which includes various lessons related to cognitive biases and their impact on reasoning.
|
||||||
@ -332,18 +330,18 @@ impl Bias {
|
|||||||
Bias::BarnumEffect => "barnum_effect".to_string(),
|
Bias::BarnumEffect => "barnum_effect".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
Bias::ConfirmationBias,
|
// Bias::ConfirmationBias,
|
||||||
Bias::TheHaloEffect,
|
// Bias::TheHaloEffect,
|
||||||
Bias::FundamentalAttributionError,
|
// Bias::FundamentalAttributionError,
|
||||||
Bias::InGroupBias,
|
// Bias::InGroupBias,
|
||||||
Bias::DunningKrugerEffect,
|
// Bias::DunningKrugerEffect,
|
||||||
Bias::BarnumEffect,
|
// Bias::BarnumEffect,
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
/// Appraisal module, which includes various lessons related to the evaluation and appraisal of arguments.
|
/// Appraisal module, which includes various lessons related to the evaluation and appraisal of arguments.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||||
@ -371,12 +369,12 @@ impl Appraisal {
|
|||||||
Appraisal::CounterArgument => "counter_argument".to_string(),
|
Appraisal::CounterArgument => "counter_argument".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn random() -> Self {
|
// pub(crate) fn random() -> Self {
|
||||||
let mut rng = rng();
|
// let mut rng = rng();
|
||||||
let variants = [
|
// let variants = [
|
||||||
Appraisal::ConversionToPropositional,
|
// Appraisal::ConversionToPropositional,
|
||||||
Appraisal::CounterArgument,
|
// Appraisal::CounterArgument,
|
||||||
];
|
// ];
|
||||||
variants.choose(&mut rng).unwrap().clone()
|
// variants.choose(&mut rng).unwrap().clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -60,16 +60,16 @@ impl Learner {
|
|||||||
clear_console();
|
clear_console();
|
||||||
|
|
||||||
let (cols, _) = size().unwrap();
|
let (cols, _) = size().unwrap();
|
||||||
let dashes = "-".repeat((cols as usize));
|
let dashes = "-".repeat(cols as usize);
|
||||||
let dots = " ".repeat((cols as usize).saturating_sub(42));
|
let dots = " ".repeat((cols as usize).saturating_sub(42));
|
||||||
|
|
||||||
println!("Progress Report for {}:", self.name);
|
println!("Progress Report for {}:", self.name);
|
||||||
println!("{}", dashes);
|
println!("{}", dashes);
|
||||||
println!("{}", format!(" Unit {} | Mastery |", dots).bold());
|
println!("{}", format!(" Unit {} | Mastery |", dots).bold());
|
||||||
|
|
||||||
let mut modules = units::Module::iter();
|
let modules = units::Module::iter();
|
||||||
for module in modules {
|
for module in modules {
|
||||||
if let Some(progress) = self.progress.get(&module) {
|
if let Some(_) = self.progress.get(&module) {
|
||||||
self.progress.get(&module).unwrap().print_progress();
|
self.progress.get(&module).unwrap().print_progress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::{fs::File, io::Read};
|
|||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
use crate::{course::story, learner::profile::{self, Learner}};
|
use crate::{course::story, learner::profile::Learner};
|
||||||
|
|
||||||
// pub fn save_learner_progress(learner: &Learner, file: &str) -> Result<(), std::io::Error> {
|
// pub fn save_learner_progress(learner: &Learner, file: &str) -> Result<(), std::io::Error> {
|
||||||
// learner.clone().save_to_file(file)?;
|
// learner.clone().save_to_file(file)?;
|
||||||
|
@ -69,7 +69,7 @@ const OFFENSIVE_TERMS: [&str; 20] = [
|
|||||||
"jew", "slut", "tit", "phag"
|
"jew", "slut", "tit", "phag"
|
||||||
];
|
];
|
||||||
|
|
||||||
const affirmations: [&str; 8] = [
|
const AFFIRMATIONS: [&str; 26] = [
|
||||||
"You're doing great!",
|
"You're doing great!",
|
||||||
"Keep up the good work!",
|
"Keep up the good work!",
|
||||||
"Fantastic effort!",
|
"Fantastic effort!",
|
||||||
@ -78,12 +78,30 @@ const affirmations: [&str; 8] = [
|
|||||||
"You're making progress!",
|
"You're making progress!",
|
||||||
"Keep it up!",
|
"Keep it up!",
|
||||||
"Great work!",
|
"Great work!",
|
||||||
|
"You're unstoppable!",
|
||||||
|
"Amazing progress!",
|
||||||
|
"You're crushing it!",
|
||||||
|
"Keep shining!",
|
||||||
|
"You're a star!",
|
||||||
|
"Outstanding work!",
|
||||||
|
"You're making a difference!",
|
||||||
|
"You're an inspiration!",
|
||||||
|
"You're reaching for the stars!",
|
||||||
|
"Keep shining like a supernova!",
|
||||||
|
"You're out of this world!",
|
||||||
|
"You're orbiting success!",
|
||||||
|
"You're a cosmic force!",
|
||||||
|
"You're a shooting star!",
|
||||||
|
"You're exploring new galaxies!",
|
||||||
|
"You're a stellar achiever!",
|
||||||
|
"You're blazing a trail through the cosmos!",
|
||||||
|
"You're a beacon in the universe!",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn random_affirmation() -> String {
|
pub fn random_affirmation() -> String {
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
let index = rng.random_range(0..affirmations.len());
|
let index = rng.random_range(0..AFFIRMATIONS.len());
|
||||||
affirmations[index].to_string()
|
AFFIRMATIONS[index].to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_name() -> String {
|
pub fn generate_name() -> String {
|
||||||
@ -109,15 +127,15 @@ pub fn generate_name() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn random_unit_intro() -> String {
|
// pub fn random_unit_intro() -> String {
|
||||||
let mut rng = rand::rng();
|
// let mut rng = rand::rng();
|
||||||
let unit_intros: [&str; 5] = [
|
// let unit_intros: [&str; 5] = [
|
||||||
"It's time to learn about",
|
// "It's time to learn about",
|
||||||
"Let's dive into",
|
// "Let's dive into",
|
||||||
"Get ready to explore",
|
// "Get ready to explore",
|
||||||
"Prepare to discover",
|
// "Prepare to discover",
|
||||||
"Let's embark on a journey to learn about",
|
// "Let's embark on a journey to learn about",
|
||||||
];
|
// ];
|
||||||
let index = rng.random_range(0..unit_intros.len());
|
// let index = rng.random_range(0..unit_intros.len());
|
||||||
unit_intros[index].to_string()
|
// unit_intros[index].to_string()
|
||||||
}
|
// }
|
@ -1,14 +1,12 @@
|
|||||||
use crossterm::{execute, style::Stylize, terminal::{size, Clear, ClearType}};
|
use crossterm::{execute, style::Stylize, terminal::{size, Clear, ClearType}};
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
|
|
||||||
use super::generators;
|
// const DELAY_SECONDS: u64 = 1;
|
||||||
|
|
||||||
const DELAY_SECONDS: u64 = 1;
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum StatementType {
|
pub enum StatementType {
|
||||||
Default,
|
Default,
|
||||||
DelayExplanation,
|
// DelayExplanation,
|
||||||
Question,
|
Question,
|
||||||
GeneralFeedback,
|
GeneralFeedback,
|
||||||
CorrectFeedback,
|
CorrectFeedback,
|
||||||
@ -160,10 +158,6 @@ pub fn print_boxed(instruction: &str, statement_type: StatementType) {
|
|||||||
StatementType::Question => {
|
StatementType::Question => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StatementType::DelayExplanation => {
|
|
||||||
wait_for_input_delay(DELAY_SECONDS);
|
|
||||||
print_boxed(&instruction, StatementType::Default);
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
wait_for_input();
|
wait_for_input();
|
||||||
}
|
}
|
||||||
@ -171,29 +165,29 @@ pub fn print_boxed(instruction: &str, statement_type: StatementType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a full-width ruler of designated characters
|
/// Prints a full-width ruler of designated characters
|
||||||
pub fn print_rule(character: char, padding: (bool, bool)) {
|
// pub fn print_rule(character: char, padding: (bool, bool)) {
|
||||||
let (cols, _) = size().unwrap();
|
// let (cols, _) = size().unwrap();
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"{}{}{}",
|
// "{}{}{}",
|
||||||
if padding.0 { "\n" } else { "" },
|
// if padding.0 { "\n" } else { "" },
|
||||||
character.to_string().repeat(cols as usize),
|
// character.to_string().repeat(cols as usize),
|
||||||
if padding.1 { "\n" } else { "" }
|
// if padding.1 { "\n" } else { "" }
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Horizontally center the desired text on the screen
|
/// Horizontally center the desired text on the screen
|
||||||
pub fn print_centered(text: &str) {
|
// pub fn print_centered(text: &str) {
|
||||||
let (cols, _) = size().unwrap();
|
// let (cols, _) = size().unwrap();
|
||||||
let text_width = text.len() as u16;
|
// let text_width = text.len() as u16;
|
||||||
let start_col = (cols.saturating_sub(text_width)) / 2;
|
// let start_col = (cols.saturating_sub(text_width)) / 2;
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"\x1B[{}C{}",
|
// "\x1B[{}C{}",
|
||||||
start_col,
|
// start_col,
|
||||||
text
|
// text
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Wait for input from the user
|
/// Wait for input from the user
|
||||||
pub fn wait_for_input() {
|
pub fn wait_for_input() {
|
||||||
@ -213,51 +207,51 @@ pub fn wait_for_input() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for input from the user
|
/// Wait for input from the user
|
||||||
pub fn print_title(title: &str) {
|
// pub fn print_title(title: &str) {
|
||||||
let (cols, _) = size().unwrap();
|
// let (cols, _) = size().unwrap();
|
||||||
let text_width = title.len() as u16;
|
// let text_width = title.len() as u16;
|
||||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"\x1B[{}C{}",
|
// "\x1B[{}C{}",
|
||||||
start_col,
|
// start_col,
|
||||||
title.bold()
|
// title.bold()
|
||||||
);
|
// );
|
||||||
|
|
||||||
wait_for_input();
|
// wait_for_input();
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Wait for input from the user
|
/// Wait for input from the user
|
||||||
pub fn wait_for_input_delay(seconds: u64) {
|
// pub fn wait_for_input_delay(seconds: u64) {
|
||||||
let prompt = format!("Remember to be mindful. Advance in {} seconds.", seconds);
|
// let prompt = format!("Remember to be mindful. Advance in {} seconds.", seconds);
|
||||||
let (cols, _) = size().unwrap();
|
// let (cols, _) = size().unwrap();
|
||||||
let text_width = prompt.len() as u16;
|
// let text_width = prompt.len() as u16;
|
||||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"\x1B[{}C{}",
|
// "\x1B[{}C{}",
|
||||||
start_col,
|
// start_col,
|
||||||
prompt.italic().dark_blue()
|
// prompt.italic().dark_blue()
|
||||||
);
|
// );
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
// std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Wait for input from the user
|
/// Wait for input from the user
|
||||||
pub fn inform_delay(seconds: u64) {
|
// pub fn inform_delay(seconds: u64) {
|
||||||
let prompt = format!("Remember to be mindful. Answers appear in {} seconds.", seconds);
|
// let prompt = format!("Remember to be mindful. Answers appear in {} seconds.", seconds);
|
||||||
let (cols, _) = size().unwrap();
|
// let (cols, _) = size().unwrap();
|
||||||
let text_width = prompt.len() as u16;
|
// let text_width = prompt.len() as u16;
|
||||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"\x1B[{}C{}",
|
// "\x1B[{}C{}",
|
||||||
start_col,
|
// start_col,
|
||||||
prompt.italic().dark_blue()
|
// prompt.italic().dark_blue()
|
||||||
);
|
// );
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn unit_screen(title: &str) {
|
pub fn unit_screen(title: &str) {
|
||||||
clear_console();
|
clear_console();
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
use inquire::{MultiSelect, Select, Text};
|
use inquire::{MultiSelect, Select, Text};
|
||||||
use crossterm::terminal;
|
use crossterm::terminal;
|
||||||
|
|
||||||
use super::printers::{clear_console, inform_delay, print_boxed, StatementType};
|
use super::printers::{clear_console, print_boxed, StatementType};
|
||||||
|
|
||||||
const DELAY_SECONDS: u64 = 1;
|
// const DELAY_SECONDS: u64 = 1;
|
||||||
|
|
||||||
pub fn ask_mcq_delayed(question: &str, options: &[&str]) -> Option<String> {
|
// pub fn ask_mcq_delayed(question: &str, options: &[&str]) -> Option<String> {
|
||||||
print_boxed(question, StatementType::Question);
|
// print_boxed(question, StatementType::Question);
|
||||||
inform_delay(DELAY_SECONDS);
|
// inform_delay(DELAY_SECONDS);
|
||||||
std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
// std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
||||||
ask_mcq(question, options)
|
// ask_mcq(question, options)
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Print a quiz question in an attractive format and get the user's choice
|
/// Print a quiz question in an attractive format and get the user's choice
|
||||||
pub fn ask_mcq(question: &str, options: &[&str]) -> Option<String> {
|
pub fn ask_mcq(question: &str, options: &[&str]) -> Option<String> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user