Уведомления

Группа в Telegram: @pythonsu

#1 Май 30, 2017 01:49:38

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10014
Репутация: +  857  -
Профиль   Отправить e-mail  

Сортировка строк

Rodegast
Например если я захочу проверять начало файла на “server”, то достаточно дописать:
  
s[6:] if s[:6] == "server" else "" [:-3]
А в случае одного среза эта возможность становится не очевидной.
Тут ты вообще создаёшь три строки (каждый срез создаёт строку, кладя всё это в память, и тому подобное). Потом ты ещё должен высчитывать сколько букв в слове server, иначе ты не будешь знать, какую цифру там поставить в срезе. Потом сходу (за секунду) непонятно, что это за выражение; сотня таких выражений в коде - и ты будешь сидеть и целый день разбираться в одном исходнике. Читаемость нарушил, а в Zen сказано “Readability counts.”, не просто так же включено в Дзен.

А к чему приводит ухудшение читаемости? К тому, что ты делаешь ошибку и потом не видишь её, так как над кодом надо слишком долго думать, чтобы её заметить. А когда над кодом надо долго думать, проще предположить, что он правильный, а проверить его потом, когда будет время для этого. Естественно, что так накапливается куча таких кодов, которые типа работают, и времени на них всё никак не находится.

Вот твой код без каких-либо изменений:
  
>>> s = 'server123.sh'
>>> s[6:] if s[:6] == "server" else "" [:-3]
'123.sh'
>>>
Перед отправкой ты его не проверил, он выдаёт совсем не то, что должен. Как же ты допустил эту ошибку в одной строке? Да очень просто - лень было превращать голову в калькулятор.


houey
Если кто знает С++ - я хочу написать полный аналог данной проги на С++, но уже на Python.
Алгоритм неправильный. Обычно выбирают то, что нужно, а не удаляют то, что не нужно. Представь просто, что у тебя миллион элементов и нужен из них только один, зачем удалять 99999 раз элементы, если можно просто один раз взять нужный.

Вот выбор нужных
  
>>> lst = ['server1.sh', 'server3.sh', 'client1.sh', 'server2.sh', '1.sh', '2.sh']
>>> 
>>> out = [i for i in lst if i.startswith('server')]
>>> out
['server1.sh', 'server3.sh', 'server2.sh']
>>>

  
>>> def filt(seq, pat):
...     return [i for i in seq if i.startswith(pat)]
... 
>>> lst = ['server1.sh', 'server3.sh', 'client1.sh', 'server2.sh', '1.sh', '2.sh']
>>> 
>>> out = filt(lst, 'server')
>>> out
['server1.sh', 'server3.sh', 'server2.sh']
>>>

Удаление элементов так же делается
  
>>> def filt(seq, pat):
...     return [i for i in seq if not i.startswith(pat)]
... 
>>> lst = ['server1.sh', 'server3.sh', 'client1.sh', 'server2.sh', '1.sh', '2.sh']
>>> 
>>> out = filt(lst, 'server')
>>> out
['client1.sh', '1.sh', '2.sh']
>>>

Add
Исправил ошибку, указанную Rodegast в сообщении.



Отредактировано py.user.next (Май 31, 2017 03:14:20)

Офлайн

#2 Май 30, 2017 08:46:36

houey
Зарегистрирован: 2017-05-28
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Сортировка строк

В итоге пришел к такому варианту:

 import re
def Match(item, pattern):
  result = item.find(pattern)
  return result >= 0
        
        
def KeyFunction(item):
  pattern = r'(\d+)\.sh$'
  result = re.search(pattern, item);
  if result is None:
    return 0
  return int(result.group(1))
  
  
items = ['server1.sh', 'server3.sh', 'client1.sh', 'client2.sh', 'server2.sh', 'server.sh', 'client.sh']
clients = [it for it in items if Match(it, "client")]
servers = [it for it in items if Match(it, "server")]
clients = sorted(clients, key=KeyFunction)
servers = sorted(servers, key=KeyFunction)
print (clients)
print (servers)

https://repl.it/IXGv

Буду рад услышать советы по улучшению программы.

Теперь, чтобы не создавать новую тему - подскажите, пожалуйста чем лучше воспользоваться чтобы последовательно (не дожидаясь завершения) открывать скрипты?

Офлайн

#3 Май 30, 2017 08:48:51

houey
Зарегистрирован: 2017-05-28
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Сортировка строк

py.user.next
Спасибо большое за ваши советы!
Отписался в теме, не посмотрев новые ответы, в итоге пришел примерно к тому, о чём Вы говорили!

Чуть позже более внимательно перечитаю ваш пост, как появится свободная минутка спасибо!

Отредактировано houey (Май 30, 2017 08:50:46)

Офлайн

#4 Май 30, 2017 12:43:57

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2842
Репутация: +  186  -
Профиль   Отправить e-mail  

Сортировка строк

> Потом сходу (за секунду) непонятно, что это за выражение;

Как раз для этого и существуют комментарии.

> Перед отправкой ты его не проверил, он выдаёт совсем не то, что должен.

Да, точно скобочки забыл Но на суть это не влияет, это была просто демонстрация того что между этими срезами можно ещё что-то вставлять.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#5 Май 30, 2017 15:43:49

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10014
Репутация: +  857  -
Профиль   Отправить e-mail  

Сортировка строк

Rodegast
Как раз для этого и существуют комментарии.
Уахаха, комментарии существуют не для этого. Код должен быть самодокументирован (в основном через понятные имена это делается); вообще, много приёмов там для этого есть, есть даже книжка про ясный код и множество видео, где она перессказывается частями. А комментарии, если и есть, то отвечают на вопрос “почему именно эта строка/оператор/блок здесь, а не другой?”. Короче, алгоритм комментируется обычно, а не код. Если же код неясен без комментария, то это мутный код. Новичковый уровень - писать код, а потом в комментариях разъяснять, что он вообще делает.

Rodegast
это была просто демонстрация того что между этими срезами можно ещё что-то вставлять
Демонстрация-то понятна, но ошибку-то ты допустил. Если ты в одной строке кода ошибку не увидел, то в десяти таких же мутных и подавно не увидишь. Это ещё код писал ты, а вот придёт тебе код от кого-нибудь другого в таком же стиле, сразу поймёшь, что к чему.


houey
Буду рад услышать советы по улучшению программы.
  
def Match(item, pattern):
  result = item.find(pattern)
  return result >= 0
Такое делается через
  
def match(item, pattern):
    return pattern in item



Отредактировано py.user.next (Май 30, 2017 15:48:33)

Офлайн

#6 Май 30, 2017 19:51:12

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2842
Репутация: +  186  -
Профиль   Отправить e-mail  

Сортировка строк

> Короче, алгоритм комментируется обычно, а не код

Комментируется то что может быть не понятным или не очевидным. По этому если что-то в коде может быть не очевидно, то это может быть прокомментировано. Это норма.

> Демонстрация-то понятна, но ошибку-то ты допустил.

Это меня отвлекли, вот скобок я и не поставил. И не в стиле проблема. Вот например у тебя тремя сообщениями выше есть такой код:

 >>> def filt(seq, pat):
...     return [i for i in lst if i.startswith(pat)]
Как видишь функция filt принимает параметр seq, но в теле функции его нигде нет, а в место него используется глобальный список lst. Это ошибка, хотя код и выглядит вполне разборчивым.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#7 Май 31, 2017 03:04:07

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10014
Репутация: +  857  -
Профиль   Отправить e-mail  

Сортировка строк

Rodegast
Это ошибка, хотя код и выглядит вполне разборчивым.
Это очень слабая ошибка, потому что её запуск пропустил. Такое бывает раз на миллион. В реальном коде она бы сразу всплыла, потому что там бы lst не было в глобальном пространстве. У тебя же ошибка именно из-за отсутствия запуска - это классический вариант ошибки, когда код кажется одним, а работает несколько по-другому.

Вот использование кода с моей ошибкой
  
>>> def filt(seq, pat):
...     return [i for i in lst if i.startswith(pat)]
... 
>>> def f():
...     lst = ['server1.sh', 'server3.sh', 'client1.sh', 'server2.sh', '1.sh', '2.sh']
...     out = filt(lst, 'server')
...     return out
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f
  File "<stdin>", line 2, in filt
NameError: global name 'lst' is not defined
>>>

Rodegast
По этому если что-то в коде может быть не очевидно, то это может быть прокомментировано.
Везде рекомендуется переписать код. И такой код сейчас называют модным понятием “код с душком” или “протухший код”. Это как бы и не спагетти, но и качество оставляет желать лучшего.
Даже в Дзене питона есть такая фраза родственная: “If the implementation is hard to explain, it's a bad idea.”
Иными словами, если у тебя код надо описывать комментариями, значит он неясный.
Это как анекдот: если всем и всегда надо объяснять, что там смешного, значит он либо сам плох, либо плохо рассказан.



Отредактировано py.user.next (Май 31, 2017 03:24:54)

Офлайн

#8 Май 31, 2017 10:55:52

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2842
Репутация: +  186  -
Профиль   Отправить e-mail  

Сортировка строк

> Это очень слабая ошибка, потому что её запуск пропустил. Такое бывает раз на миллион…В реальном коде она бы сразу всплыла, потому что там бы lst не было в глобальном пространстве…Вот использование кода с моей ошибкой

Не оправдывайся

> Иными словами, если у тебя код надо описывать комментариями, значит он неясный.

Для меня ясный, для кого-то не очень, а кто-то любой без комментариев не понимает. Это демагогия.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#9 Май 31, 2017 11:28:25

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10014
Репутация: +  857  -
Профиль   Отправить e-mail  

Сортировка строк

Rodegast
Для меня ясный, для кого-то не очень, а кто-то любой без комментариев не понимает. Это демагогия.
Почитай реальные долгоживущие крупные проекты на Github'е, там нигде не найдёшь комментариев таких. Вообще, полезно читать такой код, даже если не понимаешь его полностью, потому что там есть фишки, которые можно перенять.



Отредактировано py.user.next (Май 31, 2017 11:28:44)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version