Pull to refresh
8
0
Send message
Элегантное решение! Не было случаев, когда PDF отличается от актуального содержимого, или содержит меньше страниц?
К сожалению, принтер любые комментарии поддержки безусловно классифицирует как проплаченные наркоманским лобби (естественно, при помощи биткоинов, вырученных от продажи детского порно), тогда как негативные воспринимает как единственно здравые, интересы которых необходимо защищать. Селективное мышление во всей его красе.
Может, ну хоть теперь наконец-то запретят криптографию и tor.
Думаете, они соединены последовательно? Но лампочки бы тогда горели вообще все без разбору, разве нет?
Там под ними лампочки горят, возможно, по угасанию лампочки?

Интересно еще, питание для электроники, которая собирает электричество из этих батареек, берется все из тех же батареек?
А что случается с дохлыми батарейками, когда они окончательно становятся дохлыми?
Странно, что никто не вспомнил про лица Чернова. Автор, если вы сделаете лица котов вертикально асимметричными, и замените рандомы на внешние параметры, получится отличное средство визуализации — количество степеней свободы у кошачьих лиц будет поболее, чем у человечьих :)
Наверняка фотошоп пиратский.
Для мужчин это нормально.
Пользуясь случаем, хотел бы разместить объявление:

Куплю доллары на вес, от 400 рублей за килограмм. Год выпуска, состояние и номинал купюр значения не имеют.
Вы хотите сказать, что имеет место подлог? Шестеренки нарисовали жадные до славы идиоты-ученые?
Вы не правы. HASP выполняет шифровку/расшифровку произвольных данных при помощи симметричного алгоритма с зашитым ключом, содержит собственные часы и перезаписываемую память. Все это можно и нужно использовать. Проверка только наличия ключа — плохая практика.
Я не увидел в посте уточнения, о каком типе софта идет речь — возможно, о бухгалтерском, и попросить друга ФЛП Васисуалий Веревочкин купить за деньги взломщика еще один экземпляр на свое имя, должно быть тривиальным.
Я, возможно, сейчас глупость скажу — но что если взломщик получит два или больше экземпляров программы — что помешает ему в таком случае обнаружить отличия и тем самым выяснить точное место в коде, где создаются вотермарки?
Т.е. вы уменьшаете клиентам объем памяти без уведомления и необходимости?
«Всегда писать скобки после print» чревато этим:
>>> print('Hello', 'world')
('Hello', 'world')
>>> from __future__ import print_function
>>> print('Hello', 'world')
Hello world


Насчет logging разумно, но это если нужно полноценное логгирование. Для целей отладки, как мне кажется, callback достаточно, но тут мы истины не найдем, т.к. любой подход хорош по своему.
1. Классы лучше называть с большой буквы, чтобы визуально отличать их от переменных, содержащих экземпляры классов этого типа. Т.е. sudoku_generator.Grid вместо sudoku_generator.grid.

2. Наследуйте объекты от object — в Python 2 это избавит от неожиданностей в виде ограниченного поведения old-style classes, тогда как в Python 3 классы и так наследуются от object по-умолчанию.

3. Избегайте использования прямых вызовов print(). Если требуется отладочный вывод, дайте возможность пользователю задать свой собственный print_callback в __init__-е:
	def __init__(self, n = 3, print_callback = lambda *args, **kwarg: None):
		self.__print_callback = print_callback
		...
		self.__print_callback('The base table is ready!')


4. Используйте from __future__ import print_function в целях увеличения переносимости кода. Таким образом, print() станет функцией и код будет переносим между Python 2 и Python 3.

5. Не делайте публичными те поля класса, изменение которых после создания экземпляра класса может сломать его работу. Если хотите предоставить пользователю возможность узнать значение поля после создания экземпляра, используйте свойства:
class Grid(object):
	n = property(lambda self: self.__n)
	
	def __init__(self, n = 3):
		self.__n = n


6. Не используйте обычное деление x / y там, где вам точно нужен целочисленный результат — используйте целочисленное деление x // y. from __future__ import division включит это поведение в Python 2 для облегчения перехода.

7. Пустой метод sudoku_generator.Grid.__del__ кроме бесполезности, еще и немножко вреден — в зависимости от реализации, __del__ либо затрудняет, либо делает невозможной сборку мусора. В данном случае от метода лучше избавиться.

8. Код вида for x in range(len(foo)): bar(foo[x]) как правило, можно заменить на for x in foo: bar(x).

9. В random.randrange не нужен третий аргумент, если он равен 1, и не нужен первый аргумент, если он равен 0, т.к. это значения по умолчанию. Таким образом, random.randrange(0, N, 1) равноценно random.randrange(N).

10. В Python 2 xrange более эффективен, чем range, т.к. возвращает итератор, а не список, но в Python 3 range ведет себя, как xrange, а xrange не существует. Следует заменить все вхождения range(...) на list(range(...)), а xrange(...) на range(...), и постараться использовать range (бывший xrange) везде, где не используются методы list-а.

11. В if и while необязательны скобки вокруг условий.

12. В sudoku_generator.Grid.swap_rows_small цикл по выбору line2 может длиться сколько угодно долго, плюс имеет место дублирование кода. Возможно, было бы лучше переписать функцию следующим образом?
	def swap_rows_small(self):
		r'''Swap two rows.
		
		'''
		
		# случайные разные строки в пределах района
		line1, line2 = random.sample(range(self.__n), 2)
		
		# получение случайного района
		area = random.randrange(self.__n)
		
		# строки для обмена
		N1 = area * self.__n + line1
		N2 = area * self.__n + line2
		
		self.__table[N1], self.__table[N2] = self.__table[N2], self.__table[N1]


13. То же относится к sudoku_generator.Grid.swap_rows_area:
	def swap_rows_area(self):
		r'''Swap two area horizon.
		
		'''
		
		# случайные разные районы
		area1, area2 = random.sample(range(self.__n), 2)
		
		for i in range(self.__n):
			N1, N2 = area1 * self.__n + i, area2 * self.__n + i
			self.__table[N1], self.__table[N2] = self.__table[N2], self.__table[N1]


14. Вместо косвенного вызова вида Grid.foo(self) лучше использовать прямой вызов self.foo().

15. Метод sudoku_generator.Grid.mix использует eval — это не очень хорошая идея, т.к. каждый вызов заново дергает компилятор со всей обвязкой. Вообще eval, compile и exec в прикладных задачах нужны, как правило, крайне редко. Функцию можно переписать следующим образом:
	def mix(self, amt = 10):
		mix_func = (
			self.transposing,
			self.swap_rows_small,
			self.swap_colums_small,
			self.swap_rows_area,
			self.swap_colums_area,
		)
		
		for i in range(amt):
			random.choice(mix_func)()


16. В функции выше я также заменил выбор элемента по случайному индексу array[random.randrange(len(array))] на прямой выбор элемента random.choice(array) — меньше промежуточных шагов и понятнее решение.

17. В функции выше неправильно использован range — при отсчете от 1 количество раз, которые была применена трансформация, будет на 1 меньше. Т.е. при amt = 1 вообще ничего не произойдет.

18. Старайтесь использовать tuple ((a, b, c)) вместо list ([a, b, c]) в статических структурах — там, где не потребуется последующая модификация. Это позволит компилятору уменьшить объем памяти, потребляемой структурой, и создавать ее единожды вместо пересоздания при каждом вызове mix()

19. Для создания повторяющихся строк можно использовать умножение — "-" * 10 == "----------", а "-*=" * 3 == "-*=-*=-*=".

20. Код в конце модуля sudoku_generator лучше было бы сделать частью класса sudoku_generator.Grid.

21. Именовать методы, как и описывать docstring-и лучше в present indefinite — def transpose(self): '''Transpose grid''' вместо def transposing(self): '''Transposing grid''', таким образом, вызовы методов звучат, как действия.

22. Код модуля solver, похоже, принадлежит перу другого автора :) К нему претензий нет, написан очень хорошо.
Сеть на лазерных указках?
Прекратить создание технических условий? Т.к. пакеты торрента ничем не отличаются от пакетов SSH или пакетов SSL — это запрет шифрования в целом?

Information

Rating
Does not participate
Registered
Activity

Specialization

Software Architect