- 1
- 2
- 3
- 4
- 5
def f(x):
return x.strip()
lines = map(f, open("1.txt", "r"))
open("1.txt", "w").write(" ".join(lines))
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−105
def f(x):
return x.strip()
lines = map(f, open("1.txt", "r"))
open("1.txt", "w").write(" ".join(lines))
ХАСКЕЛЕПРОБЛЕМЫ™. Теперь и в питоне.
Исходный файл содержит 3 строчки:
just
as
planned
Питон 2.7:$ python2.7 1.py
$ cat 1.txt
just as planned
Питон 3.0:$ python3.2 1.py
$ cat 1.txt
bormand 09.03.2013 23:44 # 0
tirinox 10.03.2013 11:27 # +3
wvxvw 10.03.2013 00:04 # 0
Можно и без дополнительных функций.
bormand 10.03.2013 00:15 # 0
Большое спасибо, не знал такой фишки.
Но хаскелепроблема то не в этом ;)
Dummy00001 10.03.2013 02:15 # +2
bormand 10.03.2013 07:08 # +2
Но вот на случаях, когда первый генератор имеет побочный эффект теперь получается вот такой вот фейл. В данном случае питон успел потереть файл вторым open'ом задолго до того, как прочитал из него первую строку.
myaut 10.03.2013 07:21 # 0
bormand 10.03.2013 09:14 # 0
Да не совсем как бы ОК... скрипт работал-работал, попробовал портануть под python3 - начал херить файлы. Все-таки в питоне3 полно несовместимостей с двойкой.
> Это к тому же шеллопроблемы
Да я в курсе, еще когда с линуксом только-только начинал знакомиться нарвался на эту траблу, только вместо grep'а был sed... Кстати если обобщить - это проблема любых ленивых конвейеров.
eth0 10.03.2013 19:32 # +1
А мне кажется, что это очень и очень годно. Даже несмотря на кучу похеренного софта. Даже несмотря на необходимость выучить принципиально новый язык.
Это того стоит.
lig 13.03.2013 12:23 # 0
А в вашем мире тестов не придумали?
bormand 13.03.2013 13:42 # 0
Признайтесь, вы всегда пишете тесты для не mission-critical утилит в 20 строчек?
Lure Of Chaos 14.03.2013 11:45 # +1
Dummy00001 10.03.2013 12:28 # 0
не правда. к шелу данная проблема относится очень слабо.
шел интерпретирует сроку комманды в один проход, в следующий проход открывает файлы, в следущий проход запускает комманды. поэтому cat всегда будет видеть пустой файл. ничего не lazy, все очень детерминистично.
да и каждый админ знает что "> filename" в шелле есть самый быстрый способ обнулить файл.
Dummy00001 10.03.2013 12:34 # 0
"когда первый генератор имеет побочный эффект теперь получается вот такой вот фейл."
ацтой.....
теперь я понимаю почему после путхона 3го, народ начал еще более активно форкать 2ую версию.
roman-kashitsyn 10.03.2013 12:51 # +1
Всем давно известно, что ленивая обработка данных весьма хреново сочетается с побочными эффектами. Я за то, чтобы map был ленивым. Хочется неленивой обработки - есть for и list comprehensions.
Третий Python устранил много фейлов второго, и когда-нибудь его вытеснит. Бубунта последняя вроде на тройку окончательно перешла.
Dummy00001 10.03.2013 13:19 # 0
Но нет неленивого map'а.
> Третий Python устранил много фейлов второго [...]
Но как я вижу - так же добавил новых.
Как я на эту тему не думаю, все равно не могу себе представить жизнь на "there is only one true way to do this" языках.
bormand 10.03.2013 14:05 # +2
Ну можно вот так делать, если ленивость мешает: Ленивость в мапе то фишка то хорошая, годная. Просто за что не люблю питон - 3.0 и 2.0 не совместимы чуть более чем полностью.
Отношение Гвидо к разрабам: "Мы пилим новый убер-язык, идите нахуй со своими наработками".
roman-kashitsyn 10.03.2013 14:25 # +2
Прекрасно. К тому же, на деле всегда there is more than one way (особенно, когда дело уходит дальше hello world), но есть среди них есть самый краткий, читабельный, понятный и идиоматичный.
wvxvw 10.03.2013 02:28 # 0
Или join теперь использует yield?
wvxvw 10.03.2013 02:38 # +1
roman-kashitsyn 10.03.2013 11:30 # +3
Мне кажется, str.strip выглядит понятнее
wvxvw 10.03.2013 16:56 # 0
Но на самом деле добиться полного соответствия изначальному коду не удасться, т.е. если бы у нас был еще какой-нибудь Foo.strip, то ничего бы не получилось.
Vindicar 10.03.2013 17:10 # 0
Чорд, не дочитал.
bormand 10.03.2013 20:52 # 0
В моем говнокоде с отдельной функцией работает duck-typing, и мапать можно как обычные строки, так и юникодные, так и вообще все что угодно, лишь бы у него был strip().
В вашем же случае всегда вызывается метод класса str, с вот такими последствиями: TypeError: descriptor 'strip' requires a 'str' object but received a 'unicode'. Хотя в данном конкретном случае все будет работать.
roman-kashitsyn 10.03.2013 21:00 # +1
bormand 10.03.2013 21:15 # 0
roman-kashitsyn 12.03.2013 16:17 # 0
someone 10.03.2013 09:28 # +2
bormand 10.03.2013 09:55 # +1
А насчет в любом случае не согласен. С большими двоичными файлами часто такое не прокатит по соображениям производительности и места на диске.
Lure Of Chaos 10.03.2013 11:15 # +4
прокатит по соображениям производительности
и места на диске
а вы представьте, что надо зашифровать/дешифровать/упаковать/распаковать файл, или любую другую трансформацию. и в процессе ее оказывается, что входящий блок меньше исходящего... а файл, по определению, не резиновый, и исходящий блок просто потрет следующий входящий - эпикфейл.
так что местом на диске придется запастись... что касается производительности, то операция переименования/перемещения файла весьма дешева (в сравнении, скажем, с самой трансформацией, или тупо копирования).
поэтому архиватором @bormandа пользоваться не буду o_O
bormand 10.03.2013 11:32 # 0
> а вы представьте, что надо зашифровать/дешифровать/упаковать/распаковать файл, или любую другую трансформацию
> поэтому архиватором @bormandа пользоваться не буду o_O
А я и не предлагаю такую методику для подобных трансформаций ;)
А сам юзал запись в тот же файл без транзакции через переименование т.к. файл все равно временный, даже если он похерится или запишется не до конца - хрен бы с ним, в следующий раз заново сгенерится. А лишнюю строчку с переименованием писать было влом.
Lure Of Chaos 10.03.2013 11:42 # +1
я не буду рад проге, которая ни результат не сделает, да еще и мои файлы похерит. а все потому, что автор поленился написать одну строчку.
bormand 10.03.2013 11:48 # 0
Да я на самом деле не меньший параноик, но в данном случае (костыль, допиливающий пару строк в мейкфайле сразу после его генерации) проблем не вижу. Да и в старом питоне сфейлиться он мог только если место на диске кончилось, или при краше во время записи, что довольно маловероятно, и исправляется перегенерацией.
Lure Of Chaos 10.03.2013 11:54 # 0
кончилось, или при краше во время записи
или так сложились звезды. иногда вылетит Error - не поймаешь фейлится там, и по такой причине, откуда совсем не ждешь
bormand 10.03.2013 11:43 # 0
Lure Of Chaos 10.03.2013 11:57 # +2
к тому же, если это небольшой мейк, то можно его сначала полностью считать в память.
bormand 10.03.2013 12:00 # 0
LispGovno 10.03.2013 14:32 # −2
3.14159265 12.03.2013 16:10 # +2
anonimb84a2f6fd141 31.03.2013 23:13 # +1
Теперь по поводу перехода на третий питон. Радуйтесь своему спиду. Хотели суперпупер динамический язык, где в принципе нельзя даже переменную обьявить (аналог use strict)? Где к переменной можно обратиться как к var или как к "var"? Получите, а теперь резво радуйтесь, что статический анализ и рефакторинг не работают вообще никак и писать на этом уебище без тестов вообще нельзя, т.к. отвалиться может вообще все, что угодно и выяснится это только в момент выполнения того участка кода.
roman-kashitsyn 31.03.2013 23:15 # +4
Я всё больше убеждаюсь, что без тестов нельзя писать вообще ни на чём.
anonimb84a2f6fd141 01.04.2013 19:35 # 0
Ну а кто пишет бинарную (де)сериализацию без тестов, тот ССЗБ.