-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkii.sh
More file actions
executable file
·451 lines (374 loc) · 11.8 KB
/
kii.sh
File metadata and controls
executable file
·451 lines (374 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
#!/bin/bash
#
# Author: Oleg A. Deordiev
# For: LITKK
# Developed: 2015
#
# Programm for learn some text with check itself
#
###########################################################################
readonly VERSION="0.1.4" # Program version
readonly FILE="./trainer.lst" # File contained questions and ansvers
readonly MAXERR=12 # Threshold of max eventually errors
readonly MISNUM=3 # Threshold, after that make insert
NUMTRY=$MAXERR # Count of errors, it control threshold
COUNTER=0 # Counter multipurpose
FARR[0]=0 # Array contain questions and ansvers
USERAND= # Flag set/unset random sequesnce
lowbord= # Threshold low sting
highbord= # Threshold high string
RANDSEQ= # Randomized sequence of strings
STRINGTXT= # File string to variable
NUMSTRING= # Number of string
USERNUMSTR= # User choise number of string
userchoise= # User choise for program question
ERRQ[0]=0 # Array failed questions (pointer)
SOLVEDERR=0 # How many erros, re-ansvered
INSERTCOUNT=0 # Count turns after that make insert
ERRCOUNTER=0 # Counter of recheck question
GOODQUEST=0 # Count of good passed questions
HITTCTRL=1 # How many HIT can by for PASS ( > 0 )
###########################################################################
# Function check user ansver Yes or No
yesnofun() {
TEXTMSG="$1"
USERANSVER=
while true
do
echo $TEXTMSG" [Yes/No]"
read -s USERANSVER
if [[ $USERANSVER =~ ^([yY][eE][sS]|[yY])$ ]]
then
USERANSVER=0
break
elif [[ $USERANSVER =~ ^([nN][oO]|[nN])$ ]]
then
USERANSVER=1
break
else
echo -e $USERANSVER" - не правильный выбор, используйте Yes или No\n"
continue
fi
done
return $USERANSVER
}
# Request user to input numbers
numinfun() {
TEXTMSG="$1"
USERANSVER=
while true
do
echo $TEXTMSG
read USERANSVER
if [[ $USERANSVER =~ ^[[:digit:]]{1,}$ ]]
then
break
else
echo -e "Введнный символ: $USERANSVER, нельзя использовать (это число?), попробуйте ещё раз\n"
continue
fi
done
retval=$USERANSVER
return 0
}
goodansver() {
tput setaf 3
echo -e "\tВаш ответ правильный!\n"
tput sgr 0
echo -e "\tОригинал для сравнения: "$RIGHTANS"\n"
tput sgr 0
# Detect, if this turn was inserted
if [[ $MISNUM -eq $INSERTCOUNT ]] && [[ 0 -ne $ERRCOUNTER ]]
then
# If this recheck, add as solved
SOLVEDERR=$(($SOLVEDERR+1))
# Exclude pointer from array
for i in $(seq 0 $ERRCOUNTER)
do
# Search current value
if [[ ${ERRQ[$i]} == $USERNUMSTR ]]
then
ERRQ[$i]="OK"
break
fi
done
# Reset counter if we have remain attempts
if [ $NUMTRY -ne 0 ]
then
INSERTCOUNT=0
fi
# If this turn was usual, while erros 0
elif [[ $MISNUM -eq $INSERTCOUNT ]] && [[ 0 -eq $ERRCOUNTER ]]
then
GOODQUEST=$(($GOODQUEST+1))
else
GOODQUEST=$(($GOODQUEST+1))
fi
echo -e "\n\n\nНажмите Enter для продолжения!\n"
read
clear
}
badansver() {
echo -e "\tОтвет был таков: $(tput setaf 5)"$RIGHTANS"$(tput sgr 0)\n"
# If this recheck MISS question, disable counter
# and add pointer with error
if [[ $MISNUM -gt $INSERTCOUNT ]]
then
if [ $NUMTRY -ne 0 ]
then
NUMTRY=$(($NUMTRY-1))
fi
if [ $NUMTRY -eq 0 ] && [[ $ERRCOUNTER -eq $SOLVEDERR ]]
then
echo "Вы ответили на все вопросы из заданого диапазона"
echo -e "Выполнено завершение программы\n"
read
exit 0
fi
# Point to not ansvered question
ERRQ[$ERRCOUNTER]=$USERNUMSTR
# After add pointer, shift to next item
# increase error count
ERRCOUNTER=$(($ERRCOUNTER+1))
INSERTCOUNT=$(($INSERTCOUNT+1))
# If this error occured while recheck exist error
# not add error as dublicate
elif [[ $MISNUM -eq $INSERTCOUNT ]]
then
# Disable counter if this rotate beyond of count trying
if [ $NUMTRY -ne 0 ]
then
# If this question is not ansvered, reset counter
# and after 3 normal question, call not ansvered question
# controlled with this counter
INSERTCOUNT=0
fi
fi
echo -e "\n\n\nНажмите Enter для продолжения!\n"
read
clear
tput sgr 0
}
################################################################
if [ -f "$FILE" ]
then
echo -e "\nФайл $FILE доступен для чтения"
else
echo -e "\nФайл $FILE не обнаружен\n"
read
exit 1
fi
# Read file to array (as is, without filtering)
readarray -t TMPFARR < $FILE
echo -e "Содержимое файла $FILE прочитано в память\n"
# Get number of plain strings
RAWSTRNUM=${#TMPFARR[@]}
COUNTER=0
echo "Начата обработка строк"
for i in $(seq 0 $RAWSTRNUM)
do
echo -ne "."
# Replace continuous multiple spaces by one
TMPFARR[$i]="$(echo "${TMPFARR[$i]}" | sed -e "s/[[:space:]]\+/\ /g")"
# Skip empty string from file
if [ $i -ne $RAWSTRNUM ]
then
if [ -z "${TMPFARR[$i]}" ]
then
echo -e "Cтрока "$i" в файле пустая, она не будет использоваться"'\n'
continue
fi
else
echo ">"
echo "Анализ массива строк завершен на строке: "$i
echo "после обработки осталось строк: "$COUNTER
continue
fi
# Skip comments from file
if $(echo ${TMPFARR[$i]} | grep "^#" > /dev/null 2>&1)
then
continue
fi
# If symbol * occur often then 1 times
# count number of fields
NFIEL="$(echo "${TMPFARR[$i]}" | awk -F '*' '{print NF}')"
if [ 2 -ne $NFIEL ]
then
echo "В строке "$i" обнаружено не правильное количество полей разделенных символом [ * ]"
echo "Такое решение принято, так как в строке найдено "$NFIEL" пол(я/е/ей), а должно быть 2"
echo "Из-за этой ошибки, строка не будет использоваться"
echo -e "Проанализируйте ошибочную строку: ["$TMPFARR[$i]"]"'\n'
NFIEL=
continue
fi
# Write to normal array from temporary (after filtering)
FARR[$COUNTER]=${TMPFARR[$i]}
COUNTER="$(($COUNTER+1))"
done
COUNTER=0
NUMSTRING=${#FARR[@]}
# Request user range
if yesnofun "Использовать случайный порядок?"
then
if yesnofun "Указать диапозон вручную?"
then
while true
do
numinfun "Укажите нижний порог"
lowbord="$retval"
if [[ $lowbord -gt $NUMSTRING ]]
then
echo -e "Нижний порог не может быть больше количества всех строк: $NUMSTRING\n"
continue
else
break
fi
done
while true
do
numinfun "Укажите верхний порог"
highbord="$retval"
if [[ $highbord -gt $NUMSTRING ]]
then
echo -e "Верхний порог не может быть больше количества всех сторк: $NUMSTRING\n"
continue
elif [[ $lowbord -gt $highbord ]]
then
echo -e "Верхний порог не может быть меньше чем нижний порог: $lowbord\n"
continue
else
break
fi
done
# From there NUMSTRING - is number of strig (not a upper limit)
readonly NUMSTRING=$(($highbord-$lowbord))
else
echo -e "Будет использован диапозон: 0 - $NUMSTRING\n"
lowbord=0
highbord=$NUMSTRING
fi
# Randomize sequence to array
COUNTER=0
for i in $(seq $lowbord $highbord | sort -R)
do
RANDSEQ[$COUNTER]=$i
COUNTER=$(($COUNTER+1))
done
USERAND="YES"
else
USERAND="NO"
lowbord=0
highbord=$NUMSTRING
fi
userchoise=
clear
COUNTER=0
while true
do
echo "Отсчёт строк начинается от: "$(tput setaf 3)$lowbord$(tput sgr 0)
echo "Всего строк: "$(tput setaf 3)$NUMSTRING$(tput sgr 0)
echo "Идеальный порог ошибок: "$(tput setaf 3)$MAXERR$(tput sgr 0)
echo "Осталось допустимых ошибок: "$(tput setaf 3)$NUMTRY$(tput sgr 0)
echo "Правильных ответов: "$(tput setaf 3)$GOODQUEST$(tput sgr 0)
echo "Допущено ошибок: "$(tput setaf 3)$ERRCOUNTER$(tput sgr 0)
echo "Исправленно ошибок: "$(tput setaf 3)$SOLVEDERR$(tput sgr 0)
echo "Количество правильных частей для прохождения: "$(tput setaf 3)$HITTCTRL$(tput sgr 0)
echo "---DEBUG---"
echo "Версия программы: "$(tput setaf 3)$VERSION$(tput sgr 0)
echo "Установленный порог ходов до вставки: "$(tput setaf 3)$MISNUM$(tput sgr 0)
echo "Отсчет ходов до вставки (если есть ошибки): "$(tput setaf 3)$INSERTCOUNT$(tput sgr 0)
echo "___________________________"
# If this is first turn
if [[ $MISNUM -gt $INSERTCOUNT ]]
then
if [ $USERAND == NO ]
then
numinfun "Укажите номер строки:"
USERNUMSTR="$retval"
echo -e "Вы ввели: $USERNUMSTR\n"
COUNTER=$(($COUNTER+1))
if [[ $USERNUMSTR -gt $highbord ]]
then
echo "Ввдёное число: $USERNUMSTR, слишком большое"
echo "Попробуйте ввести любое число меньшее чем $highbord"
continue
fi
elif [ $USERAND == YES ]
then
if [ $COUNTER == $NUMSTRING ]
then
echo -e "\nВы ответили на все вопросы из выбраного диапозона\n"
exit 0
fi
USERNUMSTR=${RANDSEQ[$COUNTER]}
COUNTER=$(($COUNTER+1))
echo "В качестве номера строки выбрано: $USERNUMSTR"
fi
# Insert question from error array, if error counter not 0
elif [[ $MISNUM -eq $INSERTCOUNT ]] && [[ 0 -ne $ERRCOUNTER ]]
then
# Insert question from not ansvered array
for i in $(seq 0 $ERRCOUNTER)
do
if [[ ${ERRQ[$i]} == "OK" ]]
then
continue
else
USERNUMSTR=${ERRQ[$i]}
echo "Произведена вставка вопроса на который был дан не верный ответ"
echo -e "В качестве номера строки выбрано: "$USERNUMSTR'\n'
COUNTER=$(($COUNTER+1))
break
fi
done
fi
# Start QUESTION
echo -e "Вопрос: $(tput setaf 2)"${FARR[$USERNUMSTR]} | awk -F'*' '{print $1'\n'}'
tput sgr 0
echo -e "Введите ответ:\n"
# Read second part after * and remove spaces
ORIGSTRING="$(echo ${FARR[$USERNUMSTR]} | awk -F "*" '{print $2}' |sed -e "s/[[:space:]]\+/*/g")"
# Count numbers of fields in original string
ORIGFIL="$(echo "$ORIGSTRING" | awk -F "," '{print NF}')"
for i in $(seq 1 $ORIGFIL)
do
ORIGARR[$i]="$(echo "$ORIGSTRING" | awk -v i=$i -F ',' '{print $i}')"
done
# Get user ansver
read userchoise
ANSSTRING="$(echo "$userchoise" | sed -e "s/[[:space:]]\+/*/g")"
userchoise=
# Count numbers of fields in user string (ansver)
ANSFIL="$(echo "$ANSSTRING" | awk -F "," '{print NF}')"
for i in $(seq 1 $ANSFIL)
do
ANSARR[$i]="$(echo $ANSSTRING | awk -v i=$i -F ',' '{print $i}')"
done
HIT="0"
# Start comaprsion
for i in $(seq 1 $ORIGFIL)
do
for a in $(seq 1 $ANSFIL)
do
ORIGCOMP="$(echo ${ORIGARR[$i]} | sed -e "s/*//g")"
ANSCOMP="$(echo ${ANSARR[$a]} | sed -e "s/*//g")"
if [ "$ORIGCOMP" == "$ANSCOMP" ]
then
HIT=$(($HIT+1))
fi
done
done
RIGHTANS="$(echo $ORIGSTRING | sed -e "s/*/\ /g")"
if [ $ORIGFIL -eq $HIT ]
then
goodansver
elif [ $HIT -ge $HITTCTRL ]
then
echo -e "\tВы набрали $(tput setaf 6)$HIT$(tput sgr 0) очков из $(tput setaf 2)$ORIGFIL$(tput sgr 0) возможных, но этого достаточно\n"
goodansver
elif [ $ORIGFIL -gt $HIT ] && [ $HIT -lt $HITTCTRL ]
then
echo -e "\tВы набрали $(tput setaf 6)$HIT$(tput sgr 0) очков из $(tput setaf 2)$ORIGFIL$(tput sgr 0) возможных, и этого не достаточно\n"
badansver
fi
done