Общее·количество·просмотров·страницы

Java Dev Notes - разработка на Java (а также на JavaScript/Python/Flex и др), факты, события из АйТи

среда, 28 апреля 2010 г.

Консоль Firebug не показывает свойство next у объектов

Обнаружил интересный косяк Firebug: почему-то в консоли Firebug не отображается свойство next у объекта.

Вводим следующий код:

var o = {};
o.next = 'suxxx';
o.next1 = '111';
console.debug(o);
 


Смотрим скриншот - не показывается свойство next:



Но в то же время, можно вывести в консоль значение этого свойства:

var o = {};
o.next = 'suxxx';
o.next1 = '111';
console.debug(o.next);
 


Скриншот:



Firefox:

Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

Firebug: 1.5.3.


Вот такие интересные дела творятся в датском королевстве...

вторник, 20 апреля 2010 г.

Дистрибутивы ExtJS

Выкладываю дистрибутивы ExtJS, начиная с версии 3.0.0. На офсайте ExtJS нет ссылок на архивы (по крайней мере, для бесплатных юзеров). А иногда нужно обратиться к старой версии ExtJS. Сейчас выложено 4 версии: 3.0.0, 3.0.3, 3.1.0, 3.2.0.

ExtJS 3.0.0

ExtJS 3.0.3

ExtJS 3.1.0

ExtJS 3.2.0

UPDATE 10 Мая 2010 года: ExtJS 3.2.1

UPDATE 12 Октября 2010 года: ExtJS 3.3.0

Обрезание ExtJS

Рассмотрим, что можно выкинуть из библиотеки ExtJS, когда кладем ее в продакшн-версию приложения. Из-коробки ExtJS приходит со множеством файлов/папок, которые совсем не нужны для работы приложения. Сюда входят документация, примеры, тесты, темы и др. Вот мы и разберем, что можно выкинуть, а что можно оставить.

Вот структура каталогов ExtJS 3.2.0 (содержимое корневого каталога ExtJS):

adapter
docs
examples
pkgs
resources
src
test
welcome

+ файлы:

ext.jb2
ext-all.js
ext-all-debug.js
gpl-3.0.txt
INCLUDE_ORDER.txt
index.html
license.txt

Сразу удаляем каталоги:

docs
examples
pkgs
src
test
welcome

и все файлы в корневом каталоге, кроме ext-all.js. Так что из каталогов у нас остается только adapter, resources. Дальше правим их.

Заходим в adapter. Видим каталоги


ext
jquery
prototype
yui


Удаляем все, кроме ext. В ext есть два файла: ext-base.js, ext-base-debug.js. Файл ext-base-debug.js удаляем, он нам не нужен. На этом с каталогом adapter закончили.

Теперь переходим в resources. В нем есть каталоги css, images и несколько файлов: charts.swf, expressinstall.swf и resources.jsb. Файлы не трогаем. Переходим в css. В нем несколько каталогов, которые содержат различные темы оформления и прочее. Как правило, это все не нужно. В css удаляем все, оставляем только файл ext-all.css. Теперь идем в images. Там есть несколько каталогов с изображениями для разных тем оформления. Нам нужна только тема default. Поэтому удаляем все каталоги, кроме default.

На этом все. В результате этих действий ExtJS похудел с 44 472 007 байт (42 Мб) до 1 390 373 байт (1.32 Мб). Happy coding!

четверг, 15 апреля 2010 г.

Мартовская статистика CTR для рекламных показов на мобильных телефонах, версия от Smaato

Источник: ТехКранч, Symbian Still Leading In Mobile Ad Click-Through Rates, Android Dropping Fast.

Итак, рекламная сеть Smaato зарелизила мартовскую статистику (Март 2010 года) по CTR для показов рекламных объявлений на мобильных телефонах.



Самый высокий CTR на Symbian - 156, затем идут feature phones (телефоны с проприетарной ОС от производителя), затем WinMo, iPhone и Android. Ниже Андроида только RIM, Palm. Причем Андроид скатился со второго места в Январе-Феврале 2010 на пятое в марте.

Финалисты The Next Web Paypal X Startup Rally 2010

TheNextWeb представляет европейские стартапы.

Announcing the finalists of The Next Web Paypal X Startup Rally 2010

ТехКранч вторит им: 25 Startups That Will Be Shaping The Next Web

Мы рассмотрим их вкратце, все 25 проектов:


  1. Tribe of Noise - коммьюнити, пытающееся соединить музыкантов и лейблы. А может, попытка взять часть функционала Last.FM и ILike.com и примешать что-то новое?

  2. Inbox2 - почта + социальные контакты + документы + календарь - и все в одном месте =)

  3. Fashiolista - что-то про моду, не разобрал =) Не мое

  4. MailSuite - почтовая система

  5. pipio - система для организации разговоров (conversations)

  6. Distimo - система аналитики по app store

  7. Twittercounter - система статистики по Твиттеру

  8. ecwid - российский проект. Позволяет прикрутить SaaS-hosted интернет-магазин для любого сайта за пару минут

  9. DoubleDutch - гео-социальноый проект. Позволяет пользователям включать в свою социальную активность гео-составляющую

  10. English Attack! - обучение англискому, entertainment-based метод

  11. Fits.me - примерочная интернет-комната для одежды

  12. Next Widgets - виджеты, вирусный маркетинг

  13. Feest.je - опять гео-социальный сервис

  14. 22tracks - музыкальный сервис. Позволяет пользователям открывать новых исполнителей, новые жанры и т.д. Что прикольно - не надо никакой регистрации. Сейчас, когда я это пишу - у меня как раз играет композиция из 22tracks

  15. Sogeo Сcompany - позволяет бизнесу строить коммьюнити потребителей на основе местоположения. В общем, еще один геосоциальный сервис

  16. Peecho - cloud printing as a serice. Вот так-то вот... =) Пошел относить свой лазерник на помойку =)

  17. PressDoc - быстрые и интерактивные онлайн пресс-релизы. Социальные медиа.

  18. next2news - рекламная платформа, размещающая рекламу в новостях. Но - только на голландском.

  19. Buildor - cloud-hosted ПО для создания сайтов, редактирования HTML/CSS

  20. submate - социальный сервис - узнай своих попутчиков по метро

  21. rapportive - социальная CRM-система, встроенная в GMail

  22. shutl - почти мгновенная доставка покупок из онлайн-магазинов. Хм, интересно!

  23. brainient - помогает паблишерам видео-контента зарабатывать путем приаттачивания ссылок на продукты, упомянутые в их видео-роликах. Тоже неплохо, имхо!



Вот такие они, европейские стартапы! Мне несколько идей очень понравились!!

Twitter нашел свою бизнес-модель: promoted twits and more

На ТехКранче написали, что Твиттер приоткрывает детали своей бизес-модели: Twitter CEO Ev Williams: Revenue Is A Feature.

Рекламная платформа Твиттера называется Promoted Tweets. Она будет доступна каждому, у кого есть аккаунт на твиттере. Распределение прибыли будет 50/50 между рекламодателем и твиттерянином.

CEO Twitter Evan Williams говорит, что есть множество путей монетизировать трафик, особенно, когда его много. Мы знаем, что у Твиттера трафика не просто много, а очень много. Однако, в Твиттере хотят, чтобы их рекламный продукт был органической частью их сервиса. Promoted Tweets будут действовать также, как и обычные твиты, их можно будет ретвитить, отвечать на них, добавлять в закладки и т.п.

Сначала они будут оплачиваться cost-per-impression-базисе (CPM), но Твиттер обещает скоро ввести новую метрику - которая будет оценивать "резонанс" - и дальнейшая оплата таких твитов будет происходить на базе этой метрики. Резонансная метрика будет учитывать такие факторы, как то, как часто просматривается твит, добавляется в закладки, ретвитится и т.п. Если Твиттер соберяется изменять резонанс, то модель оплаты, видимо, очень скоро уйдет от классической CPM-модели.

Успех Promoted Tweets будет определяться тем, как пользователи воспримут их и насколько будут с ними взаимодействовать. Если они не будут восприниматься как твиты, то эта затея выродится просто в еще один вид встраиваемой рекламы.

среда, 14 апреля 2010 г.

Студенческий день Яндекса

Не могу не записать: Студенческий день Яндекса. Много хороших презентаций!!

Настройка Google App Engine Launcher

Поговорим о настройках GAE лончера. Лончер используется для того, чтобы запускать GAE-приложения на локальной машине. При запуске, по умолчанию, лончер привязывается на адрес локалхоста, т.е. на 127.0.0.1 - так называемый loopback. А что, если нам надо его привязать к внешнему адресу (в нашей локальной сети), например, на 192.168.1.100 ?

Это делается очень просто. Выделяем в лончере приложение, которое хотим привязать к внешнему IP, нажимаем Ctrl+I (или выбираем пункт меню Edit->Application Settings). Открывается окошко с настройками.



В блок Extra Command Line Flags записываем следующее:
--address=192.168.1.100
нажимаем ОК - и вуаля - приложение привязано к IP 192.168.1.100.

Единственно, что надо добавить - так это то, что эти настройки надо делать при выключенном приложении.

Помимо флага --address есть еще множество других настроек:


--help, -h View this helpful message.
--debug, -d Use debug logging. (Default false)
--clear_datastore, -c Clear the Datastore on startup.
--address=ADDRESS, -a Server binding address
--port=PORT, -p PORT Port for the server to run on.
--datastore_path=PATH Path to use for storing Datastore
file stub data
--history_path=PATH Path to use for storing Datastore
history
--require_indexes Disallows queries requiring composite
indexes not defined in index.yaml.
--smtp_host=HOSTNAME SMTP host to send test mail to.
--smtp_port=PORT SMTP port to send test mail to.
--smtp_user=USER SMTP user to connect as.
--smtp_password=PASSWORD Password for SMTP server.
--enable_sendmail Enable sendmail when SMTP is not
configured.
--show_mail_body Log the body of emails in mail stub.
--auth_domain Authorization domain



Прочитать про это можно также здесь: Google App Engine Launcher Options

пятница, 9 апреля 2010 г.

Захват видео во флеше

Рассмотрим, как показывать видео, захваченное с веб-камеры пользователя во флешке.
Перейдем сразу к коду.

Файл camtest_min.mxml:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="horizontal"
verticalAlign="middle"
backgroundColor="white">
 
<mx:Script>
<![CDATA[
private function videoDisplay_creationComplete():void {
trace('[camtest.videoDisplay_creationComplete]');
var camera:Camera = Camera.getCamera();
if (camera) {
trace('[camtest.videoDisplay_creationComplete] camera is OK');
videoDisplay.attachCamera(camera);
camera.addEventListener(ActivityEvent.ACTIVITY, camera_activity);
camera.addEventListener(StatusEvent.STATUS, camera_status);
} else {
trace('[camtest.videoDisplay_creationComplete] perhaps there is no camera on this computer');
}
}
 
private function camera_activity(evt:ActivityEvent):void {
trace('[camtest.camera_activity], evt.type='+evt.type+', evt.activating='+evt.activating);
}
 
private function camera_status(evt:StatusEvent):void {
trace('[camtest.camera_status], evt.code='+evt.code);
switch (evt.code) {
case "Camera.Muted":
// do smth
break;
case "Camera.Unmuted":
// do smth
break;
}
}
]]>
</mx:Script>
 
<mx:VideoDisplay id="videoDisplay"
creationComplete="videoDisplay_creationComplete();"
width="320"
height="240" />
 
</mx:Application>
 


Скомпилируем код следующей командой:


%SDKDIR%\bin\mxmlc -optimize=true -o camtest_min.swf camtest_min.mxml


После этого, открыв файл в браузере, получим изображение с камеры.
Во флешке вылезет окошечко с запросом на разрешение доступа к микрофону и камере.
Это окошко появляется в момент, когда камера аттачится к VideoDisplay.

Чуть более подробно можно посмотреть по ссылке Detecting changes in a camera’s activity and status in a Flex VideoDisplay control

среда, 31 марта 2010 г.

Флеш-куки

Помимо HTTP-куков можно трекать посетителе сайта с помощью флеш-куков. Флеш-куки устанавливаются с помощью объекта flash.net.SharedObject. Физически флеш-куки хранятся в каталоге с настройками флеша. Например, на Windows XP этот каталог таков:

C:\Documents and Settings\Ivan\Application Data\Macromedia\Flash Player\#SharedObjects

UPD:

Website Privacy Settings panel - по этой ссылки можно редактировать настройки флеш-параметров для сайтов.

вторник, 30 марта 2010 г.

Обратное геокодирование на Google Maps, получение региона

Понадобилось мне как-то получить регион для множества гео-объектов. У меня есть координаты точек, и более ничего. А хочется для каждого гео-объекта иметь следующее: Страну-Регион-Субрегион. После этого я смогу, например, делать кластеризацию по регионам.

Пример данных вида Страна-Регион-Субрегион: Россия-Ленинградская область-Всеволожский район. Или: Россия-город Санкт-Петербург-Фрунзенский район.

Получение адреса (хотя бы приблизительного) объекта по его географическим координатам называется обратным геокодированием. В разделе Геокодирование можно почитать о том, что это такое, и как этим пользоваться в Google Maps.

Обратное геокодирование в Google Maps выполняется следующим образом: передается запрос вида

http://maps.google.com/maps/geo?q=60.6462623161,29.7290039063&output=xml&oe=utf8

Он возвращает информацию об адресе объекта с координатами (60.6462623161,29.7290039063), формат возвращаемых данных XML (т.е. KML). Можно еще получать данные в CSV, JSON. Информация об адресе содержится в xml-контейнерах Placemark. Этих контейнеров обычно бывает несколько в XML-документе. Каждый из них содержит информацию о ближайшей к объекту точке и ее адресе. В Placemark есть контейнер AddressDetails с атрибутом Accuracy. Если Accuracy=1, то в данном плейсмарке определена только страна, если Accuracy=2, то определена страна и регион, а если Accuracy=3, то дополнительно определен и субрегион. На большие значения Accuracy я не заглядывал, т.к. значения 3 мне хватало для моих целей за глаза и за уши.

Итак, у нас есть KML-документ, теперь мы его будем парсить. Парсер написан на Python.
Сначала нам потребуются две дополнительные функции: для извлечения текста из XML-ноды, а также для получения первого дочернего элемента. Вот эти функции:

def getFirstChildNode(parent,childNodeName):
choices = [e for e in parent.childNodes if e.nodeType == e.ELEMENT_NODE and e.nodeName == childNodeName]
for c in choices:
return c
return None
 
def getNodeText(node):
result = None
for c in node.childNodes:
if c.nodeType == Node.TEXT_NODE:
result = c.data
return result


Теперь представим всю функцию под названием getRegionFromKml:

def getRegionFromKml(kml):
kmldoc = minidom.parseString(kml)
 
result = {}
 
result['ok'] = False
 
result['CountryNameCode'] = None
result['CountryName'] = None
result['AdministrativeAreaName'] = None
result['SubAdministrativeAreaName'] = None
 
nodelist_status = kmldoc.getElementsByTagName("Status")
if len(nodelist_status)==0:
return result
node_status = nodelist_status[0]
node_code = getFirstChildNode(node_status,"code")
if not node_code: return result
code = getNodeText(node_code)
if not code == '200':
return result
 
nodelist_Placemark = kmldoc.getElementsByTagName("Placemark")
 
for node_Placemark in nodelist_Placemark:
if result['ok']:
break;
node_AddressDetails = getFirstChildNode(node_Placemark,"AddressDetails")
if not node_AddressDetails: continue
attribute_Accuracy = node_AddressDetails.getAttribute("Accuracy")
if not attribute_Accuracy: continue
accuracy = int(attribute_Accuracy)
if accuracy < 2: continue
node_Country = getFirstChildNode(node_AddressDetails,"Country")
if not node_Country: continue
 
node_CountryNameCode = getFirstChildNode(node_Country,"CountryNameCode")
if not node_CountryNameCode: continue
result['CountryNameCode'] = getNodeText(node_CountryNameCode)
#logging.info("country code: %s" %(result['CountryNameCode']) )
 
node_CountryName = getFirstChildNode(node_Country,"CountryName")
if not node_CountryName: continue
result['CountryName'] = getNodeText(node_CountryName)
 
#logging.info("CountryName: '%s'" % (CountryName))
node_AdministrativeArea = getFirstChildNode(node_Country,"AdministrativeArea")
if not node_AdministrativeArea: continue
 
node_AdministrativeAreaName = getFirstChildNode(node_AdministrativeArea,"AdministrativeAreaName")
if not node_AdministrativeAreaName: continue
result['AdministrativeAreaName'] = getNodeText(node_AdministrativeAreaName)
 
node_SubAdministrativeArea = getFirstChildNode(node_AdministrativeArea,"SubAdministrativeArea")
if node_SubAdministrativeArea:
node_SubAdministrativeAreaName = getFirstChildNode(node_SubAdministrativeArea,"SubAdministrativeAreaName")
if node_SubAdministrativeAreaName:
result['SubAdministrativeAreaName'] = getNodeText(node_SubAdministrativeAreaName)
 
node_Locality = getFirstChildNode(node_AdministrativeArea,"Locality")
if node_Locality:
node_LocalityName = getFirstChildNode(node_Locality,"LocalityName")
if node_LocalityName:
result['SubAdministrativeAreaName'] = getNodeText(node_LocalityName)
 
result['ok'] = True
 
return result
 


Для парсинга XML мы пользуемся пакетом minidom, так что в код нужно добавить пару импортов:

from xml.dom import minidom 
from xml.dom.minidom import Node


А вот как может выглядеть функция, которая а вход принимает широту и долготу, а на выход выдает объект, содержащий Страну/Регион/Субрегион данных координат:

def getRegionByLatLon(lat,lon):
result = {}
result['ok'] = False
 
try:
url = "http://maps.google.com/maps/geo?q=%10.8f,%10.8f&output=xml&oe=utf8" % (lat,lon)
urlResult = urlfetch.fetch(url)
 
if urlResult.status_code == 200:
kml = urlResult.content
result = getRegionFromKml(kml)
except:
logging.info('error occured when adding station: %s' % (sys.exc_info()[0]))
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
logging.error('exceptionType: %s' % exceptionType)
logging.error('exceptionValue: %s' % exceptionValue)
logging.error('exceptionTraceback: %s' % exceptionTraceback)
 
return result


Подробнее о парсинге XML на Питоне можно прочитать по следующим ссылкам:

xml.dom.minidom — Lightweight DOM implementation

Dive in Python - Chapter 5. XML Processing

Python & XML - Chapter 1

четверг, 25 марта 2010 г.

10 бесценных от Альберта Эйнштейна

Подробная версия лежит на Хабре: 10 бесценных жизненных советов, которые дает нам Альберт Эйнштейн.

Английская версия из блога DumbLittleMan: 10 Amazing Life Lessons You Can Learn From Albert Einstein.


  1. Будьте увлеченным
    У меня нет какого-то особого таланта. Я просто страсть как любопытен.

  2. Настойчивость бесценна
    Все это так не потому что я такой умный. Это все из-за того, что я долго не сдаюсь при решении задачи.

  3. Сфокусируйся на настоящем
    Любой мужчина, который может вести машину безопасно, пока целуется с симпатичной девушкой, попросту не уделяет поцелую должного внимания.

  4. Воображение могущественно
    Воображение это все. Оно способно показать нам заранее, как будут развиваться события. Воображение важнее знания.

  5. Совершайте ошибки
    Человек, который никогда не совершал ошибок, никогда не пробовал делать ничего нового.

  6. Живи настоящим
    Я никогда не думаю о будущем – оно наступает здесь и сейчас.

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

  8. Не ждите разных результатов
    Это безумство делать одно и то же раз за разом, и при этом ждать разных результатов.

  9. Знание приходит из опыта
    Информация в чистом виде — это не знание. Настоящий источник данных это опыт.

  10. Поймите правила и побеждайте
    Вам следует выучить правила игры. И после этого вы будете играть как никто другой.

воскресенье, 21 марта 2010 г.

Чему я научился, собирая миллион долларов на стартап без бизнес-плана и финансовых прогнозов (потягивая при этом пиво)

Классный пост от Роберта Мэя: What I Learned Raising A Million Dollars For a Startup With No Business Plan and No Financial Projections (While Drinking a Beer). А на сайту StartupPoint находится его перевод. Очень и очень познавательно.

Вывод, впрочем, все тот же - нужно делать свой проект несмотря ни на что: несмотря на отсутствие инвесторов, отсутствие денег, присутствие многих других проблем, и т. д. Потому что вы и есть тот человек, которому этот проект нужен больше всего. Если вы от него откажетесь, то его не поднимет никто. Делать, делать, делать!

четверг, 4 марта 2010 г.

Генерация GUID на JavaScript

Как сгенерировать GUIDна JavaScript:

Способ номер раз (JavaScript GUID generator):

function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}


Способ номер два (by StackOverflow How to create a GUID / UUID in Javascript):

function createUUID() {
// http://www.ietf.org/rfc/rfc4122.txt
var s = [];
var hexDigits = "0123456789ABCDEF";
for (var i = 0; i < 32; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
 
var uuid = s.join("");
return uuid;
}


One-liner solution (все с того же поста на StackOverflow):

'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
}).toUpperCase();


Здесь находится мемо, которое затем стало RFC4122: A Universally Unique IDentifier (UUID) URN Namespace

Robert Kieffer опубликовал файл Math.uuid.js, который содержит две реализации генератора UUID: RFC 4122 (функция Math.uuid) и более компактную RFC4122v4 (функция Math.uuid2). Ниже привожу исходник:

/*!
Math.uuid.js (v1.4)
http://www.broofa.com
mailto:robert@broofa.com
 
Copyright (c) 2009 Robert Kieffer
Dual licensed under the MIT and GPL licenses.
*/

 
/*
* Generate a random uuid.
*
* USAGE: Math.uuid(length, radix)
* length - the desired number of characters
* radix - the number of allowable values for each character.
*
* EXAMPLES:
* // No arguments - returns RFC4122, version 4 ID
* >>> Math.uuid()
* "92329D39-6F5C-4520-ABFC-AAB64544E172"
*
* // One argument - returns ID of the specified length
* >>> Math.uuid(15) // 15 character ID (default base=62)
* "VcydxgltxrVZSTV"
*
* // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
* >>> Math.uuid(8, 2) // 8 character ID (base=2)
* "01001010"
* >>> Math.uuid(8, 10) // 8 character ID (base=10)
* "47473046"
* >>> Math.uuid(8, 16) // 8 character ID (base=16)
* "098F4D35"
*/

Math.uuid = (function() {
// Private array of chars to use
var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
 
return function (len, radix) {
var chars = CHARS, uuid = [];
radix = radix || chars.length;
 
if (len) {
// Compact form
for (var i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
} else {
// rfc4122, version 4 form
var r;
 
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
 
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (var i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
 
return uuid.join('');
};
})();
 
// A more compact, but less performant, RFC4122v4 compliant solution:
Math.uuid2 = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
}).toUpperCase();
};


Остальные реализации генератора GUID на JavaScript можно найти в уже упоминавшемся топике How to create a GUID / UUID in Javascript на StackOverflow.

среда, 17 февраля 2010 г.

23 хака для работы

Данный пост написан по мотивам поста Hack Your Work: 23 Ways to Get Ahead, Work Less and Achieve More из блога Dumb Little Man - Tips for Life.


  1. Одна цель

    Установите одну цель, которую хочется достигнуть в этом году. Слишком сложно достигать несколько целей одновременно, т.к. это рассеивает ваши усилия, энергию. Выберите одну цель на следующие 12 месяцев, и затем одну цель на ближайшие 3-6 месяцев (но такую, которая бы приближала вас к годовой цели). Затем выберите что-либо, что можно сделать в течении 1-2 недель, и что приближает к 3-6-месячной цели. После этого приложите все усилия, чтобы достигнуть свою краткосрочную цель. А затем двигайтесь в том же духе дальше.

  2. Найди свою страсть

    Все последующие советы всего лишь немного улучшат ситуацию, если вы работаете на работе, которая вам очень нравится. Если вы не на такой работе, то следует выяснить, какая работа вам больше всего нравится. Необязательно прямо сейчас увольняться с текущей работы, но стоит начать небольшое исследование на тему, что же вам нравится, и что вы любите делать. Поговорите с друзьями, родными, побродите по Интернету, попробуйте разные занятия. Сделайте это целью на ближайший год - выяснить, что вам нравится делать.

  3. Поработай из дома

    Возможно, большую часть работы можно выполнять из дома, особенно сейчас, во времена развитых компьютерных сетей и интернета.

  4. Приходи на работу раньше

    Попробуй приходить на работу на 30-60 мин раньше всех остальных. Тебе придется рано вставать, но выгоды очевидны: ты не попадаешь в утренние пробки, день начинается бодро, ты можешь быть впереди остальных, и успеть сделать больше. Ранний старт рабочего дня - отличный способ быть более продуктивным.

  5. Работай 4 дня

    Если ты можешь управлять своим расписанием, попробуй работать меньше дней в неделю, чем обычно. Например, четыре дня, а не пять. Это дает: дополнительный выходной, это заставляет тебя быть более продуктивным (на 20%). Подумай сам: если ты знаешь, что твоя рабочая неделя закончится в четверг, а не в пятницу, будешь ли отвлекаться на посторонние вещи? Думаю, вряд ли.

  6. Работай 6 часов в день

    Аналогично предыдущему пункту. Но предыдущий пункт может подойти не для всех. Тогда стоит попробовать работать по 6 часов в день, и при этом рано вставать. Представь, работу начинаешь в 7 утра, а заканчиваешь уже в час дня!

  7. Работай 20 часов в неделю

    Если ограничить работу 20 часами в неделю (например, у вас удаленная работа), то скоро почувствуешь, что ты стал более сфокусированных и успеваешь сделать больше за меньшее время.

  8. СВЗ

    СВЗ - Самые Важные Задачи. В начале каждого дня пиши список из трех самых важных задач, которые нужно сделать за сегодня. Сделай по крайней мере одну из них приближающей тебя к Твоей Главной Цели. Это должны быть действительно важные задачи, те, которые повлияют положительно на тебя и твой доход в долгосрочной перспективе. И попробуй сделать их с утра, самыми первыми, до того, как на тебя свалится масса других дел.

  9. Пакетное выполнение

    Есть множество маленьких дел, которые, тем не менее, отвлекают тебя от твоей работы. Это могут быть телефонные звонки, работа с бумагами, выписка счетов, составление и отправка email, и т.д. Ты уже понимаешь, что надо их выписывать на листочек, а затем делать все сразу, за один присест, и больше к ним не возвращаться в течении дня. Это называется "пакетное выполнение", по аналогии в пакетными файлами в Юникс.

  10. Работай удаленно один день в неделю

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

  11. Фрилансить в свободно время

    Комментарии здесь излишни: нужно выделить свободное время, и начать фриланс-практику.

  12. Обедать на работе

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

  13. Ездить на работу на велосипеде

    Это сэкономленные деньги на бензине, сохраненные нервы от стояния в пробках, ежедневные физические упражнения.

  14. Занимайся проектами с потенциально высокой отдачей

    Ежедневная текучка не сделает тебя звездой. Если ты примешься за проект, который может принести высокую отдачу, сильно продвинуть твою компанию вперед, то, если ты его хорошо выполнишь, это благоприятно отразится на твоем положении в компании. Сделай задачи по этому проекту своими СВЗ, и начинай каждый день с работы над ними.

  15. Автоматизируй свой бизнес

    Автоматизированный бизнес высвобождает твое время для более интересных и творческих задач.

  16. Откладывай добавочный доход

    Если твой доход увеличился, не спеши его тратить - и вообще, не спеши увеличивать траты. Отложи добавку в банк. Это не увеличивает, конечно, твою производительность, но зато увеличивает финансовую стабильность.

  17. Расчисти рабочее место

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

  18. Разделяй и властвуй

    Если задача целиком кажется неподъемной, раздели ее на ряд небольших подзадач, и выполни их одна за одной.

  19. Делегируй

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

  20. Избавься от необязательных задач

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

  21. Не отвлекайся

    Телефонные звонки, email, твиттер и т.п. отвлекают тебя от дел. Больше фокусируйся, и ты больше сделаешь.

  22. Убей митинги

    Долгие митинги - это пустая трата времени. Большинство проблем, которые обсуждаются на митинге, можно решить через email или телефонным звонком.

  23. Чтение и написание Email - один раз в день

    Выдели время на электронную почту - прочитай ее и напиши письма, если необходимо. Затем в течении дня не притрагивайся к электронке.

четверг, 11 февраля 2010 г.

Google собирается проложить экспериментальную сеть на 1 Гб/сек

Think big with a gig: Our experimental fiber network - пост в Гугл-блоге, в котором Гугл объявляет о том, что планирует проложить экспериментальную сеть, с пропускной способностью для конечного пользователя в 1 Гб/сек. Сеть запускается, чтобы протестировать новые возможности, новые приложения и др. Сеть будет доступна 50 тыс пользователям, с возможностью расширения до 500 тыс пользователей.

Вышел релиз Google App Engine SDK 1.3.1. Новые возможности Datastore

Это мой первый пост в новом 2010 году!!!

Итак, вышел релиз Google App Engine SDK 1.3.1. Основные изменения касаются хранилища данных! По порядку:

  • Появились курсоры - курсоры позволяют приложению ставить "закладки" при проходе по набору записей, полученных в результате запроса.

  • Отменен лимит на 1000 записей!!! Юхуууу! Хранилище теперь может возвращать столько записей, сколько потребуется!

  • Уменьшилось количество ошибок хранилища Теперь App Engine автоматически повторяет все запросы к хранилищу, если произошла ошибка доступа к Bigtable. Это уменьшает количество ошибок при put-запросах в 3-4 раза, при get-запросах в 10-30 раз


Дополнительно еще есть много других изменений (см. лист изменений для Python SDK).

По мотивам поста App Engine SDK 1.3.1, Including Major Improvements to Datastore! в блоге Google App Engine.

понедельник, 28 декабря 2009 г.

Удаление элемента из массива JavaScript

Как не надо удалять элемент из массива в JavaScript:

var list = [4,5,6];
delete list[1];
print(list); // [4, undefined, 6]
 


Как правильно:

var list = [4,5,6];
list.splice(1, 1); // Remove one element, returns the removed ones.
print(list); // [4, 6]


И еще правильно:

var visibleIds = [4,5,6];
visibleIds.splice(visibleIds.indexOf(5), 1);
print(visibleIds); // [4, 6]


См. также JavaScript: Remove element from Array.

Постоянные читатели