Experto en enfermedades (versión en Odin)
Descripción del contenido de la página
Sistema experto sobre enfermedades, escrito en Odin.
Etiquetas:
Código fuente
// main.odin
//
// This file is part of Experto en enfermedades (Expert on diseases)
// Last modified 20250626T0103+0200.
/*
Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).
Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).
Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.
This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.
*/
// ==========================================================================
package eee
import "../lib/anodino/src/par"
import "../lib/anodino/src/term"
import "../lib/anodino/src/type"
import "core:fmt"
import "core:math"
TITLE :: "Experto en enfermedades"
// Set the debug level, taken from the `--define:DEBUG_LEVEL=X` compilation option
// where `X` can be a number between 0 and 2:
// 0: do not include debug code (this is the default)
// 1: add the test options to the main menu
// 2: also print debugging messages during the main loop
DEBUG_LEVEL :: #config(DEBUG_LEVEL, 0)
MAX_ANSWER :: 5
MIN_ANSWER :: -MAX_ANSWER
Mode :: enum { Normal, Random_Demo, Value_Demo }
mode : Mode
demo_value : int // used in value demo mode
init :: proc() {
// Anodino's type package is used by Anodino's par package. When type's
// `max_lines_printed_before_a_pause` is set to zero, no pause is issued
// during the printing of the paragrahps:
type.max_lines_printed_before_a_pause = 0
}
consult :: proc() {
DISEASES :: 91
SYMPTOMS :: 68
max_prob := [DISEASES]f64{}
min_prob := [DISEASES]f64{}
prob := [DISEASES]f64{}
asked := [SYMPTOMS]bool{}
symptoms_count := [DISEASES]int{}
symptoms_left := [DISEASES]int{}
value := [SYMPTOMS]f64{}
answer_value : int
disease_name : string
disease_prob : f64
hypothesis : int
symptom : int
current_prob : f64
con_prob : f64
pro_prob : f64
// Find the a priori probability and the rule values
when DEBUG_LEVEL > 1 {
fmt.println("Find the a priori probability and the rule values")
}
for disease in 0 ..< DISEASES {
disease_name, prob[disease] = disease_data(disease)
current_prob = prob[disease]
when DEBUG_LEVEL > 1 {
fmt.printf("Disease #%v: \"%v\" (current prob: %v)\n", disease, disease_name, current_prob)
}
for disease_symptom := 0 ; ; disease_symptom += 1 {
symptom, pro_prob, con_prob = symptom_data(disease, disease_symptom) or_break
symptoms_left[disease] += 1
value[symptom] +=
math.abs( \
current_prob * pro_prob \
/ (current_prob * pro_prob + (1 - current_prob) * con_prob) \
- \
current_prob * (1 - pro_prob) \
/ (current_prob * (1 - pro_prob) + (1 - current_prob) * (1 - con_prob)) \
)
when DEBUG_LEVEL > 1 {
fmt.printf("Symptom #%v (value: %v)\n", symptom, value[symptom])
}
}
symptoms_count[disease] = symptoms_left[disease]
}
for {
// Find the most important symptom and ask about it
when DEBUG_LEVEL > 1 {
fmt.println("Find the most important symptom and ask about it")
}
min_value : f64 = 0
NO_SYMPTOM :: -1
symptom_to_ask_for := NO_SYMPTOM
for symptom in 0 ..< SYMPTOMS {
if value[symptom] > min_value {
symptom_to_ask_for = symptom
min_value = value[symptom]
when DEBUG_LEVEL > 1 {
fmt.printf("Symptom to ask for: #%v, \"%v\" (value: %v)\n", symptom_to_ask_for, question(symptom_to_ask_for), min_value)
}
}
value[symptom] = 0
}
if symptom_to_ask_for == NO_SYMPTOM {
par.whole("No hay más preguntas.")
return
}
when DEBUG_LEVEL == 0 {
if mode == .Normal do term.clear_screen()
}
par.whole(question(symptom_to_ask_for))
switch mode {
case .Random_Demo :
answer_value = random_answer()
par.whole(fmt.tprintf("%v", answer_value))
case .Value_Demo :
answer_value = demo_value
par.whole(fmt.tprintf("%v", answer_value))
case .Normal :
answer_value = user_answer()
}
asked[symptom_to_ask_for] = true
// Update the a priori probabilities
when DEBUG_LEVEL > 1 {
fmt.println("Update the a priori probabilities")
}
for disease in 0 ..< DISEASES {
disease_name, _ = disease_data(disease)
when DEBUG_LEVEL > 1 {
fmt.printf("Disease #%v: \"%v\"\n", disease, disease_name)
}
for s in 0 ..< symptoms_count[disease] {
symptom, pro_prob, con_prob, _ = symptom_data(disease, s)
if symptom == symptom_to_ask_for && symptoms_left[disease] > 0 {
symptoms_left[disease] = symptoms_left[disease] - 1
current_prob = prob[disease]
pe := current_prob * pro_prob + (1 - current_prob) * con_prob
if answer_value > 0 {
prob[disease] = \
current_prob \
* (1 + (pro_prob / pe - 1) * f64(answer_value) \
/ MAX_ANSWER)
} else {
prob[disease] = \
current_prob \
* (1 \
+ (pro_prob - (1 - pro_prob) * pe / (1 - pe)) \
* f64(answer_value) / MAX_ANSWER)
}
if prob[disease] == math.trunc(prob[disease]) {
symptoms_left[disease] = 0
}
}
}
}
// Find new min and max rule values
current_min_prob : f64
for disease in 0 ..< DISEASES {
current_prob = prob[disease]
a1 : f64 = 1
a2 : f64 = 1
a3 : f64 = 1
a4 : f64 = 1
disease_name, disease_prob = disease_data(disease)
for s in 0 ..< symptoms_count[disease] {
symptom, pro_prob, con_prob, _ = symptom_data(disease, s)
if ! asked[symptom] && symptoms_left[disease] > 0 {
if con_prob > pro_prob {
pro_prob = 1 - pro_prob
con_prob = 1 - con_prob
}
value[symptom] = \
value[symptom] \
+ current_prob * pro_prob \
/ (current_prob * pro_prob + (1 - current_prob) * con_prob) \
- current_prob * (1 - pro_prob) \
/ (current_prob * (1 - pro_prob) + (1 - current_prob) * (1 - con_prob))
a1 = a1 * pro_prob
a2 = a2 * con_prob
a3 = a3 * (1 - pro_prob)
a4 = a4 * (1 - con_prob)
}
}
max_prob[disease] = current_prob * a1 / (current_prob * a1 + (1 - current_prob) * a2)
min_prob[disease] = current_prob * a3 / (current_prob * a3 + (1 - current_prob) * a4)
if max_prob[disease] < disease_prob {
symptoms_left[disease] = 0
}
if min_prob[disease] > current_min_prob {
hypothesis = disease
current_min_prob = min_prob[disease]
when DEBUG_LEVEL > 1 {
disease_name, _ := disease_data(hypothesis)
fmt.printf("Hipótesis: %v (#%v), probabilidad mínima: %v\n", disease_name, hypothesis, current_min_prob)
}
}
}
// Search for a clearly possible hypothesis
for disease in 0 ..< DISEASES {
if min_prob[hypothesis] <= max_prob[disease] && disease != hypothesis {
current_min_prob = 0
}
}
if current_min_prob != 0 do break
}
disease_name, _ = disease_data(hypothesis)
par.whole(
fmt.tprintf(
"El resultado más probable es %v con probabilidad %v.",
disease_name,
prob[hypothesis]
)
)
}
print_credits :: proc() {
par.whole(TITLE)
par.whole(fmt.tprintf("Versión %v", VERSION))
fmt.println()
par.whole("(C) 1985, Chris Naylor: en Sinclair BASIC.")
par.whole("(C) 1988, 1989, Marcos Cruz (programandala.net): en SuperBASIC.")
par.whole("(C) 2023, 2024, Marcos Cruz (programandala.net): en Odin.")
fmt.println()
}
main :: proc() {
init()
for {
term.clear_screen()
print_credits()
if ready() {
consult()
press_enter()
} else {
break
}
}
}
// data.odin
//
// This file is part of Experto en enfermedades (Expert on diseases)
// Last modified 20250624T2035+0200.
/*
Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).
Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).
Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.
This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.
*/
// ==========================================================================
package eee
// Return name and probability of the given disease.
disease_data :: proc(disease : int) -> (name : string, prob : f64) {
switch disease {
case 00: return "resfriado común", 0.02
case 01: return "rinitis alérgica", 0.01
case 02: return "sinusitis", 0.01
case 03: return "faringitis", 0.02
case 04: return "amigdalitis", 0.001
case 05: return "gripe", 0.01
case 06: return "laringitis", 0.01
case 07: return "tumor de laringe", 0.00004
case 08: return "bronquitis aguda", 0.005
case 09: return "bronquitis crónica", 0.005
case 10: return "asma", 0.02
case 11: return "enfisema pulmonar", 0.01
case 12: return "neumonía", 0.003
case 13: return "pleuresia", 0.001
case 14: return "neumotórax", 0.0002
case 15: return "bronquiectasia", 0.00001
case 16: return "abceso pulmonar", 0.00001
case 17: return "neumoconiosis", 0.001
case 18: return "cáncer de pulmón", 0.001
case 19: return "fibrosis intersticial", 0.00001
case 20: return "edema pulmonar", 0.001
case 21: return "gastritis", 0.01
case 22: return "hernia de hiato", 0.001
case 23: return "úlcera duodenal", 0.01
case 24: return "úlcera gástrica", 0.01
case 25: return "diverticulitis intestinal", 0.001
case 26: return "enterocolitis", 0.0001
case 27: return "enfermedad de Crohn", 0.0001
case 28: return "oclusión intestinal", 0.00001
case 29: return "apendicitis", 0.001
case 30: return "intoxicación alimentaria", 0.001
case 31: return "gastroenteritis", 0.01
case 32: return "litiasis renal", 0.001
case 33: return "pielonefritis aguda", 0.001
case 34: return "litiasis biliar", 0.01
case 35: return "colecistitis", 0.001
case 36: return "herpes", 0.001
case 37: return "trombloflebitis", 0.0005
case 38: return "artritis reumatoide", 0.001
case 39: return "insuficiencia cardiaca", 0.001
case 40: return "ansiedad", 0.01
case 41: return "depresión", 0.01
case 42: return "trombosis coronaria", 0.01
case 43: return "angina de pecho", 0.01
case 44: return "embolia pulmonar", 0.0001
case 45: return "apoplegía", 0.001
case 46: return "ataque isquémico transitorio", 0.001
case 47: return "tuberculosis", 0.0001
case 48: return "hemorroides", 0.01
case 49: return "hipotiroidismo", 0.001
case 50: return "colon irritable", 0.0007
case 51: return "cáncer intestinal", 0.001
case 52: return "colitis ulcerosa", 0.0004
case 53: return "enfermedad de Meniere", 0.0005
case 54: return "espondilosis cervical", 0.006
case 55: return "hemorragia subdural", 0.000001
case 56: return "tumor cerebral", 0.000001
case 57: return "meningitis", 0.000001
case 58: return "hemorragia subaracnoidea", 0.00001
case 59: return "glaucoma agudo", 0.01
case 60: return "arteritis de la temporal", 0.001
case 61: return "dispepsia", .1
case 62: return "bloqueo cardiaco", 0.0003
case 63: return "anemia perniciosa", 0.0004
case 64: return "jaqueca", .1
case 65: return "hipertensión esencial", .15
case 66: return "eccema", 0.03
case 67: return "urticaria", 0.03
case 68: return "sarna", 0.001
case 69: return "sarampión", 0.02
case 70: return "rubeola", 0.01
case 71: return "varicela", 0.001
case 72: return "psoriasis", 0.02
case 73: return "pitiriasis rubra", 0.01
case 74: return "acné rosáceo", 0.01
case 75: return "tirotoxicosis", 0.001
case 76: return "diabetes mellitus", 0.01
case 77: return "cáncer de estómago", 0.0003
case 78: return "fibrilación auricular", 0.001
case 79: return "enfermedad de Hodgkin", 0.0001
case 80: return "fiebre glandular", 0.001
case 81: return "linfoma", 0.0001
case 82: return "paperas", 0.01
case 83: return "parálisis facial", 0.0003
case 84: return "enfermedad de Parkinson", 0.001
case 85: return "artritis reumatoide", 0.01
case 86: return "cistitis", 0.01
case 87: return "tumor renal", 0.001
case 88: return "tumor en la vejiga", 0.0004
case 89: return "iritis", 0.0005
case 90: return "hepatitis aguda", 0.001
}
return
}
// Return probabilities of the given disease and symptom, and a flag to
// indicate whether the list of symptoms of the given disease is exhausted.
symptom_data :: proc(disease, disease_symptom : int ) ->
(symptom: int, pro_prob, con_prob: f64, ok: bool) {
switch disease {
case 0:
switch disease_symptom {
case 0: return 0, .9, 0.05, true
case 1: return 1, .8, 0.02, true
case 2: return 2, .8, 0.02, true
case 3: return 4, .6, 0.01, true
case 4: return 5, 1, 0.01, true
case 5: return 6, .2, 0.01, true
case 6: return 7, .5, 0.01, true
case 7: return 14, .8, 0.01, true
case 8: return 33, 0, 0.01, true
}
case 1:
switch disease_symptom {
case 0: return 0, 1, 0.01, true
case 1: return 1, 1, 0.01, true
case 2: return 5, .9, 0.01, true
case 3: return 9, .7, 0.01, true
case 4: return 10, .7, 0.01, true
case 5: return 11, .6, 0.01, true
case 6: return 19, .9, 0.01, true
}
case 2:
switch disease_symptom {
case 0: return 1, .5, 0.01, true
case 1: return 5, .5, 0.01, true
case 2: return 6, .8, 0.01, true
case 3: return 12, .9, 0.01, true
case 4: return 13, .8, 0.01, true
case 5: return 14, .8, 0.01, true
case 6: return 21, .5, 0.01, true
case 7: return 62, .9, 0.01, true
}
case 3:
switch disease_symptom {
case 0: return 2, 1, 0.01, true
case 1: return 7, .5, 0.01, true
case 2: return 10, .9, 0.01, true
case 3: return 15, .9, 0.01, true
case 4: return 36, .8, .3, true
case 5: return 63, .4, 0.01, true
}
case 4:
switch disease_symptom {
case 0: return 2, 1, 0.01, true
case 1: return 6, .9, 0.01, true
case 2: return 7, .9, 0.01, true
case 3: return 14, 1, 0.01, true
case 4: return 15, .7, 0.01, true
case 5: return 18, 0, .5, true
case 6: return 33, 0, 0.01, true
case 7: return 63, .8, 0.01, true
}
case 5:
switch disease_symptom {
case 0: return 0, .9, 0.01, true
case 1: return 2, .9, 0.01, true
case 2: return 5, .5, 0.01, true
case 3: return 6, .7, 0.01, true
case 4: return 7, 1, 0.01, true
case 5: return 14, 1, 0.01, true
case 6: return 16, .8, 0.01, true
case 7: return 17, .6, 0.01, true
case 8: return 33, 0, 0.01, true
}
case 6:
switch disease_symptom {
case 0: return 3, 1, 0.01, true
case 1: return 4, .9, 0.01, true
case 2: return 7, .6, 0.01, true
case 3: return 14, 0.05, 0.01, true
case 4: return 15, .7, 0.01, true
case 5: return 36, .8, .3, true
case 6: return 20, .1, 0.01, true
}
case 7:
switch disease_symptom {
case 0: return 3, 1, 0.01, true
case 1: return 33, .99, 0.01, true
case 2: return 36, .8, .3, true
}
case 8:
switch disease_symptom {
case 0: return 4, 1, 0.01, true
case 1: return 7, 1, 0.01, true
case 2: return 11, 1, 0.01, true
case 3: return 14, 1, 0.01, true
case 4: return 17, .5, 0.01, true
case 5: return 20, 1, 0.01, true
case 6: return 21, .9, 0.01, true
case 7: return 30, .9, 0.01, true
case 8: return 33, 0, 0.01, true
}
case 9:
switch disease_symptom {
case 0: return 4, 1, 0.01, true
case 1: return 11, .9, 0.01, true
case 2: return 13, .5, 0.01, true
case 3: return 20, 1, 0.01, true
case 4: return 21, .8, 0.01, true
case 5: return 33, 1, 0.01, true
case 6: return 35, .9, 0.01, true
case 7: return 36, .8, .3, true
}
case 10:
switch disease_symptom {
case 0: return 11, .8, 0.01, true
case 1: return 21, 1, 0.01, true
case 2: return 22, .5, 0.01, true
case 3: return 23, .5, 0.01, true
case 4: return 24, .5, 0.01, true
case 5: return 25, .5, 0.01, true
case 6: return 30, .8, 0.01, true
}
case 11:
switch disease_symptom {
case 0: return 4, .6, 0.01, true
case 1: return 11, .6, 0.01, true
case 2: return 20, .6, 0.01, true
case 3: return 21, 1, 0.01, true
case 4: return 25, .8, 0.01, true
case 5: return 36, .8, .3, true
}
case 12:
switch disease_symptom {
case 0: return 7, 1, 0.01, true
case 1: return 14, 1, 0.01, true
case 2: return 16, .9, 0.01, true
case 3: return 17, .8, 0.01, true
case 4: return 21, 1, 0.01, true
case 5: return 22, .5, 0.01, true
case 6: return 25, .5, 0.01, true
case 7: return 26, .2, 0.01, true
case 8: return 27, .1, 0.01, true
case 9: return 28, 0.02, 0.01, true
case 10: return 30, .9, 0.01, true
case 11: return 31, .5, 0.005, true
case 12: return 35, .1, .9, true
}
case 13:
switch disease_symptom {
case 0: return 4, .8, 0.01, true
case 1: return 7, .9, 0.01, true
case 2: return 14, 1, 0.01, true
case 3: return 21, .5, 0.01, true
case 4: return 30, .8, 0.01, true
case 5: return 31, .8, 0.01, true
case 6: return 33, 0, 0.01, true
}
case 14:
switch disease_symptom {
case 0: return 17, .8, 0.01, true
case 1: return 21, .8, 0.01, true
case 2: return 31, .8, 0.005, true
}
case 15:
switch disease_symptom {
case 0: return 4, 1, 0.01, true
case 1: return 13, .5, 0.01, true
case 2: return 20, 1, 0.01, true
case 3: return 26, .5, 0.01, true
}
case 16:
switch disease_symptom {
case 0: return 17, .5, 0.01, true
case 1: return 20, .5, 0.01, true
case 2: return 26, .5, 0.01, true
case 3: return 32, .9, 0.01, true
}
case 17:
switch disease_symptom {
case 0: return 8, 1, 0.01, true
case 1: return 20, .8, 0.01, true
case 2: return 21, 1, 0.01, true
case 3: return 35, 1, 0.01, true
}
case 18:
switch disease_symptom {
case 0: return 4, 1, 0.01, true
case 1: return 11, .5, 0.01, true
case 2: return 17, .8, 0.01, true
case 3: return 20, .8, 0.01, true
case 4: return 21, .5, 0.01, true
case 5: return 26, .5, 0.01, true
case 6: return 36, .99, .3, true
}
case 19:
switch disease_symptom {
case 0: return 20, .6, 0.01, true
case 1: return 21, .8, 0.01, true
case 2: return 34, .8, 0.01, true
}
case 20:
switch disease_symptom {
case 0: return 11, .8, 0.01, true
case 1: return 21, .9, 0.01, true
case 2: return 24, .9, 0.01, true
case 3: return 25, .5, 0.01, true
case 4: return 26, .5, 0.01, true
case 5: return 29, .5, 0.01, true
}
case 21:
switch disease_symptom {
case 0: return 7, .4, 0.01, true
case 1: return 36, .9, .5, true
case 2: return 40, 0.01, .8, true
case 3: return 42, .8, 0.01, true
case 4: return 41, .5, 0.01, true
}
case 22:
switch disease_symptom {
case 0: return 15, .9, 0.01, true
case 1: return 17, .9, 0.01, true
case 2: return 31, .5, 0.005, true
case 3: return 40, .8, 0.01, true
case 4: return 41, .8, 0.005, true
case 5: return 56, .9, 0.01, true
}
case 23:
switch disease_symptom {
case 0: return 36, .8, .2, true
case 1: return 40, .8, 0.01, true
case 2: return 41, .99, 0.005, true
case 3: return 56, .7, 0.01, true
}
case 24:
switch disease_symptom {
case 0: return 19, .8, 0.01, true
case 1: return 40, .7, 0.01, true
case 2: return 41, .9, 0.005, true
case 3: return 45, .5, 0.01, true
case 4: return 55, .9, 0.01, true
case 5: return 61, 0.0001, 0.01, true
}
case 25:
switch disease_symptom {
case 0: return 7, .5, 0.01, true
case 1: return 40, .5, 0.01, true
case 2: return 41, .6, 0.005, true
case 3: return 42, .5, 0.01, true
case 4: return 55, .8, 0.01, true
}
case 26:
switch disease_symptom {
case 0: return 7, .3, 0.01, true
case 1: return 22, .3, 0.01, true
case 2: return 40, .3, 0.01, true
case 3: return 41, .9, 0.005, true
case 4: return 42, .7, 0.01, true
}
case 27:
switch disease_symptom {
case 0: return 7, .7, 0.01, true
case 1: return 14, .9, 0.01, true
case 2: return 41, .9, 0.005, true
case 3: return 42, .9, 0.01, true
case 4: return 61, 0.00001, 0.01, true
}
case 28:
switch disease_symptom {
case 0: return 40, .5, 0.01, true
case 1: return 41, .9, 0.005, true
case 2: return 42, .8, 0.01, true
}
case 29:
switch disease_symptom {
case 0: return 7, .8, 0.01, true
case 1: return 33, .1, .9, true
case 2: return 40, .8, 0.01, true
case 3: return 41, .9, 0.005, true
case 4: return 43, 0, .5, true
}
case 30:
switch disease_symptom {
case 0: return 6, .8, 0.01, true
case 1: return 40, .9, 0.01, true
case 2: return 41, .5, 0.005, true
case 3: return 42, .9, 0.01, true
}
case 31:
switch disease_symptom {
case 0: return 7, .5, 0.01, true
case 1: return 40, .8, 0.01, true
case 2: return 41, .7, 0.005, true
case 3: return 42, .9, 0.01, true
}
case 32:
switch disease_symptom {
case 0: return 41, .7, 0.005, true
}
case 33:
switch disease_symptom {
case 0: return 7, .8, 0.01, true
case 1: return 40, .7, 0.01, true
case 2: return 41, .9, 0.005, true
case 3: return 66, .9, 0.01, true
}
case 34:
switch disease_symptom {
case 0: return 40, .5, 0.01, true
case 1: return 41, .5, 0.005, true
case 2: return 56, .9, 0.01, true
}
case 35:
switch disease_symptom {
case 0: return 7, .9, 0.01, true
case 1: return 40, .8, 0.01, true
case 2: return 41, .8, 0.005, true
case 3: return 44, .8, 0.001, true
}
case 36:
switch disease_symptom {
case 0: return 1, .6, 0.01, true
case 1: return 7, .5, 0.01, true
case 2: return 13, .8, 0.01, true
case 3: return 17, .5, 0.01, true
case 4: return 58, .9, 0.01, true
case 5: return 59, .9, 0.01, true
}
case 37:
switch disease_symptom {
case 0: return 39, .8, 0.01, true
}
case 38:
switch disease_symptom {
case 0: return 14, .8, 0.01, true
case 1: return 16, .8, 0.01, true
case 2: return 39, .5, 0.001, true
}
case 39:
switch disease_symptom {
case 0: return 11, .6, 0.01, true
case 1: return 17, .5, 0.01, true
case 2: return 21, .9, 0.01, true
case 3: return 24, .5, 0.001, true
case 4: return 25, .3, 0.001, true
case 5: return 31, .3, 0.001, true
case 6: return 35, .5, 0.01, true
case 7: return 38, .5, 0.01, true
case 8: return 41, .5, 0.01, true
case 9: return 46, .9, 0.01, true
}
case 40:
switch disease_symptom {
case 0: return 6, .5, 0.01, true
case 1: return 14, .5, 0.01, true
case 2: return 15, .3, 0.01, true
case 3: return 21, .5, 0.01, true
case 4: return 22, .6, 0.01, true
case 5: return 27, .3, 0.01, true
case 6: return 37, .5, 0.01, true
case 7: return 38, .8, 0.01, true
case 8: return 42, .2, 0.01, true
case 9: return 45, .9, 0.01, true
case 10: return 46, .6, 0.01, true
case 11: return 47, .6, 0.01, true
case 12: return 49, .5, 0.01, true
case 13: return 56, .5, 0.01, true
case 14: return 57, .5, 0.01, true
}
case 41:
switch disease_symptom {
case 0: return 6, .5, 0.01, true
case 1: return 14, .5, 0.01, true
case 2: return 46, .5, 0.01, true
case 3: return 48, .5, 0.01, true
case 4: return 49, .5, 0.01, true
case 5: return 61, .8, 0.01, true
}
case 42:
switch disease_symptom {
case 0: return 14, .9, 0.01, true
case 1: return 17, .5, 0.01, true
case 2: return 19, .5, 0.01, true
case 3: return 21, .5, 0.01, true
case 4: return 22, .5, 0.01, true
case 5: return 31, .9, 0.001, true
case 6: return 35, 0, .2, true
case 7: return 37, .5, 0.01, true
case 8: return 40, .5, 0.01, true
}
case 43:
switch disease_symptom {
case 0: return 17, .9, 0.01, true
case 1: return 19, .9, 0.01, true
case 2: return 21, .5, 0.01, true
case 3: return 22, .5, 0.01, true
case 4: return 31, 1, 0.001, true
case 5: return 35, .9, 0.01, true
case 6: return 36, .8, .3, true
case 7: return 37, .5, 0.01, true
}
case 44:
switch disease_symptom {
case 0: return 17, .7, 0.01, true
case 1: return 20, .6, 0.01, true
case 2: return 21, 1, 0.01, true
case 3: return 24, .5, 0.001, true
case 4: return 25, .4, 0.001, true
case 5: return 26, .5, 0.001, true
}
case 45:
switch disease_symptom {
case 0: return 27, .8, 0.01, true
case 1: return 37, .7, 0.01, true
case 2: return 50, .8, 0.001, true
case 3: return 57, .9, 0.01, true
case 4: return 60, .9, 0.01, true
}
case 46:
switch disease_symptom {
case 0: return 19, .5, 0.01, true
case 1: return 27, .8, 0.01, true
case 2: return 33, 0, 0.01, true
case 3: return 37, .7, 0.01, true
case 4: return 50, .8, 0.001, true
case 5: return 57, .9, 0.01, true
case 6: return 60, .9, 0.01, true
}
case 47:
switch disease_symptom {
case 0: return 4, .5, 0.01, true
case 1: return 6, .5, 0.01, true
case 2: return 7, .5, 0.01, true
case 3: return 11, .5, 0.01, true
case 4: return 14, .5, 0.01, true
case 5: return 17, .5, 0.01, true
case 6: return 21, .5, 0.01, true
case 7: return 22, .5, 0.01, true
case 8: return 26, .5, 0.001, true
case 9: return 29, .5, 0.01, true
case 10: return 61, 0.0001, 0.01, true
}
case 48:
switch disease_symptom {
case 0: return 48, .8, 0.01, true
case 1: return 51, .9, 0.001, true
case 2: return 55, .9, 0.01, true
case 3: return 58, .5, 0.01, true
}
case 49:
switch disease_symptom {
case 0: return 3, .5, 0.01, true
case 1: return 16, .5, 0.01, true
case 2: return 22, 0.001, 0.01, true
case 3: return 23, 0, 0.01, true
case 4: return 38, 0.001, 0.01, true
case 5: return 42, 0, 0.01, true
case 6: return 45, 0.001, 0.01, true
case 7: return 47, 0.001, 0.01, true
case 8: return 48, .8, 0.01, true
case 9: return 61, .9, 0.05, true
}
case 50:
switch disease_symptom {
case 0: return 40, .3, 0.01, true
case 1: return 41, .8, 0.001, true
case 2: return 42, .5, 0.01, true
case 3: return 48, .5, 0.01, true
case 4: return 55, .5, 0.01, true
case 5: return 56, .9, 0.01, true
}
case 51:
switch disease_symptom {
case 0: return 41, .5, 0.005, true
case 1: return 42, .9, 0.01, true
case 2: return 48, .9, 0.01, true
case 3: return 51, .5, 0.001, true
case 4: return 55, .9, 0.01, true
case 5: return 61, 0.0001, 0.01, true
}
case 52:
switch disease_symptom {
case 0: return 7, .5, 0.01, true
case 1: return 22, .5, 0.01, true
case 2: return 33, .4, 0.01, true
case 3: return 40, .5, 0.01, true
case 4: return 41, .8, 0.005, true
case 5: return 42, .8, 0.01, true
case 6: return 51, .6, 0.001, true
case 7: return 55, .9, 0.01, true
}
case 53:
switch disease_symptom {
case 0: return 19, .9, 0.01, true
case 1: return 33, .5, 0.01, true
case 2: return 37, .9, 0.001, true
case 3: return 40, .8, 0.01, true
}
case 54:
switch disease_symptom {
case 0: return 6, .5, 0.01, true
case 1: return 37, .5, 0.01, true
case 2: return 53, .9, 0.01, true
case 3: return 57, .9, 0.01, true
case 4: return 60, .5, 0.01, true
}
case 55:
switch disease_symptom {
case 0: return 6, .9, 0.01, true
case 1: return 19, .5, 0.01, true
case 2: return 27, .9, 0.001, true
case 3: return 33, .5, 0.01, true
case 4: return 37, .9, 0.01, true
case 5: return 40, .9, 0.01, true
case 6: return 54, .99, 0.001, true
}
case 56:
switch disease_symptom {
case 0: return 6, .9, 0.01, true
case 1: return 33, .5, 0.01, true
case 2: return 37, .8, 0.01, true
case 3: return 40, .9, 0.01, true
case 4: return 49, .8, 0.01, true
}
case 57:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 6, .9, 0.01, true
case 2: return 7, .9, 0.01, true
case 3: return 27, .7, 0.01, true
case 4: return 40, .9, 0.01, true
case 5: return 53, .9, 0.01, true
case 6: return 59, .5, 0.01, true
}
case 58:
switch disease_symptom {
case 0: return 1, .8, 0.01, true
case 1: return 6, .99, 0.01, true
case 2: return 27, .7, 0.01, true
case 3: return 37, .7, 0.01, true
case 4: return 40, .8, 0.01, true
case 5: return 53, .9, 0.01, true
}
case 59:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 6, .9, 0.01, true
case 2: return 19, .8, 0.01, true
case 3: return 33, .8, 0.01, true
case 4: return 40, .7, 0.01, true
case 5: return 62, .9, 0.01, true
case 6: return 67, .9, 0.01, true
}
case 60:
switch disease_symptom {
case 0: return 6, .9, 0.01, true
case 1: return 7, .7, 0.01, true
case 2: return 16, .7, 0.01, true
case 3: return 22, .8, 0.01, true
case 4: return 62, .99, 0.01, true
}
case 61:
switch disease_symptom {
case 0: return 6, .7, 0.01, true
case 1: return 19, .9, 0.01, true
case 2: return 40, .7, 0.01, true
case 3: return 41, .7, 0.01, true
case 4: return 56, .7, 0.01, true
case 5: return 61, 0.001, 0.01, true
}
case 62:
switch disease_symptom {
case 0: return 17, .6, 0.01, true
case 1: return 21, .5, 0.01, true
case 2: return 38, .6, 0.01, true
case 3: return 57, .8, 0.01, true
}
case 63:
switch disease_symptom {
case 0: return 21, .9, 0.01, true
case 1: return 27, .4, 0.01, true
case 2: return 35, .9, 0.01, true
case 3: return 38, .9, 0.01, true
case 4: return 41, .5, 0.01, true
case 5: return 44, .5, 0.01, true
case 6: return 49, .5, 0.01, true
case 7: return 57, .9, 0.01, true
}
case 64:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 6, 1, 0.01, true
case 2: return 14, .9, 0.01, true
case 3: return 19, .9, 0.01, true
case 4: return 33, .9, 0.01, true
case 5: return 40, .9, 0.01, true
case 6: return 42, .5, 0.01, true
case 7: return 62, .99, 0.01, true
}
case 65:
switch disease_symptom {
case 0: return 6, .5, 0.01, true
case 1: return 14, .9, 0.01, true
case 2: return 33, .9, 0.01, true
case 3: return 38, .5, 0.01, true
}
case 66:
switch disease_symptom {
case 0: return 58, .9, 0.01, true
case 1: return 59, .1, 0.01, true
}
case 67:
switch disease_symptom {
case 0: return 45, .5, 0.01, true
case 1: return 58, .9, 0.01, true
case 2: return 59, 1, 0.01, true
}
case 68:
switch disease_symptom {
case 0: return 58, 1, 0.01, true
case 1: return 59, 1, 0.01, true
}
case 69:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 4, .9, 0.01, true
case 2: return 5, .9, 0.01, true
case 3: return 6, .5, 0.01, true
case 4: return 7, 1, 0.01, true
case 5: return 10, .9, 0.01, true
case 6: return 14, 1, 0.01, true
case 7: return 33, 0, 0.01, true
case 8: return 42, .5, 0.01, true
case 9: return 59, 1, 0.01, true
}
case 70:
switch disease_symptom {
case 0: return 7, .5, 0.01, true
case 1: return 33, 0, 0.01, true
case 2: return 53, .2, 0.01, true
case 3: return 59, .9, 0.01, true
case 4: return 63, .5, 0.01, true
}
case 71:
switch disease_symptom {
case 0: return 6, .5, 0.01, true
case 1: return 7, .8, 0.01, true
case 2: return 14, .5, 0.01, true
case 3: return 33, 0, 0.01, true
case 4: return 58, 1, 0.01, true
case 5: return 59, 1, 0.01, true
}
case 72:
switch disease_symptom {
case 0: return 2, .5, 0.01, true
case 1: return 45, .6, 0.01, true
case 2: return 58, .5, 0.01, true
case 3: return 59, .99, 0.01, true
}
case 73:
switch disease_symptom {
case 0: return 33, .5, 0.01, true
case 1: return 58, .9, 0.01, true
case 2: return 59, 1, 0.01, true
}
case 74:
switch disease_symptom {
case 0: return 1, .5, 0.01, true
case 1: return 33, .8, 0.01, true
case 2: return 59, .9, 0.01, true
}
case 75:
switch disease_symptom {
case 0: return 1, .5, 0.01, true
case 1: return 21, .8, 0.01, true
case 2: return 22, .9, 0.01, true
case 3: return 23, .9, 0.01, true
case 4: return 38, .9, 0.01, true
case 5: return 42, .8, 0.01, true
case 6: return 45, .9, 0.01, true
case 7: return 46, .8, 0.01, true
case 8: return 47, .9, 0.01, true
case 9: return 61, 0.00001, 0.01, true
case 10: return 63, .3, 0.01, true
case 11: return 67, .3, 0.01, true
}
case 76:
switch disease_symptom {
case 0: return 1, .5, 0.01, true
case 1: return 60, .5, 0.01, true
case 2: return 61, 0.0001, 0.01, true
case 3: return 65, .99, 0.01, true
case 4: return 67, 1, 0.01, true
}
case 77:
switch disease_symptom {
case 0: return 40, .5, 0.01, true
case 1: return 41, .7, 0.005, true
case 2: return 51, .6, 0.001, true
case 3: return 55, .5, 0.01, true
case 4: return 61, 0.0001, 0.01, true
}
case 78:
switch disease_symptom {
case 0: return 19, .4, 0.01, true
case 1: return 37, .5, 0.01, true
case 2: return 38, .8, 0.01, true
case 3: return 57, .5, 0.01, true
}
case 79:
switch disease_symptom {
case 0: return 22, .5, 0.01, true
case 1: return 53, .8, 0.01, true
case 2: return 58, .7, 0.01, true
case 3: return 62, .6, 0.01, true
case 4: return 63, .99, 0.01, true
}
case 80:
switch disease_symptom {
case 0: return 2, .9, 0.01, true
case 1: return 6, .9, 0.01, true
case 2: return 7, .9, 0.01, true
case 3: return 14, .9, 0.01, true
case 4: return 44, .5, 0.001, true
case 5: return 53, .8, 0.01, true
case 6: return 59, .5, 0.01, true
case 7: return 63, .8, 0.01, true
}
case 81:
switch disease_symptom {
case 0: return 7, .8, 0.01, true
case 1: return 14, .8, 0.01, true
case 2: return 22, .5, 0.01, true
case 3: return 53, .8, 0.01, true
case 4: return 58, .8, 0.01, true
case 5: return 61, 0.001, 0.01, true
case 6: return 63, .9, 0.01, true
}
case 82:
switch disease_symptom {
case 0: return 2, .8, 0.01, true
case 1: return 7, .8, 0.01, true
case 2: return 14, .9, 0.01, true
case 3: return 15, .7, 0.01, true
case 4: return 53, .6, 0.01, true
case 5: return 63, .99, 0.01, true
}
case 83:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 50, .9, 0.01, true
case 2: return 62, .5, 0.01, true
}
case 84:
switch disease_symptom {
case 0: return 27, .2, 0.01, true
case 1: return 33, 1, 0.01, true
case 2: return 47, .9, 0.01, true
case 3: return 49, .2, 0.01, true
case 4: return 50, .8, 0.01, true
case 5: return 52, .8, .5, true
}
case 85:
switch disease_symptom {
case 0: return 6, .8, 0.01, true
case 1: return 7, .8, 0.01, true
case 2: return 14, .8, 0.01, true
case 3: return 47, .1, 0.01, true
case 4: return 58, 0.001, 0.01, true
case 5: return 59, .5, 0.01, true
case 6: return 63, .8, 0.01, true
}
case 86:
switch disease_symptom {
case 0: return 7, .5, 0.01, true
case 1: return 64, .9, 0.01, true
case 2: return 65, .9, 0.01, true
case 3: return 66, .9, 0.01, true
}
case 87:
switch disease_symptom {
case 0: return 7, .6, 0.01, true
case 1: return 40, .5, 0.01, true
case 2: return 41, .5, 0.01, true
case 3: return 61, 0.0001, 0.01, true
case 4: return 64, .7, 0.01, true
}
case 88:
switch disease_symptom {
case 0: return 7, .3, 0.01, true
case 1: return 41, .5, 0.01, true
case 2: return 64, .9, 0.01, true
case 3: return 65, .5, 0.01, true
case 4: return 66, .5, 0.01, true
}
case 89:
switch disease_symptom {
case 0: return 1, .9, 0.01, true
case 1: return 67, .9, 0.01, true
}
case 90:
switch disease_symptom {
case 0: return 7, .8, 0.01, true
case 1: return 14, .8, 0.01, true
case 2: return 16, .5, 0.01, true
case 3: return 40, .5, 0.01, true
case 4: return 41, .5, 0.01, true
case 5: return 44, .5, 0.01, true
}
}
return 0, 0, 0, false
}
// Return the question about the given symptom.
question :: proc(symptom : int) -> string {
switch symptom {
case 0: return "¿Estornudas mucho?"
case 1: return "¿Te duelen los ojos, o lagrimeas mucho?"
case 2: return "¿Te duele la garganta?"
case 3: return "¿Tienes ronquera o afonía?"
case 4: return "¿Toses mucho?"
case 5: return "¿Tienes mucosidad nasal muy fluida?"
case 6: return "¿Te duele la cabeza, o sufres, en general, de dolores de cabeza?"
case 7: return "¿Tienes alta temperatura (superior a 37 grados centígrados)?"
case 8: return "¿Te ves obligado, por tu trabajo, a pasar muchas horas respirando aire viciado o polvoriento?"
case 9: return "¿Te pica la nariz?"
case 10: return "¿Tienes la garganta reseca?"
case 11: return "¿Respiras con dificultad y fatiga?"
case 12: return "¿Tienes la nariz muy taponada?"
case 13: return "¿Has tenido recientemente un resfriado u otra infección similar?"
case 14: return "¿Tienes malestar general?"
case 15: return "¿Tienes dificultad para tragar?"
case 16: return "¿Tienes dolores musculares?"
case 17: return "¿Sientes cualquier tipo de dolor en el pecho?"
case 18: return "¿Te han extirpado las amigdalas?"
case 19: return "¿Tus síntomas tienden a aparecer en ataques, y no a estar presentes continuamente?"
case 20: return "¿Tienes una tos productiva, o sea una tos en la que expulsas algo?"
case 21: return "¿Respiras entrecortadamente?"
case 22: return "¿Sudas mucho? (No ya cuando haces un esfuerzo, sino cuando estás físicamente relajado)."
case 23: return "¿Tienes la frecuencia cardiaca elevada? (Normalmente debe estar entre 60 y 80 pulsaciones por minuto, y algo más rápida para personas de edad superior a 70 o inferior a 20)."
case 24: return "¿Sufres ataques de dificultades respiratorias tan fuertes que llegan a preocuparte?"
case 25: return "¿Tienes cianosis, es decir, se te ha puesto la piel de un color ligeramente azulado?"
case 26: return "¿Cuando toses, presentan sangre los esputos?"
case 27: return "¿Estás aturdido o perplejo sobre cuanto acontece a tu alrededor?"
case 28: return "¿Estás (o está el paciente) en estado delirante, hablando incoherentemente y con mala coordinación muscular?"
case 29: return "¿Tienes una tos seca (no productiva)?"
case 30: return "¿Sientes dolor al respirar o al toser?"
case 31: return "¿Has sentido en estos días un dolor muy fuerte en el pecho?"
case 32: return "¿Tienes sensaciones alternantes de frío y calor?"
case 33: return "¿Hace ya tiempo (seis semanas o más) que presentas alguno de estos síntomas?"
case 34: return "¿Tienes los dedos hipocráticos, o en «palillos de tambor»? (Se llaman así cuando las cutículas casi han desaparecido, y las uñas se abomban excesivamente hacia la punta)."
case 35: return "¿Tienes síntomas que aparecen fundamentalmente al realizar algún esfuerzo?"
case 36: return "¿Fumas? responde con el número que resulta de dividir por cinco el número de cigarrillos diarios. El número máximo para la respuesta es 5. Si no fumas, responde -5."
case 37: return "¿Tienes sensaciones de vértigo?"
case 38: return "¿Tienes palpitaciones (sensación de que el corazón late más fuerte, o más rápido, o menos regularmente de lo que debiera)?"
case 39: return "¿Tienes algún tobillo excesivamente hinchado?"
case 40: return "¿Tienes vómitos, o fuertes náuseas?"
case 41: return "¿Sufres de algún tipo de dolor abdominal, o dolor localizado entre las costillas inferiores y las ingles?"
case 42: return "¿Padeces diarrea, o sueles tener crisis de diarrea?"
case 43: return "¿Te han extirpado el apéndice?"
case 44: return "¿Tienes ictericia? (La ictericia no es una enfermedad, sino un síntoma. Con frecuencia es más patente en los ojos: la parte blanca se torna amarillenta)."
case 45: return "¿Te sientes tenso o inquieto?"
case 46: return "¿Te cuesta conciliar el sueño, o te desvelas frecuentemente por la noche?"
case 47: return "¿Tienes contracciones involuntarias o temblores?"
case 48: return "¿Sufres de estreñimiento, o sueles tener crisis de estreñimiento?"
case 49: return "¿Te falla la memoria, tienes dificultad para recordar hechos aislados, ya sea ocasional o regularmente?"
case 50: return "¿Sufres afasia, es decir, has perdido capacidad para expresarte con palabras?"
case 51: return "¿Has tenido alguna hemorragia por el recto?"
case 52: return "¿Eres hombre o mujer? Responde con 5 para hombre y -5 para mujer. Una respuesta 0 hace que el diagnóstico sea independiente del sexo."
case 53: return "¿Tienes rigidez o dolor en el cuello?"
case 54: return "¿Has sufrido algún golpe o herida de cualquier tipo en la cabeza durante las últimas semanas? (Un golpe incluso leve puede ser importante)."
case 55: return "¿Has expulsado recientemente heces de aspecto anormal?"
case 56: return "¿Expulsas muchos gases, por cualquier vía?"
case 57: return "¿Tienes sensaciones repentinas de desmayo, es decir, de sentirte desfallecido y mareado, incluso, quizás con pérdida de consciencia?"
case 58: return "¿Te pica alguna parte del cuerpo, tengas o no erupción en ella?"
case 59: return "¿Tienes alguna erupción o lesión de cualquier tipo en la piel?"
case 60: return "¿Tienes alguna parte del cuerpo entumecida, o con sensación de comezón u hormigueo, como de «agujas y alfileres»?"
case 61: return "¿Es tu peso anormal? Responde con 5 para un peso excesivamente elevado, con -5 si es excesivamente bajo y con 0 si es normal."
case 62: return "¿Sufres de algún dolor en la cara o en la frente?"
case 63: return "¿Tienes algún bulto, hinchazón o abultamiento, en cualquier parte del cuerpo?"
case 64: return "¿Es anormal el color de tu orina?"
case 65: return "¿Orinas con una frecuencia anormal?"
case 66: return "¿Tienes dolores al orinar?"
case 67: return "¿Tienes alguna anormalidad en la visión, como ver borroso o doble, o luces destelleantes? (No cuentan los defectos que pueden corregirse con gafas)."
}
return ""
}
// user_input.odin
//
// This file is part of Experto en enfermedades (Expert on diseases)
// Last modified 20250624T2035+0200.
/*
Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).
Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).
Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.
This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.
*/
// ==========================================================================
package eee
import "../lib/anodino/src/par"
import "../lib/anodino/src/read"
import "core:fmt"
import "core:math/rand"
import "core:strconv"
import "core:strings"
user_input_string :: proc() -> string {
PROMPT :: "> "
fmt.print(PROMPT)
return read.a_string() or_else ""
}
print_menu :: proc() {
when DEBUG_LEVEL == 0 {
par.whole("Comandos:")
} else {
par.whole("Comandos principales:")
}
par.whole("- Consultar")
par.whole("- Finalizar")
when DEBUG_LEVEL > 0 {
par.whole("Comandos para depuración:")
par.whole("- Probar (modo automático con respuestas aleatorias)")
par.whole(fmt.tprintf("- Número de %v a %v (modo automático con respuesta única)", MIN_ANSWER, MAX_ANSWER))
}
}
// Ask the user for permission to start a new consult; return `true` for yes
// and `false` for no.
ready :: proc() -> bool {
for {
print_menu()
answer := strings.to_lower(user_input_string())
switch {
case strings.has_prefix("consultar", answer):
mode = .Normal
return true
case strings.has_prefix("finalizar", answer):
return false
case strings.has_prefix("probar", answer):
when DEBUG_LEVEL > 0 {
mode = .Random_Demo
return true
}
case :
when DEBUG_LEVEL > 0 {
value_demo_mode : bool
demo_value, value_demo_mode = valid_answer(answer)
if value_demo_mode {
mode = .Value_Demo
return true
}
}
}
}
return false
}
press_enter :: proc() {
fmt.println()
par.whole("Pulsa la tecla «intro» para empezar.")
user_input_string()
}
// Check the given user answer string; if it is valid, return its numerical
// value and `true`; otherwise return 0 and `false`.
valid_answer :: proc(answer : string) -> (int, bool) {
switch len(answer) {
case 1:
if ! strings.contains("012345", answer) {
return 0, false
}
case 2:
if ! strings.contains("+-", strings.cut(answer, 0, 1)) {
return 0, false
}
if ! strings.contains("012345", strings.cut(answer, 1, 1)) {
return 0, false
}
case:
return 0, false
}
return strconv.parse_int(answer)
}
// Prompt the user for a valid answer, check it and return it.
user_answer :: proc() -> int {
answer_value : int
for {
par.whole(fmt.tprintf(
"Responde con un número de %v a %v:",
MIN_ANSWER, MAX_ANSWER)
)
par.whole(fmt.tprintf(
"%v (no, nunca) … 0 … %v (sí, siempre)",
MIN_ANSWER, MAX_ANSWER)
)
answer_value = valid_answer(user_input_string()) or_continue
break
}
return answer_value
}
// Return a random number in the range `MIN_ANSWER ..= MAX_ANSWER`.
random_answer :: proc() -> int {
return rand.int_max(MAX_ANSWER - MIN_ANSWER + 1) + MIN_ANSWER
}
// VERSION.odin
//
// This file is part of Experto en enfermedades (Expert on diseases)
// Last modified 20250624T2035+0200.
/*
Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).
Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).
Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.
This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.
*/
// ==========================================================================
package eee
VERSION :: "0.1.0-dev.0.28.2+20250626T0103CEST"
Descargas
La descarga estará disponible tras la publicación del repositorio.
