Windows Server 2008 R2. Новые возможности служб AD DS
Александр Емельянов
djoin.exe /provision /domain имя_целевого_домена /machine имя_компьютера /dcname имя_контроллера_домена [/downlevel] /savefile c:\blob.txt
djoin.exe /requestODJ /loadfile c:\blob.txt /windowspath %SystemRoot% /localos
-----------------------------------------------------------------------------------------------------------------
Мониторинг состояния температурных датчиков с помощью протокола SNMP
Вадим Шпурик
$ cd ~
$ mkdir sensTable
$ cd sensTable
$ env MIBS="/usr/share/snmp/mibs/SENSOR-MIB.mib.txt" mib2c -c mib2c.mfd.conf \ sensTable
$ grep -n "TODO:" *.[ch] | sed 's/\([^ ]*\)\(.*\)TODO\(.*\)/\3 (\1)/' | sort -n
$ snmptranslate -m /usr/share/snmp/mibs/SENSOR-MIB.mib.txt -Tp -IR sensTable
1,"Sensor 241",1,"22.6",226,0,14991,0
1,"Sensor 241",1,"22.6",226,0,14991,0
2,"Sensor 242",1,"11.4",114,0,14992,0
3,"Sensor 243",1,"2.2",22,0,14993,0
4,"Sensor 244",1,"21.5",215,0,14994,0
5,"Sensor 245",1,"20.6",206,0,14995,0
6,"Sensor 246",1,"24.0",240,0,14996,0
#!/bin/bash
CSVPATH="/home/snmp/sensTable/"
CSVFILE=${CSVPATH}"sensor.csv"
SENSOR[1]="1,\"Sensor 241\",1,\"24.5\",245,0,14991,0"
SENSOR[2]="2,\"Sensor 242\",1,\"36.6\",366,0,14992,0"
SENSOR[3]="3,\"Sensor 243\",1,\"12.2\",122,0,14993,0"
SENSOR[4]="4,\"Sensor 244\",1,\"21.5\",215,0,14994,0"
SENSOR[5]="5,\"Sensor 245\",1,\"20.6\",206,0,14995,0"
SENSOR[6]="6,\"Sensor 246\",1,\"31.7\",317,0,14996,0"
if [ ! -f ${CSVFILE} ]
then
for index in 1 2 3 4 5 6 # Six lines.
do
printf "%s\n" "${SENSOR[index]}" >> ${CSVFILE}
done
else
cat $CSVFILE | awk -F"," '
BEGIN {
srand(systime())
# [min,max] values
SENS[1] = "21,34" # 21.0 .. 34.9
SENS[2] = "10,15" # 10.0 .. 15.9
SENS[3] = "1,6" # 1.0 .. 6.9
SENS[4] = "0,0" # do nothing
SENS[5] = "0,0" # do nothing
SENS[6] = "23,29" # 23.0 .. 29.9
}
function randint(n) { return int(n * rand()) }
{
split(SENS[NR], temp, ",")
min = temp[1]
max = temp[2]
if (min == max) {
SENS[NR] = $0
} else {
grad = min + randint(max-min)
fraction = randint(9)
split($0, sens, ",")
gsub("\"", "", sens[2])
SENS[NR] = sprintf("%s,\"%s\",%s,\"%d.%1d\",%d%1d,%s,%s,%s",
sens[1],sens[2],sens[3],
grad,fraction,grad,fraction,
sens[6],sens[7],sens[8])
}
}
END {
for (x in SENS) {
printf "%s\n", SENS[x] | "sort > '$CSVFILE'"
}
}'
fi
$ crontab -e
SHELL=/bin/bash
*/10 * * * * /home/snmp/sensTable/sensor.sh > /dev/null 2>&1
$ diff sensTable_data_access.c.orig sensTable_data_access.c > patchfile.patch
$ patch sensTable_data_access.c.orig -i patchfile.patch -o sensTable_data_access.c
$ make -f sensTable_Makefile
$ net-snmp-config --base-cflags
$ net-snmp-config --agent-libs
$ ldd sensTable
# service snmpd start
# ps fax | grep snmpd | grep -v grep
# cd /home/snmp/sensTable
# ./sensTable -f -DsensTable,verbose:sensTable,internal:sensTable
# ./sensTable -f &
# ps fax | grep sensTable | grep -v grep
# snmpwalk -v2c localhost -c public .1.3.6.1.4.1.21796.3.3.3
# snmpwalk -v2c localhost -c public .1.3.6.1.4.1.21796.3.3.3.1.2
# snmpwalk -v2c localhost -c public .1.3.6.1.4.1.21796.3.3.3.1.6.1
cfg_file=/etc/nagios/objects/switch.cfg
define host{
use generic-switch
host_name poseidon
alias Poseidon 3262
address 127.0.0.1
hostgroups switches
}
define hostgroup{
hostgroup_name switches
alias Network Switches
}
define service{
use generic-service
host_name poseidon
service_description Sensor_1
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.1
}
define service{
use generic-service
host_name poseidon
service_description Sensor_2
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.2
}
define service{
use generic-service
host_name poseidon
service_description Sensor_3
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.3
}
define service{
use generic-service
host_name poseidon
service_description Sensor_4
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.4
}
define service{
use generic-service
host_name poseidon
service_description Sensor_5
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.5
}
define service{
use generic-service
host_name poseidon
service_description Sensor_6
check_command check_snmp!-C public -o .1.3.6.1.4.1.21796.3.3.3.1.5.6
}
-----------------------------------------------------------------------------------------------------------------
Веб-топ-решение на основе Ulteo Virtual Desktop
Антон Борисов
Листинг 1. Пример конфигурационного файла Windows-агента Ulteo
SERVERNAME=10.10.250.10
SESSION_MANAGER_URL=http://10.10.2.10/sessionmanager
LOG_FLAGS="info warn error"
WEBPORT=8082
1) switch ($prefs->get('UserDB', 'enable')) {
2) case 'activedirectory':
3) $prefs_ad = $prefs->get('UserDB', 'activedirectory');
4) $windows_login = $user->getAttribute('real_login').'@'.$prefs_ad['domain'];
6) break;
7) case 'ldap':
8) $prefs_ldap = $prefs->get('UserDB', 'ldap');
9) if ($prefs_ldap['ad'] == 1) {
10) $buf = $prefs_ldap['suffix'];
11) $suffix = suffix2domain($buf);
12) if (! is_string($suffix)) {
13) Logger::error('main', 'LDAP suffix is invalid for AD usage : '.$buf);
14) break;
15) }
16) $windows_login = $user->getAttribute('login').'@'.$suffix;
17) }
18) break;
19) default:
20) $windows_login = $user->getAttribute('login');
21) break;
22) }
-----------------------------------------------------------------------------------------------------------------
Веб-топ-решение на основе Ulteo Virtual Desktop
Антон Борисов
# mke2fs -j /media/hda1
# umount /media/hda1
# mount –o rw /media/hda1
# mkdir /media/hda1/knoppix
# df -h /media/hda1
# free –m
# dd if=/dev/zero of=/media/hda1/knoppix/myswap bs=1M count=1000
# mkswap /media/hda1/knoppix/myswap
# chmod 0600 /media/hda1/knoppix/myswap
# swapon /media/hda1/knoppix/myswap
# mkdir -p /media/hda1/knoppix/master/KNOPPIX
# mkdir -p /media/hda1/knoppix/source/KNOPPIX
# cp -Rp /KNOPPIX/* /media/hda1/knoppix/source/KNOPPIX
# cp /cdrom/index.html /media/hda1/knoppix/master
# cp /cdrom/autorun.* /media/hda1/knoppix/master
# cp /cdrom/cdrom.ico /media/hda1/knoppix/master
# cp /cdrom/KNOPPIX && find . -size -10000k -type f -exec cp -p -parents '[]' /media/hda1/knoppix/master/KNOPPIX/ \;
# chroot /media/hda1/knoppix/source/KNOPPIX
# mount -t proc /proc proc
# dpkg-query -W -showformat ='$(Installed-Size) $(Package)/n' | sort -nr | less
# dpkg-query -l | sort -nr | less
# dpkg-query -s openoffice-de-en
# apt-get remove openoffice-de-en
knoppix@2[~]$ dpkg-query -s kmahjongg
# aptitude purge openoffice-de-en kmahjongg
# apt-get install abiword
# deborphan | less
# deborphan | xargs apt-get -y remove
# apt-get clean
# umount /proc
# mkisofs -R -U -V "My Knoppix" -publisher "Ivan I. Ivanov" -hide-rr-moved -cache-inodes -no-bak -pad /media/hda1/knoppix/source/KNOPPIX | nice -5 /usr/bin/create_compressed_fs - 65536 > /media/hda1/knoppix/master/KNOPPIX/KNOPPIX
# cd /media/hda1/knoppix/master
# mkisofs -pad -l -r -J -v -V "MyKnop" -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -hide-rr-moved -o /media/hda1/knoppix/knoppix.iso /media/hda1/knoppix/master
# cdrecord -v -data knoppix.iso
-----------------------------------------------------------------------------------------------------------------
OSSEC-HIDS. Установка и настройка
Сергей Яремчук
31100
%3Cscript|%2Fscript|script>|script%3E|SRC=javascript|IMG%20|
%20ONLOAD=|INPUT%20|iframe%20
XSS (Cross Site Scripting) attempt.
attack,
$ sudo apt-get install build-essentials
$ wget –c http://www.ossec.net/files/ossec-hids-2.1.1.tar.gz
$ wget –c http://www.ossec.net/files/ossec-hids-2.1.1_checksum.txt
$ cat ossec-hids-2.1.1_checksum.txt
$ md5sum ossec-hids-2.1.1.tar.gz
$ sha1sum ossec-hids-2.1.1.tar.gz
$ tar xzvf ossec-hids-2.1.1.tar.gz
$ cd ossec-hids-2.1.1/
$ sudo ./install.sh
$ sudo cat /var/ossec/logs/active-responses.log
/var/ossec/bin/ossec-control start|stop
79200
/etc,/usr/bin, /usr/sbin
/etc/hosts.deny
// Запись в журнал
1
// Отправка почтового сообщения
7
host-deny
local
6
600
$ sudo tail -f /var/ossec/logs/ossec.log
$ sudo /var/ossec/bin/manage_agents
$ sudo /var/ossec/bin/agent_control -i 001
$ sudo ./ossec-batch-manager.pl -a --ip 192.168.1.1 -n agent_1 -a --ip 192.168.1.2 -n agent_1
$ cat /var/ossec/logs/alerts/2009/Aug/ossec-alerts-28.log
my $datepath=`date "+%Y/%b/ossec-alerts-%d.log"`;
my $LOG='/var/ossec/logs/alerts/'. $datepath;
$ sudo env LC_ALL=POSIX ./ossectop.pl
$ sudo cat ossec-alerts-28.log | ./ossec_report_contrib.pl -s | mail root -s 'OSSEC summary report'
00 01 * * * (cat ossec-alerts-28.log | ./ossec_report_contrib.pl -s)
$ wget –c http://www.ossec.net/files/ui/ossec-wui-0.3.tar.gz
$ tar xzvf ossec-wui-0.3.tar.gz
$ sudo mv ossec-wui-0.3 /var/www/ossec-wui
$ /var/www/ossec-wui
$ sudo chmod 770 /var/www/ossec-wui/tmp
$ sudo chgrp www-data /var/www/ossec-wui/tmp
$ sudo ./setup.sh
$ sudo vi /etc/group
$ cd src; make setmaxagents
$ cd ..; sudo ./install.sh
$ ulimit –a
$ sudo ulimit –n 4096
$ sudo sysctl -w kern.maxfiles=4096
USER_BINARYINSTALL="x"
-----------------------------------------------------------------------------------------------------------------
DBMS_SHEDULER. Запуск последовательных и зависимых заданий
Антон Пищулин
--Создание типа сообщения
create or replace type dwh_que_type as object
(
msg_id number,
msg varchar2(50)
);
--Создание таблицы DWH_QUE_TEST
begin
dbms_aqadm.create_queue_table(
queue_table => 'DWH_QUE_TEST',
queue_payload_type => 'DWH.DWH_QUE_TYPE',
sort_list => 'ENQ_TIME',
multiple_consumers => true,
message_grouping => sys.dbms_aqadm.transactional);
end;
--Создание очереди DWH_QUE_TST
begin
dbms_aqadm.create_queue(
queue_name => 'DWH_QUE_TST',
queue_table => 'DWH_QUE_TEST',
queue_type => sys.dbms_aqadm.normal_queue,
max_retries => 500,
retry_delay => 0,
retention_time => 0);
end;
--Создание расписания TEST_SCH
--(в Oracle EM Administration > Schedules)
BEGIN
dbms_scheduler.create_event_schedule(
event_condition => 'tab.user_data.msg = ''TST_BEGIN''',
queue_spec => '"DWH"."DWH_QUE_TST"',
start_date => systimestamp at time zone 'Europe/Moscow',
schedule_name => '"DWH"."TEST_SCH"');
END;
--Создание пустой цепочки DWH_CH_TST
--(в Oracle EM Administration > Chains)
BEGIN
sys.dbms_scheduler.create_chain(
chain_name => '"DWH"."DWH_CH_TST"');
END;
--Создания рабочих процедур
create or replace procedure p1
is
n number;
BEGIN
n:=0;
--Здесь нужно вставить рабочий код.
--Если возникает ошибка, то ее обязательно нужно
--обработать и сгенерить новый exception
exception when others then
raise_application_error(-20112, 'p1');
END p1;
create or replace procedure p2
is
n number;
BEGIN
n:=0;
--Здесь нужно вставить рабочий код.
--Если возникает ошибка, то ее обязательно нужно
--обработать и сгенерить новый exception
exception when others then
raise_application_error(-20112, 'p2');
END p2;
create or replace procedure p3
is
n number;
BEGIN
n:=0;
--Здесь нужно вставить рабочий код.
--Если возникает ошибка, то ее обязательно нужно
--обработать и сгенерить новый exception
exception when others then
raise_application_error(-20112, 'p3');
END p3;
--Создание программ (в Oracle EM Administration > Programs)
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name=>'"DWH"."pr1"',
program_action=>'begin
p1();
end;',
program_type=>'PLSQL_BLOCK',
number_of_arguments=>0,
enabled=>TRUE);
END;
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name=>'"DWH"."pr2"',
program_action=>'begin
p2();
end;',
program_type=>'PLSQL_BLOCK',
number_of_arguments=>0,
enabled=>TRUE);
END;
--Последняя программа отличается от других
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name=>'"DWH"."pr3"',
program_action=>'
begin
begin
p3();
end;
--Далее идет сервисная часть, посылающая клиенту
--сообщение о завершении работы цепочки
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
message DWH_QUE_TYPE;
BEGIN
message := DWH_QUE_TYPE(1, ''TST_END'');
DBMS_AQ.ENQUEUE(
queue_name => ''DWH_QUE_TST'',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
COMMIT;
END;
end;
',
program_type=>'PLSQL_BLOCK',
number_of_arguments=>0,
enabled=>TRUE);
END;
--Создание шагов цепочки
BEGIN
dbms_scheduler.define_chain_step(
chain_name => '"DWH"."DWH_CH_TST"',
step_name => '"S1"',
program_name => '"DWH"."pr1"');
END;
BEGIN
dbms_scheduler.define_chain_step(
chain_name => '"DWH"."DWH_CH_TST"',
step_name => '"S2"',
program_name => '"DWH"."pr2"');
END;
BEGIN
dbms_scheduler.define_chain_step(
chain_name => '"DWH"."DWH_CH_TST"',
step_name => '"S3"',
program_name => '"DWH"."pr3"');
END;
--Создание правил в цепочке
BEGIN
dbms_scheduler.define_chain_rule(
chain_name => '"DWH"."DWH_CH_TST"',
condition => 'true',
rule_name => 'rule1',
action => 'START "S1","S2"');
END;
BEGIN
dbms_scheduler.define_chain_rule(
chain_name => '"DWH"."DWH_CH_TST"',
condition => 'S1 COMPLETED AND S2 COMPLETED',
rule_name => 'rule2',
action => 'START "S3"');
END;
BEGIN
dbms_scheduler.define_chain_rule(
chain_name => '"DWH"."DWH_CH_TST"',
condition => 'S3 COMPLETED',
rule_name => 'rule3',
action => 'END');
END;
--Активация цепочки
BEGIN
dbms_scheduler.enable('"DWH"."DWH_CH_TST"');
END;
--Создание пакетной задачи
--(в Oracle EM Administration > Jobs)
BEGIN
dbms_scheduler.create_job(
job_name => '"DWH"."JOB_TST"',
job_type => 'CHAIN',
job_action => '"DWH"."DWH_CH_TST"',
schedule_name => '"DWH"."TEST_SCH"',
job_class => '"DEFAULT_JOB_CLASS"',
auto_drop => FALSE,
enabled => FALSE);
dbms_scheduler.set_attribute( name => '"DWH"."JOB_TST"',
attribute => 'logging_level',
value => DBMS_SCHEDULER.LOGGING_FULL);
dbms_scheduler.enable( '"DWH"."JOB_TST"' );
END;
--Добавление пользователя dwh как подписчика очереди
--сообщений(в Oracle EM Maintenance > Management >
--Messaging)
declare
subscriber sys.aq$_agent;
begin
subscriber := sys.aq$_agent('"DWH"', '', 0);
dbms_aqadm.add_subscriber(
queue_name => '"DWH"."DWH_QUE_TST"',
subscriber=> subscriber, rule=> '' ,
transformation=> '');
end;
--Запуск очереди
begin
DBMS_AQADM.START_QUEUE(
'DWH_QUE_TST');
end;
--Запуск цепочки
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
message DWH_QUE_TYPE;
BEGIN
message := DWH_QUE_TYPE(1, 'TST_BEGIN');
--Помещение в очередь сообщения TST_BEGIN
DBMS_AQ.ENQUEUE(
queue_name => 'DWH.DWH_QUE_TST',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
COMMIT;
/*Ожидание сообщения о завершении работы цепочки*/
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
message DWH_QUE_TYPE;
s varchar(20);
s2 varchar2(20);
BEGIN
s2 := 'TST_END';
s := ''''||s2||'''';
dequeue_options.consumer_name := 'DWH';
dequeue_options.wait := DBMS_AQ.FOREVER;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.deq_condition := ?
'tab.user_data.msg = '||s;
--Читаем очередь, ожидаем сообщения TST_END
DBMS_AQ.DEQUEUE(
queue_name => 'DWH.DWH_QUE_TST',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
COMMIT;
END;
END;
-----------------------------------------------------------------------------------------------------------------
Основные грани Ruby. От главных конструкций до приложения
Дмитрий Васильев
irb(main):001:0> (10 == 012) && (10 == 0xa) && (10 == 0b1010)
irb(main):002:0> 12345678901234567890 / 4.5
irb(main):003:0> -33 == 33
irb(main):001:0> ("test" == 'test') && ("test" == %q/test/)
irb(main):002:0> < "test\n" != 'test\n'
irb(main):006:0> "#{10 * 10} times"
irb(main):007:0> '#{10 * 10} times'
irb(main):001:0> [1, 4.5, "test"]
irb(main):002:0> [[1, 2], [3, 4]]
irb(main):003:0> [[1, 2], [3, 4]][0]
irb(main):004:0> [[1, 2], [3, 4]][-1]
irb(main):001:0> {"one" => 1, 2 => "two"}
irb(main):002:0> {"one" => 1, 2 => "two"}["one"]
irb(main):003:0> {"one" => 1, 2 => "two"}[2]
irb(main):004:0> {"one" => 1, 2 => "two"}["2"]
irb(main):001:0> 1..10
irb(main):002:0> "a"..."z"
irb(main):003:0> (1..10).to_a
irb(main):004:0> ("a"..."f").to_a
irb(main):001:0> PI = 3.1415
irb(main):002:0> PI = 3.1415
irb(main):003:0> $count = 0
irb(main):004:0> (1..10).each {|i| $count += i}
irb(main):005:0> $count
irb(main):001:0> (1..10).each do |i|
irb(main):002:1* printf "#{i} "
irb(main):003:1> end
irb(main):001:0> n = 100
irb(main):002:0> if n == 100 then
irb(main):003:1* "hundred"
irb(main):004:1> elsif n == 10 then
irb(main):005:1* "ten"
irb(main):006:1> else
irb(main):007:1* "one"
irb(main):008:1> end
irb(main):001:0> n = 100
irb(main):002:0> unless n == 100 then
irb(main):003:1* "ten"
irb(main):004:1> else
irb(main):005:1* "hundred"
irb(main):006:1> end
irb(main):001:0> n = 100
irb(main):002:0> case n
irb(main):003:1> when 1...10 then 1
irb(main):004:1> when 10...100 then 2
irb(main):005:1> when 100...1000 then 3
irb(main):006:1> end
irb(main):001:0> while line = gets
irb(main):002:1> printf "Line: #{line}"
irb(main):003:1> end
irb(main):001:0> i = 0
irb(main):002:0> until i > 5
irb(main):003:1> i += 1
irb(main):004:1> end
irb(main):005:0> i
irb(main):001:0> for i in [100, 10, 1]
irb(main):002:1> printf "#{i} "
irb(main):003:1> end
class Shape
def area()
raise "Method not implemented"
end
end
class Circle < Shape
attr_reader :radius
def initialize(radius)
@radius = radius
end
def area()
Math::PI * @radius
end
end
class Square < Shape
attr_reader :side
def initialize(side)
@side = side
end
def area()
@side * @side
end
end
irb(main):001:0> require "area"
irb(main):002:0> s = Shape.new
irb(main):003:0> s.area
irb(main):004:0> c = Circle.new 10
irb(main):005:0> c.radius
irb(main):006:0> c.radius = 20
irb(main):007:0> c.area
irb(main):008:0> sq = Square.new 10
irb(main):009:0> sq.side
irb(main):010:0> sq.area
@shapes = {
"circle" => Circle,
"square" => Square
}
def area(line)
parts = line.split
raise "Wrong number of parameters" if parts.length < 2
shape = @shapes.fetch parts[0], nil
raise "Unknown shape" if !shape
arity = shape.allocate.method(:initialize).arity
sizes = parts[1..-1].map {|i| i.to_f}
raise "Wrong number of arguments" if arity != sizes.length
shape.new(*sizes).area
end
def main()
begin
print "> "
begin
break if !line = gets
puts area line
rescue Interrupt
break
rescue RuntimeError => why
print "?#{why}\n"
end
end while true
end
main
$ ruby area.rb
> circle 1
> circle 40.3
> square 20
> unknown 30
-----------------------------------------------------------------------------------------------------------------
Язык Python. Дополнительные типы коллекций
Сергей Супрунов
>>> import collections
>>> User = collections.namedtuple('User', 'name phone login speed')
>>> vasya = User('Петров В. И.', 22343, 'vasya', 128)
>>> for field in vasya:
... print(field) # поведение аналогично кортежу
>>> print(vasya[3]) # работает как обычный кортеж
>>> print(vasya.login, vasya.speed)
>>> tvasya = tuple(vasya) # если нужен простой кортеж
>>> tvasya
>>> Bool = collections.namedtuple('Bool', 'False True', rename=True)
>>> test = Bool('2 > 3', '7 < 8')
>>> test
NAME, PHONE, LOGIN, SPEED = (0, 1, 2, 3) # или range(4)
vasya = ('Петров В. И.', 22343, 'vasya', 128)
print(vasya[LOGIN])
>>> counter = {}
>>> sample = [1,2,1,4,2,3,4]
>>> for dig in sample:
... counter[dig] += 1
...
# Первый способ
if dig in counter:
counter[dig] += 1
else:
counter[dig] = 1
# Второй способ
counter[dig] = counter.get(dig, 0) + 1
# Третий способ
counter[dig] = counter.setdefault(dig, 0) + 1
# Четвёртый способ
try:
counter[dig] += 1
except KeyError:
counter[dig] = 1
counter = collections.defaultdict(int)
for dig in sample:
counter[dig] += 1
>>> fifo = collections.deque()
>>> stack = collections.deque()
>>> fifo.appendleft(1)
>>> fifo.appendleft(2)
>>> fifo.appendleft(3)
>>> fifo.pop()
>>> fifo.pop()
>>> stack.append(1)
>>> stack.append(2)
>>> stack.append(3)
>>> stack.pop()
>>> stack.pop()
#!/usr/local/bin/python3.1
import collections, random
baraban = collections.deque((1,0,0,0,0,0))
baraban.rotate(random.randint(5,99))
for shot in range(len(baraban)):
input('Чья очередь - нажмите Enter... ')
if baraban[shot]:
print('БА-БАХ!!!')
break
else:
print('клац')
print('Финита ля комедия, господа!')
>>> od = c.OrderedDict()
>>> od['w'] = 123
>>> od['a'] = 34
>>> od.keys()
>>> sample = [1,2,1,4,2,3,4]
>>> cnt = collections.Counter(sample)
>>> cnt
>>> cnt[4]
>>> text = open('/home/amsand/reconf.py').read()
>>> cnt = c.Counter(text)
>>> cnt.most_common(3)
>>> a = [1,2,3]
>>> b = a
>>> b[2] = 5
>>> a
>>> b
>>> a is b
-----------------------------------------------------------------------------------------------------------------