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
|
||||
|
||||
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 the AI Applications in Education course team at Utah State University.
|
||||
- Open-source contributors and the developer community.
|
||||
- Special thanks to Seth Poulsen and his AI Applications in Education course at Utah State University.
|
||||
- Portions of this work are produced by generative AI, but all content is manually reviewed and edited.
|
@ -1,6 +1,6 @@
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
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();
|
||||
options.push("Get hint".to_string());
|
||||
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 => {
|
||||
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();
|
||||
options.push("Get hint".to_string());
|
||||
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 correct = selected_indices.iter().all(|&index| correct_indices.contains(&index)) && selected_indices.len() == correct_indices.len();
|
||||
if correct {
|
||||
print_boxed("Correct!", printers::StatementType::CorrectFeedback);
|
||||
print_boxed(&format!("Correct! {}", random_affirmation()), printers::StatementType::CorrectFeedback);
|
||||
learner.update_progress(unit.clone(), true);
|
||||
learner.progress.get_mut(&unit).unwrap().print_progress();
|
||||
break;
|
||||
|
@ -90,12 +90,12 @@ impl Tracker {
|
||||
self.milestones_completed as f64 / self.milestones as f64
|
||||
}
|
||||
|
||||
pub fn get_milestones(&self) -> usize {
|
||||
self.milestones
|
||||
}
|
||||
pub fn get_milestones_completed(&self) -> usize {
|
||||
self.milestones_completed
|
||||
}
|
||||
// pub fn get_milestones(&self) -> usize {
|
||||
// self.milestones
|
||||
// }
|
||||
// pub fn get_milestones_completed(&self) -> usize {
|
||||
// self.milestones_completed
|
||||
// }
|
||||
|
||||
pub(crate) fn print_progress(&self) {
|
||||
let (cols, _) = size().unwrap();
|
||||
|
@ -1,8 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use rand::{rng, seq::IndexedRandom};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
// use rand::{rng, seq::IndexedRandom};
|
||||
// use strum_macros::EnumIter;
|
||||
|
||||
/// 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()),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
Module::Logic(Logic::random()),
|
||||
Module::Fallacy(Fallacy::random()),
|
||||
Module::Bias(Bias::random()),
|
||||
Module::Appraisal(Appraisal::random()),
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// Module::Logic(Logic::random()),
|
||||
// Module::Fallacy(Fallacy::random()),
|
||||
// Module::Bias(Bias::random()),
|
||||
// Module::Appraisal(Appraisal::random()),
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
pub fn iter() -> impl Iterator<Item = Self> {
|
||||
vec![
|
||||
Module::Introduction,
|
||||
@ -125,11 +123,11 @@ impl Logic {
|
||||
Logic::BooleanAlgebra => "boolean_algebra".to_string(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [Logic::LogicalOperations, Logic::BooleanAlgebra];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [Logic::LogicalOperations, Logic::BooleanAlgebra];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
|
||||
/// 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()),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
Fallacy::FormalFallacy(FormalFallacy::random()),
|
||||
Fallacy::InformalFallacy(InformalFallacy::random()),
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// Fallacy::FormalFallacy(FormalFallacy::random()),
|
||||
// Fallacy::InformalFallacy(InformalFallacy::random()),
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
/// Formal fallacies, which are errors in the structure of an argument.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
@ -199,16 +197,16 @@ impl FormalFallacy {
|
||||
FormalFallacy::QuantificationalFallacy => "quantificational".to_string(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
FormalFallacy::PropositionalFallacy,
|
||||
FormalFallacy::ProbabilisticFallacy,
|
||||
FormalFallacy::SyllogisticFallacy,
|
||||
FormalFallacy::QuantificationalFallacy,
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// FormalFallacy::PropositionalFallacy,
|
||||
// FormalFallacy::ProbabilisticFallacy,
|
||||
// FormalFallacy::SyllogisticFallacy,
|
||||
// FormalFallacy::QuantificationalFallacy,
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
/// Informal fallacies, which are errors in reasoning that do not involve the structure of the argument.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
@ -272,26 +270,26 @@ impl InformalFallacy {
|
||||
InformalFallacy::BeggingTheQuestion => "begging_the_question".to_string(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
InformalFallacy::PostHocErgoPropterHoc,
|
||||
InformalFallacy::SlipperySlope,
|
||||
InformalFallacy::TexasSharpshooter,
|
||||
InformalFallacy::HastyGeneralization,
|
||||
InformalFallacy::OverGeneralization,
|
||||
InformalFallacy::NoTrueScotsman,
|
||||
InformalFallacy::QuotingOutOfContext,
|
||||
InformalFallacy::AdHominem,
|
||||
InformalFallacy::TuQuoque,
|
||||
InformalFallacy::Bandwagon,
|
||||
InformalFallacy::StrawMan,
|
||||
InformalFallacy::AdIgnorantiam,
|
||||
InformalFallacy::SpecialPleading,
|
||||
InformalFallacy::BeggingTheQuestion,
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// InformalFallacy::PostHocErgoPropterHoc,
|
||||
// InformalFallacy::SlipperySlope,
|
||||
// InformalFallacy::TexasSharpshooter,
|
||||
// InformalFallacy::HastyGeneralization,
|
||||
// InformalFallacy::OverGeneralization,
|
||||
// InformalFallacy::NoTrueScotsman,
|
||||
// InformalFallacy::QuotingOutOfContext,
|
||||
// InformalFallacy::AdHominem,
|
||||
// InformalFallacy::TuQuoque,
|
||||
// InformalFallacy::Bandwagon,
|
||||
// InformalFallacy::StrawMan,
|
||||
// InformalFallacy::AdIgnorantiam,
|
||||
// InformalFallacy::SpecialPleading,
|
||||
// InformalFallacy::BeggingTheQuestion,
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
|
||||
/// 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(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
Bias::ConfirmationBias,
|
||||
Bias::TheHaloEffect,
|
||||
Bias::FundamentalAttributionError,
|
||||
Bias::InGroupBias,
|
||||
Bias::DunningKrugerEffect,
|
||||
Bias::BarnumEffect,
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// Bias::ConfirmationBias,
|
||||
// Bias::TheHaloEffect,
|
||||
// Bias::FundamentalAttributionError,
|
||||
// Bias::InGroupBias,
|
||||
// Bias::DunningKrugerEffect,
|
||||
// Bias::BarnumEffect,
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
/// Appraisal module, which includes various lessons related to the evaluation and appraisal of arguments.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
@ -371,12 +369,12 @@ impl Appraisal {
|
||||
Appraisal::CounterArgument => "counter_argument".to_string(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn random() -> Self {
|
||||
let mut rng = rng();
|
||||
let variants = [
|
||||
Appraisal::ConversionToPropositional,
|
||||
Appraisal::CounterArgument,
|
||||
];
|
||||
variants.choose(&mut rng).unwrap().clone()
|
||||
}
|
||||
// pub(crate) fn random() -> Self {
|
||||
// let mut rng = rng();
|
||||
// let variants = [
|
||||
// Appraisal::ConversionToPropositional,
|
||||
// Appraisal::CounterArgument,
|
||||
// ];
|
||||
// variants.choose(&mut rng).unwrap().clone()
|
||||
// }
|
||||
}
|
||||
|
@ -60,16 +60,16 @@ impl Learner {
|
||||
clear_console();
|
||||
|
||||
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));
|
||||
|
||||
println!("Progress Report for {}:", self.name);
|
||||
println!("{}", dashes);
|
||||
println!("{}", format!(" Unit {} | Mastery |", dots).bold());
|
||||
|
||||
let mut modules = units::Module::iter();
|
||||
let modules = units::Module::iter();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::{fs::File, io::Read};
|
||||
|
||||
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> {
|
||||
// learner.clone().save_to_file(file)?;
|
||||
|
@ -69,7 +69,7 @@ const OFFENSIVE_TERMS: [&str; 20] = [
|
||||
"jew", "slut", "tit", "phag"
|
||||
];
|
||||
|
||||
const affirmations: [&str; 8] = [
|
||||
const AFFIRMATIONS: [&str; 26] = [
|
||||
"You're doing great!",
|
||||
"Keep up the good work!",
|
||||
"Fantastic effort!",
|
||||
@ -78,12 +78,30 @@ const affirmations: [&str; 8] = [
|
||||
"You're making progress!",
|
||||
"Keep it up!",
|
||||
"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 {
|
||||
let mut rng = rand::rng();
|
||||
let index = rng.random_range(0..affirmations.len());
|
||||
affirmations[index].to_string()
|
||||
let index = rng.random_range(0..AFFIRMATIONS.len());
|
||||
AFFIRMATIONS[index].to_string()
|
||||
}
|
||||
|
||||
pub fn generate_name() -> String {
|
||||
@ -109,15 +127,15 @@ pub fn generate_name() -> String {
|
||||
}
|
||||
|
||||
|
||||
pub fn random_unit_intro() -> String {
|
||||
let mut rng = rand::rng();
|
||||
let unit_intros: [&str; 5] = [
|
||||
"It's time to learn about",
|
||||
"Let's dive into",
|
||||
"Get ready to explore",
|
||||
"Prepare to discover",
|
||||
"Let's embark on a journey to learn about",
|
||||
];
|
||||
let index = rng.random_range(0..unit_intros.len());
|
||||
unit_intros[index].to_string()
|
||||
}
|
||||
// pub fn random_unit_intro() -> String {
|
||||
// let mut rng = rand::rng();
|
||||
// let unit_intros: [&str; 5] = [
|
||||
// "It's time to learn about",
|
||||
// "Let's dive into",
|
||||
// "Get ready to explore",
|
||||
// "Prepare to discover",
|
||||
// "Let's embark on a journey to learn about",
|
||||
// ];
|
||||
// let index = rng.random_range(0..unit_intros.len());
|
||||
// unit_intros[index].to_string()
|
||||
// }
|
@ -1,14 +1,12 @@
|
||||
use crossterm::{execute, style::Stylize, terminal::{size, Clear, ClearType}};
|
||||
use std::io::stdout;
|
||||
|
||||
use super::generators;
|
||||
|
||||
const DELAY_SECONDS: u64 = 1;
|
||||
// const DELAY_SECONDS: u64 = 1;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum StatementType {
|
||||
Default,
|
||||
DelayExplanation,
|
||||
// DelayExplanation,
|
||||
Question,
|
||||
GeneralFeedback,
|
||||
CorrectFeedback,
|
||||
@ -160,10 +158,6 @@ pub fn print_boxed(instruction: &str, statement_type: StatementType) {
|
||||
StatementType::Question => {
|
||||
return;
|
||||
}
|
||||
StatementType::DelayExplanation => {
|
||||
wait_for_input_delay(DELAY_SECONDS);
|
||||
print_boxed(&instruction, StatementType::Default);
|
||||
}
|
||||
_ => {
|
||||
wait_for_input();
|
||||
}
|
||||
@ -171,29 +165,29 @@ pub fn print_boxed(instruction: &str, statement_type: StatementType) {
|
||||
}
|
||||
|
||||
/// Prints a full-width ruler of designated characters
|
||||
pub fn print_rule(character: char, padding: (bool, bool)) {
|
||||
let (cols, _) = size().unwrap();
|
||||
// pub fn print_rule(character: char, padding: (bool, bool)) {
|
||||
// let (cols, _) = size().unwrap();
|
||||
|
||||
println!(
|
||||
"{}{}{}",
|
||||
if padding.0 { "\n" } else { "" },
|
||||
character.to_string().repeat(cols as usize),
|
||||
if padding.1 { "\n" } else { "" }
|
||||
);
|
||||
}
|
||||
// println!(
|
||||
// "{}{}{}",
|
||||
// if padding.0 { "\n" } else { "" },
|
||||
// character.to_string().repeat(cols as usize),
|
||||
// if padding.1 { "\n" } else { "" }
|
||||
// );
|
||||
// }
|
||||
|
||||
/// Horizontally center the desired text on the screen
|
||||
pub fn print_centered(text: &str) {
|
||||
let (cols, _) = size().unwrap();
|
||||
let text_width = text.len() as u16;
|
||||
let start_col = (cols.saturating_sub(text_width)) / 2;
|
||||
// pub fn print_centered(text: &str) {
|
||||
// let (cols, _) = size().unwrap();
|
||||
// let text_width = text.len() as u16;
|
||||
// let start_col = (cols.saturating_sub(text_width)) / 2;
|
||||
|
||||
println!(
|
||||
"\x1B[{}C{}",
|
||||
start_col,
|
||||
text
|
||||
);
|
||||
}
|
||||
// println!(
|
||||
// "\x1B[{}C{}",
|
||||
// start_col,
|
||||
// text
|
||||
// );
|
||||
// }
|
||||
|
||||
/// Wait for input from the user
|
||||
pub fn wait_for_input() {
|
||||
@ -213,51 +207,51 @@ pub fn wait_for_input() {
|
||||
}
|
||||
|
||||
/// Wait for input from the user
|
||||
pub fn print_title(title: &str) {
|
||||
let (cols, _) = size().unwrap();
|
||||
let text_width = title.len() as u16;
|
||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
// pub fn print_title(title: &str) {
|
||||
// let (cols, _) = size().unwrap();
|
||||
// let text_width = title.len() as u16;
|
||||
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
|
||||
println!(
|
||||
"\x1B[{}C{}",
|
||||
start_col,
|
||||
title.bold()
|
||||
);
|
||||
// println!(
|
||||
// "\x1B[{}C{}",
|
||||
// start_col,
|
||||
// title.bold()
|
||||
// );
|
||||
|
||||
wait_for_input();
|
||||
}
|
||||
// wait_for_input();
|
||||
// }
|
||||
|
||||
/// Wait for input from the user
|
||||
pub fn wait_for_input_delay(seconds: u64) {
|
||||
let prompt = format!("Remember to be mindful. Advance in {} seconds.", seconds);
|
||||
let (cols, _) = size().unwrap();
|
||||
let text_width = prompt.len() as u16;
|
||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
// pub fn wait_for_input_delay(seconds: u64) {
|
||||
// let prompt = format!("Remember to be mindful. Advance in {} seconds.", seconds);
|
||||
// let (cols, _) = size().unwrap();
|
||||
// let text_width = prompt.len() as u16;
|
||||
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
|
||||
println!(
|
||||
"\x1B[{}C{}",
|
||||
start_col,
|
||||
prompt.italic().dark_blue()
|
||||
);
|
||||
// println!(
|
||||
// "\x1B[{}C{}",
|
||||
// start_col,
|
||||
// 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
|
||||
pub fn inform_delay(seconds: u64) {
|
||||
let prompt = format!("Remember to be mindful. Answers appear in {} seconds.", seconds);
|
||||
let (cols, _) = size().unwrap();
|
||||
let text_width = prompt.len() as u16;
|
||||
let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
// pub fn inform_delay(seconds: u64) {
|
||||
// let prompt = format!("Remember to be mindful. Answers appear in {} seconds.", seconds);
|
||||
// let (cols, _) = size().unwrap();
|
||||
// let text_width = prompt.len() as u16;
|
||||
// let start_col = (cols.saturating_sub(text_width)) / 2 + 1;
|
||||
|
||||
println!(
|
||||
"\x1B[{}C{}",
|
||||
start_col,
|
||||
prompt.italic().dark_blue()
|
||||
);
|
||||
// println!(
|
||||
// "\x1B[{}C{}",
|
||||
// start_col,
|
||||
// prompt.italic().dark_blue()
|
||||
// );
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
pub fn unit_screen(title: &str) {
|
||||
clear_console();
|
||||
|
@ -1,16 +1,16 @@
|
||||
use inquire::{MultiSelect, Select, Text};
|
||||
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> {
|
||||
print_boxed(question, StatementType::Question);
|
||||
inform_delay(DELAY_SECONDS);
|
||||
std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
||||
ask_mcq(question, options)
|
||||
}
|
||||
// pub fn ask_mcq_delayed(question: &str, options: &[&str]) -> Option<String> {
|
||||
// print_boxed(question, StatementType::Question);
|
||||
// inform_delay(DELAY_SECONDS);
|
||||
// std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
|
||||
// ask_mcq(question, options)
|
||||
// }
|
||||
|
||||
/// Print a quiz question in an attractive format and get the user's choice
|
||||
pub fn ask_mcq(question: &str, options: &[&str]) -> Option<String> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user