LINUX.ORG.RU

Покритикуйте говнокод на баше

 


0

2
#!/bin/bash

tput civis
declare -a x
declare -a y
declare -a v
x=( [1]=21 [2]=22 [3]=23 )
y=( [1]=45 [2]=46 [3]=47 )
v=( [1]=1 [2]=1 [3]=1 )
km=3
maxx=$(stty size | awk '{ print $1 }')
maxy=$(stty size | awk '{ print $2 }')

while [[ $km -lt 180 ]]
do
	clear
	for ((i=1; i<=km; i++)); do
		r=$(( ( RANDOM % 4 )  + 1 ))
		case "$r" in
			1)  if [[ $((${x["$i"]}+1)) -lt $maxx ]]; then
				x["$i"]=$((${x["$i"]}+1))
			fi	
    			;;
			2)  if [[ $((${x["$i"]}-1)) -gt 0 ]]; then
				x["$i"]=$((${x["$i"]}-1))
			fi
    			;;
			3)  if [[ $((${y["$i"]}+1)) -lt $maxy ]]; then
				y["$i"]=$((${y["$i"]}+1))
			fi
    			;;
			4)  if [[ $((${y["$i"]}-1)) -gt 0 ]]; then
				y["$i"]=$((${y["$i"]}-1))
			fi
   			;;
		esac
		tput cup "${x["$i"]}" "${y["$i"]}"	
		echo '*'
		v["$i"]=$((${v["$i"]}+1))		
	done # done for

	for ((xi=1; xi<=km; xi++));do
		for ((yi=1; yi<=km; yi++));do
			if [[ $xi -ne $yi ]]; then
				if [[ "${x["$xi"]}" -eq "${x["$yi"]}" ]]; then
					if [[ "${y["$xi"]}" -eq "${y["$yi"]}" ]]; then
						km=$((km+1))
						x[$km]=$(( RANDOM % maxx ))
						y[$km]=$(( RANDOM % maxy ))
						v[$km]=1
						echo $(date +"%F %T %N") "kol-vo muh " "$km" >> /tmp/muhi.log
					fi
				fi	
			fi	
		done
	done # done for2

done # done while
echo 'kol-vo muh= ' "$km"
echo 'maxx= ' "$maxx"
echo 'maxy= ' "$maxy"

tput cnorm

Хотел попробовать поработать с массивами, ну и написал такое. Может гуру что-то подскажут\оптимизируют.

Если бы кто-то показал аналогично работающий код на пайтоне, то я буду благодарен.

★★★

shell - это язык обработки потоков данных. Массивы, вложенные циклы и условия выглядят в нем отвратительно.

tailgunner ★★★★★
()
Ответ на: комментарий от GoNaX

Перл - Pathologically Eclectic Rubbish Lister. Язык обработки текстовых данных на сверхдозе стероидов.

tailgunner ★★★★★
()
maxx=$(stty size | awk '{ print $1 }')
maxy=$(stty size | awk '{ print $2 }')

Юзать echo плохо.

size=`stty size`
maxx=${size%% *}
maxy=${size##* }

А вообще баш говно и не нужен. Спасибо за внимание.

vasily_pupkin ★★★★★
()

Ужасный код, все ужасно

slyjoeh ★★★
()

$((${x[«$i»]}+1))

$(( x[$i] + 1 ))

Внутри $(( .. )) разыменования переменных (внешние) можно опускать.

intelfx ★★★★★
()

Критикую. Твой код слишком хорош для баша.

Bagrov ★★★★★
()

Покритикуйте говнокод на баше

отправил критику на баш, заапрувят - в пятницу почитаешь :) Но в общем от скобачек рябит

slackwarrior ★★★★★
()

Кстати в кейсе ошибка, но поправить пост не могу.

GoNaX ★★★
() автор топика

kol-vo muh

классика

anonymous
()

Говно. Сам такое же пишу.

Amet13 ★★★★★
()
Ответ на: комментарий от anonymous

Верно. У него же не ассоциативный массив, а обычный.

Пояснение ТСу: для обычных массивов внутри квадратных скобок разыменования тоже автоматические. В том числе вне $(( .. )).

declare -a array1
var=1
array1[var]=42
echo $(( array1[var] * 10 ))

но

declare -A array2
var=x
array2[$var]=42
echo $(( array2[$var] * 10 ))
intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 5)

Что конкретно покритиковать?
В суть не вчитывался.
По оформлению - вполне читабельно. Хотя я кое-что писал по-другому:

1. Дело каждого, но я все переменные именую заглавными буквами

2.

x=( [1]=21 [2]=22 [3]=23 )

Почему не
x=( 21 22 23 )

?
Правда тогда индексация с нуля начинается - и правильно.

3.
km=3

Что такое 3? Если длинна массива, то лучше написать
km="${#x[@]}"

По результату - то же, а код более понятный. Если 3 - не длинна массива, то как-то более правильно назвать переменную, или сделать комментарий, объясняющий что такое 3.

И, да, я все значения пишу в двойных кавычках - дабы напоминать себе что в bash всё есть строки.

4.
for ((i=1; i<=km; i++)); do

Тебе нужно пройтись по всем элементам массива то лучше так:
for E in "${x[@]}" ; do

Плюс в том, что будет пропускать «дырки» если таковые есть. Также, не нужно вводить дополнительную переменную km, и не нужно на каждой итерации проверять условия выхода из цикла. Да и вообще более родная для bash конструкция.
Только не забудь двойные кавычки, чтобы значения с пробелами правильно интерпретировались.

5.
if [[ $((${x["$i"]}+1)) -lt $maxx ]]; then
  x["$i"]=$((${x["$i"]}+1))
fi

Когда в блоке if одна команда, проще так:
[[ $((${x["$i"]}+1)) -lt $maxx ]] && x["$i"]=$((${x["$i"]}+1))


6.
case "$r" in

Я люблю вконце писать что-то типа такого:
* ) echo "ERROR in source code" >&2 ;;

ну, и какую-то информацию чтобы было понятно где или почему произошло. Иногда помогает.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Kroz

Также, не нужно вводить дополнительную переменную km, и не нужно на каждой итерации проверять условия выхода из цикла.

Там вроде как km ещё юзается выше уровнем в while, так что возможно, что она всё же нужна.

sT331h0rs3 ★★★★★
()
Ответ на: комментарий от GoNaX

Python, Ruby читаются хорошо. Haskell, С читаются хорошо при знании языка. Perl и Bash читаются плохо всегда.

Aswed ★★★★★
()
Последнее исправление: Aswed (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.