הבעיה היא לא הgoto
-
@שואף
לא הבנתי מה קורה בתוך הפונקציה readAGI?
למה לא לעשות לולאה ולהעביר לפונקציה את מספר הפעמים שהלולאה אמורה לרוץ כל עוד לא התקבל תגובה?
ואם אתה מעביר "0" הלולאה תרוץ לנצח.
ואז מבחוץ זה יראה משהו כזה:$bankInputAkdama = 'ברוך הבא למערכת איתור חשבונות בנק מוגבלים'; $bank = readAGI($bankInputAkdama . TEXT . 'הזן מספר בנק ולסיום סולמית', NUMBERSNOSTAR,1); if (!$bank) $bank = readAGI(TEXT . 'הזן מספר בנק ולסיום סולמית', NUMBERSNOSTAR,0);
אמנם זה לא פותר את הבעיה של חזרה שלב אחד אחורה
אבל במקומות אחרים שלא צריך את זה
הקוד יראה קצת יותר אלגנטי -
@WWW אמר בהבעיה היא לא הgoto:
@חוקר ב API של ימות זה עוד יותר מסובך. כל העניין של חזרה אחורה.
באסטריסק זה הרבה יותר קל.אני לא מכיר עדיין אסטריסק אבל מקטע הקוד שהעתיק כאן @שואף אני לומד שגם שם זה לא קורה מחשבות של המתכנת.., ועדיין הוא צריך לכתוב קוד שמבצע מה יקרה במידה כזו או כזו, אם כן הקיש או לא הקיש.
אז בזה אני לא רואה חילוק בין הAPI של ימות לאסטריסק. -
במקרה של שואף אפשר לעשות בלולאות
אחת על הכל "לבדיקה חדשה הקש כוכבית"
ועל כל מקטע ומקטע עד שהתשובה לא ריקה (והכי טוב להעביר לפוקנציה וכנאמר).
אבל הgoto במקרה של flow של שיחה הוא הגיוני לחלוטין, מותר וצריך להשתמש בו לדעתי,
הטענה שלי הייתה שיעשו משהו גנרי וקל לכאלה מקרים, אבל אני מסכים עם שואף שזה בקלות יכול להסתבך. אני חושב על קובץ כמו XML ששמה עושים את הסתעפויות, כולל תנאים וכו' והקוד יידע להריץ אתת הקובץ הזה ולנהל לפיו שיחה. -
@dovid כשאתה מבקש נתונים מהמשתמש באפליקציית קונסול, (CLI), איך תנהל את זה?
בעצם זה שקול לאותו דבר.....כן הייתי מוסיף את זה לתוך הפונקצייה של ReadAGI כי שם זה לכאורה המקום שלו.
אבל זה הגיוני במרכזייה
הגיוני גם מה שאתה אומר, שאם יש יותר מנתון אחד, שתהיה פונקצייה מרכזית שתדע לקבל הכל (ואולי גם את הולידציות הנדרשות....) -
הנה דוגמא בnodejs
$ node contact.js a # The Above command lauches a prompt ? Enter firstname .. John ? Enter lastname .. Doe ? Enter phone number .. +145**** ? Enter email address .. john.doe@contacto.com New contact added
הכל אוטומטי וגנרי בזכות ספריות מתאימות, זה ההגדרה:
const questions = [ { type : 'input', name : 'firstname', message : 'Enter firstname ..' }, { type : 'input', name : 'lastname', message : 'Enter lastname ..' }, { type : 'input', name : 'phone', message : 'Enter phone number ..' }, { type : 'input', name : 'email', message : 'Enter email address ..' }
זה הקוד! :
prompt(questions).then((answers) => addContact(answers));
-
@dovid אמר בהבעיה היא לא הgoto:
הנה דוגמא בnodejs
א. איך חוזרים שלב בודד אחורה? ולאחר מכן ממשיכים לקבל את הנתון הבא מחדש (למרות שכבר התקבל פעם אחת).
ב. יש לי תנאי, שאם הוא בחר למשל סטטוס אישי = תלמיד ישיבה, אני אצטרך ג"כ לבקש ממנו שיזין את קוד הישיבה, ואחרת אין צורך לדרוש נתון זה.
איך מתמודדים עם זה? -
@nigun לא נראה לי שזה אמור להיות מורכב, קח פונקציה כזו
function buildQuestions (questions) { var answers = {}; for (var i = 0; i < questions.length; i++) { var question = questions[i]; var input = read(question); answers[question.name] = input; } return answers; } function read (question) { var input = readAGI(question.massage, question.type); if (!input && question.isRequired && question.tryAgain) { --question.tryAgain; return read(question); } return input; }
ותעביר לה גייסון כמו שדוד הציע, תוסיף לגייסון שדות כמו isRequired tryAgain ויש לך קוד שיתאים לכל השיחות
-
צורת הדברים כבר נידונה והתבשלה כאן
https://tchumim.com/post/59303
ועדיין אין לי פיתרון לשלוחה שאמורה להיות עם תפריטים ותפריטי משנה וכו'.
אציין שלכן אני עדיין לא עברתי לצורת העבודה של מערך נתונים נדרשים, כי לרוב אני מתחיל עם תפריטים וכו, ורק בשלב כלשהוא יש לי למשל רישום שאני עובד כעת לקבל רשימת נתונים בזה אחר זה.
ולכן יותר נוח לי לעבוד על ידי שאני דורש נתון נתון ומבצע פקודות לפי הנתון שקיבלתי -
@חוקר שקול כתיבה בצורה כזו
const questions = { firstname: { type: 'input', name: 'firstname', message: 'Enter firstname ..', nextStep () { if(answers.talmid) return this.yeshivaCode; else return this.otherStep } } }
אפשר לשכלל את זה ולעבוד עם שני סוגי מחלקות, מחלקת Menu ומחלקת Question, כל תפריט יכיל מערך של שאלות, וה nextStep או שיחזיר את השאלה הבאה או מופע של תת תפריט.
ואל תאמר מה לי ולצרה זו, ההשקעה שווה. לא לחינם דוד התחלחל למראה הקוד הפרוצדורלי, קשה לי להבין איך מתחזקים כזה קוד, קוד כזה עם תתי תפריטים הופך להיות בלתי אפשרי לתחזוקה, אם תעבוד מונחה עצמים אני בטוח שתרגיש את ההבדל -
@יוסף-בן-שמעון
הקושי שלי הוא כזה, ליצור בתחילת הקוד אובייקט עם כל סוגי הסיטואציות שאולי יהיו בדף בתת תפריט של תת תפריט, והכל יככב לי בראש הקוד, הוא מאוד מאוד מסורבל, ויזיק יותר משיועיל, כי אני חייב לראות מול העיניים בכל שלב את השלב שלפניו.
דוגמא פשוטה לבעיה, אחד הערכים שאני משתמש הוא איזה ספרות לאפשר למאזין להקיש בתפריט/השאלה הנוכחית, ואם עשיתי תפריט שבתחילת כתיבת הקוד חשבתי לתת לו לבחור את האפשרויות 1258 בלבד, ולאחר כתיבת הקוד אני מחליט להוסיף את אפשרות 7 לתפריט, אז אני מוסיף תנאי באם ההקשה שווה 7 מה לבצע, אך אני חייב לזכור להוסיף למקשים המותרים את 7 וס"ה יהיה 12578, וכן לשנות בהודעת התפריט את החלק הנוסף.
אם המערך יהיה למעלה, אני יסתובב הלוך ושוב ואני ישאיר חלקים לעדכון אח"כ ואני ישכח וכו'.
אם אני רואה לפני כל שלב את השלב שלפניו אני יזכור יותר טוב ויוכל ביותר גמישות להוסיף שלבים וכו'.
לכן אני חשבתי לעשות כך:
יהיה לי בתחילת הקוד אובייקט ריק שאני יגדיר שבכל פעם שאני קורא לפונקציית read זה יאכלס לאובייקט (אם לא קיים) את ההגדרות ושם הערך הנוכחי, ואז אני חוזר לנקודה שיש לי אובייקט של ההגדרות, ומאידך אני בונה אותו לפי התקדמות הקוד והתפריטים.
וכעת אוכל כבר להוסיף בהגדרות ערך בשם first ששם אוכל לכתוב את שם השלב הקודם, ואז בהקשה על המקש הייעודי נניח כוכבית הפונקציה תדרוש מחדש את הקשת הערך הקודם, לפי ההגדרות המאוכלסות באובייקט.