[Перевод] Steam Greenlight и Steam Direct: что нужно знать инди-разработчикам |
38% of all Steam games were released in 2016 pic.twitter.com/JiX2pt6JhB
— Steam Spy (@Steam_Spy) November 30, 2016
Метки: author PatientZero разработка игр steam direct steam greenlight |
Перевод отрывков из книги Роберта Хайнлайна «Заберите себе правительство» — часть 26 |
Собранные вами в день выборов избирательные голоса могут бесследно исчезнуть в ночь после выборов. Один из любимейших приемов подтасовки результатов голосования – использование того факта, что, проголосовав за основного партийного кандидата, многие избиратели забывают отметить свой выбор относительно кандидатов на остальные посты в правительстве. И если в бюллетене кандидаты от разных партий сгруппированы по постам, на которые они баллотируются, то после закрытия голосования очень просто проставить напротив нужных кандидатов недостающие метки. Например, если выбирают губернатора и конгрессмена, то, имея 300 бюллетеней, из которых голос за конгрессмена помечен только в 250, за 5 минут работы за закрытыми дверями очень легко превратить результаты выборов из соотношения в 110 голосов – за кандидата Двусмыслина и 140 – за кандидата Добропорядина – в соотношение: 160 голосов – за кандидата Двусмыслина и 140 – за кандидата Добропорядина, не оставив никаких следов проведенной подтасовки.
Еще чаще бюллетени со сгруппированными по партийным спискам кандидатами подтасовывают, просто выбрасывая частично помеченные бюллетени, как неверно заполненные – в том случае, если они в них указан нежелательный кандидат – и оставляя, если в них указан нужный кандидат, не обращая внимания ни на какие допущенные в бюллетене ошибки.
Прямой вброс фальшивых бюллетеней в избирательные урны встречается очень редко. Подкуп избирателей встречается еще реже, примеры выборов, результат которых был подтасован такими методами, можно найти, разве что, в архивах.
Эти грубые и вопиюще нечестные методы не используются успешными профессиональными политиками, даже если их организация насквозь коррумпирована. Они пользуются другими, более эффективными, надежными (и относительно честными) методами, характерными для профессиональной политики. Если уж эти профессионалы прибегают к грубому подлогу, значит их организация катится в пропасть. Вспомните уголовные дела о фальсификации выборов в Канзасе.
Конечно, наблюдатель на избирательном пункте не может лично проверить подсчет голосов, потому что подсчетом занимается одновременно несколько человек, и наблюдателю невозможно за всеми уследить. Однако, присутствие наблюдателя, официально зарегистрированного участковой избирательной комиссией – почти стопроцентная защита от попыток подтасовки голосов. В дополнение к созданию видимости внимательного наблюдения за подсчетом, наблюдатель должен считать сколько бюллетеней отвергнуто как испорченные и по какой именно причине, потому, что они могут сильно повлиять на исход тех выборов, где доля голосов соперников отличается не очень сильно.
При использовании машин для голосования, вышеописанная процедура становится ненужной. Но тогда становятся возможными другие, более тонкие способы подтасовки, не имеющие ничего общего с грубыми методами принуждения или подкупа избирателей. То что сконструировал один инженер, может подправить другой инженер – таким образом, чтобы машина для голосования выдавала неверные результаты. И в такой ситуации ваш наблюдатель не сможет ничего поделать. Обнаружение следов вмешательства во внутреннее устройство этих машин потребует целого расследования, которое, вероятно, ФБР – по плечу, а вашему наблюдателю – нет.
По окончанию подсчета голосов наблюдатель докладывает по телефону в штаб-квартиру результаты, где по поступающим сведениям вы и кандидат, нервничая, и догрызая от волнения ногти на руках, ведете подсчет общего количества голосов. Наблюдатель же после телефонного доклада может ехать на послевыборную вечеринку.
Когда закроются все избирательные пункты, из штаб-квартиры вы перемещаетесь в зал, в котором обычно проходят заседания клуба агитаторов. На этот раз сюда придет в три раза больше человек, чем числится в Клубе Агитаторов, но вы готовы к этому, пусть приходят, от этого будет только веселее.
Вы даже не успели поужинать, и ваш желудок сводят спазмы голода. Все чего вы сейчас хотели бы – это перехватить на ходу сэндвич. В это время возвращается с объезда избирательных участков ваш кандидат, и вы вдвоем, в кои-то веки без окружающей вас толпы сторонников, за исключением, может быть секретарши вашей штаб-квартиры и еще пары человек, готовитесь к вечеринке. Вы оставляете кого-то у телефона, поручив ему принимать звонки от наблюдателей и записывать подсчет голосов. Включаете радио и ловите свою любимую радиостанцию, которая уже начинает передавать предварительные итоги выборов в основных округах. В зале вы поставили большую школьную доску, поручив одному из сотрудников записывать на ней предварительные итоги, чтобы все могли их видеть. Теперь вы переключаетесь на организацию банкета.
В Клубе Агитаторов состоит 100 человек, но на вечеринку придет в три раза больше – 300 человек, каждому из которых, в среднем, достаточно по литру пива. Поэтому вы запаслись 300 литрами пива. Это немало, и вы покупали пиво целыми бочонками, если конечно вам не удалось организовать, чтобы вас им бесплатно снабдили ваши сторонники. И конечно же, вы договорились с продавцом о том, что за неиспользованные бочонки вам вернут деньги, поэтому выставляете в зал по одному бочонку, храня остальные в запертом помещении. Вы также не забыли запастись 500 одноразовыми бумажными стаканчиками.
Для тех, кто спиртного не пьет, у вас есть кофе и лимонад. В запасе также есть небольшое количество легких закусок, вроде пончиков, сыра, и крекеров, которые вы не выкладываете, пока не наступит час ночи.
Не нужно подавать крепкие спиртные напитки, ваш бюджет этого не вынесет. Но некоторые посетители все равно принесут их с собой, и напьются. Не препятствуйте им, у нас свободная страна.
Начинают собираться посетители, выводя вас и мистера Честнягу из той прострации, в которую вы впали с того момента, как окончилось голосование. Они собираются вокруг кандидата, жмут ему руку, хлопают по плечу, и желают с ним выпить. Кто-то из посетителей подходит и к вам.
После этих первых ласточек, народ начинает валить валом, зал быстро наполняется. Большинство из пришедших – ваши друзья, но есть и прожженные тусовщики, посещающие каждую послевыборную вечеринку каждой партии. Вы спрятались позади стола, чтобы вам не докучали журналисты, и едите сэндвич, запивая его кофе, одним ухом прислушиваясь к телефону, и в то же время, пытаясь не упустить ход обновления предварительных результатов, записываемых принимающим звонки. Одновременно вы слушаете радио, которое сообщает, что судья Лужайкин имеет внушительный перевес в голосах за его номинацию на кандидата на губернаторский пост. Вам эта новость доставляет радость – имея Лужайкина во главе партийного списка, вам будет легче выиграть основные выборы.
Начали приходить первые телефонные доклады о результатах подсчета голосов, для вас не очень радостные. Съеденный вами сэндвич норовит подкатить обратно к горлу. Честняга продирается сквозь толпу, улыбаясь и бросая реплики окружающим, нагибается к вам, бросает взгляд на предварительные результаты. Его лицо становится озабоченным, но он ободряюще хлопает вас по плечу – «Не расстраивайся» — говорит он, «Все это стоит того, чтобы пережить, даже если мы проиграем. Если когда-нибудь я буду баллотироваться снова, я хочу, чтобы руководил моей кампанией именно ты». Эта фраза трогает вас до слез, но вы крепитесь: вокруг слишком много посторонних.
Через какое-то время результаты начинают меняться: намечается перевес в сторону Честняги. У Честняги 982 голоса, у Надежды – 1005. Честняга-2107, Надежда-2043. Вы впереди! Честняга-5480, Надежда-5106, вы восстанавливаете ваше до того сбивчивое дыхание. Честняга-9817, Надежда-8166. Честняга-12042, Надежда… погодите, кажется, вы слышите по радио номер вашего избирательного округа, и тут же начинает трезвонить телефон.
«Тишина! Потише, пожалуйста!» Окружающий гам замолкает, по крайней мере, в ближайших окрестностях радиоприемника, из которого диктор бодро вещает: «Определились результаты выборов в округах. Кандидат на выдвижение в конгресс от Демпубликанской партии в Тридевятом округе Джек Надежда, по результатам голосования уступил достопочтенному Джонатану Честняге – как сообщил нам управляющий его кампании, призывая всех поддержать этого кандидата осенью на выборах. К сожалению, мы не смогли дозвониться до мистера Честняги, но уже понятно, что…» Остальное вы не слышите. Вы победили!!!
Остаток вечера вы проводите с облегченным сердцем. Вы перестает отслеживать новости по радио, разгуливаете по залу и общаетесь, хотя ваши ноги просто отваливаются от усталости. Наливаете себе бокал пива, но тут же оставляете его пениться и выдыхаться, потому что выборы генерального прокурора приняли неожиданный оборот. Похоже, в будущем это может вызвать трудности. Около трех ночи, вы с новоиспеченным кандидатом от партии на выборы в конгресс, и парой доверенных лиц, протискиваетесь к стойке круглосуточной забегаловки, и заказываете самую обильную трапезу из тех, что ели в последние две недели. У вас в руках уже предварительные итоги выборов, вы читаете их вслух… В 4 часа утра вы, наконец, доплетаетесь до своей кровати, и засыпаете мертвым сном
Честняга-16107, Надежда-11373
Итак, вы поставили рекорд: все предыдущие выборы в вашем округе показывали, что при гонке двух кандидатов один из них может получить максимум 10 000 голосов избирателей, если проведет свою кампанию «на отлично». Сравнение количества проголосовавших с предыдущими выборами в вашем округе и с другими округами показывает, что в этот раз в вашем округе проголосовало на 2000 больше избирателей, чем обычно. Таким образом, методы, которыми велась ваша кампания, смогли собрать на 6000 голосов больше, чем побитый вами рекорд предыдущих выборов, и вы получили 2000 голосов тех избирателей, которые до того на праймериз не ходили, что убедительно подтверждает правильность ваших методов ведения кампании. Это не тот случай, когда вы выигрываете только за счет недостатков кампании конкурирующего кандидата, а не за счет превосходства своей кампании. Детальное изучение результатов по избирательным участкам показало, что лично ваш кандидат собрал от трети до четверти перевешивающих голосов, остальное собрали агитаторы. Значит, ваше решение послать Честнягу самолично обходить дома избирателей было правильным.
Фонд кампании пуст, но все счета оплачены. Почти все – есть еще счета за пиво, за него вы платили уже из собственного кармана. Не забудьте вернуть нетронутые два бочонка – это поможет вам уменьшить свои убытки. Кроме того, на волне победной эйфории, вам наверняка удастся уговорить пару-тройку соратников разделить с вами недостачу в вашем бюджете. Честняга обещал возместить ваши расходы, но вы не будете ловить его на слове – он и сам потратил, больше, чем собирался.
Вернее, вы не выиграли. Предположим, у вас что-то не получилось, или может быть, среди ваших сторонников произошел раскол, и вы финишировали с таким раскладом: Честняга-12785, Надежда-12009.
В такой ситуации очень легко начать кричать о подтасовке голосов, валить все на политическую мафию, использование грязных политических методов, и вброс подделанных бюллетеней. Скорее всего, вы будете неправы, и проиграли выборы совсем не по этим причинам, и не потому что у вас было недостаточно сторонников, или потому что ваши агитаторы недостаточно усердно работали. На любых выборах есть высокий процент не проголосовавших избирателей. На праймериз таких избирателей больше 50%. И вы не можете их обвинить в подтасовке результатов выборов. Конечно может быть и так, что вы сделали все что могли, а на исход выборов действительно повлияли какие-то грязные приемы, примененные на избирательных пунктах, или еще где-то. Однако, даже при таком раскладе, результаты выборов все же отражают волю американского народа, выраженную избирателями – хотя бы даже путем неявки на выборы. Смиритесь с этим.
Пока не озадачивайте своих агитаторов работой, по крайней мере, до следующего собрания клуба агитаторов. А до тех пор у вас много дел.
Во-первых, вам надо собрать списки проголосовавших избирателей, чтобы в следующую кампанию, вам не надо было их добывать у местных властей всеми правдами и неправдами. Некоторые из командиров отрядов агитаторов могут оказаться достаточно дисциплинированными, чтобы помочь вам в этом, но большинство будут динамить вас так долго, что записи о проголосовавших уже уйдут в архив. Поэтому лучше все делать самому. Списки избирателей очень удобно переснимать обыкновенным фотоаппаратом. Но скопировать списки для всего округа – слишком большая работа для одного человека, даже с фотоаппаратом. Так что скопируйте все, что сможете, а когда вам понадобятся остальные списки – достаньте их у чиновников. Скопированные списки учитывайте в блокноте, чтобы не делать двойной работы.
Разберитесь с этим делом побыстрее, чтобы после того, как в партийном комитете штата пройдет собрание победивших на праймериз кандидатов, вы и ваш кандидат могли хотя бы на неделю съездить отдохнуть перед началом финальной предвыборной кампании. В идеале, – неплохо бы еще и отдохнуть несколько дней сразу после праймериз. Но скорее всего, прежде чем вы решитесь уехать, вам нужно будет заняться упрочением своей победы, консолидировав партийные организации своего округа. Потому что после выборов целый ряд членов вашего Клуба Агитаторов избраны в партийный комитет округа, и вы – среди них. Так что теперь вы контролируете состав делегации округа на партийный съезд. Мистер Честняга после своей победы на праймериз автоматически становится временным членом партийного комитета штата, и делегатом на съезд партии штата. Советуясь с вами, он составил список членов партийного комитета штата, включив туда и вас. Теперь вы можете посещать проводимые в столице штата заседания партийного комитета, но у вас может не быть на это времени, ведь надо сделать столько всего. (В вашем штате порядки в партийной организации могут быть и другие, но то, что я описываю – это типичные действия партийных организаций после выборов. Вам надо быть готовым к участию в подобных мероприятиях, в каком бы порядке они ни проходили, и к работе в них, не покладая рук, даже если в партийные комитеты штата и области попало меньше ваших людей, чем нужно для того, чтобы контролировать политическую жизнь округа).
Однако, наипервейшей вашей задачей должно быть налаживание контакта с вашим бывшим соперником – Джеком Надеждой, если, конечно, он – полноценный член вашей партии, а не марионетка, засланная соперничающей партией. На финальных выборах вам понадобится его поддержка. Свяжитесь с ним, или его управляющим, пригласите их обоих к себе в гости на обед. Не забудьте позвать мистера Честнягу. После обеда вы обсудите ваши совместные действия в будущей предвыборной кампании. Не предлагайте им никаких сделок, и не подразумевайте, что они поддержат вас в обмен на что-то. Принимайте как должное то, что ваш бывший соперник по праймериз и его управляющий поддержат на выборах весь список партийных кандидатов, включая, естественно, и мистера Честнягу. Который, кстати, предложит Надежде быть председателем окружного комитета партийной кампании, пояснив при этом, что его работа на этом посту будет настолько интенсивной, насколько он сам того захочет. Ведь, по сути, этот пост – исключительно номинальный, поскольку, исполнительным директором комитета, и фактическим управляющим его работой будете вы сами. Кроме того, вы продолжите работать управляющим предвыборной кампанией мистера Честняги, а, являясь одновременно и председателем партийной делегации от вашего округа, будете отвечать за всю партийную деятельность в округе. Но Джеку Надежде вы всего этого не говорите. Вы всего лишь ему предлагаете, в обмен на его номинальную поддержку, занять номинальный пост самого высшего уровня в вашем округе. Его управляющему вы предлагаете пост вице-председателя того же окружного комитета и членство в исполнительном совете вашей предвыборной кампании. Они могут согласиться, энергично взяться за работу, и принести вам большую пользу, а могут, скептически хмыкнув, вежливо удалиться, чтобы «обдумать предложение». Или в обмен на свою поддержку прямо потребовать денег или гарантий назначения на правительственный пост, или и того и другого. У них могли остаться долги от только что прошедшей кампании, которые надо заплатить. Или же они просто хотят, работая на вашу кампанию, заработать много денег.
Бывший ваш соперник может пожелать иметь возможность распределять значительную долю правительственных постов, или же захотеть, чтобы вы помогли ему выполнить обещание, данное своему управляющему, пристроив того на секретарский пост в Конгрессе, если Честняга выиграет выборы. По каким-то загадочным причинам многие проигравшие выборы кандидаты, судя по всему, считают, что их более успешные соперники просто обязаны помочь им расплатиться с долгами, оставшимися от кампании и посодействовать им в выполнении их обещаний, данных в ходе кампании. Это что-то вроде шантажа, не поддавайтесь на него.
В этом случае ваш кандидат должен объяснить им, что не может обещать посты в правительстве каждому, кто их потребует, и что постоянно отказывает в таких обещаниях даже своим собственным соратникам. И назначениями на посты он будет заниматься только после выборов, если, конечно, их выиграет. Что же касается финансовой помощи, то денег у него просто нет.
Услышав все это, ваши бывшие соперники могут неуклюже пойти на попятную, особенно, если у них нет другого выбора, и предпочтя сохранить за собой достаточно высокое положение в партийной иерархии. Или же, они могут отвергнуть ваше предложение и гордо уйти. Не вините их, они поступили так не из-за своей испорченности. Ваш отказ заплатить по долгам, cделанными ими в попытках победить вас на праймериз, по каким-то причинам, для них может выглядеть чудовищно несправедливым по отношению к ним поступком.
В таком случае привлеките себе на помощь тяжелую артиллерию. Пусть кто-нибудь из Больших Шишек вашей партии, желательно из окружения партийного кандидата в губернаторы, свяжется с Джеком Надеждой, и вежливо, но твердо объяснит ему, что если тот хочет сохранить в партии какой-то политический вес, то лучше ему вести себя корректно – предоставить свое имя в поддержку политической кампании Честняги, призвать своих сторонников поддержать победившего кандидата, и поучаствовать, как минимум, в одном-двух публичных митингах за кандидатов из партийного списка, включая и мистера Честнягу. Возможно, после этого вы получите поддержку своего бывшего соперника. Только ни в коем случае не покупайте эту поддержку: она того не стоит.
Занимаясь всем этим, одновременно проследите, чтобы каждый из тех, кто участвовал в вашей кампании, получил от вас личное письмо с благодарностью за поддержку. Письма можете отпечатать на автомате Гувена, Пусть те, кто непосредственно обходил избирателей, получат письма, отличающиеся от типового текста: постарайтесь в них выразить особенно глубокую вашу признательность. Пусть текст письма одновременно содержит и призыв агитаторам к новой битве – финальной кампании. Кроме того, на ближайшей встрече Клуба Агитаторов устройте для них церемонию чествования: поблагодарите каждого персонально, подчеркнув тот исключительный вклад, который он внес в победу на праймериз.
Начните проводите партийные званые завтраки, о которых я писал выше. В будущем, работа по сплочению партийных рядов окупится сторицей. На званые завтраки приглашайте всех, кого сможете. Ведь в дополнение к группе сторонников мистера Надежды, в округе есть не менее двадцати других партийных фракций – по одной на каждого кандидата на каждый выборный пост. И вам понадобится поддержка их всех. Так что пригласите на завтрак каждого из проигравших праймериз кандидатов персонально по телефону, в дополнение к традиционному приглашению, высланному по почте. Партийные завтраки помогут вам уладить множество разногласий, примирить между собой множество партийных лидеров. И это будет намного легче, чем привлечь на свою сторону Джека Надежду, потому что здесь вы выступаете как посредник в урегулировании интересов многих групп. Главное же, для чего вы все это делаете – это создание единого предвыборного комитета для кандидатов партийного списка. Это лучший способ обеспечить для вашего кандидата победу на выборах. Свои планы вы превращаете в поступки окружающих людей, помогая им «сохранить лицо» и упрочить свой авторитет в партии, благородно выступая публично в поддержку своих бывших соперников по праймериз – кандидатов из партийного списка. С помпой и фанфарами раздавайте номинальные посты в комитете предвыборной кампании каждому из членов партии, который их попросит (количество комбинаций из таких слов, как «вице», «председатель», «директор», «секретарь», «координатор» и «комитет» – поистине неисчерпаемо).
Из привлеченных вами членов других партийных фракций, наберите в свой Клуб Агитаторов новых сотрудников, пусть даже лишь на время кампании. Можете даже временно переименовать ваш клуб, если это поможет заполучить в него новых членов. Для финальной кампании вам понадобится в четыре раза больше агитаторов, чем наибольшее количество ваших агитаторов во время праймериз.
Вновь встает вопрос о деньгах для фонда кампании. Теперь собрать их будет легче, но зато и понадобится их больше. Лучше всего вы сделаете, если сбор денег в фонд кампании кандидатов партийного списка переложите на управляющего кампанией кандидата в губернаторы от партии, распоряжаясь при этом ресурсами на свою кампанию самостоятельно. И обязательно настаивайте на том, чтобы национальный партийный комитет сделал взнос в фонд вашей избирательной кампании, предварительно позаботившись, о том, чтобы какой-нибудь умник–коммерсант от политики через свои налаженные связи в национальном комитете не перехватил у вас эти деньги. Некоторые партийные комитеты штатов и областей, судя по всему, уверены, что партийные кандидаты – это их дойные коровы, с которых они могут собирать деньги в обмен на свою поддержку. Это совершенно неверное представление: комитеты должны сами собирать деньги и пускать их на поддержку кандидатов. Так что если партийная организация выступит с подобным предложением, не платите им за поддержку: она не стоит потраченных денег.
Зато от правильных партийных комитетов вы сможете получить и деньги в фонд кампании и активную помощь. В том числе – бесплатную, или частично бесплатную печать ваших агитационных материалов. Поэтому, ваши расходы на печать в этой кампании будут ниже, чем в предыдущей – вы сможете пользоваться типовой печатной агитацией, предоставляемой партией всем партийным кандидатам из списка. Но вы можете напечатать и свои собственные материалы, где имя вашего кандидата будет выделено в партийном списке крупным шрифтом или расположением.
Я не буду описывать во всех подробностях финальную предвыборную кампанию, она во многом похожа на праймериз – за исключением того, что борьба в ней – напряженнее, численные показатели – выше, эмоции — сильнее, денежные траты – больше, а ваше положение в этой борьбе по сравнению с соперниками – более невыгодно, так как вы боретесь, в том числе, и с предыдущим обладателем выборного поста, пока находящимся у власти – с достопочтенным мистером Стулером, у которого больше влиятельных друзей, чем у вас. С другой стороны, за время правления Стулер допустил кое-какие ошибки, и нажил какое-то количество врагов, что дает преимущество уже вам. Но все же, нахождение претендента на пост у власти, обычно рассматривается как неоспоримое преимущество, вам необходимо учитывать это преимущество в своих планах. Если же Стулер является марионеткой мощной и сплоченной находящейся у власти политической мафии, то вам не только нужно работать очень усердно над своей кампанией, нужно и быть готовым к грязным политическим трюкам и приемам, самый вероятные из которых в такой ситуации – это махинации с подсчетом голосов в ночь выборов. Поэтому, прикиньте, на каких избирательных участках могут возникнуть проблемы такого рода, и пошлите туда наблюдателем самую миниатюрную женщину из числа ваших волонтеров: такой наблюдатель будет в полной безопасности, в то время, как посланный вами наблюдатель-мужчина может вернуться, например, со сломанной рукой. Больше, чем в праймериз вам будут докучать и другие персонажи: Влиятельные Фигуры, торговцы «карманными голосами», путающиеся под ногами праздные бездельники, и искатели правительственных постов – в общем, все те, кто усложняет политическую работу, не принося при этом дополнительных избирательных голосов.
Но даже в самом эпицентре всей этой сутолоки и сумятицы, не забывайте о том, самом главном, для чего вы занимаетесь всем этим – избирательных голосах, которые, по-прежнему находятся там, где живут избиратели, то есть, на избирательных участках. И что бы вам ни советовали Важные Персоны из центрального офиса партии, посещение избирателей – по-прежнему единственный способ собрать те самые голоса, в которых вы так нуждаетесь.
Следуйте своему заведенному в прошлую кампанию обычаю посвящать обходу избирателей два дня в неделю, каждый раз по полдня. Назначьте вашему кандидату очередные 500 часов обхода избирателей, составив его расписание так, чтобы он успевал заниматься и остальными делами.
Как и в прошлый раз, стройте свою кампанию вокруг деятельности своих агитаторов, которые, вплоть до дня выборов, не должны заниматься чем-то иным, кроме обхода избирателей.
Так же, как и в прошлый раз, игнорируйте оппозицию.
Единственные отличия финальной кампании от праймериз таковы:
а) В целом, в своей кампании вы агитируете за весь партийный список, выделяя своего кандидата более частым его упоминанием в агитации за партийный список и партийную программу.
б) Как и раньше, вы обходите избирателей, согласно своим спискам, игнорируя, однако, избирателей, проголосовавших на праймериз. Потому что на них можно положиться – за исключением тех, кого надо персонально отвезти на выборы (а вы сделаете это и на этот раз). Эти избиратели сами придут на выборы и проголосуют за кандидатов из партийного списка. Вместо них обходите тех избирателей вашей партии, которые не голосовали на праймериз, сторонников второстепенных партий, а также не определившихся, игнорируя избирателей соперничающей партии. Вам и так надо будет обойти примерно 40 000 человек, на что у вас не хватит ни людей, ни времени. Поэтому, направьте ваши усилия на то, чтобы получить как можно больше голосов избирателей вашей партии, и, в первую очередь, – голосов «спящих» избирателей.
в) Чтобы осуществить вышесказанное, вам надо будет поработать еще больше, чем раньше над организацией ваших действий в день выборов. Если партийные комитеты области или штата смогут предоставить вам дополнительных сотрудников, они будут вам очень полезны, поскольку для работы им не понадобится вникать в местную ситуацию, достаточно будет только подготовленного вами списка избирателей, имея который они смогут обходить избирателей, помогать вам в день выборов, и быть вашими наблюдателями на участках.
По мере приближения вашей предвыборной кампании к финишной прямой, на вас будет оказываться сильное давление в попытке заставить вас отказаться от победы на выборах. И один из источников этого давления, может оказаться совершенно неожиданным – вам вдруг позвонит заслуженный член партии, с самого начала кампании входящий в номинальный предвыборный штаб вашего кандидата, много хорошего сделавший для кампании, и неявно, но доходчиво, намекнет, что вам нужно прекратить предвыборную борьбу и позволить выиграть вашему сопернику мистеру Стулеру. Он скажет вам, что вы провели хорошую схватку, но у вашего кандидата нет шансов выиграть выборы. Что мистер Честняга не совсем готов к работе на этом посту, и созреет для этого лишь через два-четыре года, но уж точно не в этом году. Кроме того, он случайно узнал, что на следующих выборах мистер Стулер собирается баллотироваться в Сенат, и поддержит тогда мистера Честнягу всем своим авторитетом, если тот пойдет ему навстречу, и откажется от борьбы на этих выборах. Так почему бы ему не уступить, ведь это отличный задел на будущее? Для этого вам даже не надо будет прекращать поддержку других кандидатов из партийного списка, просто убедите мистера Честнягу не тратить время, силы и деньги на заведомо проигрышное дело, и ненадолго «заболеть», выйдя из предвыборной борьбы. Что же касается вас, то какой правительственный пост вы бы хотели занять? Возможно, это можно будет устроить!
Здесь у вас появляется редкая в вашей политической карьере возможность, не сдерживаться, и сказать своему собеседнику все, что вы думаете о нем и о его предложении. Но пользы делу это не принесет. Так что просто пошлите его далеко и надолго. Не созывайте по этому поводу экстренных заседаний комитета, просто проследите за тем, чтобы позвонившего вам деятеля никогда больше не было ни на каких мероприятиях, касающихся вашей кампании – если конечно вы в силах это обеспечить. Этот человек – троянский конь в вашем лагере.
Не теряйте из-за этого прискорбного события веру в человечество! Эти жулики не пытались бы вас подкупить, если бы не были напуганы, видя, как ширятся ряды ваших сторонников – искренних и честных людей, всецело подтверждающих вашу веру в добропорядочность обычного гражданина. Ведя кампанию своими методами и продвигая свои политические взгляды, вы на практике доказали свою правоту. И ваши соперники это поняли.
А по прошествии еще некоторого времени, вы снова будете сидеть за столом на послевыборной вечеринке. Снова будет надрываться радио, беспрерывно трезвонить телефон, а вы – будете пытаться прожевать свой сэндвич, слушая новости, и одновременно думая, как наскрести денег на отправку восьми-девяти сотен писем, которыми ваш кандидат должен будет поблагодарить своих агитаторов в течение следующих двух недель.
Первые подсчеты голосов обнадеживают: Честняга даже выходит вперед, хотя и ненамного. Но нельзя сбрасывать со счетов Стулера, чья кампания ведется профессиональными и опытными сотрудниками. Вы решаете до следующей недели забыть о предстоящих почтовых расходах: деньги на это найдутся, раз до сих пор всегда находились. Сейчас есть заботы и поважнее: результатов подсчета голосов на выборах в конгресс не сообщают уже целый час – вы начинаете нервничать. Радиоведущий тем временем представляет кандидатов и всяких знаменитостей – и почему эти субъекты всегда такие напыщенные?
Наконец, начинают сообщать результаты голосования: 9-й округ, 10-й, 11-й, 12-й. Тут ведущий замолкает. Что на него нашло?
«Дорогие радиослушатели, после небольшой паузы нам сообщат новые результаты подсчета голосов, а пока – небольшая новость: новые результаты показывают, что в Тридесятом округе, неожиданно для всех, Джонатан Честняга по числу голосов обходит прежнего заслуженного депутата от этого округа – конгрессмена Стулера, предварительные результаты показывают, что…» Вы не дослушиваете… Вы добились избрания своего конгрессмена! Это значит, что завтра вы не сможете уехать отдохнуть. И течение нескольких следующих недель – тоже. Кроме рассылки благодарственных писем, вам нужно будет проводить заседания клуба агитаторов, устраивать еженедельные партийные завтраки, участвовать в заседаниях партийных комитетов штата и области. Мистер Честняга захочет обсудить с вами кандидатуры для назначения на посты своих секретарей. Вы же для себя решили, что не собираетесь ехать с ним в Вашингтон, и не будете даже его секретарем в округе. Потому что не хотите быть наемным сотрудником, и хотите остаться независимым в своих суждениях. Именно поэтому, у вас есть право принимать, или отвергать предлагаемые Честнягой кандидатуры, как сейчас, так и во время его работы в Конгрессе. К тому же, у вас есть собственные планы – связать клуб агитаторов напрямую с политической столицей страны, путем получения от Честняги еженедельных сводок новостей о ситуации в столичных органах власти, регулярных докладов о событиях в правительстве, о смысле этих событий, и проведении голосований. Вы же, в свою очередь, будете сообщать в столицу об одобрении или неодобрении клубом всех этих событий, чтобы Честняга и два сенатора от вашего округа учитывали ваше мнение в своей работе.
Когда вы, почти полтора года спустя после описанных событий, сидя у себя дома, будете листать очередной номер Вестника Конгресса – одно из немногих оставшихся у вас материальных свидетельств двух проведенных вами кампаний, вы наткнетесь на список членов Конгресса, проголосовавших за принятие интересующего вас закона. Вы считаете, что это – хороший, и нужный для всей страны закон. И у вас в руках – отчет об окончательном голосовании по нему, после которого закон уйдет на подпись президенту. Вы с радостью заметите, что Честняга проголосовал именно так, как вы желали: еще до рассмотрения закона он сообщил вам, что будет голосовать за этот закон. И теперь закон принят – хотя и со скрипом, с перевесом всего в один голос. Только теперь вы понимаете всю важность проведенной вами кампании. Потому что без того самого единственного, решающего, голоса вашего конгрессмена, этот закон не был бы принят, а мистер Стулер заведомо проголосовал бы против него.
Всего один голос – ваш голос!
Вы, своими собственными мыслями, речами, и поступками, добились принятия хорошего закона, которым отныне будут руководствоваться все 140 000 000 американских граждан – вы сделали это своими собственными руками, и руками волонтеров, тех, кто вам доверял и помогал.
И это – очень приятное чувство!
-> Часть 1, где есть ссылки на все остальные части
Метки: author sunman читальный зал хайнлайн политика |
[Перевод] Привилегированные порты — причина глобального потепления |
if
. Сломается всё, что полагалось на не-криптографическую защиту вроде номера порта для безопасности, поскольку такие вещи легко подделать.bind()
не указывает, что адрес (0.0.0.0 или ::0) будет прослушивать пакеты или соединения на всех интерфейсах, для которых текущий пользователь имеет соответствующее разрешение на привязку, а исходящие соединения по умолчанию будут направляться на первый интерфейс, принадлежащий пользователю.
|
Синхронизация Vivaldi: ответы на вопросы |
Метки: author Shpankov браузеры блог компании vivaldi technologies as vivaldi vivaldi technologies синхронизация |
[Из песочницы] Запуск Java классов и JAR-ов не по учебнику |
update-binfmts --display
...
jar (enabled):
package = openjdk-8
type = magic
offset = 0
magic = PK\x03\x04
mask =
interpreter = /usr/bin/jexec
detector =
invalid file (bad magic number): Exec format error
#!/bin/sh
#/usr/bin/jarinvoke
JAR=$1
shift
exec java -jar $JAR $@
sudo update-binfmts --disable jar && sudo update-binfmts --enable jar
#!/bin/sh
# /usr/bin/clsinvoke
CLASS_FILE=$1
shift
ABSOLUTE_PATH=`readlink -f $CLASS_FILE`
CLASS=`basename $ABSOLUTE_PATH`
CLASS=${CLASS%.*}
CLASSPATH=`dirname $ABSOLUTE_PATH`
exec java -cp $CLASSPATH $CLASS $@
sudo update-binfmts --package clsinvoke --install clsinvoke /usr/bin/clsinvoke --magic '\xca\xfe\xba\xbe'
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
javac HellWorld.java
chmod +x HelloWorld.class
./HelloWorld.class
Hello, World
Метки: author Foror разработка под linux java linux ubuntu bash scripting |
Темные моменты SELinux |
В процессе эксплуатации систем с SELinux я выделил несколько интересных кейсов, решения которых вряд-ли описаны в Интернете. Сегодня я решил поделиться с вами своими наблюдениями в надежде, что число сторонников SELinux еще немного возрастет :)
Если вы не знали, то сообщаю: весь SELinux насквозь файловый, и никакой магии там нет. Поэтому можно прям при включенном SELinux переустановить пакет полиси, если что-то пошло не так.
Пример для centos 7 & selinux-policy-minimum
#!/bin/sh
setenforce 0
semanage export > exports.semanage
yum remove -y selinux-policy-minimum
rm -rf /etc/selinux/minimum
yum install -y selinux-policy-minimum
semodule -RB
semanage import -f exports.semanage
Причина в том, что некоторые программы пытаются изменить контекст ( по аналогии с setuid/setgid ) перед exec(3), но используют неверный контекст для этого.
Пример: демон crond, который обрабатывает crontab пользователя user, контекст которого неизвестен. В этом случае он execlp(3) вернет ошибку 'Invalid context'.
Если по каким-то причинам авторелейбл не произошел и файл остался вообще без контекста, либо с мусором вместо контекста, доступ к нему так-же может быть заблокирован из-за того, что open(3) упадет при попытке сравнить контексты.
Как происходит включение SELinux?
Проблемы наступают на этапе два: ядро знает только о контекстах модулей, которые были явно включены до перезагрузки. Например, если не был включен модуль systemd, то:
Это проблема возникает тогда, когда после обновления не могут быть решены циклические зависимости между модулями или контекстами. Например:
При обновлении до версии 1.1 модуль local_module будет установлен после того, как будут применены настройки контекста для "/opt/local", что может привести к циклической зависимости. На самом деле от одного модуля это бывает редко, а вот когда их 30 и они ссылаются друг на друга и несут часть настроек "снаружи" ( через semanage fcontext или semanage port например ) — вот тогда проблемы почти гарантированы.
semanage export > outfile
semanage fcontext -D
semanage user -D
semanage port -D
semanage login -D
# update your packages
semanage import -f outfile
Autorelabeling — боль для владельцев больших серверов. Средний сервер с базой данных может перезагружаться 3-4 часа из-за включения SELinux, что абсолютно неприемлемо для бизнеса.
На самом деле метки на файлах лежат в extended-атрибутах файловой системы, доступ к которым можно получить при помощи команд getfattr(1)/setfattr(1)/attr(1). Атрибут называется security.selinux и содержит контекст в виде строки. При этом даже на выключенном SELinux работает команда matchpathcon из libselinux-utils, которая показывает дефолтный контекст для того или иного пути.
Совмещая оба этих факта, получаем возможность сделать audorelabel прямо во время работы сервера, не тратя на это время при перезагрузке.
Сегодня днем я выложил свой код на github, утилита называется offrestorecon. Не забудьте предварительно включить все нужные модули и удалить файл /.autorelabel!
Используйте ключ -P для setsebool, либо semanage boolean
Если вам интересна тема SELinux, присылайте комментарии по своим странным кейсам и их решениям, я буду добавлять их в эту статью. Возможно, что это сделает жизнь следующих security-админов немного проще.
Метки: author kreon системное администрирование настройка linux *nix selinux troubleshooting tips amp;amp; tricks |
Критическая уязвимость механизма аутентификации BIND позволяет похищать и изменять DNS-записи серверов |
14-Jun-2017 07:48:55.003 client 172.17.42.1#50445/key tsig_key: updating zone 'example.com/IN': adding an RR at 'i.can.inject.records.in.the.zone.example.com' TXT "injected"
ISC #BIND #TSIG #Authentication Bypass
— Attack Detection (@AttackDetection) July 10, 2017
CVE-2017-3143
Affected: 9.9 - 9.11#Suricata rules and pcap:https://t.co/guHgAPhsNN https://t.co/LJWhrdKswc
Метки: author ptsecurity информационная безопасность блог компании positive technologies dns bind tsig аутентификация уязвимости |
Вводим рейтинг участника «Хабра» и «Тостера» на «Моём круге» |
|
[Из песочницы] Проброс портов или как попасть в сеть за NAT используя Node.JS |
cd node-tunnel
npm install
node server
node client
N_T_AGENT_DATA_HOST=localhost
N_T_AGENT_DATA_PORT=22
node agent
ssh -p 8000 localhost
N_T_SERVER_HOST=хост ПК с внешним IP
N_T_AGENT_DATA_HOST=Windows PC внутри удалённой сети
N_T_AGENT_DATA_PORT=3389
N_T_AGENT_NAME=test-rdp
node agent
node server
предварительно склонив репозиторий и установив модули npm.N_T_SERVER_HOST=хост ПК с внешним IP
N_T_CLIENT_NAME=test-rdp
N_T_CLIENT_PORT=3388
node client
. Здорово! Теперь мы можем подключиться по RDP на localhost:3388 открыв rdp сессию к ПК внутри сети агента.node client .env.rdp
agentSocket.pipe(clientSocket)
clientSocket.pipe(agentSocket)
Метки: author xlenz node.js forwarding tunneling |
Банк «Открытие» проводит харвест по кредитованию малого бизнеса |
Метки: author Otkritie блог компании открытие харвест хакатон кредитование бизнес |
CSS и iOS Safari |
.ov-scroll{
overflow-y: auto;
-webkit-overflow-scrolling:touch;
}
body{
-webkit-text-size-adjust: none;
}
a, label{
-webkit-tap-highlight-color: transparent;
}
input[type=text], input[type=submit], textarea{
-webkit-appearance: none;
}
@media (hover){
.plus__item:hover{
transform: scale(0.6);
}
}
body:before {
content: '';
background-image: url(...);
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
}
.modal{
position: fixed;
z-index: -9;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0;
pointer-events: none;
}
.nav{
.........
position: absolute;
}
.nav_fix{
position: fixed;
}
@supports ((position:-webkit-sticky) or (position:sticky)){
.nav, .nav_fix{
position: sticky;
position: -webkit-sticky;
}
}
.nav{
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: -70px;
padding-bottom: 70px;
transform: translateY(70px);
}
Метки: author lipton_ice_tea разработка под ios safari css css3 web ios для ios webkit |
[Из песочницы] Линейное программирование в python силами библиотеки scipy |
fact x y supply
0 F_01 59.250276 59.871183 389
1 F_02 84.739320 14.179336 409
2 F_03 42.397937 42.474530 124
3 F_04 19.539202 13.714643 70
4 F_05 41.280669 37.860993 386
5 F_06 37.159066 41.353602 196
6 F_07 96.890453 64.420010 394
7 F_08 86.267499 81.662811 365
shop x y demand
0 S_01 13.490869 73.269974 200
1 S_02 85.435435 66.637250 20
2 S_03 28.578297 8.997380 320
3 S_04 31.324145 91.839907 360
4 S_05 40.338575 15.487028 360
5 S_06 41.642451 42.121572 120
6 S_07 53.983692 20.950457 360
7 S_08 75.761895 87.067552 60
8 S_09 81.836739 36.799647 80
9 S_10 54.260517 25.920108 100
10 S_11 67.918105 68.108601 340
11 S_12 92.200710 10.898110 360
12 S_13 19.966539 39.046271 60
fact supply shop demand distance cost_kg rev_kg del_kg cost_week
99 F_08 365 S_09 80 44.863164 200 800 20 10000
100 F_08 365 S_10 100 55.742703 200 800 20 10000
101 F_08 365 S_11 340 13.554211 200 800 20 10000
102 F_08 365 S_12 360 70.764701 200 800 20 10000
103 F_08 365 S_13 60 42.616540 200 800 20 10000
res = linprog(c, A_ub=A, b_ub=b, bounds=(x0_bounds, x1_bounds), options={"disp": True})
## ff - table with factories and shops
coefs = []
for f in ff.iterrows():
coefs.append((f[1]['rev_kg'] - f[1]['cost_kg'] - f[1]['del_kg']*f[1]['distance'])*(-1))
A = []
b = []
for f in ff['fact'].values:
A.append((ff['fact'] == f)*1)
b.append(ff[ff['fact'] ==f]['supply'].max())
for f in ff['shop'].values:
A.append((ff['shop'] == f)*1)
b.append(ff[ff['shop'] ==f]['demand'].max())
x0_bounds = []
x1_bounds = []
for f in ff.iterrows():
x0_bounds.append(0)
x1_bounds.append(f[1]['demand'])
x0_bounds = tuple(x0_bounds)
x1_bounds = tuple(x1_bounds)
A.append(coefs)
b.append(-10000*13)
res = linprog(coefs, A_ub=A, b_ub=b, bounds=list(zip(x0_bounds, x1_bounds)), options={"disp": True, 'maxiter' : 50000}
)
ff['supply_best'] = res.x
ff['stay_opened'] = (ff['supply_best'] > 0)*1
ff['profit'] = (ff['supply_best']*(ff['rev_kg']- ff['cost_kg'] - ff['distance'] * ff['del_kg']))*ff['stay_opened']
net_profit = ff['profit'].sum() - ff[ff['stay_opened']==1]['shop'].nunique()*10000
grouped = ff.groupby(['fact', 'shop'])['supply_best'].sum().reset_index()
f = {'supply_best': 'sum', 'supply': 'max'}
ff.groupby('fact')['supply_best', 'supply'].agg(f)
fact shop supply_best
0 F_01 S_01 166.0
17 F_02 S_05 360.0
24 F_02 S_12 49.0
31 F_03 S_06 120.0
38 F_03 S_13 4.0
50 F_04 S_12 70.0
58 F_05 S_07 346.0
61 F_05 S_10 40.0
73 F_06 S_09 80.0
74 F_06 S_10 60.0
77 F_06 S_13 56.0
78 F_07 S_01 34.0
79 F_07 S_02 20.0
88 F_07 S_11 340.0
94 F_08 S_04 305.0
98 F_08 S_08 60.0
supply_best demand
shop
S_01 200.0 200
S_02 20.0 20
S_03 0.0 320
S_04 305.0 360
S_05 360.0 360
S_06 120.0 120
S_07 346.0 360
S_08 60.0 60
S_09 80.0 80
S_10 100.0 100
S_11 340.0 340
S_12 119.0 360
S_13 60.0 60
Метки: author paveltro python линейное программирование scipy |
Новый подход к кэшированию процессора |
Метки: author Anrewer системное администрирование it- инфраструктура процессор память кэш |
[Из песочницы] Нагрузочное тестирование Web-систем. Как к нему подготовиться |
Метки: author Nick-Monk тестирование веб-сервисов высокая производительность нагрузочное тестирование web- сайт |
И еще 9 инструментов для разработки мобильных приложений |
Метки: author nanton разработка мобильных приложений блог компании everyday tools плагины платформы языки программирования |
Перевод книги Appium Essentials. Глава 5 |
adb -e install <путь до apk>
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
DesiredCapabilities caps = new DesiredCapabilities();//создаем объект
File app=new File("path of the apk");//создаем объект File, чтобы определить путь до apk
caps.setCapability(MobileCapabilityType.APP,app);//требуется, если приложение еще НЕ установлено на эмулятор.
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");//указываем версию Android
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");//Сообщаем, что будет использоваться эмулятор
caps.setCapability("avd","Name of the AVD to launch");//Указываем, какой конкретно эмулятор хотим запустить
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "package name of your app (you can get it from apk info app)");//определяем package для запуска
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "Launch activity of your app (you can get it from apk info app)");//activity для запуска
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
DesiredCapabilities caps = new DesiredCapabilities();//создаем объект
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");//указываем версию Android
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");//Сообщаем, что будет использоваться эмулятор
caps.setCapability("avd","Name of the AVD to launch");//Указываем, какой конкретно эмулятор хотим запустить
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser"); //для запуска браузера
import io.appium.java_client.android.AndroidDriver;
import java.net.URL;
AndroidDriver driver = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps); //caps был создан выше
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class TestAppIication {
AndroidDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
//Определяем desired capabilities
DesiredCapabilities caps = new DesiredCapabilities();
File app=new File("path of the apk");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");
caps.setCapability("avd","Name of the AVD to launch");
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "package name of your app (you can get it from apk info app)");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "Launch activity of your app (you can get it from apk info app)");
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser");// при работе с веб-приложением
driver = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
//здесь будет сам тест
}
@AfterClass
public void tearDown(){
driver.closeApp();//CloseApp() функция используется для закрытия нативного или гибридного приложения, а quit() и close() - для веба
}
}
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
DesiredCapabilities caps = new DesiredCapabilities();//создаем объект
File app=new File("path of the app");//создаем объект File, чтобы определить путь до приложения
caps.setCapability(MobileCapabilityType.APP,app);//указываем путь до приложения
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");//Версия iOS
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");//Укажите корректное имя эмулятора или Appium сгенерирует исключение
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
DesiredCapabilities caps = new DesiredCapabilities();//создаем объект
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");//Версия iOS
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");//Укажите корректное имя эмулятора или Appium сгенерирует исключение
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); //Чтобы запустить Safari
import io.appium.java_client.ios.IOSDriver;
import java.net.URL;
IOSDriver driver = new IOSDriver (new URL("http://127.0.0.1:4723/wd/hub"),caps);
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class TestAppIication {
IOSDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
//Задаем desired capabilities
DesiredCapabilities caps = new DesiredCapabilities();
File app=new File("path of the .app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");// при работе с веб-приложением
driver = new IOSDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
//здесь будет сам тест
}
@AfterClass
public void tearDown(){
driver.closeApp();//для нативных или гибридных приложений
//driver.quit(); //для веб-приложений
}
}
caps.setCapability("avd","AVD_Nexus_4");// Mention the created AVD name
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.android.calculator2.Calculator");
WebElement five=driver.findElement(By.name("5"));
WebElement four=driver.findElement(By.name("4"));
WebElement plus=driver.findElement(By.name("+"));
WebElement equalTo=driver.findElementByAccessibilityId("equals"));
five.click();
plus.click();
four.click();
equalTo.click();
public class TestAppIication {
AndroidDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");
caps.setCapability("avd","AVD_Nexus_4");// Mention the created AVD name
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.android.calculator2.Calculator");
driver = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
WebElement five=driver.findElement(By.name("5"));
five.click();
WebElement plus=driver.findElement(By.name("+"));
plus.click();
WebElement four=driver.findElement(By.name("4"));
four.click();
WebElement equalTo=driver.findElementByAccessibilityId("equals"));
equalTo.click();
}
@AfterClass
public void tearDown(){
driver.closeApp();
}
}
File app=new File("/Users/mhans/appium/ios/TestApp.app");//You can change it with your app address
caps.setCapability(MobileCapabilityType.APP,app);
WebElement editBox1=driver.findElement(By.name("TextField1"));
WebElement editBox2=driver.findElement(By.name("TextField2"));
WebElement computeSumBtn=driver.findElementByAccessibilityId("Compute Sum"));
editBox1.sendKeys("10");
editBox2.sendKeys("20");
computeSumBtn.click();
public class TestAppIication {
IOSDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
File app=new File("/Users/mhans/appium/ios/TestApp.app");//You can change it with your app address
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");
driver = new IOSDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
WebElement editBox1=driver.findElement(By.name("TextField1"));
editBox1.sendKeys("10");
WebElement editBox2=driver.findElement(By.name("TextField2"));
editBox2.sendKeys("20");
WebElement computeSumBtn=driver.findElementByAccessibilityId("Compute Sum"));
computeSumBtn.click();
}
@AfterClass
public void tearDown(){
driver.closeApp();
}
}
caps.setCapability("avd","AVD_Nexus_4");
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser");
driver.get("https://www.google.com");
WebElement searchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appium for mobile automation");
public class TestAppIication {
AndroidDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");
caps.setCapability("avd","AVD_Nexus_4");// Mention the created AVD name
driver = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample() {
driver.get("https://www.google.com");
WebElement searchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appium for mobile automation");
}
@AfterClass
public void tearDown(){
driver.quit();
}
}
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");
driver.get("https://www.google.com");
WebElement searchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appium for mobile automation");
public class TestAppIication {
IOSDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");
driver = new IOSDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
driver.get("https://www.google.com");
WebElement searchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appium for mobile automation");
}
@AfterClass
public void tearDown(){
driver.quit();
}
}
File app=new File("C:\\Appium_test\\testApp.apk");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability("avd","AVD_Nexus_4");
caps.setCapability(MobileCapabilityType.APP_PACKAGE, " com.example.testapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, " MainActivity");
WebElement editBox=driver.findElement(By.id("com.example.testapp:id/urlField"));
editBox.sendKeys("https://www.google.com");
WebElement goButton=driver.findElement(By.name("Go"));
goButton.click();
Set
contexts = driver.getContextHandles();
for (String context : contexts) {
System.out.println(context); //выведет список контекстов вроде NATIVE_APP или WEBVIEW_com.example.testapp
}
driver.context("WEBVIEW_com.example.testapp");
driver.context((String) contextNames.toArray()[1]);
WebElement images=driver.findElement(By.linkText("Images"));
images.click();
public class TestAppIication {
AndroidDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
File app= new File("/Users/mhans/appium/ios/webViewApp. app");
caps.setCapability(MobileCapabilityType.APP,app");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Android emulator");
caps.setCapability("avd","AVD_Nexus_4");// Mention the created AVD name
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium");//Use Selendroid in case of <4.4 android version
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.example.testapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.example.testapp.MainActivity");
driver = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
WebElement editBox=driver.findElement(By.id("com.example.testapp:id/urlField"));
editBox.sendKeys("https://www.google.com");
WebElement goButton=driver.findElement(By.name("Go"));
goButton.click();
Set contexts = driver.getContextHandles();
for (String context : contexts) {
System.out.println(context);
}
driver.context((String) contexts.toArray()[1]);
WebElement images=driver.findElement(By.linkText("Images"));
images.click();
}
@AfterClass
public void tearDown(){
driver.closeApp();
}
}
File app=new File("/Users/mhans/appium/ios/WebViewApp.app");
caps.setCapability(MobileCapabilityType.APP,app);
WebElement editBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("www.google.com");
WebElement goButton=driver.findElement(By.name("Go"));
goButton.click();
Set contexts = driver.getContextHandles();
for (String context : contexts) {
System.out.println(context);
}
driver.context("WEBVIEW_com.example.testapp");
илиdriver.context((String) contextNames.toArray()[1]);
WebElement images=driver.findElement(By.linkText("Images"));
images.click();
public class TestAppIication {
IOSDriver driver;
@BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 5");
driver = new IOSDriver (new URL("http://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
WebElement editBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("https://www.google.com");
WebElement goButton=driver.findElement(By.name("Go"));
goButton.click();
Set contexts = driver.getContextHandles();
for (String context : contexts) {
System.out.println(context);
}
driver.context((String) contexts.toArray()[1]);
WebElement images=driver.findElement(By.linkText("Images"));
images.click();
}
@AfterClass
public void tearDown(){
driver.closeApp();
}
}
Метки: author EreminD читальный зал appium automation testing тестирование тестирование мобильных приложений |
Эксперимент: возникает ли финансовое неравенство при случайной раздаче денег |
«Представьте себе комнату, в которой одновременно находится 100 человек. У каждого из них есть по 100 долларов. Каждую секунду каждый из находящихся в комнате дает доллар одному случайно выбранному человеку. Как по прошествии некоторого времени распределятся деньги между всеми, кто есть в комнате?».
library(tidyverse)
library(gganimate)
NUMPLAYERS = 45
ROUNDS = 5000
INITWEALTH = 45
#initialize the bank
#columns wealths of the NUMPLAYERS players
#rows show wealths of each of the ROUNDS ticks of the clocks
bank = matrix(0, nrow = ROUNDS, ncol = NUMPLAYERS)
bank[1,] = c(rep(INITWEALTH, NUMPLAYERS))
#function to give a dollar to someone other than oneself
get_recipient = function(player) {
sample(setdiff(1:NUMPLAYERS, player), 1)}
#execute trades and update the ledger
for (i in 2:ROUNDS) {
#every player with wealth chooses another person to receive a buck
recipients = sapply(which(bank[i - 1,] > 0), get_recipient)
#table of the dollars owed each person
count_table = table(recipients)
#get the indices of the people owed money
indices = as.integer(names(count_table))
#everyone gives up a dollar, unless they are at zero
bank[i,] = ifelse(bank[i - 1,] > 0, bank[i - 1,] - 1, bank[i - 1,])
#selected people receive dollars
bank[i, indices] = bank[i, indices] + count_table
}
####################Animate it
#Make a suitable long data frame
df = as.data.frame(bank)
names(df) = 1:NUMPLAYERS
df = df %>%
mutate(frame = 1:ROUNDS) %>%
gather(person, wealth, 1:NUMPLAYERS) %>%
mutate(person = as.numeric(person)) %>%
arrange(frame) %>%
group_by(frame) %>%
mutate(rank = rank(wealth, ties.method = "random")) %>%
ungroup() %>%
gather(histtype,playerid,c(person,rank)) %>%
mutate(histtype = sprintf("Ordered by %s", histtype))
p <- ggplot(df, aes(x = playerid, y = wealth, frame = frame, fill=histtype)) +
theme_minimal() +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()) +
geom_rect(aes( xmin = playerid - .4, xmax = playerid +.4, ymin = 0, ymax = wealth)) +
scale_x_continuous(breaks = 1:NUMPLAYERS) +
coord_cartesian(xlim = c(0, NUMPLAYERS), y = c(0, 5 * INITWEALTH)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
labs(x='players',y='dollars') +
facet_wrap( ~ histtype,ncol=1) +
theme(legend.position = "none")
p
#set options for the animation package. Need ImageMagick installed on your computer
animation::ani.options(nmax = ROUNDS,
convert = 'C:\\Program Files\\ImageMagick-7.0.6-Q16')
#save the movie
gganimate(p, "dollar_stacked.mp4", interval = .01)
Метки: author itinvest ненормальное программирование визуализация данных блог компании itinvest данные эксперимент финансы |
Запись с 1 млн нейронов: новые планы DARPA |
Универсальный характер шины сделает возможной работу и с другими участками мозга — для этого потребуется соответствующее ПО.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Метки: author it_man высокая производительность блог компании ит-град ит-град нейроинтерфейс darpa |
Анализ трафика GSM сетей в Wireshark |
wireshark -k -f udp -Y gsmtap -i lo
./mobile -i 127.0.0.1
telnet localhost 4247
Метки: author antgorka разработка систем передачи данных информационная безопасность open source osmocom gsm infosec calypso |
Анонимный трудоголик: как мотивировать самого себя |
Тут место небольшому лирическому отступлению. Про бабло.
Часто мы рассуждаем так: было бы бабло — остальное приложится. Но на такие деньги ты тратишь большую часть жизни, нервов, энергии и здоровья. Знаю, мне в комментариях напишут: «На деньги я куплю всё». Ничего подобного. Не буду повторять прописные истины о том, что здоровье и любовь не купишь. Увы! Пришёл к выводу: если ради этого самого бабла целый день ходишь на полусогнутых, проклинаешь всё на свете, конца рабочего дня ждёшь, как спасения, то в конце концов опустишься на колени, а там и поползёшь. Сильно богатым ты всё равно вряд ли станешь, а вот злым и ненавистным — точно. Короче, душу за бабло продавать не хочу! Лучше я её в хорошую работу вложу.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
|