COMMAND EDITING
ctrl+ a # go to the start of the command line
ctrl+ e # go to the end of the command line
ctrl+ k # delete from cursor to the end of the command line
ctrl+ u # delete from cursor to the start of the command line
ctrl+ w # delete from cursor to start of word (i.e. delete backwards one word)
ctrl+ y # paste word or text that was cut using one of the deletion shortcuts (such as the one above) after the cursor
ctrl+ xx # move between start of command line and current cursor position (and back again)
alt+ b # move backward one word (or go to start of word the cursor is currently on)
alt+ f # move forward one word (or go to end of word the cursor is currently on)
alt+ d # delete to end of word starting at cursor (whole word if cursor is at the beginning of word)
alt+ c # capitalize to end of word starting at cursor (whole word if cursor is at the beginning of word)
alt+ u # make uppercase from cursor to end of word
alt+ l # make lowercase from cursor to end of word
alt+ t # swap current word with previous
ctrl+ f # move forward one character
ctrl+ b # move backward one character
ctrl+ d # delete character under the cursor
ctrl+ h # delete character before the cursor
ctrl+ t # swap character under cursor with the previous one
COMMAND RECALL
ctrl+ r # search the history backwards
ctrl+ g # escape from history searching mode
ctrl+ p # previous command in history (i.e. walk back through the command history)
ctrl+ n # next command in history (i.e. walk forward through the command history)
alt+ . # use the last word of the previous command
COMMAND CONTROL
ctrl+ l # clear the screen
ctrl+ s # stops the output to the screen (for long running verbose command)
ctrl+ q # allow output to the screen (if previously stopped using command above)
ctrl+ c # terminate the command
ctrl+ z # suspend/stop the command
BASH BANG COMMAND !
!! # run last command
!blah # run the most recent command that starts with ‘blah’ (e.g. !ls)
!blah:p # print out the command that !blah would run (also adds it as the latest command in the command history)
!$ # the last word of the previous command (same as alt+ .)
!$:p # print out the word that !$ would substitute
!* # the previous command except for the last word (e.g. if you type ‘_find somefile.txt /’, then !* would give you ‘_find somefile.txt’)
!*:p # print out what !* would substituteCOMMAND
'<>'' represents the shortcut to enter in command mode of tmux. Initialy ctrl+n, for me ctrl+q
<> : # in a tmux session launch a command line (abstract tmux command)
tmux ls
tmux list-sessions
tmux list-windows -t $session # list windows in session $session (or current)
tmux / tmux new / tmux new-session # launch a new session
tmux new -s $session # launch a new session with a name $session
<> : kill-session -t $session # kill session $session (name or number)
<> : kill-session -a # kill all sessions
<> : kill-session -a -t $session # kill all but session $session
<> : rename-session -t $session# rename session
<> : rename-window -t $session:$window # rename window
<> : detach / : attach -d # detach session
<> : a / : attach -t $session:$windows # attach session / windows (or current session)
<> : switch -t $session # switch to session $session
SHORTCUTS
session
<> + d # detach current session
<> + ) # move to next session
<> + ( # move to previous session
<> + s # interactive session selection
window
<> + c # create a new window in current session
<> + n # switch to next window
<> + p # switch to previous window
<> + $n # switch to a specific terminal $n (start from 0)
<> + , # rename current window
<> + w # interactive window selection
pane
<> + " # new horizontal pane below
<> + % # new vertical pane to the right
<> + x # kill pane
<> + z # toggle between pane zoom
<> + ctrl+n # switch to next pane
<> + ctrl+p # switch to previous pane
<> + { # swap the current pane with the previous pane
<> + } # swap the current pane with the next pane
<> + space # switch layout
<> + q # show panes number
<> + q $n # move to pane $n
<> + ! # convert pane to window
<> + left # move to left
<> + right # move to right
<> + up # move to up
<> + down # move to down
others
<> + ? # show all shortcuts
<> + t # show time in windows
<> + [ # enter in copy-mode (q or <esc> to quit)
perso
<> + R # Reload conf file
<> + m # enable mouse mode
<> + M # disable mouse mode
<> + k # kill window
<> + K # kill server
copy mode
ctrl + PageUp # enter in copy mode & scroll page up
alt + Up / alt+up # enter in copy mode & scroll page up
ctrl+s # search in history in copy mode
PLUGINS
https://github.com/tmux-plugins
RESURRECT
resurect / Persists tmux environment across system restarts
https://github.com/tmux-plugins/tmux-resurrect
<> + ctrl+s # to save current worspace (sessions)
<> + ctrl+r # to restore worspace (sessions)
The last saved worspace is a symlink 'last' to the active worspace in ~/.tmux/resurrect/ where are keeped history of saved works
autostart
sudo cat > /etc/systemd/system/tmux.service << EOF
[Unit]
Description=tmux default session (detached)
Documentation=man:tmux(1)
[Service]
Type=forking
User=nikita
Group=nikita
Environment=DISPLAY=:0
ExecStart=/usr/bin/tmux new-session -d
ExecStop=/home/${USER}/.tmux/plugins/resurect/scripts/save.sh
ExecStop=/usr/bin/tmux kill-server
KillMode=none
RestartSec=2
[Install]
WantedBy=default.target
EOF
systemctl enable tmux --nowinstall
conf
sudo sh -c "echo '\n# sublime-text hack\n127.0.0.1\tsublimetext.com\n127.0.0.1\twww.sublimetext.com\n127.0.0.1\tlicense.sublimehq.com' >> /etc/hosts"
apt install -y iptables-persistent
ips="45.55.255.55"
for ip in ${ips}; do sudo iptables -A OUTPUT -d ${ip} -j DROP; done
path="/etc/iptables"
[ -d "${path}" ] || sudo mkdir "${path}"
sudo iptables-save -f /etc/iptables/rules.v4
build 3211
----- BEGIN LICENSE -----
Member J2TeaM
Single User License
EA7E-1011316
D7DA350E 1B8B0760 972F8B60 F3E64036
B9B4E234 F356F38F 0AD1E3B7 0E9C5FAD
FA0A2ABE 25F65BD8 D51458E5 3923CE80
87428428 79079A01 AA69F319 A1AF29A4
A684C2DC 0B1583D4 19CBD290 217618CD
5653E0A0 BACE3948 BB2EE45E 422D2C87
DD9AF44B 99C49590 D2DBDEE1 75860FD2
8C8BB2AD B2ECE5A4 EFC08AF2 25A9B864
------ END LICENSE ------
build 3176
—– BEGIN LICENSE —–
sgbteam
Single User License
EA7E-1153259
8891CBB9 F1513E4F 1A3405C1 A865D53F
115F202E 7B91AB2D 0D2A40ED 352B269B
76E84F0B CD69BFC7 59F2DFEF E267328F
215652A3 E88F9D8F 4C38E3BA 5B2DAAE4
969624E7 DC9CD4D5 717FB40C 1B9738CF
20B3C4F1 E917B5B3 87C38D9C ACCE7DD8
5F7EF854 86B9743C FADC04AA FB0DA5C0
F913BE58 42FEA319 F954EFDD AE881E0B
—— END LICENSE ——
packagecontrol
https://packagecontrol.io # packages info + shortcuts
COLOR SCHEME
package control / Install Package / PackageResourceViewer
package control / PackageResourceViewer / Open Resource / select scheme
package control / PackageResourceViewer / Theme - Default / adaptive / Adaptive.sublime-theme
SIZE
/home/$USER/.config/sublime-text-3/Packages/Theme - Default/adaptive/Adaptive.sublime-theme
/home/$USER/.config/sublime-text-3/Packages/Theme - Default/Default.sublime-theme
PACKAGE
python
- Anaconda
Anaconda turns your Sublime Text 3 in a full featured Python development IDE - Python Debugger
Graphical Debugger for Sublime Text - Python 3
Python 3 and Cython language bundles for Sublime Text and TextMate - DocBlockr_Python
Sublime Text DocBlockr for python. Simplifies writing docstring comments in Python
https://wiki.manjaro.org/index.php?title=Pacman_Overview
https://wiki.archlinux.fr/pacman
https://community.chakralinux.org/t/how-to-use-pacman-to-search-for-install-upgrade-and-uninstall-packages
PACMAN CONF
all configurations for pacman are stored in:
/etc/pacman.conf
UPGRADE -U
yay -U /var/cache/pacman/pkg/python-3.9.3-1-x86_64.pkg.tar.zst # install a specific version
IGNORE
/etc/pacman.conf
sudo sed -i '/^#IgnorePkg/a IgnorePkg = libvirt' /etc/pacman.conf
sudo sed -i '/^#IgnorePkg/a Include = /etc/pacman.d/ignorepcks' /etc/pacman.conf
sudo sh -c "echo -e 'IgnorePkg = libvirt\nIgnorePkg = libvirt-python' > /etc/pacman.d/ignorepcks"
SYNC -S
pacman -Si $package # get informlation about package
pacman -Sl $repo # list all packages from repository
pacman -Sy # update local packages list
pacman -Syy # replace local packages list
pacman -Su # upgrade packages
pacman -Suu # upgrade & downgrade if needed
pacman -Syu # update & upgrade
pacman -Syyu
pacman -Syyuu
pacman -Syuc # update, upgrade, clean
pacman -S package # install package
pacman -S core/package_name # install a specified repo/core package
pacman -S plasma-{desktop,mediacenter,nm} # install tree name packages
pacman -Ss $regex # search packages
pacman -Ssq $regex # search packages with minimal print
pacman -S $pack... # install packages
pacman -S $repo/$pack # install package from specific repo
REMOVE -R
pacman -R $pack... # remove packages
pacman -Rs $pack... # remove packages and dependencies
pacman -Ru $pack... # remove unneeded packages
pacman -Qdt # list orphane packages
pacman -Rsn $(pacman -Qdtq) # remove orphan packages
QUERY -Q
pacman -Qqettn # List of Native installed packages
pacman -Qqettm # List of AUR installed packages
DOWNGRADE
pamac install downgrade # install downgrade
downgrade $package # interactive downgrade package
PACMAN-MIRRORS
pacman-mirrors --country-list # get list of countries for repositories
pacman-mirrors -c France # select a country for repositories
pacman-mirrors -i # generate an interactive mirrolist
pacman-mirrors -c all # reset custom mirrorlist
PACTREE
pactree package_name # list all the packages recursively depending on an installed package
pactree -r package_name # whoneeds package_name
AUR REPO & YAOURT
https://wiki.manjaro.org/index.php/D%C3%A9p%C3%B4t_AUR_%28Arch_User_Repository%29
POST-INSTALLATION
http://stephenmyall.com/manjaro/
https://dolys.fr/forums/topic/mon-installation-post-installation-manjaro/
AUDIO
For audio micro+headphone 08bb:2902
file=/lib/udev/rules.d/90-pulseaudio.rules
sudo cp -a ${file} ${file}.$(date +%s)
sudo sed -i '/08bb.*2902.*behringer-umc22/ s|^|#|' ${file}
LXD
cgroup v2 error messaging
file=/lib/udev/rules.d/90-pulseaudio.rules
part='systemd.unified_cgroup_hierarchy=0'
sudo cp -a ${file} ${file}.$(date +%s)
grep -q "^GRUB_CMDLINE_LINUX=.*${part}" ${file} || sudo sed -i '/^GRUB_CMDLINE_LINUX=/ s|"$| ${part}"|' ${file}
sudo update-grub
EFIVARFS
file=/etc/default/grub
part='efi=runtime'
sudo cp -a ${file} ${file}.$(date +%s)
grep -q "^GRUB_CMDLINE_LINUX=.*${part}" ${file} || sudo sed -i '/^GRUB_CMDLINE_LINUX=/ s|"$| ${part}"|' ${file}
sudo update-grub
&
file=/etc/mkinitcpio.conf
part='efivarfs'
sudo cp -a ${file} ${file}.$(date +%s)
grep -q "^MODULES=.*${part}" ${file} || sed -i '/^MODULES=/ s|)$| ${part})|' ${file}
sudo mkinitcpio -P
LOGIN-SCREEN
/etc/dconf/db/gdm.d/02-logo
[org/gnome/login-screen]
logo='/path/to/logo.png'
logo
gsettings set org.gnome.login-screen logo '/path/to/logo.png'
dconf # /org/gnome/login-screen/logo
https://wiki.archlinux.org/index.php/GDM
DEVICES
lsmod # show modules
lspci -k # show pci devices with used informations
inxi -Fxz # show details of device
VIDEO
inxi -G # show video informations
sudo mhwd -a pci nonfree 0300 # install non free driver
mhwd -li # show installed driver from mhwd
yay -S system-config-printer manjaro-printer
sudo usermod -a -G cups $USER
sudo gpasswd -a $USER sys
sudo systemctl enable --now org.cups.cupsd.service
RADIOTRAY
sudo ln -sv /usr/lib/libjsoncpp.so.24 /usr/lib/libjsoncpp.so.22
KVM QEMU Virt-Manager
https://computingforgeeks.com/install-kvm-qemu-virt-manager-arch-manjar/
GRUB COMMAND
press 'c' while launching to interrupt grub launching and entre in grub command
CHANGE GRUB DISPLAY RESOLUTION
vbeinfo # list available resolutions
modify in /etc/default/grub (ex: 800x600)
GRUB_GFXMODE=$resolution
CLEAR SECTOR 32
dd if=/dev/zero of=/dev/sda bs=512 count=1 seek=32
grub-install $device
USB3 MSI GAMING
add in /etc/default/grub
GRUB_CMDLINE_LINUX="iommu=soft"
LXD
/etc/default/grub
GRUB_CMDLINE_LINUX="... systemd.unified_cgroup_hierarchy=0
GRUB_TIMEOUT
Modify set timeout for choosed value in /boot/grub/grub.cfg
if [ "$recordfail_broken" = 1 ]; then
cat << EOF
if [ \$grub_platform = efi ]; then
set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
if [ x\$feature_timeout_style = xy ] ; then
set timeout_style=menu
fi
fi
EOF
fi
MANJARO
OS real name for btrfs
file="/etc/grub.d/30_os-prober"
file_keep="$file.keep$(date +%s)"
if ! grep -q 'LONGNAME="${LONGNAME} ${BTRFSsubvol/#subvol=/}"' "$file"; then
sudo cp -a "$file" "$file.keep$(date +%s)" && sudo chmod -x "$file_keep"
sudo sed -i "/LONGNAME=\"\${LABEL}\"/ a\ else\n LONGNAME=\"\${LONGNAME} \${BTRFSsubvol/#subvol=/}\"" "$file"
sudo update-grub
fi
UBUNTU 18.04
Remove error in startup log : systemd-backlight@backlight:acpi_video0.service, add in /etc/default/grub
acpi_osi='!Windows 2012'
acpi_backlight=vendor in GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub
BOOT ENTRY
https://linux.die.net/man/8/efibootmgr
efibootmgr
efibootmgr # list all boot entries
-v # list all boot entries with details
-B -b XXXX # delete boot entry number XXXX
example for 970g
efibootmgr -c -g -d /dev/sda1 -p 1 -w -L 'Manjaro' -l '\EFI\Manjaro\grubx64.efi'
efibootmgr -c -g -d /dev/sda1 -p 1 -w -L 'ubuntu' -l '\EFI\ubuntu\shimx64.efi'
efibootmgr -c -g -d /dev/sda1 -p 1 -w -L 'Windows Boot Manager' -l '\EFI\Microsoft/Boot\bootmgfw.efi'
>>
Timeout: 1 seconds
BootOrder: 0000,0001,0002
Boot0000* Manjaro HD(1,GPT,8e91a305-046d-4e90-8548-efca286325a7,0x800,0x32000)/File(\EFI\Manjaro\grubx64.efi)
Boot0001* ubuntu HD(1,GPT,8e91a305-046d-4e90-8548-efca286325a7,0x800,0x32000)/File(\EFI\ubuntu\shimx64.efi)
Boot0002* Windows Boot Manager HD(1,GPT,8e91a305-046d-4e90-8548-efca286325a7,0x800,0x32000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)TYPES
str
unicode
list
tuple
buffer
xrange
PRIORITY ORDER
x in s # True if an item of s is equal to x, else False
x not in s # False if an item of s is equal to x, else True
s + t # the concatenation of s and t
s * n , n * s # n shallow copies of s concatenated
s[i] # i'th item of s, origin 0
s[i:j] # slice of s from i to j
s[i:j:k] # slice of s from i to j with step k
len(s) # length of s
min(s) # smallest item of s
max(s) # largest item of s
METHOD
s.index(str) # return first position of str in s
s.count() # return then number of elements
SLICE
first included, second excluded (even with negative step)
s[start:end:step]
syntax
s[start:]
s[:end]
s[:] # duplicates element
s[start:-end] # from index1 to (index2 from last)
s[-start:-end] # from (index1 from last) to (index2 from last)
s[-start:end] # from (index1 from last) to index2 -> empty
s[-start:end:-step] # from (index1 from last) to (index2 from last)
s[::-1] # reverse
s[start:end:-2] # with start > end else return None # reverse a part with step
s[start;start] = [n] # insert element n in s at position start
s[start:end] = [] # unset elements between start and end (start included & end excluded)
examples
l = [0, 2, 4, 8, 16, 32, 64, 128]
l
l[-1:1:-2]
l[2:4] = [100, 200, 300, 400, 500]
l256colors for nested tmux
20.04
export TERM=xterm-256color
turn off/disable bluetooth device startup
18.04
grep -n DEVICES_TO_DISABLE_ON_STARTUP /etc/default/tlp
auto login
sudo sh -c "echo '
# autologin
[Seat:*]
autologin-session=xubuntu
autologin-user=${USER}
autologin-user-timeout=0' >> /etc/lightdm/lightdm.confINSTALL
install
apt-get install -y opendkim opendkim-tools
data
domain="17112018.fr"
path_keys="/etc/opendkim/keys"
dkim="dkim"
KEYS
mkdir -p ${path_keys}/${domain}
cd ${path_keys}/${domain}
opendkim-genkey --bits=2048 -s ${dkim} -d ${domain}
chown opendkim:opendkim ${dkim}.private
chmod g-rwx ${dkim}.private
test
opendkim-testkey -d ${domain} -s ${dkim} -k /etc/opendkim/keys/${domain}/${dkim}.private -vvv
CONF
/etc/opendkim.conf
AutoRestart Yes
AutoRestartRate 10/1h
UMask 002
Syslog yes
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:12301@localhost
/etc/default/opendkim
SOCKET="inet:12301@localhost"
/etc/postfix/main.cf
milter_protocol = 2
milter_default_action = accept
# without spamassassin
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301
# with spamassassin
#smtpd_milters = unix:/spamass/spamass.sock, inet:localhost:12301
#non_smtpd_milters = unix:/spamass/spamass.sock, inet:localhost:12301
/etc/opendkim/TrustedHosts
127.0.0.1
localhost
# IP senders
$SENDER_IP
# Domains senders
*.${domain}
/etc/opendkim/KeyTable
${dkim}._domainkey.${domain} ${domain}:${dkim}:${path_keys}/${domain}/${dkim}.private
/etc/opendkim/SigningTable
*@${domain} ${dkim}._domainkey.${domain}
RESTART
systemctl restart postfix opendkimSENDER
/etc/postfix/main.cf
relayhost = [$receiver_ip]
RECEIVER
/etc/postfix/main.cf
myhostname = $domain_to_relay
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost.localdomain, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 $sender_ip1 $sender_ip2
virtual_alias_maps = hash:/etc/postfix/virtual
alias
/etc/postfix/virtual
$email_alias $email_to_send
Compile modifications
postmap /etc/postfix/virtual
postfix reload
postmap -q $email_alias /etc/postfix/virtual
RESTART
systemctl restart postfix.serviceALIASES / EXIM4
http://debian-facile.org/doc:reseau:exim4:redirection-mails-locaux
# add alias to container
ls /vm/root/*/etc/aliases|xargs -L 1 sed -i "\$a root: tech@17112018.fr"
cat /vm/root/*/etc/aliases
vz-launch -y "newaliases" all
vz-launch -y "exim -bt root" all
vz-launch -y "systemctl restart exim4" all
# test alias
exim -bt rootINSTALL
get mybb-1.8.19.tgz & put it in $path_install
domain="17112018.fr"
subdomain="forum"
path_install="/var/share/www/17112018.fr"
path="$path_install/forum"
version="1.8.19"
file_mybb="mybb-${version}"
cd "$path_install"
tar xzf "${file_mybb}.tgz"
ln -sv "$file_mybb" "$subdomain"
ln -sv "$file_mybb/Upload/" "$subdomain"
PRECONF
cp -a "$subdomain/htaccess.txt" "$subdomain/.htaccess"
sed -i '/Order Deny,Allow/d' "$subdomain/.htaccess"
sed -i 's/Deny from all/Require all denied/' "$subdomain/.htaccess"
# add subdomain in apache conf
nano /etc/apache2/sites-available/$domain.conf
sysars
a2ensite ${domain}.conf
SETUP
https://${subdomain}.${domain} # launch
POSTCONF
systemctl restart apache2.service
nano inc/config.php
chmod 666 "$subdomain/inc/config.php" "$subdomain/inc/settings.php"
chmod 777 "$subdomain/cache/" "$subdomain/cache/themes/" "$subdomain/uploads/" "$subdomain/uploads/avatars/"! before creation of DBs !
MASTER
/etc/mysql/conf.d/master.cnf
[mysqld]
# master
server_id=1
log-bin
log-basename=master1
binlog_do_db="nextcloud"
binlog_do_db="postfixadmin"
# db
replicate_do_db="nextcloud"
replicate_do_db="postfixadmin"
GRANT REPLICATION SLAVE ON *.* TO 'replic'@'10.0.0.12%' IDENTIFIED BY '${pwd}'; # user
systemctl restart mariadb # restart
SLAVE
/etc/mysql/conf.d/slave.cnf
[mysqld]
# slave
server_id=2
relay-log=relay-bin
expire_logs_days=32 # master expire_logs_days setting + 2
# db
replicate_do_db="nextcloud"
replicate_do_db="postfixadmin"
mariadb create dump user
GRANT SELECT, RELOAD, SUPER, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'dump'@'localhost' IDENTIFIED BY '${pwd}';
#GRANT RELOAD, SUPER, REPLICATION CLIENT ON *.* TO 'dump'@'localhost' IDENTIFIED BY '${pwd}';
#GRANT SELECT, LOCK TABLES ON *.* TO 'dump'@'localhost';
mariadb create purge user
GRANT SUPER ON *.* TO 'purge'@'localhost' IDENTIFIED BY '${pwd}';
restart
systemctl restart mariadb
start
with mysql client
CHANGE MASTER TO
MASTER_HOST='10.0.0.120',
MASTER_USER='replic',
MASTER_PASSWORD='${pwd}',
MASTER_PORT=3306,
MASTER_LOG_FILE='master1-bin.000001',
MASTER_LOG_POS=330,
MASTER_CONNECT_RETRY=10;
START SLAVE;
CRON
look at 'cron'
/etc/cron.d/mariadb-dump-slave # dump from vm slave to host
# dump replicated mariadb databases & rotate files
cmd=/usr/local/bs/mysql-dump-slave
opts="${pwd}=${pwd} path2=$path"
0 1 * * * root test -x $cmd && $cmd $opts # every day at 01h00
# 0 */1 * * * root test -x $cmd && $cmd # every hour
Change rights
chmod 700 /etc/cron.d/mariadb-dump-slave
/etc/cron.d/ns388803-mariadb # get dump from an other host, put this file to secondary server to get file from the host server
# cron for get mariadb dump from ns388803 to local
host="ns398616"
*/10 * * * * root rsync -av root@node2:/save/mariadb/ /save/$host/mariadb/ >/dev/null 2&>1 # synchronize every 10mn
SYSTEM
MASTER LOGS
RESET MASTER;
//RESET MASTER TO 'master1-bin.000006';
PURGE MASTER LOGS TO 'master1-bin.000006';
PURGE MASTER LOGS BEFORE '2018-11-15 12:00:00';
FLUSH LOGS;
purge binary logs to file
PURGE BINARY LOGS TO 'master1-bin.000006';
PURGE BINARY LOGS BEFORE '2018-11-15 12:00:00';
SHOW
SHOW SLAVE STATUS\G;
SHOW MASTER STATUS;
DELAYED REPLICATION
STOP SLAVE;
CHANGE MASTER TO master_delay=3600;
START SLAVE;
DUMP ON MASTER
mysqldump -udump -p${pwd} ${db} --no-data --master-data --single-transaction > "${path2}/${file}-struct.sql"
mysqldump -udump -p${pwd} ${db} --no-create-info --master-data --single-transaction | gzip -c > "${path2}/${file}.sql.gz"
DUMP ON SLAVE
mysqldump -udump -p${pwd} ${db} --no-data --dump-slave --single-transaction | gzip -c > ${path2}/${file}-struct.sql.gz
mysqldump -udump -p${pwd} ${db} --no-create-info --dump-slave --single-transaction| gzip -c > ${path2}/${file}.sql.gz
RESTORE FROM DUMP
-
SLAVE
# stop replication user=; pwd= mysql -u${user} -p${pwd} -e "STOP SLAVE;" # show replication mysql -u${user} -p${pwd} -e "SHOW SLAVE STATUS \G;"|head -n20 -
MASTER
user=; pwd=; db=; path2=; file= # lock tables mysql -u${user} -p${pwd} ${db} -e "FLUSH TABLES WITH READ LOCK;" # dump mysqldump -u${user} -p${pwd} ${db} --no-data --master-data --single-transaction | gzip -c > "${path2}/${db}-old_stru.sql.gz" mysqldump -u${user} -p${pwd} ${db} --no-create-info --master-data --single-transaction | gzip -c > "${path2}/${db}-old_data.sql.gz" # drop db mysql -u${user} -p${pwd} -e "DROP DATABASE IF EXISTS ${db};" # create db mysql -u${user} -p${pwd} -e "CREATE DATABASE ${db};" # show dbs mysql -u${user} -p${pwd} -e "SHOW DATABASES;" # restore dump gzip -dc ${path2}/${file}_stru.sql.gz | mysql -u${user} -p${pwd} ${db} # erase if exists gzip -dc ${path2}/${file}_data.sql.gz | mysql -u${user} -p${pwd} ${db} # show status mysql -u${user} -p${pwd} ${db} -e "SHOW MASTER STATUS;" # unlock tables mysql -u${user} -p${pwd} ${db} -e "UNLOCK TABLES;" -
SLAVE
user=; pwd=; db=; path2=; file= # drop db mysql -u${user} -p${pwd} -e "DROP DATABASE IF EXISTS ${db};" # create db mysql -u${user} -p${pwd} -e "CREATE DATABASE ${db};" # show dbs mysql -u${user} -p${pwd} -e "SHOW DATABASES;" # restore dump gzip -dc ${path2}/${file}_stru.sql.gz | mysql -u${user} -p${pwd} ${db} # erase if exists gzip -dc ${path2}/${file}_data.sql.gz | mysql -u${user} -p${pwd} ${db} # show replication mysql -u${user} -p${pwd} -e "SHOW SLAVE STATUS \G;"|head -n20 # change replication mysql -u${user} -p${pwd} -e "CHANGE MASTER TO MASTER_LOG_FILE='';" mysql -u${user} -p${pwd} -e "CHANGE MASTER TO MASTER_LOG_POS=;" # start replication mysql -u${user} -p${pwd} -e "START SLAVE;" # show replication mysql -u${user} -p${pwd} -e "SHOW SLAVE STATUS \G;"|head -n20
RESTORE FROM SCRATCH
-
MASTER: lock tables
mysql -u${user} -p${pwd} ${db} -e "FLUSH TABLES WITH READ LOCK;" mysql -u${user} -p${pwd} ${db} -e "SHOW MASTER STATUS;" -
MASTER: dump master container with keeping MASTER position
# all databases mysqldump -u${user} -p${pwd} --all-databases --master-data --single-transaction | gzip -c > ${path2}/all.sql.gz # # or list of databases in ${dbs} mysqldump -u${user} -p${pwd} ${db} -e "FLUSH TABLES WITH READ LOCK;" for db in ${dbs}; do mysqldump -u${user} -p${pwd} ${db} --no-data --master-data --single-transaction | gzip -c > ${path2}/${file}-stru.sql.gz mysqldump -u${user} -p${pwd} ${db} --no-create-info --master-data --single-transaction | gzip -c > ${path2}/${file}-data.sql.gz done -
MASTER: unlock tables
mysql -u${user} -p${pwd} ${db} -e "SHOW MASTER STATUS;" mysql -u${user} -p${pwd} ${db} -e "UNLOCK TABLES;" -
SLAVE: stop & reset slave service
mysql -u${user} -p${pwd} -e "STOP SLAVE; RESET SLAVE;" -
load master data to slave
# all databases gzip -dc ${path2}/all.sql.gz | mysql -u${user} -p${pwd} # # or list of databases in ${dbs} for db in ${dbs}; do gzip -dc ${path2}/${file}-stru.sql.gz | mysql -u${user} -p${pwd} ${db} # erase if exists gzip -dc ${path2}/${file}-data.sql | mysql -u${user} -p${pwd} ${db} done -
start mariadb service in slave
mysql -u${user} -p${pwd} -e "START SLAVE;" -
show state
mysql -u${user} -p${pwd} -e "START SLAVE;" mysql -u${user} -p${pwd} -e "SHOW SLAVE STATUS\G;"
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
Allow to execute codes define in object himself in enter & exit methods
Propagates an exception based on the return value of the exit method:
- False -> propagate
- True -> does not propagate
Difference between try/finally & with/as are about the place of codes executed in finally or enter/exit:
- for try/finally, codes are in codes arround object
- for with/as, codes are in embeded in object
syntax
with expression as name:
...
catch specific exception in __exit__
def __exit__(self, exc_type, exc_value, traceback):
example
with as
import time
class Timer:
def __enter__(self):
print("Entering Timer")
self.start = time.time()
return self
def __exit__(self, *args):
print(f"execution time {time.time() - self.start}")
# propagate exception
return False
def __str__(self):
return f"delay {time.time() - self.start}s"
with Timer() as t:
sum(x for x in range(10_000_000))
1/0
print(t)
sum(x**2 for x in range(10_000_000))
or
import time
try:
with Timer():
time.sleep(0.5)
1/0
except Exception as exc:
# on va bien recevoir cette exception
print(f"OOPS -> {type(exc)}")
try finally
import time
try:
start = time.time()
print(sum(x for x in range(10_000_000)))
1/0
print(f"delay {time.time() - start}s")
print(sum(x**2 for x in range(5_000_000)))
except ZeroDivisionError as e:
print(f"OOPS, {type(e)}, {e}")
finally:
print(f"execution time {time.time() - start}")
catch specific exception
class Timer2:
def __enter__(self):
print("Entering Timer1")
self.start = time.time()
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is None:
# pas d'exception levée dans le corps du 'with'
print(f"Total duration {time.time()-self.start:2f}")
# dans ce cas la valeur de retour n'est pas utilisée
else:
if exc_type in (ZeroDivisionError,) :
print("on étouffe")
# on peut l'étouffer en retournant True
return True
else:
print(f"OOPS : on propage l'exception "
f"{exc_type} - {exc_value}")
# et pour ça il suffit... de ne rien faire du tout
# ce qui renverra None
with a filtered exception
try:
with Timer2():
time.sleep(0.5)
1/0
except Exception as e:
# on va bien recevoir cette exception
print(f"OOPS -> {type(e)}")
with an other exception
try:
with Timer2():
time.sleep(0.5)
raise OSError()
except Exception as e:
# on va bien recevoir cette exception
print(f"OOPS -> {type(e)}")
decorator
example
from contextlib import contextmanager
@contextmanager
def compact_timer(message):
start = time.time()
yield
print(f"{message}: duration = {time.time() - start}")
with compact_timer("Squares sum"):
print(sum(x**2 for x in range(10**5)))https://docs.python.org/3/reference/datamodel.html#specialnames
https://docs.python.org/3/reference/datamodel.html#object.__new__
https://docs.python.org/3/reference/datamodel.html#object.__repr__
__init__ # called after the constructor and implement instance of class
__repr__ # called when the object calls without printing. if missing, use __str__ instead
__str__ # print when print method is called on object
__bool__ # used for test on object
__len__ # called in place of __bool__ if missing
__add__, __mul__, __sub__, __div__, __and__, ... called by sum, +, *, ... methods
__contains__ # called by 'in' method
__len__ # called by 'len' method
__getitem__ # used by slice, calling element[], make element an iterable
__eq__ # called to compare object '==', 'is'. depends of hash, if __eq__ are implemented __hash__ have to be it also
__hash__ # https://docs.python.org/3/reference/datamodel.html?highlight=__hash__#object.__hash__
__call__ # use instance (object) of class like a function
EXAMPLES
__call__
class PlusClosure:
def __init__(self, initial):
self.initial = initial
def __call__(self, *args):
return self.initial + sum(args)
plus2 = PlusClosure(2)
plus2(5)
__getattr__
class RPCProxy:
def __init__(self, url, login, password):
self.url = url
self.login = login
self.password = password
def __getattr__(self, function):
"""
Crée à la volée une méthode sur RPCProxy qui correspond
à la fonction distante 'function'
"""
def forwarder(*args):
print(f"Envoi à {self.url}...")
print(f"de la fonction {function} -- args= {args}")
return "retour de la fonction " + function
return forwarder
rpc_proxy = RPCProxy (url='http://cloud.provider.com/JSONAPI',
login='dupont',
password='***')
# cette partie du code, en tant qu'utilisateur de l'API, est supposée connaître les détails des arguments à passer et de comment utiliser les valeurs de retour
nodes_list = rpc_proxy.GetNodes (
[ ('phy_mem', '>=', '32G') ] )
# réserver un noeud
node_lease = rpc_proxy.BookNode (
{ 'id' : 1002, 'phy_mem' : '32G' } )
Point
class Point:
a = 0
b = 0
d = [a, b]
def __init__(self, x=0, y=0, len=0):
self.x = x
self.y = y
self.p = [x, y]
def __repr__(self):
return f"Pt[{self.x}, {self.y}]"
class Point_eh(Point):
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __hash__(self):
return (11 * self.x + self.y)
p1 = Point(0,1)
p2 = Point(0,1)
p3 = Point(0,1)
s = {p1, p2}
p1
s
# __eq__
p1 == p2
peh1 = Point_eh(0,1)
peh2 = Point_eh(0,1)
s = {peh1, peh2}
Matrix
class Matrix:
def __init__(self, *args):
"""
le constructeur accepte
(*) soit les 4 coefficients individuellement
(*) soit une liste - ou + généralement une séquence - des mêmes
"""
# on veut pouvoir créer l'objet à partir des 4 coefficients
# souvenez-vous qu'avec la forme *args, args est toujours un tuple
if len(args) == 4:
self.coefs = args
# ou bien d'une séquence de 4 coefficients
elif len(args) == 1:
self.coefs = tuple(*args)
def __repr__(self):
"l'affichage"
return "[" + ", ".join([str(c) for c in self.coefs]) + "]"
def __add__(self, other):
"""
l'addition de deux matrices retourne un nouvel objet
la possibilité de créer une matrice à partir
d'une liste rend ce code beaucoup plus facile à écrire
"""
return Matrix([a + b for a, b in zip(self.coefs, other.coefs)])
def __bool__(self):
"""
on considère que la matrice est non nulle
si un au moins de ses coefficients est non nul
"""
# ATTENTION le retour doit être un booléen
# ou à la rigueur 0 ou 1
for c in self.coefs:
if c:
return True
return False
Remarquez que les opérandes sont apparemment inversés dans le sens où pour evaluer 'reel * matrice'
On écrit une méthode qui prend en argument la matrice, puis le réel mais n'oubliez pas qu'on est en fait en train d'écrire une méthode sur la classe Matrix2
def multiplication_scalaire(self, alpha):
return Matrix2([alpha * coef for coef in self.coefs])
on ajoute la méthode spéciale rmul
Matrix2.__rmul__ = multiplication_scalairesyntax
class Myclass(parentclass1, parentClass2, ...):
- implicit
If the girl class does not define the method at all; - redefined
If one rewrites the method entirely; - modified
if we rewrite the method in the class girl, but using the code of the mother class.
super().method_name() can be used in place of Class_parent_name.method_name(self)
example
class Fleur:
def implicite(self):
print('Fleur.implicite')
def redefinie(self):
print('Fleur.redéfinie')
def modifiee(self):
print('Fleur.modifiée')
class Rose(Fleur):
def redefinie(self):
print('Rose.redefinie')
def modifiee(self):
Fleur.modifiee(self)
print('Rose.modifiee apres Fleur')
# with use of super()
class Rose(Fleur):
def modifiee(self):
super().modifiee()
print('Rose.modifiee apres Fleur')
COMPOSITION
class Tige:
def implicite(self):
print('Tige.implicite')
def redefinie(self):
print('Tige.redefinie')
def modifiee(self):
print('Tige.modifiee')
class Rose:
def __init__(self):
self.externe = Tige()
def implicite(self):
self.externe.implicite()
def redefinie(self):
print('Rose.redefinie')
def modifiee(self):
self.externe.modifiee()
print('Rose.modifiee apres Tige')
NAMEDTUPLE
The objects will be unmutable (in fact they are tuples)
Incidentally we can access the different fields by their name as well as by an index
example
from collections import namedtuple
TuplePoint = namedtuple('TuplePoint', ['x', 'y'])
p3 = TuplePoint(1, 2)
p3.x
p3[0]
class Point2(namedtuple('Point2', ['x', 'y'])):
# l'égalité va se baser naturellement sur x et y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
# du coup la fonction de hachage
# dépend aussi de x et de y
def __hash__(self):
return (11 * self.x + self.y) // 16
q1 is q2
q1 == q2
s = {q1, q2}
q3 in s
# unmutable
try:
q1.x = 100
except Exception as e:
print(f"OOPS {type(e)}")
DATACLASS
https://docs.python.org/3/library/dataclasses.html
Record data class
frozen=True -> unmutable
example
from dataclasses import dataclass
>>>
@dataclass(frozen=True)
class Point:
x: float
y: float
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __hash__(self):
return (11 * self.x + self.y) // 16
p1, p2, p3 = Point(1, 1), Point(1, 1), Point(1, 1)
s = {p1, p2}
len(s)
p3 in s
try:
p1.x = 10
except Exception as e:
print(f"OOPS {type(e)}")
MULTIPLE HERITAGE
class Myclass(First_parent_class, Second_parent_class)
Order of attribute resolution is order of declaration of parent class
class C:
c = C()
Return the class name of object
c.__class__
C.__class__
Return direct parent (super) classes of object (not instance)
c.__bases__
Return order to interprete attribute resolution
C.__mro__
C.mro()
example
# STRANGE ORDER
class A1:
pass
class B1:
pass
class C1:
pass
class A2(A1, C1):
pass
class B2(B1):
pass
class C3(A2, B2, C1):
pass
C3.mro()
SCOPE
For class attributes, the resolution order follow the tree of heritage
example
a = 1
class C():
a = 2
class B():
def f(self):
print(a)
print(C.a)
c = C.B()
c.f()
SCOPE
For class attributes, the resolution order follow the tree of heritage
example
class A():
def __init__(self):
print('A')
class B(A):
def __init__(self):
#super(B, self).__init__()
print('B')
class C(B):
def __init__(self):
super().__init__()
print('C')
class D(C):
def __init__(self):
super(B, self).__init__()
print('D')
a = A()
print('')
b = B()
print('')
c = C()
print('')
d = D()
print('')GLOBAL
https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers
https://docs.python.org/3/tutorial/classes.html#tut-private
- A Class & class instance is mutable
- Inheritance tree: instance -> class -> parent class....
- Attributes are calculate dynamicaly in time
- Instance & class are shared same attributes
- Self for instance is just a convention
class Test:
att = 0
t = Test
s = "Here is !"
class Myclass:
def initia(self, s):
self.word = s
p = Myclass()
p.initia(s)
Myclass.initia(p,s)
VARS
vars(Myclass) <=> Myclass.__dict__ # return space name
DYNAMIC OVERLOAD
class Test:
att = 0
def addatt(self, val):
self.att = self.att + val
Test.addatt = addatt
PROPERTY
https://docs.python.org/3.6/library/functions.html#property
To use an encapsulation with attributes, use property to define the setters or getters, the calling attributes launch automatically the setters or getters
ATTRIBUTES CLASS VS INSTANCE
- Class attribute defined in class are shared with all instances
- Attributes reference are shared & changed according to whether it is mutable or not
class Point:
a = 0
b = 0
d = [a, b]
def __init__(self, x=0, y=0, len=0):
self.x = x
self.y = y
self.p = [x, y]
def __repr__(self):
return f"Pt[{self.x}, {self.y}]"
# class attribute
t = Point()
print(f"t.d {t.d}", f"t.p {t.p}", f"Point.d {Point.d}", sep="\n")
print(f"Point.p {Point.p}")
# class -> instance
Point.a = 1
t2 = Point()
print(f"Point.a {Point.a}", f"t.a {t.a}", f"t2.a {t2.a}", sep="\n")
# attribute not mutable: instance !-> class
# loose reference
t2.a = 2
print(f"Point.a {Point.a}", f"t.a {t.a}", f"t2.a {t2.a}", sep="\n")
Point.a = 3
print(f"Point.a {Point.a}", f"t.a {t.a}", f"t2.a {t2.a}", sep="\n")
# attribute mutable: instance -> class
t2.d.append(3)
print(f"Point.d {Point.d}", f"t.d {t.d}", f"t2.d {t2.d}", sep="\n")
Point.d.append(4)
print(f"Point.d {Point.d}", f"t.d {t.d}", f"t2.d {t2.d}", sep="\n")
## instance attribute
t = Point()
print(f"t.p {t.p}", f"t2.p {t2.p}", sep="\n")
t.p.append(1)
print(f"t.p {t.p}", f"t2.p {t2.p}", sep="\n")
INSTANCE: ID, NOT VALUES
2 instances are compared by the id not values
p1 = Point1(2, 3)
p2 = Point1(2, 3)
p3 = Point1(2, 3)
Equality test instance id, not class values
p1 == p2
In test instance id, not class values
s = {p1, p2}
p1 in s
p3 in s
See examples in class-special-methods for hash eq__
GETATTR, SETATTR & HASATTR
import math
math.pi
hasattr(math, 'pi')
getattr(math, 'pi')
getattr(math, 'pi2', 'not found')
setattr(math, 'pi', math.pi*2)
math.pi
ENUM
https://docs.python.org/3/library/enum.html
enumeration
from enum import Enum
class Flavour(Enum):
CHOCOLATE = 1
VANILLA = 2
PEAR = 3
chocolate = Flavour['CHOCOLATE']
chocolate
chocolate.name
INTENUM
https://docs.python.org/3/library/enum.html
IntEnum is Enum with comparison
from enum import IntEnum
class HttpError(IntEnum):
OK = 200
REDIRECT = 301
REDIRECT_TMP = 302
NOT_FOUND = 404
INTERNAL_ERROR = 500
def is_redirect(self):
return 300
example
class Temperature:
K = 273.16
RF = 5 / 9
KF = (K / RF) - 32
def __init__(self, kelvin=None, celsius=None, fahrenheit=None):
if kelvin is not None:
self.kelvin = kelvin
elif celsius is not None:
self.celsius = celsius
elif fahrenheit is not None:
self.fahrenheit = fahrenheit
else:
self.kelvin = 0
raise ValueError("need to specify at least one unit")
def __repr__(self):
return f""
def __str__(self):
return f"{self.kelvin:g}K"
def _get_kelvin(self):
return self._kelvin
def _set_kelvin(self, kelvin):
if kelvin < 0:
raise ValueError(f"Kelvin {kelvin} must be positive")
self._kelvin = kelvin
kelvin = property(_get_kelvin, _set_kelvin)
# les deux autres properties font la conversion, puis
# sous-traitent à la property kelvin pour le contrôle de borne
def _set_celsius(self, celsius):
# using .kelvin instead of ._kelvin to enforce
self.kelvin = celsius + self.K
def _get_celsius(self):
return self._kelvin - self.K
celsius = property(_get_celsius, _set_celsius)
def _set_fahrenheit(self, fahrenheit):
# using .kelvin instead of ._kelvin to enforce
self.kelvin = (fahrenheit + self.KF) * self.RF
def _get_fahrenheit(self):
return self._kelvin / self.RF - self.KF
fahrenheit = property(_get_fahrenheit, _set_fahrenheit)
t = Temperature(200)
t
t.kelvin
t.kelvin = -30
t
complete example
class Temperature:
## les constantes de conversion
# kelvin / celsius
K = 273.16
# fahrenheit / celsius
RF = 5 / 9
KF = (K / RF) - 32
def __init__(self, kelvin=None, celsius=None, fahrenheit=None):
"""
Création à partir de n'importe quelle unité
Il faut préciser exactement une des trois unités
"""
# on passe par les properties pour initialiser
if kelvin is not None:
self.kelvin = kelvin
elif celsius is not None:
self.celsius = celsius
elif fahrenheit is not None:
self.fahrenheit = fahrenheit
else:
self.kelvin = 0
raise ValueError("need to specify at least one unit")
# pour le confort
def __repr__(self):
return f""
def __str__(self):
return f"{self.kelvin:g}K"
# l'attribut 'kelvin' n'a pas de conversion à faire,
# mais il vérifie que la valeur est positive
def _get_kelvin(self):
return self._kelvin
def _set_kelvin(self, kelvin):
if kelvin DOMAINS
domains_17112018_fr="17112018.fr,ada.17112018.fr,admin.17112018.fr,blog.17112018.fr,carte.17112018.fr,chat.17112018.fr,chiffres.17112018.fr,cloud.17112018.fr,cms.17112018.fr,code.17112018.fr,compta.17112018.fr,datadoghq.17112018.fr,democratie.17112018.fr,dev.17112018.fr,diaspora.17112018.fr,discord.17112018.fr,discourse.17112018.fr,down.17112018.fr,elastik.17112018.fr,fil.17112018.fr,filerun.17112018.fr,files.17112018.fr,forum.17112018.fr,gestion.17112018.fr,git.17112018.fr,gitea.17112018.fr,gitlab.17112018.fr,goaccess.17112018.fr,grav.17112018.fr,graylog.17112018.fr,info.17112018.fr,kibana.17112018.fr,lcr.17112018.fr,liens.17112018.fr,links.17112018.fr,log.17112018.fr,manage.17112018.fr,matomo.17112018.fr,metrics.17112018.fr,monitor.17112018.fr,nextcloud.17112018.fr,pfa.17112018.fr,piwik.17112018.fr,plumxml.17112018.fr,pma.17112018.fr,roundcube.17112018.fr,shaarli.17112018.fr,snippet.17112018.fr,social.17112018.fr,st.17112018.fr,statistiques.17112018.fr,stats.17112018.fr,test.17112018.fr,tiddly.17112018.fr,tuleap.17112018.fr,vma.17112018.fr,vmail.17112018.fr,webmail.17112018.fr,wiki.17112018.fr,www.17112018.fr,zabbix.17112018.fr"
domains_17112018_ovh="17112018.ovh,ada.17112018.ovh,admin.17112018.ovh,blog.17112018.ovh,carte.17112018.ovh,chat.17112018.ovh,chiffres.17112018.ovh,cloud.17112018.ovh,cms.17112018.ovh,code.17112018.ovh,compta.17112018.ovh,datadoghq.17112018.ovh,democratie.17112018.ovh,dev.17112018.ovh,diaspora.17112018.ovh,discord.17112018.ovh,discourse.17112018.ovh,down.17112018.ovh,elastik.17112018.ovh,fil.17112018.ovh,filerun.17112018.ovh,files.17112018.ovh,forum.17112018.ovh,gestion.17112018.ovh,git.17112018.ovh,gitea.17112018.ovh,gitlab.17112018.ovh,goaccess.17112018.ovh,grav.17112018.ovh,graylog.17112018.ovh,info.17112018.ovh,kibana.17112018.ovh,lcr.17112018.ovh,liens.17112018.ovh,links.17112018.ovh,log.17112018.ovh,manage.17112018.ovh,matomo.17112018.ovh,metrics.17112018.ovh,monitor.17112018.ovh,nextcloud.17112018.ovh,pfa.17112018.ovh,piwik.17112018.ovh,plumxml.17112018.ovh,pma.17112018.ovh,roundcube.17112018.ovh,shaarli.17112018.ovh,snippet.17112018.ovh,social.17112018.ovh,st.17112018.ovh,statistiques.17112018.ovh,stats.17112018.ovh,test.17112018.ovh,tiddly.17112018.ovh,tuleap.17112018.ovh,vma.17112018.ovh,vmail.17112018.ovh,webmail.17112018.ovh,wiki.17112018.ovh,www.17112018.ovh,zabbix.17112018.ovh"
domains_ambau_ovh="ambau.ovh,ada.ambau.ovh,admin.ambau.ovh,blog.ambau.ovh,carte.ambau.ovh,chat.ambau.ovh,chiffres.ambau.ovh,cloud.ambau.ovh,cms.ambau.ovh,code.ambau.ovh,compta.ambau.ovh,datadoghq.ambau.ovh,democratie.ambau.ovh,dev.ambau.ovh,diaspora.ambau.ovh,discord.ambau.ovh,discourse.ambau.ovh,down.ambau.ovh,elastik.ambau.ovh,fil.ambau.ovh,filerun.ambau.ovh,files.ambau.ovh,forum.ambau.ovh,gestion.ambau.ovh,git.ambau.ovh,gitea.ambau.ovh,gitlab.ambau.ovh,goaccess.ambau.ovh,grav.ambau.ovh,graylog.ambau.ovh,info.ambau.ovh,kibana.ambau.ovh,lcr.ambau.ovh,liens.ambau.ovh,links.ambau.ovh,log.ambau.ovh,manage.ambau.ovh,matomo.ambau.ovh,metrics.ambau.ovh,monitor.ambau.ovh,nextcloud.ambau.ovh,pfa.ambau.ovh,piwik.ambau.ovh,plumxml.ambau.ovh,pma.ambau.ovh,roundcube.ambau.ovh,shaarli.ambau.ovh,snippet.ambau.ovh,social.ambau.ovh,st.ambau.ovh,statistiques.ambau.ovh,stats.ambau.ovh,test.ambau.ovh,tiddly.ambau.ovh,tuleap.ambau.ovh,vma.ambau.ovh,vmail.ambau.ovh,webmail.ambau.ovh,wiki.ambau.ovh,www.ambau.ovh,zabbix.ambau.ovh"
domains_ggj_fr="ggj.fr,ada.ggj.fr,admin.ggj.fr,blog.ggj.fr,carte.ggj.fr,chat.ggj.fr,chiffres.ggj.fr,cloud.ggj.fr,cms.ggj.fr,code.ggj.fr,compta.ggj.fr,datadoghq.ggj.fr,democratie.ggj.fr,dev.ggj.fr,diaspora.ggj.fr,discord.ggj.fr,discourse.ggj.fr,down.ggj.fr,elastik.ggj.fr,fil.ggj.fr,filerun.ggj.fr,files.ggj.fr,forum.ggj.fr,gestion.ggj.fr,git.ggj.fr,gitea.ggj.fr,gitlab.ggj.fr,goaccess.ggj.fr,grav.ggj.fr,graylog.ggj.fr,info.ggj.fr,kibana.ggj.fr,lcr.ggj.fr,liens.ggj.fr,links.ggj.fr,log.ggj.fr,manage.ggj.fr,matomo.ggj.fr,metrics.ggj.fr,monitor.ggj.fr,nextcloud.ggj.fr,pfa.ggj.fr,piwik.ggj.fr,plumxml.ggj.fr,pma.ggj.fr,roundcube.ggj.fr,shaarli.ggj.fr,snippet.ggj.fr,social.ggj.fr,st.ggj.fr,statistiques.ggj.fr,stats.ggj.fr,test.ggj.fr,tiddly.ggj.fr,tuleap.ggj.fr,vma.ggj.fr,vmail.ggj.fr,webmail.ggj.fr,wiki.ggj.fr,www.ggj.fr,zabbix.ggj.fr"
domains_ggj_ovh="ggj.ovh,ada.ggj.ovh,admin.ggj.ovh,blog.ggj.ovh,carte.ggj.ovh,chat.ggj.ovh,chiffres.ggj.ovh,cloud.ggj.ovh,cms.ggj.ovh,code.ggj.ovh,compta.ggj.ovh,datadoghq.ggj.ovh,democratie.ggj.ovh,dev.ggj.ovh,diaspora.ggj.ovh,discord.ggj.ovh,discourse.ggj.ovh,down.ggj.ovh,elastik.ggj.ovh,fil.ggj.ovh,filerun.ggj.ovh,files.ggj.ovh,forum.ggj.ovh,gestion.ggj.ovh,git.ggj.ovh,gitea.ggj.ovh,gitlab.ggj.ovh,goaccess.ggj.ovh,grav.ggj.ovh,graylog.ggj.ovh,info.ggj.ovh,kibana.ggj.ovh,lcr.ggj.ovh,liens.ggj.ovh,links.ggj.ovh,log.ggj.ovh,manage.ggj.ovh,matomo.ggj.ovh,metrics.ggj.ovh,monitor.ggj.ovh,nextcloud.ggj.ovh,pfa.ggj.ovh,piwik.ggj.ovh,plumxml.ggj.ovh,pma.ggj.ovh,roundcube.ggj.ovh,shaarli.ggj.ovh,snippet.ggj.ovh,social.ggj.ovh,st.ggj.ovh,statistiques.ggj.ovh,stats.ggj.ovh,test.ggj.ovh,tiddly.ggj.ovh,tuleap.ggj.ovh,vma.ggj.ovh,vmail.ggj.ovh,webmail.ggj.ovh,wiki.ggj.ovh,www.ggj.ovh,zabbix.ggj.ovh"
domains_otokoz_ovh="otokoz.ovh,ada.otokoz.ovh,admin.otokoz.ovh,blog.otokoz.ovh,carte.otokoz.ovh,chat.otokoz.ovh,chiffres.otokoz.ovh,cloud.otokoz.ovh,cms.otokoz.ovh,code.otokoz.ovh,compta.otokoz.ovh,datadoghq.otokoz.ovh,democratie.otokoz.ovh,dev.otokoz.ovh,diaspora.otokoz.ovh,discord.otokoz.ovh,discourse.otokoz.ovh,down.otokoz.ovh,elastik.otokoz.ovh,fil.otokoz.ovh,filerun.otokoz.ovh,files.otokoz.ovh,forum.otokoz.ovh,gestion.otokoz.ovh,git.otokoz.ovh,gitea.otokoz.ovh,gitlab.otokoz.ovh,goaccess.otokoz.ovh,grav.otokoz.ovh,graylog.otokoz.ovh,info.otokoz.ovh,kibana.otokoz.ovh,lcr.otokoz.ovh,liens.otokoz.ovh,links.otokoz.ovh,log.otokoz.ovh,manage.otokoz.ovh,matomo.otokoz.ovh,metrics.otokoz.ovh,monitor.otokoz.ovh,nextcloud.otokoz.ovh,pfa.otokoz.ovh,piwik.otokoz.ovh,plumxml.otokoz.ovh,pma.otokoz.ovh,roundcube.otokoz.ovh,shaarli.otokoz.ovh,snippet.otokoz.ovh,social.otokoz.ovh,st.otokoz.ovh,statistiques.otokoz.ovh,stats.otokoz.ovh,test.otokoz.ovh,tiddly.otokoz.ovh,tuleap.otokoz.ovh,vma.otokoz.ovh,vmail.otokoz.ovh,webmail.otokoz.ovh,wiki.otokoz.ovh,www.otokoz.ovh,zabbix.otokoz.ovh"
domains_coworking-lannion_org="cloud.coworking-lannion.org"
#domains="coworking-lannion.org"
domains="17112018.fr 17112018.ovh ambau.ovh ggj.fr ggj.ovh otokoz.ovh";
CLEAN
Clean one domain
domain="17112018.fr"
files="/etc/letsencrypt/archive/${domain} /etc/letsencrypt/csr/${domain} /etc/letsencrypt/keys/${domain} /etc/letsencrypt/live/${domain} /etc/letsencrypt/renewal/${domain}.conf"
for file in $files; do [ -e "$file" ] && rm -fR "$file"; done
Clean all domains
files="/etc/letsencrypt/archive/* /etc/letsencrypt/csr/* /etc/letsencrypt/keys/* /etc/letsencrypt/live/* /etc/letsencrypt/renewal/*"
for file in $files; do [ -e "$file" ] && rm -fR "$file"; done
CERBOT
stop services OpenVZ
ctids_web="$(vzlist -h "*-php*" -Ho ctid|xargs) $(vzlist -h "*-apache*" -Ho ctid|xargs)"
netstat -lnt | grep ':80'
# stop port 80
service haproxy stop
vz-launch -y 'systemctl stop apache2.service' $ctids_web
#vz-launch -y 'duniter stop' 189
netstat -lnt | grep ':80'
create new domain
for domain in ${domains}; do
subdomains=domains_${domain//./_}
echo "-- ${domain} --"
certbot certonly --standalone -d ${!subdomains}
cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /etc/server/ssl/private/letsencrypt-${domain}.pem
done
renew domains
file="/etc/server/ssl/private/letsencrypt.pem.lst"
domains=$(ls /etc/letsencrypt/renewal/|sed 's|\.conf||g')
certbot renew
[ -f "$file" ] && mv "$file" "$file.keep$(date +%s)"
for domain in ${domains}; do
file_pem="/etc/server/ssl/private/letsencrypt-${domain}.pem"
cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > "$file_pem"
echo "${file_pem}" >> "${file}"
done
start services
# start port 80
vz-launch -y 'systemctl start apache2.service' $ctids_web
#vz-launch -y 'duniter webstart --webmhost 10.0.0.189' 189
service haproxy start
netstat -lnt | grep ':80'https://docs.python.org/3/reference/simple_stmts.html#the-import-statement
module are:
- are mutable !!
- define a namespace
- is a .py file
- the file are searched first in sys.path (after in local path)
import are only made on time during a program
IMPORT
import <module>
- import as
- absolute import
- the file are searched first in sys.path (after in local path)
# module_name is a string, it can be a variable
from importlib import module_name
module_othername = module_name('ma'+'th')
# alias
import module_name as module_othername
RELATIVE IMPORT
- local path first (before look in sys.path)
- import global module with namespace reference
- abstract the calling !!
import a module
from . import module_name as module_othername
import just an object from module
# import selected object in module without entire module
from .module_name import object_name as object_othername
- local parent path first
- import global module with namespace reference
import a module
from .. import module_name as module_othername
import just an object from module
# import selected object in module without entire module
from ..module_name import object_name as object_othername
ENTRY POINT
for the entry point of program, _name__ return main and not the filename !
So you can find in the main file
if __name__ == "__main__":
....
Let program make specific codes when apply file is calling directly from interpreter & not from an import when calling a file directly from the interpreter, the entry point sets name to 'main', so it s almost impossible to use relative imports in this situation
To use test envirronement:
python3 -m unittest package_name.module_name
http://sametmax.com/un-gros-guide-bien-gras-sur-les-tests-unitaires-en-python-partie-1/
IMPORTLIB
Use a variable for module name
from importlib import import_module
modulename = "ma" + "th"
loaded = import_module(modulename)
math is loaded
Import math <=> math = import_module('math')
from pathlib import Path
<=>
tmp = import_module('pathlib')
Path = tmp.Path
del tmp
IMPORT / FROM ... IMPORT
import
- import all objects from module
- complete isolation
- access to all objects in module with notation MODULE.OBJECT
From ... import
- import only selected object
- no isolation & iomportation of object in current namespace
- no access to other object in module
RELOAD
Force to reload manualy a module
from importlib import reload
reload(MODULE)
AUTORELOAD
Load magic 'autoreload'
%load_ext autoreload
Enable autoreload
%autoreload 2
ATTRIBUTES
https://docs.python.org/3/tutorial/modules.html#importing-from-a-package
__name__
Module name
__file__
The complete path of package definition file: init.py
__all__
redefine the behavior of import *
PATH
https://docs.python.org/3/tutorial/modules.html#the-module-search-path
Environnement variable
import os
os.getcwd() # return current working directory
os.listdir(path) # return the list of path & files in path (if empty return current path)
os.environ # dict of full os informations
os.environ['PATH'] os.environ['PYTHONPATH']
sorted([i for i in os.environ])
Include paths
import sys
sys.path
Add path when launch python script
PYTHONPATH=/path python script.py
SYS.MODULES
https://docs.python.org/3/library/sys.html#sys.modules
example
import sys
# test on loaded modules
'csv' in sys.modules
import csv
'csv' in sys.modules
csv is sys.modules['csv']
# unload module
del sys.modules['multiple_import']
# A tuple of strings giving the names of all modules that are compiled into this Python interpreter
sys.builtin_module_names
# modules.keys() only lists the imported modules
sys.modules.keys()
'csv' in sys.modules.keys()
CWD
from pathlib import Path
Path.cwd()
IMPORT FILE FROM ANYWHERE
from pathlib import Path
directory_installation = Path(__file__).parent
import sys
sys.path.append(directory_installation)
MODTOOLS
Show_module
from modtools import show_module
import math
show_module(math)
SETUPTOOLS / PYPI
https://pypi.org/project/setuptools/
https://pypi.org/
Deploy setuptools
pip3 install setuptools
PACKAGE
https://docs.python.org/3/tutorial/modules.html#packages
A package are:
- a folder with the same name
- a namespace
- this folder have to contains a mandatory file init.py
import package
import package_name
import package_name as package_othername
Use namespace
package_name.object
not recommended
package_name.module_name.object
Subpackage
Package physically inside another
import package_name.subpackage_name
import package_name.subpackage_name.module_name.element_name
EXCERCISE
import this
def decode_zen(this):
return ''.join(this.d[i] if i in this.d else i for i in this.s)
# better
def decode_zen(this):
return ''.join(this.d.get(i) for i in this.s)LAMBDA
Anonym function, to use as an expression
from functools import reduce
from operator import add
def factoriel(x):
return reduce(lambda x, y: x*y, range(1, x+1), 1)
def fibonacci(x):
return reduce(operator.add, range(1, x+1), 0)
def fibonacci(x):
return reduce(add, range(1, x+1), 0)
With comprehension
[(lambda x: x**2)(x) for x in range(10) if x % 2 == 0]
MAP
Return an iterator that applies function to every item of iterable, yielding the results
list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, range(10))))
FILTER
Construct an iterator from those elements of iterable for which function returns true
list(filter(lambda x: x % 2 == 0, range(10)))
EXERCISE
1-1
More efficient, don't duplicate listes
def multi_tri(listes):
for liste in listes:
liste.sort()
return listes
def multi_tri(listes):
return list(map(sorted, listes))
1-2
More efficient, don't duplicate listes
def multi_tri_reverse(listes, reverses):
for x,y in zip(listes, reverses):
x.sort(reverse=y)
return listes
def multi_tri_reverse(listes, reverses):
return [sorted(x, reverse=y) for x,y in zip(listes, reverses)]
def multi_tri_reverse(listes, reverses):
return list(map(lambda x, y: sorted(x, reverse=y), listes, reverses))
2-1
def doubler_premier(f, arg, *args):
return f(2*arg,*args)
def doubler_premier(f, arg1, *args):
from functools import reduce
from operator import add, mul
return reduce(
f,
args + (arg1*2,),
1 if f is mul else 0
)
2-2
def doubler_premier_kwds(f, arg, *args, **kwargs):
return f(2*arg, *args, **kwargs)
def doubler_premier_kwds(f, arg1, *args, y=0, z=0):
from functools import reduce
return reduce(
f,
[arg for arg in args + (arg1*2,) + (y,) + (z,) if arg],
1 if f.__name__ == 'mul3' else 0
)
3-1
def compare_all(f, g, entrees):
return [f(entree) == g(entree) for entree in entrees]
3-2
def compare_args(f, g, entrees):
return [f(*entree) == g(*entree) for entree in entrees]https://docs.python.org/fr/3.7/howto/functional.html
https://docs.python.org/3/library/itertools.html
ITERATOR
- iterator allow to calculate data of function only on read it
- builtin function all methods on object
s = {0, 1, 'string1', 3, 'string2',5 , 6}
[x for x in s if type(x) is int]
i = iter(s)
type(i)
dir(i)
next(i)
i.__next__()
ITERABLE
- Object contains a method 'iter', which gives iterator methods
- An object wich on you can use iterator methods
ITERTOOLS
https://docs.python.org/3/library/itertools.html
This module implements a number of iterator building blocks
import itertools
Infinite iterators
count(start, [step])
start, start+step, start+2*step, …
count(10) --> 10 11 12 13 14 ...
cycle(p)
p0, p1, … plast, p0, p1, …
cycle('ABCD') --> A B C D A B C D ...
repeat(elem [,n])
elem, … endlessly or up to n times
repeat(10, 3) --> 10 10 10
Iterators terminating on the shortest input sequence
accumulate(p[,func])
p0, p0+p1, p0+p1+p2, …
accumulate([1,2,3,4,5]) --> 1 3 6 10 15
chain(p, q, …)
p0, p1, … plast, q0, q1, …
chain('ABC', 'DEF') --> A B C D E F
chain.from_iterable(iterable)
p0, p1, … plast, q0, q1, …
chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
compress(data, selectors)
(d[0] if s[0]), (d[1] if s[1]), …
compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
dropwhile(pred, seq)
seq[n], seq[n+1], starting when pred fails
dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
filterfalse(pred, seq)
elements of seq where pred(elem) is false
filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
groupby(iterable[, keyfunc])
sub-iterators grouped by value of keyfunc(v)
islice(seq, [start,] stop [, step])
elements from seq[start:stop:step]
islice('ABCDEFG', 2, None) --> C D E F G
starmap(func, seq)
func(seq[0]), func(seq[1]), …
starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
takewhile(pred, seq)
seq[0], seq[1], until pred fails
takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
tee(it, n)
it1, it2, … itn splits one iterator into n
zip_longest(p, q, …)
(p[0], q[0]), (p[1], q[1]), …
zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
Combinatoric iterators
product(p, q, … [repeat=1])
cartesian product, equivalent to a nested for-loop
product('ABCD', repeat=2) -> AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations(p[, r])
r-length tuples, all possible orderings, no repeated elements
permutations('ABCD', 2) -> AB AC AD BA BC BD CA CB CD DA DB DC
combinations(p, r)
r-length tuples, in sorted order, no repeated elements
combinations('ABCD', 2) -> AB AC AD BC BD CD
combinations_with_replacement(p, r)
r-length tuples, in sorted order, with repeated elements
combinations_with_replacement('ABCD', 2) -> AA AB AC AD BB BC BD CC CD DD
EXPRESSION
https://docs.python.org/fr/3.7/howto/functional.html
create an generator of iterator in place of comprehension
(treatment for ... if ...)
carre = (x**2 for x in range(1000))
palin = (x for x in carre if str(x) == str(x)[::-1])
carre
palin
# only now, calculate
list(palin)
GENERATOR FUNCTION
http://python-history.blogspot.fr/2010/06/from-list-comprehensions-to-generator.html
def carre(a, b):
for i in range(a, b):
yield i**2
def palin(it):
for i in it:
if (isinstance(i, (str, int)) and
str(i) == str(i)[::-1]):
yield i
list(palin(x**2 for x in range(1000)))
EXCERCISE
def produit_scalaire(X, Y):
return sum(x*y for x, y in zip(X, Y))
g = produit_scalaire((1, 2), (3, 4))https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
ages = [10, 120, 110, 25, 30, 40, 50]
l1 = [a+1 if a < 100 else a for a in ages]
l2 = [a+1 for a in ages if a < 100]
ages = {'ana':20, 'EVE':30, 'bob':40}
prenoms = [p.lower() for p, a in ages.items()]
SET
prenoms = ['ana', 'eve', 'ALICE', 'Anne', 'bob']
s = {p.lower() for p in prenoms if p.lower().startswith('a')}
DICT
ages = {'ana':20, 'EVE':30, 'bob':40}
d = {p.lower():a + 1 for p, a in ages.items()}
prenoms = ['ana', 'eve', 'ALICE', 'Anne', 'bob']
ages = [10, 20, 30, 40, 50]
d = {p.lower():a + 1 for p, a in zip(prenoms, ages)}
# Some troubles with mixed list & set
prenoms = ['ana', 'eve', 'ALICE', 'Anne', 'bob']
ages = [10, 20, 30, 40, 50]
list(zip(prenoms, ages))
NESTING
flat nesting : 1 level => [n(p(..., ...) ,...)]
[... for ... for ...]
[... > ... > ...]
for n ...
for p ...
...
[str(n) + str(p) for n in [2, 4] for p in [10, 20, 30]]
classic "sub"
[... for n in [... p ...] if ...]
for p ...
for n ...
embedded "sub" nesting 2 levels => [p[n... ], ...]
[[... for ...] for ...]
[[... < ...] < ...]
for p ...
for n ...
[[str(n) + str(p) for n in [2, 4]] for p in [10, 20, 30]]
FLAT
[item for sublist in list for item in sublist]
for sublist in list
for item in sublist
item
REPEAT
# compare:
[x + y for x in (1,2,3) for y in (10,20) for z in (0,2)]
[x + y for x in (1,2,3) for z in (0,2) for y in (10,20)]
[x + y for x in (1,2,3) for z in (0,2) for y in (10,20)]
t = (y for y in (x**2 for x in range(1000)) if str(y) == str(y)[::-1])
with restriction
[str(n) + str(p) for n in [2, 4] for p in [10, 20, 30] if n*p >= 40]
BREAK
def end_of_loop():
raise StopIteration
even = list(end_of_loop() if n == 412 else n for n in numbers if 0 == n % 2)
even = list(next(iter(())) if n == 412 else n for n in numbers if 0 == n % 2)
EXERCISE
1
# flat vs nested
[[str(n) + str(p) for n in (2, 4)] for p in (10, 30, 50)]
[str(n) + str(p) for p in (10, 30, 50) for n in (2, 4)]
# flat vs nested
[[str(n) + str(p) for n in (2, 4)] for p in (10, 30, 50)]
[str(n) + str(p) for p in (10, 30, 50) for n in (2, 4)]
def aplatir(conteneurs):
return [c2 for c1 in conteneurs for c2 in c1]
def aplatir(conteneurs):
r=[]
for c1 in conteneurs:
for c2 in c1:
r.append(c2)
return r
aplatir(((1, [2, 3]), [], 'a', ['b', 'c']))
2
def alternat(c1, c2):
return [c_2 for c_1 in zip(c1, c2) for c_2 in c_1]
alternat( (1, 2, 3), ('a', 'b', 'c'))
3
def intersect(A, B):
return {c2 for c1 in ((v1, v2) for i1, v1 in A for i2, v2 in B if i1 == i2) for c2 in c1}
intersect({ (1, 'unA'), (2, 'deux'), (3, 'troisA')}, { (1, 'unB'), (2, 'deux'), (4, 'quatreB')})
# more elegante
def intersect(A, B):
return {v for dictionnaire in [dict(A),dict(B)] for k,v in dictionnaire.items() if k in dict(A) and k in dict(B)}
def intersect(A, B):
return { i for item in (dict(A).keys() & dict(B).keys()) for i in (dict(A)[item], dict(B)[item]) }phpquery
print informations about php version & modules
-v version -s sapi_name -M
-V # list all available versions of php client
-v $version -S # list all available sapi
-v $version -S $sapi -M # list all available modules
-v $version -s $sapi -m $module # return informations about module $module
tests the availability of the module
phpquery -q -v $version -s $sapi -m $module && echo YESSCOPE
https://www.programiz.com/python-programming/namespace
Order to interprate variables is LEGB
- Local
- Enclosing
- Global
- Builtin
locals()
return a list of actual local scope variables
globals()
return a list of actual global scope variables
Global scope & function error !!
Because var is referenced like global by "print(var)" & use like local with "var = 'local'"
Solution: remove "print(var)" or remove "var = 'local'" or put it after "var = 'local'"
var = 'global'
def f():
print(var)
var = 'local'
f()
print(var)
GLOBAL
to use global variable locally
var = 'global'
def f():
global var
var = 'local'
print(var)
f()
print(var)
NONLOCAL
- To use upper local scope variable locally
- The upper scope local variable is the closest one
- A nonlocal variable have to be a binding variable in upper local scope (in function definition, not in the global scope) else an exception are called
a = 'a global'
def f():
a = 'a f'
def g():
nonlocal a
a = 'a g'
print(a)
g()
print(a)
f()
print(a)
BUILTINS
import builtins
modules with all builtin functions
dir(builtins)
dir(builtins.str)
To ensure to call a really builtin function
import builtins
with builtins.open(...) as f:
GLOBAL VARIABLES
vars()
globals()
To access object to other namespace
print(dir(spam))
print(dir(spam.__builtins__))GENERAL
https://docs.python.org/3/library/stdtypes.html#truth-value-testing
https://docs.python.org/3/reference/expressions.html#conditional-expressions
http://legacy.python.org/dev/peps/pep-0308/
https://docs.python.org/3/tutorial/datastructures.html#more-on-conditions
Order to return test:
- call bool
- call len
bool(object)
- object.bool()
- object.len()
type built-in
false : False None [] {} () ''
true : others
INSTRUCTION / EXPRESSION
For if you can use any of expressions
Instructions Expressions
assignment function call
import operators is, in, ==, ...
instruction if conditional expression
instruction for List Comprehensions
syntax
if condition:
...
elif condition:
...
else:
...
inputs = [23, 65, 24]
def condition(n):
return (n**2) % 10 == 5
if [value for value in inputs if condition(value)]:
print("au moins une entrée convient")
FEW OPERATORS TEST IN LINE
if 0 < a < 10 < b:
instruction
TERNARY OPERATORS & SHORT TEST
(result_if_false, result_if_true)[condition]
Result_if_true if condition else result_if_false # ternary operators
is_nice = True
if is_nice:
state = "nice"
else:
state = "not nice"
<=>
# ternary operators
state = "nice" if is_nice else "not nice"
<=>
# short test
state = ("not nice", "nice")[is_nice]
print(state)
SHORT-CIRCUIT
if the first tests are sufficient the following ones are not evaluated
# stop at first test
false and true
true or false
NESTING
valeur = -1 if x < -10 else (0 if x <= 10 else 1)
BOOL
Use bool function to test the behavior of return
def show_bool(x):
print(f"condition {repr(x):>10} considérée comme {bool(x)}")
for exp in [None, "", 'a', [], [1], (), (1, 2), {}, {'a': 1}, set(), {1}]:
show_bool(exp)
OPERATORS
| Famille | |Exemples | |---------|-|---------| | Égalité | |==, !=, is, is not | | Appartenance | | in | | Comparaison | | <=, <, >, >= | | Logiques | | and, or, not |
PRIORITY ORDER
a and not b or c and d
<=>
(a and (not b)) or (c and d)
Operators can be used with others than boolean
The last non evaluated elements is always return else when the short-circuit can be used
1 and [1, 2]
1 or [1, 2]
1 and 2 and 3
1 and 2 and 3 and '' and 4
[] or "" or {}
[] or "" or {} or 4 or set()
EXCERCISE
1
def dispatch1(a, b):
def isimpair(x): return(x%2)
def ispair(x): return(not x%2)
if ispair(a) and ispair(b): return(a**2 + b**2)
elif ispair(a) and isimpair(b): return(a * (b - 1))
elif isimpair(a) and ispair(b): return((a - 1) * b)
else: return(a**2 - b**2)
2
def dispatch2(a, b, A, B):
if a in A and not (b in B): return(a * (b - 1))
elif not (a in A) and b in B: return((a - 1) * b)
else: return(a**2 + b**2)
3
def libelle(ligne):
for i in [" ", "\t"]:
ligne = ligne.replace(i, '')
ligne = ligne.split(',')
if len(ligne) != 3:
return
prenom, nom, rang = ligne
if not rang: rang = "-ème"
elif int(rang) == 1: rang = "1er"
else: rang = f"{rang}-ème"
return(f"{nom}.{prenom} ({rang})")WHILE
Execute the loop while condition is true and execute else:
while condition:
...
else:
...
continue
Step in a loop to the next loop
break
Break the loop definitively
while true
while true, continual loop with a break to exit
while true:
...
break
example
while liste:
element = liste.pop()
print(element)
FOR
for item in element
...
else
...
EXCERCISE
1
def pgcd(a, b):
if a == 0:
return(b)
elif b == 0:
return(a)
while True:
if b > a:
b = b % a
if b == 0:
return(a)
else:
a = a % b
if a == 0:
return(b)
2
def taxes(income):
taxe = 0
if income > 150_000:
taxe += (income - 150_000) * (45/100)
income = 150_000
if income > 45_000:
taxe += (income - 45_000) * (40/100)
income = 45_000
if income > 11_500:
taxe += (income - 11_500) * (20/100)
income = 11_500
return (int(taxe))
2 bis
def taxes(income):
taxe = 0
limit_rates = (
(150_000, 45),
(45_000, 40),
(11_500, 20)
)
for limit, rate in limit_rates:
if income > limit:
taxe += (income - limit) * (rate/100)
income = limit
return (int(taxe))A function performs a variable passing by reference !!
class Test:
"""
class Test to make a test
with a long text to see differtence
"""
def __init__(self):
"""init property listin with an empty list"""
self.listin = []
def add(self, value):
"""add value to listin property"""
self.listin.append(value)
def print(self):
"print listin property to stdout"
print(self.listin)
a = [0]
p.add(a)
p.print()
a[0] = 100
p.print()
DOC
https://legacy.python.org/dev/peps/pep-0257/
help(Class)
Complet help for Test class
Class?
Short help, for ipython
Class.doc
Progamming help
Class.add?
Method help, ipython
TOOLS
isinstance(type)
Return boolean & support class inheritance
class Animal:
def __init__(self, name):
self.name = name
class Mammifere(Animal):
def __init__(self, name):
Animal.__init__(self, name)
isinstance(baleine, Mammifere)
isinstance(baleine, Animal)
types # constants types
from types import FunctionType
isinstance(factoriel, FunctionType)
isinstance(len, BuiltinFunctionType)
# list all types
import types
dir(types)
TYPE HINTS
https://docs.python.org/3/library/typing.html
Since python 3.5, allow optionnal type hinting
var : int = 0
def fact(n : int) -> int:
List
def foo(x: List[int]) -> List[str]:
Iterable
def lower_split(sep: str, inputs : Iterable[str]) -> str:
Multi typing
from typing import Dict, Tuple, List
ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: List[Server]) -> None:
...
https://docs.python.org/3/library/typing.html#user-defined-generic-types
Extension
from typing import NewType
UserId = NewType('UserId', int)
user1_id : UserId = 0
example
from typing import TypeVar, Generic
from logging import Logger
T = TypeVar('T')
class LoggedVar(Generic[T]):
def __init__(self, value: T, name: str, logger: Logger) -> None:
self.name = name
self.logger = logger
self.value = value
def set(self, new: T) -> None:
self.log('Set ' + repr(self.value))
self.value = new
def get(self) -> T:
self.log('Get ' + repr(self.value))
return self.value
def log(self, message: str) -> None:
self.logger.info('%s: %s', self.name, message)GENERAL
Order of parameters
ordered
named
*tuple
**dict
ORDERED
Ordered (mandatory) arguments have to be in first in list of arguments
def f(arg1, arg2, ...):
...
default/optionnal parameters
Default parameters have to be placed in last in list of parameters
def f(arg1, arg2, arg3=opt, arg4=opt, ...):
...
NAMED
You can give parameters to the function with naming
def f(arg1, arg2, arg3):
...
f(arg2=data, arg3=data, arg1=data)
TUPLE
def f(*t):
...
def f(arg1, arg2, *t):
print(f"arg1: {arg1}\narg2: {arg2}\nothers: {t}")
f('nom', 'prenom', list(range(5)), 'et moi', ['etc'])
With optionnal parameters
def f(nom, prenom='henriette', *d):
print(f"nom: {nom}\nprenom: {prenom}\nd: {d}")
f('louis', 'mom', 20, 'pierre', ['tyt'])
DICTIONNARY
def f(**d):
print(f"d: {d}")
f(tata='mom', tonton='pierre', maman='tyt')
With optionnal parameters
def f(nom, prenom='henriette', **d):
print(10*"=" + f"\nnom: {nom}\nprenom: {prenom}\nd: {d}")
f('louis', 'prenom', tata='mom', tonton='pierre', maman='tyt')
f('louis', tata='mom', tonton='pierre', maman='tyt')
UNPACKING
Used to send arguments to a function from a list / tuple / set
With a good lenght of arguments !!
def f(a, b):
print(10*"-" + f"\na: {a}\nb: {b}")
l = [10, 'toto']
f(*l)
l = (10, 'toto')
f(*l)
l = set([10, 'toto']);
f(*l)
DICTIONNARY SENDING
Use a dictionnary to send arguments to function
Keys names of dictionnary have to be match with arguments names
def f(a, b):
print(10*"-" + f"\na: {a}\nb: {b}")
{'a': 10, 'b': 'toto'}
f(**d)
Use for print (& wrapping)
pp = {'sep':'-', 'end':' >EOL'}
print(10, 20, **pp)
TRAP
named argument & tuple argument
https://docs.python.org/3/reference/expressions.html#calls
def foo(a, b, c, d):
print(a, b, c, d)
#good
foo(1, c=3, *(2,), **{'d':4})
# wrong
foo (1, b=3, *(2,), **{'d':4})
don t use mutable object in default argument
https://docs.python.org/3/faq/programming.html#why-are-default-values-shared-between-objects
import random
def ajouter_un_aleatoire(resultats=[]):
resultats.append(random.randint(0, 10))
return resultats
ajouter_un_aleatoire()
ajouter_un_aleatoire()
EXCERCISE
1
def distance(*arg):
from math import sqrt
result = sqrt(sum([i**2 for i in arg]))
return result if result != 0 else 0
2
def numbers(*args):
return (sum(args), min(args, default=0), max(args, default=0))https://www.python.org/dev/peps/pep-3132/
assignment
tuple1 = 1, 2
tuple2 = (1, 2)
tuple3 = 1, 2,
tuple4 = (1, 2,)
Assignment of one element
simple1 = 1,
simple2 = (1,)
Pretty print
tuple1 = (
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
)
addition
tuple3 = tuple1 + tuple2
tuple1 += (3, 4,)
cast
tuple = tuple(list)
SEQUENCE UNPACKING
En réalité, les seules contraintes fixées par Python sont que:
- Le terme à droite du signe = soit un itérable (tuple, liste, string, etc.) ;
- Le terme à gauche soit écrit comme un tuple ou une liste - notons tout de même que l'utilisation d'une liste à gauche est rare et peu pythonique ;
- Les deux termes aient la même longueur - en tout cas avec les concepts que l'on a vus jusqu'ici, mais voir aussi plus bas l'utilisation de *arg avec le extended unpacking.
Switch variables
a, b = b, a
EXTENDED UNPACKING
1
reference = [1, 2, 3, 4, 5]
a, *b, c = reference
print(f"a={a} b={b} c={c}")
a, b, *_ = reference # '_' is for tell to reader that the following values are not used
print(f"a={a} b={b} c={c}")
2
reference = [1, 2, 3]
_, milieu, _ = reference
print('milieu', milieu)
3
ignored, ignored, right = reference
print('right', right)
Deep
structure = ['abc', [(1, 2), ([3], 4)], 5]
(a, (b, ((trois,), c)), d) = structure
print('trois', trois)
(a, (b, ([trois], c)), d) = structure
print('trois', trois)
Ultra deep
Un exemple très alambiqué avec plusieurs variables *extended
tree = [1, 2, [(3, 33, 'three', 'thirty-three')], ( [4, 44, ('forty', 'forty-four')])]
*_, ((_, *x3, _),), (*_, x4) = tree
print(f"x3={x3}, x4={x4}")
# for
l = [(1, 2), (3, 4), (5, 6)]
for a, b in l:
print(f"a={a} b={b}")
for i, j, k in zip(range(3), range(100, 103), range(200, 203)):
print(f"i={i} j={j} k={k}")
enumerate()
Return an enumerate object with iterator in index and value as value
villes = ["Paris", "Nice", "Lyon"]
for i, ville in enumerate(villes):
print(i, ville)
EXERCISE
1
def comptage(in_filename, out_filename):
import re
with open(in_filename, "r", encoding='utf-8') as f_in:
with open(out_filename, "w", encoding='utf-8') as f_out:
i = 0
for line_in in f_in:
i += 1
# wc = len(re.findall('(\w|\.\.\.+)+',line_in))
wc = len(line_in.split())
cc = len(line_in)
f_out.write(f"{i}:{wc}:{cc}:{line_in}")
2
def surgery(liste):
l=len(liste)
if l in [0, 1]: pass
elif l%2 == 0: liste[1], liste[0] = liste[0], liste[1]
elif l%2 == 1: liste[-2], liste[-1] = liste[-1], liste[-2]
return(liste)https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset
- Usefull to stock only uniq elements
- Set is mutable but element in set ar to be immutable => unable to create a set of set
- Like distionnary, set are not ordered
INIT
s = set()
s = {key1, key2, ...}
s = set([key1, key2, ...])
METHODS
(key) in s
Return true in key is in s
len(s)
Print length of s
s.clear()
Clear elements of s
s.add()
Add a key in set
s.update(s2)
Merge a set into a set
s.discard(key)
Remove elements, no error if not found
s.remove(key)
Remove elements, launch exception if not found
try:
s.remove(key)
except KeyError as e:
print("text", e)
s.pop()
Remove last or indexed element but there is no order in a set !
s = [1, 2, 3, 4, 5]
while s:
s = s.pop()
print("set", s)
print("set is now empty", s)
OPERATIONS
union
s1 | s2
Return the union of sets
intersection
s1 & s2
Return intersection of sets
difference
s2 - s3
Return difference of two sets
symmetrical difference
s1 ^ s2
AΔB=(A−B)∪(B−A)=(A∪B)-(A∩B)
equality
s1 == s2
inclusion
s1 <= s2
s1 < s2
Disjoint sets
s.isdisjoint(s2)
FROZENSET
Immutable set to serve to key of dictionnary or element of set
init
fs = frozenset()
fs = frozenset([key1, key2, ...])
Available methods
copy()
isdisjoint()
symmetric_difference()
difference()
issubset()
union()
intersection()
issuperset()
EXCERCISE
1
def read_set(filename):
s=set()
with open(filename, "r", encoding='utf-8') as f:
for line in f:
#print(line)
s.update({line.strip()})
return(s)
2
def search_in_set(filename_reference, filename):
s = set()
l = []
with open(filename_reference, "r", encoding='utf-8') as f_ref:
for line in f_ref:
s.update({line.strip()})
with open(filename, "r", encoding='utf-8') as f_test:
for line in f_test:
line = line.strip()
l.append((line, line in s))
return(l)
3
def diff(extended, abbreviated):
# get ships
ships_ext = set([i[0] for i in extended])
ships_abb = set([i[0] for i in abbreviated])
ships_name = {i[0]: i[4] for i in extended}
# get sets
id_ext_abb = ships_ext - ships_abb
id_abb_ext = ships_abb - ships_ext
id_abb_and_ext = ships_ext & ships_abb
# get ships name
name_ext_abb = [ships_name[i] for i in list(id_ext_abb)]
name_abb_and_ext = [ships_name[i] for i in list(id_abb_and_ext)]
# return
return((set(name_ext_abb), set(name_abb_and_ext), set(id_abb_ext)))by default all is reference !
==
Test equality of value
is
Test equality of reference (use copy.deepcopy() to secure it b = a[:] can create mistake with level of mutable)
COPY / DEEP COPY
Mutable elements propagate changes to shared references
a = [1, 2]
b = a
a[0] = 'shared'
print(b)
Use shallow copy for one level
b = a[:]
b = copy.copy(a)
Use deep copy for all levels
import copy
b = copy.deepcopy(a)
VARIABLE IDENTIFIER
https://docs.python.org/3/reference/datamodel.html#objects-values-and-types
id(v)
Return the identifier of variable
a = 3
b = 3
print(id(a), id(b))
b is a
CIRCULAR REFERENCE
DELETE
https://docs.python.org/3/reference/simple_stmts.html#the-del-statement
del(v)
Delete variable
a = 10
del(a)
try:
print('a=', a)
except NameError as e:
print("a n'est pas définie")
delete a part
l = list(range(10))
del l[2:10:2]
l
delete few elements
d = dict(foo='bar', spam='eggs', a='b')
del(d['a'], d['spam'])
SHARED ASSIGNMENT
shared reference
b = a = []
cellule = [0]
liste = [cellule, cellule, cellule]
liste[0][0] = 1
print(liste, cellule)
shared assignment
liste = 3 * [[0]]
l[0][0] = 1
print(l)
copy assignment
liste = [[0], [0], [0]]
l[0][0] = 1
print(l)
assignment
+= *= ... # make default assignment by reference <=> make assignment by reference if variable is mutable
mutable
b = a = [1]
a += [1]
print(a); print(b); print(b is a); print(b == a)
not mutable
b = a = 1
a += 1
print(a); print(b); print(b is a); print(b == a)PATHLIB
https://docs.python.org/3/library/pathlib.html
exists()
test if file exists
from pathlib import Path
filename = '/tmp/test'
path = Path(filename)
path.exists()
with open(filename, 'w', encoding='utf-8') as f:
f.write('0123456789\n')
path.exists()
stat()
return statistiques about file
path.stat()
st_mode
st_ino
st_dev
st_nlink
st_uid
st_gid
st_size
st_atime
st_mtime
st_ctime
path.stat().st_size
from datetime import datetime
datetime.fromtimestamp(path.stat().st_mtime)
f"{mtime_datetime:%H:%M}"
unlink()
delete file
try:
path.unlink()
except FileNotFoundError:
print("no need to remove")
path = Path('/tmp')
for json in dirpath.glob("*.json"):
print(json)
CLASS
path = Path('/tmp')
type(path)
from pathlib import PosixPath
issubclass(PosixPath, Path)
isinstance(path, Path)
FILE FORMAT
https://docs.python.org/3/library/fileformats.html
json
https://docs.python.org/3/library/json.html
limitations
Tuple, qui se fait encoder comme une liste / complex, set et frozenset, que l'on ne peut pas encoder du tout (sans étendre la bibliothèque)
pickle
https://docs.python.org/3/library/pickle.html
csv
https://docs.python.org/3/library/csv.html
SYS
import sys
autre_stdout = open('ma_sortie.txt', 'w', encoding='utf-8')
tmp = sys.stdout
print('sur le terminal')
sys.stdout = autre_stdout
print('dans le fichier')
sys.stdout = tmp
autre_stdout.close()
print('de nouveau sur le terminal')
with open("ma_sortie.txt", encoding='utf-8') as check:
print(check.read())
OS
Old fashion
os.path.join()
ajoute '/' ou '' entre deux morceaux de chemin, selon l'OS
os.path.basename()
trouve le nom de fichier dans un chemin
os.path.dirname()
trouve le nom du directory dans un chemin
os.path.abspath()
calcule un chemin absolu, c'est-à-dire à partir de la racine du filesystem
os.path.exists()
pour savoir si un chemin existe ou pas (fichier ou répertoire)
os.path.isfile .isdir()
Pour savoir si un chemin est un fichier (et un répertoire)
os.path.getsize()
pour obtenir la taille du fichier
os.path.getatime()
et aussi getmtime et getctime pour obtenir les dates de création/modification d'un fichier
os.chdir()
change current directory
os.remove()
(ancien nom os.unlink), qui permet de supprimer un fichier
os.rmdir()
pour supprimer un répertoire (mais qui doit être vide)
os.removedirs()
pour supprimer tout un répertoire avec son contenu, récursivement si nécessaire
os.rename()
pour # renommer un fichier
glob.glob()
comme dans par exemple glob.glob("*.txt")
https://docs.python.org/3/library/functions.html#open
options
r # open for reading (default)
w # open for writing, truncating the file first
x # open for exclusive creation, failing if the file already exists
a # open for writing, appending to the end of the file if it exists
b # binary mode
t # text mode (default)
+ # open a disk file for updating (reading and writing)
U # universal newlines mode (deprecated)
f = open('file', 'options'[, encoding=])
f.close()
encoding
Necessary if you don't use option binary 'b'
f = open('/tmp/spam', 'w', encoding='utf8')
f.close()
f = open('/tmp/spam', 'bw')
f.close()
CONTEXT MANAGER
Close automaticaly file after treatment and exception
# writing
with open("foo.txt", "w", encoding='utf-8') as f:
for i in range(2):
f.write(f"{i}\n")
# reading
with open("foo.txt", "r", encoding='utf-8') as f:
for line in f:
print(line, end='')
iterator
with open("foo.txt", encoding='utf-8') as f:
print(f.__iter__() is f)
ADVANCED
repr()
View real content
with open("foo.txt", encoding='utf-8') as f:
for bloc in range(2):
print(f"Bloc {bloc} >>{repr(f.read(4))}<<")
read()
Read all content of file
with open("foo.txt", encoding='utf-8') as entree:
full_contents = entree.read()
print(f"Contenu complet\n{full_contents}", end="")
flush()
Force writing to disk
binary mode
with open('strbytes', 'w', encoding='utf-8') as output:
output.write("déjà l'été\n")
with open('strbytes', 'rb') as rawinput:
octets = rawinput.read()
print("on a lu un objet de type", type(octets))
for i, octet in enumerate(octets):
print(f"{i} → {repr(chr(octet))} [{hex(octet)}]")
Difference between characters & octets
with open('strbytes', encoding='utf-8') as textfile:
print(f"en mode texte, {len(textfile.read())} caractères")
with open('strbytes', 'rb') as binfile:
print(f"en mode binaire, {len(binfile.read())} octets")TRY
https://docs.python.org/3/tutorial/errors.html#handling-exceptions
SYNTAX
try:
....
except ...Error as e:
...
except ...Error2 as e:
...
else
...
finally
except:
Catch all errors
except Error_name:
Catch only Error_name
except (Error_name1,Error_name2):
Catch only Error_names
except Error_name, value:
Catch only Error_name with only value Value
else
Execute instruction if except don't catch error
finally
Execute always instruction at the end even after a return
def return_with_finally(number):
try:
return 1/number
except ZeroDivisionError as e:
print(f"OOPS, {type(e)}, {e}")
return("zero-divide")
finally:
print("on passe ici même si on a vu un return")
RAISE
http://www.python.50webs.com/CHAP_8/chap_8.html
raise Error_name
Launch an exception
raise Error_name, value
Launch an exception with specific value
Exceptions under Class & Class instance
raise can take 5 forms:
- raise
- raise String
- raise String, value
- raise Class, instance
for class or parent class
- raise instance.class, instance
- raise instance
L'utilité est que, lorsque l'on gère une grande quantité d'exceptions, il n'est pas nécessaire de mettre de nom après "except", car le nom de l'exception levée sera traité dans la classe. De plus il est possible de rajouter des sous-classes afin de compléter un domaine d'exception et ceci sans toucher au code existant dans la classe parente.
ASSERT
- Les assertions peuvent être enlevées du byte code si l'option -O est appelée lors de la compilation
- Les assertions sont principalement utilisées pendant le développement
- Il est impératif d'éviter les effets de bord dans les assertions car,
lors de leurs suppressions, l'effet est aussi enlevé
assert TEST
Assert launch always a AssertionError exception
assert TEST, VALUES
Equal to:
if __debug__ :
if not <test> :
raise AssertionError, <values>https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
- Dict allow to associate keys and values
- Keeps only uniq keys
- key of dict have to be globally immutable
IMMUTABLE
OK: tuple is immutable
d[(key, value)] = str
KO: list is mutable
d[(key, [key, value])] = str
INDEX
Use dict to index dict
# Example with list comprehension
personnes = [
{'nom': 'Pierre', 'age': 25, 'email': 'pierre@example.com'},
{'nom': 'Paul', 'age': 18, 'email': 'paul@example.com'},
{'nom': 'Jacques', 'age': 52, 'email': 'jacques@example.com'},
]
index_par_nom = {personne['nom']: personne for personne in personnes}
init
Syntax:
dic = {}
dic = dict()
dic = {key1: value1, key2: value2, ...}
dic= dict([(key1, value1), (key2, value2), ...])
dic= dict(key1=value1, key2=value2, ...])
assign
dic[key]
dic.get(key, index)
merge
x = {'a':1, 'b':2}
y = {'b':3, 'c':4}
z = {**x, **y}
del(k), del(d)
delete a key or an entire dictionnary
del(dic[key])
del(dic)
k in d
test the existence of key
k in dic
print()
print dictionnary
print(key in dic)
print(dic[key])
items()
iterate on items
for k, v in dic.items():
print(f"{k}, value {v}")
#return tuple
for item in dic.items():
print(f"{item} - type(item)")
keys()
iterate on keys
for k in dic.keys():
print(f"{k}, {age[k]}")
values()
iterate on values
for v in dic.values():
print(v)
len()
print length oif dictionnary
len(age)
update()
update (merge) dictionnary
dic.update({'key1':value1, 'key2':value2})
setdefault(key, value)
only append a tuple if not already exists
dic.setdefault(key, value)
COLLECTIONS CLASS
collections.OrderedDict
guarantee of keeping order in collection
from collections import OrderedDict
d = OrderedDict()
for i in [value1, value2, ...]:
d[i] = i
assign
d = OrderedDict({key1: value1, key2: value2, ...})
d = OrderedDict([(key1, value1), (key1, value1), ...])
collections.defaultdict
merge dict without test of existance
from collections import defaultdict
resultat = defaultdict(list)
for x, y in tuples:
resultat[x].append(y)
# or with int
from collections import defaultdict
compteurs = defaultdict(int)
phrase = "une phrase dans laquelle on veut compter les caractères"
for c in phrase:
compteurs[c] += 1
EXCERCISE
1
def graph_dict(filename):
summits = {}
with open(filename, "r", encoding='utf-8') as f_in:
for line in f_in:
(s1, lenght, s2) = line.split()
if s1 in summits:
summits[s1].append((s2, int(lenght)))
else:
summits[s1]=[(s2, int(lenght))]
return summits
2
def index(extended):
ships={}
for ship in extended:
# (id, latitude, longitude, date_heure, nom_bateau, code_pays) = ship
(id, *_) = ship
ships[id] = ship
return ships
3
def merge(extended, abbreviated):
ships={}
for ship in extended:
(id, latitude, longitude, date_heure, nom_bateau, code_pays, *_) = ship
if id in ships:
ships[id].append((latitude, longitude, date_heure))
else:
ships[id] = [nom_bateau, code_pays, (latitude, longitude, date_heure)]
for ship2 in abbreviated:
(id, *data) = ship2
ships[id].append(tuple(data))
return shipshttps://pypi.org/
https://pypi.org/project/autopep8/
INDENTATION
- prefere space than tabulation
- use 4 spaces by indentation
- use : after commands if else elif def
x = y + z
def foo(x, y):
def foo(
x,
y
):
foo(x, y, z)
foo(
x,
y
)
x=[
: 0,
: 1,
]
pass
Do nothing but in a accepted syntax, void foo
def foo():
pass
while condition:
pass
if condition:
pass
else:
foo()
COMMENTS
# single line
""" single line """
"""
multiple
lines
"""
VARIABLES
authorized characters for name
a-z A-Z 0-9 _
authorized characters for the beginning of name
a-z A-Z
And as assert break class continue def del elif else except false finally for from global if import in is lambda none nonlocal not or pass raise return true try while with yield
https://docs.python.org/3/library/stdtypes.html#string-methods
STRING
text.split(sep)
split string with a separator
'sep'.join(list)
join a list with a separator
text.replace(sch,str,count)
replace text by another with an optionnal counter replace
text.replace(sch,str).replace(sch2,str2)
text.strip()
strip all occurences of space,tab... in string
in text
return boolean, true if string are found in text
not in text
the opposite of in
text.find(sch)
return the first place of first occurence of a string in another (return -1 if not found)
text.rfind(sch)
return the first place of last occurence of a string in another (return -1 if not found)
index()
equal at find but launch an exception if not found
try:
"abcdefcdefghefghijk".index("zoo")
except Exception as e:
print("OOPS", type(e), e)
text.count(sch[, start[, end]])
count he number of ocuurences of text in string
text.startswith(sch)
return boolean, true if text are started with string
text.endswith(sch)
return boolean, true if text are ended with string
text.upper()
change all characters to uppercase
text.lower()
change all characters to lowercase
text.swapcase()
swat case for all characters
text.capitalize()
put first character in text in uppercase
text.title()
put first character of each 'words' in text in uppercase
https://docs.python.org/3/library/string.html#formatstrings
print()
print any types of elements
print(1, 'a', 12 + 4j, clas)
# replace the EOL by one space
print("une", "autre", end=' '); print('ligne')
F-PRINT
Evaluate {} and return text (don't print)
f"dans 10 ans {prenom} aura {age + 10} ans"
f"nous avons pour l'instant {len(notes)} notes"
f"pi avec seulement 2 chiffres apres la virgule {pi:.2f}"
f"{prenom:<10} -- {nom:^12} -- {solde:>8} €"
Left center right
< ^ >
FORMAT
Evaluate {} & print
"{} {} a {} ans".format(prenom, nom, age)
"{le_prenom} {le_nom} a {l_age} ans".format(le_nom=nom, le_prenom=prenom, l_age=age)
"pi avec seulement 2 chiffres apres la virgule {flottant:.2f}".format(flottant=pi)
Les données à afficher
comptes = [
('Apollin', 'Dupont', 127),
('Myrtille', 'Lamartine', 25432),
('Prune', 'Soc', 827465),
]
for prenom, nom, solde in comptes:
print(f"{prenom:<10} -- {nom:^12} -- {solde:>8} €")
%
"%s %s a %s ans" % (prenom, nom, age)
variables = {'le_nom': nom, 'le_prenom': prenom, 'l_age': age}
"%(le_nom)s, %(le_prenom)s, %(l_age)s ans" % variables
INPUT
Get answer always in a string !!
nom_ville = input("Entrez le nom de la ville : ")
print(f"nom_ville={nom_ville}")
int(input("Nombre de lignes ? ")) + 3STRING
s[start:end:step]
manipulate string by indexes, first included, second excluded (even with negative step)
s[start:] # from index to end
s[:end] # fro mstart to index
s[:] # duplicates element
s[start:-end] # from start to (end from last)
s[-start:-end] # from (start from last) to (end from last)
s[-start:end] # from (start from last) to end -> empty
s[-start:end:-step] # from (start from last) to (end from start) by rollback
s[::-1] # reverse
s[start;start] = [n] # insert element n in s at position start
s[start:end] = [] # unset elements between start and end (start included & end excluded)
LIST
Manipulate list with slice
l = [0, 2, 4, 8, 16, 32, 64, 128]
l
l[-1:1:-2]
l[2:4] = [100, 200, 300, 400, 500]
l
NUMPY
import numpy as np
un_cinq = np.array([1, 2, 3, 4, 5])
un_cinq
array = 10 * un_cinq[:, np.newaxis] + un_cinq
array
centre = array[1:4, 1:4]
centre
coins = array[::4, ::4]
coins
tete_en_bas = array[::-1,:]
tete_en_basA simulator: https://pythex.org
REGEXP - MATCH
import re
import re.MatchObject class
raw-string
raw-string: don't interprete '\' in regexp
re.match(regexp,text)
return the beginning matching of text
regexp = "(.*)-(.*)\.txt"
text = "abc-def.txt"
match = re.match(regexp, text)
print(match[1], match[2])
re.search(regexp,text)
return the matching of text
re.findall(regexp,text)
return all matching sequences
sentences = ['Lacus a donec, vitae gravida proin sociis.', 'Neque ipsum! rhoncus cras quam.']
for sentence in sentences:
print(f"---- dans >{sentence}<")
print(re.findall(r"\w*[am]\W", sentence))
re.split(regexp,text)
split string with a regexp
for sentence in sentences:
print(f"---- dans >{sentence}<")
print(re.split(r"\W+", sentence))
print()
re.sub(regexp,replace,text)
replace matching parts
for sentence in sentences:
print(f"---- dans >{sentence}<")
print(re.sub(r"(\w+)", r"X\1Y", sentence))
print()
re.compile(regexp).match(sample)
compile before matching
RESULT
search()
example: (?P<name>) affect name 'name' to matched text
# get
sample = " Isaac Newton, physicist"
match = re.search(r"(\w+) (?P<name>\w+)", sample)
# group return a list indexed (start at 1) by number & by name with (?P<name>)
# group() or group(0) return complete string
match.group()
match.groups() # list of groups
match.groupdict() # dict of all named groups
match.re()
The regular expression object whose match() or search() method produced this match instance
match.string()
The string passed to match() or search()
expand()
expand format in the string results of match
match.expand(r"last_name \g<name> first_name \1")
span()
span return index of matched text at the index of original text
begin, end = match.span('name')
sample[begin:end]
FLAG
IGNORECASE # ignore case
UNICODE # (alias U), use utf8 properties for \w sequence
LOCALE # (alias L), use current LOCAL for \w sequence
MULTILINE # (alias M), multiline
DOTALL # (alias S), catch all characters with . included EOL \n
regexp = "a*b+"
re_obj = re.compile(regexp, flags=re.IGNORECASE | re.DEBUG)
print(regexp, "->", nice(re_obj.match("AabB")))
SEQUENCE
[number]
Matches the contents of the group of the same number
alphanumeric
\w # Matches Unicode word characters
\W # Matches any character which is not a word character
\b # Matches the empty string, but only at the beginning or end of a word
\B # Matches the empty string, but only when it is not at the beginning or end of a word
\~ # Alphanumeric
\s # Matches whitespace characters including [ \t\n\r\f\v], and also many other characters
\S # Matches any character which is not a whitespace character
number
\d # Matches any decimal digit
\D # Matches any character which is not a decimal digit
others
\A # similar to ^, begining of text else in MULTILINE mode
\Z # similar to $, ending of text
regexp - greedy
by default * + ? match a longest chain found, ? allow to inverse the method to match the shortest string
*?
+?
??
GROUP
(...) # anonymous group
(?P<name>...) # named group
(?:...) # without group, optimize the render by not including content in entries table
(?P=name) # match text using predecessor matched text indexed with 'name'
(?=...)
(?!...)
(?<=...)
example: test the last named group id is equal at the first
regexp3 = "(?P<id>[0-9]+)[A-Za-z]+(?P<needle>[0-9]+)[A-Za-z]+(?P=id)"
examples
regexp_phone = r"(\+33|0)(?P<number>[0-9-]{9})\Z"
regexp_phone = r"(?i)\A(?P<proto>http|https|ftp|ssh)://((?P<user>[a-z]+)(:(?P<password>.+))?@)?(?P<hostname>[\w\._]+)(?P<port>\:\d+)?/(?P<path>[\w/]+)?\Z"https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
INIT
l = [] # empty list
l= [e1, e2, e3, ..., en]
vec = [e] * n # n values
matrix = [[0]*n for i in range(n)] # n dimensions at n values
l = list(tuple) # cast
METHODS
l.append(element) # append only one elment at the end
l.extend([element1,element2]) # append elments of list at the end
l.insert(index,element) <=> l[index:index]=[element] # insert one element at index
l.remove(element) # remove the first occurence of the element
l.element=pop(index) # remove element at index & return element
l.reverse() # reverse elements
l.sort() # sort elements
l.sort(reverse=True) # sort items by reversing order
ls=sorted(l) # return a new sorted list of list passed in argument
[[l1.element1, l2.element1, ...], [l1.element2, l2.element2, ...] ] # associate lists
zip(l1, l2, ...) # return an iterator that aggregates elements from each of the iterables
COMPREHENSION
list2 = [treatment for i in list if cond]
receive string with numbers and other characters in multiple lines
have to be return a list of square separate by ':'
def carre(ligne):
import re
l = re.findall('(\d+)',ligne)
l = [int(i)**2 for i in l]
l = [str(i) for i in l]
return(':'.join(l))
received a list of numbers
return result of polynomial function
def P(x):
return(2*x**2 -3*x -2)
def liste_P(liste_x):
return([P(x) for x in liste_x])
graph
import numpy as np
import matplotlib.pyplot as plt
# un échantillon des X entre -10 et 10
X = np.linspace(-10, 10)
# et les Y correspondants
Y = liste_P(X)
# on n'a plus qu'à dessiner
plt.plot(X, Y)
plt.show()SHEBANG
#!/usr/bin/env python3
IDLE
install
sudo apt install idle-python3.6 && idle-python3.6
alt+p
for previous line in history
alt+n
for next line in history
IPYTHON
install
sudo apt install ipython3 && ipython3
configuration
ipython3 profile create
file=~/.ipython/profile_default/ipython_config.py
[ -f "$file.keep" ] && cp -a "$file" "$file.keep$(date +%s)"
sch="c.InteractiveShell.color_info"; sed -i "/^#\?${sch}/ a ${sch} = True" "$file"
sch="c.InteractiveShell.colors"; sed -i "/^#\?${sch}/ a ${sch} = 'Linux'" "$file"
sch="c.TerminalInteractiveShell.highlighting_style"; sed -i "/^#\?${sch}/ a ${sch} = 'monokai'" "$file"
sch="c.TerminalInteractiveShell.highlight_matching_brackets"; sed -i "/^#\?${sch}/ a ${sch} = True" "$file"
!tail $file # access to bash commands with
COMMENTS
# line
"""
multiple
lines
"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
print(var)
print("a=",a," b=",b)
print(f"a={a}, b={b}")
DIR
dir(object)
return the list properties & methods of object
TYPE
isinstance(var,'type')
return instance type
ID
id(x)
return identifier of variable ('is' operator return True if id() is equal
NUMERIC
0b # prefix binary
0o # prefix octal
int # no size limit
float # 4.3, 15number 53b
complex # (float)+(float)j
bool # True 1 / False 0
cast
int()
float()
complex()
bool()
bin()
operators
=
+=
-=
/=
*=
**=
%=
<<=
>>=
+
-
*
**
/
//
%
comparators
==
<
>
<=
>=
CLASS
fraction
from fractions import Fraction
Fraction(3,10) - Fraction(2,10) == Fraction(1,10)
decimal
from decimal import Decimal
Decimal('0.3') - Decimal('0.2') == Decimal('0.1')
BITWISE
operator
~
&
|
^
<<
>>
MUTABLE / IMMUTABLE
immutable
int
float
complex
bool
str
tuple
frozenset
bytes
mutable
list
bytearray
set
dict
class
...
PRINT SOURCE CODE
import inspect
lines = inspect.getsource(function)
print(lines)<html lang="fr">
<head>
<meta charset="utf-8">
<title>menu nextcloud</title>
<link rel="stylesheet">
<style type="text/css">
a {
border: 0;
margin: 0;
padding: 0;
border: 0;
outline: 0;
text-decoration: none;
cursor: pointer;
}
#appmenu_perso {
width: 50px;
margin-left: 300px;
background-color: #1e84d0;
direction: rtl;
}
#appmenu_perso:hover > #appmenu_perso1 { display: flex }
#appmenu_perso_menu {
width: 50px;
height: 50px;
opacity: 0.6;
}
#appmenu_perso_menu:hover {
opacity: 1;
}
#appmenu_perso_menu svg {
margin: 15px;
}
#appmenu_perso1 {
display: none;
flex-flow: column wrap;
width: 250px;
background-color: #fff;
border: 5px solid #1e84d0;
direction: ltr;
}
#appmenu_perso1 > * {
display: flex;
flex-flow: row;
}
#appmenu_perso1 a {
/*position: relative;*/
margin: 0;
height: 50px;
width: 50px;
align-items: center;
justify-content: center;
opacity: 0.6;
}
#appmenu_perso1 a:hover {
opacity: 1;
}
</style>
</head>
<body>
<div id="appmenu_perso">
<div id="appmenu_perso_menu" aria-label="More">
<a href="#">
<svg viewBox="0 0 20 20" alt="" height="20">
<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/check-plus.svg"></image>
</svg>
</a>
</div>
<div id="appmenu_perso1">
<!-- CONTROL
-->
<div>
<a href="http://ambau.ovh:1777/haproxy-stats?" title="HAproxy ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/haproxy.svg"></image>
</svg>
</a>
<a href="https://ambau.ovh/server-status" title="Apache status ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/apache-status.svg"></image>
</svg>
</a>
<a href="https://ambau.ovh/server-info" title="Apache info ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/apache-info.svg"></image>
</svg>
</a>
<a href="http://ambau.ovh/status-www?html&full" title="PHP status ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="15" width="40" height="22" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/php.svg"></image>
</svg>
</a>
<a href="http://ambau.ovh:1778/" title="RspamD ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/rspamd.svg"></image>
</svg>
</a>
</div>
<!-- TOOLS
-->
<div>
<a href="https://code.ambau.ovh/" title="Shaarli code ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/shaarli-code.svg"></image>
</svg>
</a>
<a href="https://info.ambau.ovh/" title="Shaarli info ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/shaarli-info.svg"></image>
</svg>
</a>
<a href="https://links.ambau.ovh/" title="Shaarli links ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/shaarli-links.svg"></image>
</svg>
</a>
</div>
<!-- OVH
-->
<div>
<a href="https://www.ovh.com//manager/web/login.html" title="ovh" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/ovh.svg"></image>
</svg>
</a>
<a href="https://www.kimsufi.com/fr/manager/#/login" title="kimsufi" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/kimsufi.svg"></image>
</svg>
</a>
</div>
<!-- GESTON
-->
<div>
<a href="https://matomo.ambau.ovh/" title="Matomo ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/matomo.svg"></image>
</svg>
</a>
<a href="https://pma.ambau.ovh/" title="phpMyAdmin ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/pma.svg"></image>
</svg>
</a>
<a href="https://pfa.ambau.ovh/" title="PostFixAdmin ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/pfa.svg"></image>
</svg>
</a>
<a href="https://roundcube.ambau.ovh/" title="RopundCube ambau" target="_blank">
<svg viewBox="0 0 50 50" alt="" height="50">
<image x="5" y="5" width="40" height="40" preserveAspectRatio="xMinYMin meet" xlink:href="../Pictures/logos/roundcube.svg"></image>
</svg>
</a>
</div>
</div>
</div>
</body>
</html>Suite de Fibonacci
result = []
num = 2
while (len(result) < 100):
i = 2
while (num % i) != 0 and i <= num: i += 1
if (i == num): result.append(num)
num += 1
print(result, len(result))PROCESS
!Important you have to launch command with & in start to allow run/stop processes
ps # Get a listing of processes running on the system
jobs # Display a list of current children jobs running in the background
fg ID # Move a background children process into the foreground
bg ID # Move a process into background & start it if a process are already in background
ctrl+z # Pause the current foreground process & move it into the background
kill %ID # End the background running process by his id
nohup $CMD & # Launch in detached process command
wait # Suspend script execution until all children processes running in background have terminated
wait $PID # Suspend script execution until the process with PID id have terminated
cat >pipe # read from stdin
ctrl+d # send EOF to pipe
JOBS
# Display status of jobs
jobs
-l # lists all informations about all processes
-n # lists only processes that have changed status since the last notification
-p # lists PIDs
-r # restrict output to running jobs
-s # restrict output to stopped jobs
job identifier
%N # Job number [N]
%S # Invocation (command-line) of job begins with string S
%?S # Invocation (command-line) of job contains within it string S
%% # "current" job (last job stopped in foreground or started in background)
%+ # "current" job (last job stopped in foreground or started in background)
%- # Last job
$! # Last background process
DISOWN
# unbind jobs from current shell & jobs control; kepp ONLY running jobs
disown
-a # remove all jobs
-h # remobe BUT hold it in jobs control
-r # remove only running jobs
KILL
Note that if the process you are trying to stop by PID is in your shell's job table, it may remain visible there, but terminated, until the process is fg'd again.
kill -TSTP $PID # SIGTSTP, 'polite' stop
kill -STOP $PID # SIGSTOP, 'hard' stop
kill signal -CONT $PID # SIGCONT, resume execution of the process
pkill -f PATTERN # send kill
SID
# Run a program in a new session
setsid $cmd
-w $cmd # Run a program in a new session & wait process finished
PROCESS LIST
pgrep
# return pids list of process matched command name
pgrep $PATTERN
example
pgrep -lf $PATTERN # return full informations process list with matched command name
/proc/PID
cat /proc/PID/status|awk '{print $5}' # return PGRP, ps is VERY LONG *10 / use instead cat /proc...|awk, see man proc
ps/pidof
ps -l $PID # long format
ps -f --pid $PID # full format
ps --ppid $PID # return children processes of parent process $PID
ps auT # return infos on processes associated with this terminal
ps -C $CMD # return process started by command $CMD
ps -g 15603 -o uid,pid,ppid,pgid,egid,rgid,pgrp,tty,time,cmd # return PID process of selected PGRP= PGID=
ps -o pid --no-headers --ppid PID # return chilren PIDS of parent PID
pidof $CMD # return list of pid started with command
EXAMPLES
jobs playing
timeout 20s sleep 200 &
jobs -l
disown -h %1
exit
lock process
FILEPID=/var/run/${0##*/}.pid
FILELOCK=/var/lock/${0##*/}.lock
PID=$$
(
trap "rm -f $FILEPID; exit" INT TERM EXIT
flock -xw 5 9 && echo "IN $PID" || (echo "///// ERROR \\\\\\" && exit 1)
echo $PID >$FILEPID
sleep 3
echo OUT $PID
) 9>$FILELOCK
listen stdin pipe
tail -f $fifo| while read line; do $cmd; done
tail -f /tmp/pipe | while read line; do ssh root@10.0.0.201 "echo $line >> /tmp/toto"; done
read test < <(echo hello world)
# from pipe
read a <$fifo
while read line; do $cmd; done < <(pipe)
while read line; do $cmd; done < <(tail -f pipe)
nc server
nc -l 12345 | nc www.google.com 80
Port 12345 represents the request This starts a nc server on port 12345 and all the connections get redirected to google.com:80. If a web browser makes a request to nc, the request will be sent to google but the response will not be sent to the web browser. That is because pipes are unidirectional. This can be worked around with a named pipe to redirect the input and output.
mkfifo $fifo
nc -l 12345 0<$fifo | nc www.google.com 80 1>$fifoPRIORITY
0 emerg Emergency: system is unusable # A "panic" condition - notify all tech staff on call? (Earthquake? Tornado?) - affects multiple apps/servers/sites.
1 alert Alert: action must be taken immediately # Should be corrected immediately - notify staff who can fix the problem - example is loss of backup ISP connection.
2 crit Critical: critical conditions # Should be corrected immediately, but indicates failure in a primary system - fix CRITICAL problems before ALERT - example is loss of primary ISP connection.
3 err Error: error conditions # Non-urgent failures - these should be relayed to developers or admins; each item must be resolved within a given time.
4 warning Warning: warning conditions # Warning messages - not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.
5 notice Notice: normal but significant condition # Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
6 info Informational: informational messages # Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
7 debug Debug: debug-level messages # Info useful to developers for debugging the app, not useful during operations.
FACILITY
0 kern kernel messages
1 user user-level messages
2 mail mail system
3 daemon system daemons
4 auth security/authorization messages
5 syslog messages generated internally by syslogd
6 lpr line printer subsystem
7 news network news subsystem
8 uucp UUCP subsystem
9 cron clock daemon
10 authpriv security/authorization messages
11 FTP daemon
12 NTP subsystem
13 log audit
14 log alert
15 clock daemon
16 local0 local use 0
17 local1 local use 1
18 local2 local use 2
19 local3 local use 3
20 local4 local use 4
21 local5 local use 5
22 local6 local use 6
23 local7 local use 7
BALANCER
# balancer
#$template balancer,"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag% %msg%\n"
#$template balancer,"%$DAY%-%$MONTH%-%$YEAR% %HOSTNAME% %syslogtag% %msg%\n"
#$template BALANCER,"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag% %msg%\n"
#$template _balancer,"%timegenerated% %HOSTNAME% %syslogtag% %msg%\n"
$template _balancer,"%timegenerated:::date-mysql% %timereported:::date-subseconds% %HOSTNAME% %syslogtag% %msg%\n"
# local7._balancer /var/log/balancer/_balancerd.log;_balancer
#local7._worker /var/log/balancer/_worker.log;_balancer
#if $msg startswith 'Mar' and $syslogpriority-text == 'err' then /var/log/_balancer/_balancerd.error;_balancer
if $msg contains '_balancerd' and $syslogpriority-text == 'err' then /var/log/_balancer/_balancerd.error
#:msg, regex, "_balancerd" /var/log/_balancer/_balancerd.error
#:rawmsg, regex, "bal" /var/log/_balancer/_balancerd.error
#:rawmsg, regex, "^Mar" /var/log/_balancer/_balancerd.error
#:msg, contains, "_balancerd" /var/log/_balancer/_balancerd.error
#:syslogpriority, isequal, "err" \
#/var/log/_balancer/_balancerd.error;_balancer
BALANCER
#local7.debug /var/log/_balancer.debug;balancer
$template localhost,"%timegenerated% %HOSTNAME% %syslogtag% %programname%%msg%\n" # default
$template balancer,"%timegenerated:::date-mysql% %timereported:::date-subseconds% %msg%\n"
template(name="TEST" type="string" string="%timegenerated% -HOSTNAME=%HOSTNAME% -syslogtag=%syslogtag% -programname=%programname% -syslogfacility=%syslogfacility% -syslogfacility-text=%syslogfacility-text% -syslogseverity=%syslogseverity% -syslogseverity-text=%syslogseverity-text% -syslogpriority=%syslogpriority% -syslogpriority-text=%syslogpriority-text% -inputname=%inputname% -app-name=%app-name% -procid=%procid% -msgid=%msgid% %msg%")
BIND
#:msg, regex, "balancerd" /var/log/balancer/balancerd.err
#& stop
#:rawmsg, regex, "bal" /var/log/_balancer/_balancerd.err; template & stop
#:msg, contains, "_balancerd" /var/log/_balancer/_balancerd.err
#:syslogpriority, isequal, "err" \
#/var/log/_balancer/_balancerd.err;_balancer
############################## TEMPLATE
#
# local7.debug /var/log/_balancer.debug;balancer
# $template balancer,"%timegenerated:::date-mysql% %timereported:::date-subseconds% %HOSTNAME% %syslogtag% %programname% %msg%\n"
################ MESSAGE
#
# datetime
# template(name="TIME" type="string" string="%timegenerated:::date-mysql%.%timereported:::date-subseconds% %programname%%msg%\n")
#
# default
# template(name="DEFAULT" type="string" string="%timegenerated% %HOSTNAME% %syslogtag% %programname%%msg%\n")
#
# all properties
# template(name="ALL" type="string" string="%timegenerated% -HOSTNAME=%HOSTNAME% -syslogtag=%syslogtag% -programname=%programname% -syslogfacility=%syslogfacility% -syslogfacility-text=%syslogfacility-text% -syslogseverity=%syslogseverity% -syslogseverity-text=%syslogseverity-text% -syslogpriority=%syslogpriority% -syslogpriority-text=%syslogpriority-text% -inputname=%inputname% -app-name=%app-name% -procid=%procid% -msgid=%msgid% -fromhost=%fromhost% -fromhost-ip=%fromhost-ip% %msg%\n")
$template APACHE,"%msg%\n"
############### FILE
#
# file template to agregate virtualhost logs with unique & global containers view
# $template DYNFILE,"/var/lib/vz/log/apache2/%programname%.%syslogseverity-text%"
# file template to separate virtualhost logs by containers Ip provenance
# $template DYNFILE,"/var/lib/vz/log/%fromhost-ip%/apache2/%programname%.%syslogseverity-text%"
# WARNNING: if you change the path, you must have to adjust parameters in fail2ban & logrotate config file
$template DYNFILE,"S_HOSTING_PATH_LOG/apache2/%programname%.%syslogseverity-text%"
############################## BIND
#
# examples:
# :msg, contains, "localhost" /var/log/apache2/localhost.log; localhost & stop
# :msg, regex, "balancerd" /var/log/balancer/balancerd.err
# :rawmsg, regex, "bal" /var/log/_balancer/_balancerd.err
# :msg, contains, "_balancerd" /var/log/_balancer/_balancerd.err
# :syslogpriority, isequal, "err" \
# & stop
# if $msg == '' and $syslogpriority-text == 'info' then /var/log/apache2/localhost.log; localhost
# if $programname == 'apache2' and $syslogpriority-text == 'info' then /var/log/apache2/localhost.log; balancerd
:syslogtag, contains, "apache" -?DYNFILE; APACHE & stop
# WARNNING: if you change the path, you must have to adjust parameters in fail2ban & logrotate config file
:syslogtag, contains, "apache" -S_HOSTING_PATH_LOG/apache2/others.log; APACHE & stoplets you install, configure, refresh and remove snaps. Snaps are packages that work across many different Linux distributions, enabling secure delivery and operation of the latest apps and utilities
list
list installed package with last revision
snap list
-all # list installed package with all resions
info
shows detailed information about snaps
snap info <snap>
--color=[auto|never|always] # Use a little bit of color to highlight some things. (default: auto)
--unicode=[auto|never|always] # Use a little bit of Unicode to improve legibility. (default: auto)
--abs-time # Display absolute times (in RFC 3339 format). Otherwise, display relative times up to 60 days, then YYYY-MM-DD
--verbose # Include more details on the snap (expanded notes, base, etc.)
find
find package with his name
snap find <snap>
remove
remove package with all revisions
sudo snap remove <snap>
--revision $REV # remove package with for only a revision
purge disabled
snap list --all | grep disabled$ | awk '{ print $1" "$3 }' | xargs -l bash -c 'sudo snap remove $0 --revision $1'CLIENT
endline options
\g # formated list, is default option ;
\G # inline list
command options
# the MariaDB command-line tool
mysql [options] db_name
# output
-B, --batch # Print results using tab as the column separator, with each row on a new line
-E, --vertical # Print query output rows vertically (one line per column value)
-H, --html # Produce HTML output
-L, --skip-line-numbers # Do not write line numbers for errors
-N, --skip-column-names # Do not write column names in results
-r, --raw # For tabular output, the “boxing” around columns enables one column value to be distinguished from another
-s, --silent # Silent mode. Produce less output
-t, --table # Display output in table format
-v, --verbose # Verbose mode
-X, --xml # Produce XML output
--show-warnings # Cause warnings to be shown after each statement if there are any
--line-numbers # Write line numbers for errors
-# ., --debug[=debug_options] # Write a debugging log. A typical debug_options string is 'd:t:o,file_name'. The default is 'd:t:o,/tmp/mysql.trace'
--binary-mode # By default, ASCII '\0' is disallowed and '\r\n' is translated to '\n'
# connection
-D ., --database=db_name # The database to use
-h ., --host=host_name # Connect to the MariaDB server on the given host
-P ., --port=port_num # The TCP/IP port number to use for the connection or 0 for default to
-u ., --user=user_name # The MariaDB user name to use when connecting to the server
# used
-c, --comments # Whether to preserve comments in statements sent to the server
-C, --compress # Compress all information sent between the client and the server if both support compression
-e ., --execute=statement # execute statement
-f, --force # Continue even if an SQL error occurs
-n, --unbuffered # Flush the buffer after each query
-w, --wait # If the connection cannot be established, wait and retry instead of aborting
-V, --version # Display version information and exit
--delimiter=str # Set the statement delimiter. The default is the semicolon character (“;”)
--tee=file_name # Append a copy of output to the given file
--max-allowed-packet=num # Set the maximum packet length to send to or receive from the server. (Default value is 16MB, largest 1GB.)
# others
--abort-source-on-error # Abort 'source filename' operations in case of errors
--auto-rehash # Enable automatic rehashing
--auto-vertical-output # Automatically switch to vertical output mode if the result is wider than the terminal width
--character-sets-dir=path # The directory where character sets are installed
--column-names # Write column names in results
--column-type-info, -m # Display result set metadata
--connect-timeout=seconds # Set the number of seconds before connection timeout
--debug-check # Print some debugging information when the program exits
--debug-info, -T # Prints debugging information and memory and CPU usage statistics when the program exits
--default-auth=name # Default authentication client-side plugin to use
--default-character-set=charset_name # Use charset_name as the default character set for the client and connection
--defaults-extra-file=filename # Set filename as the file to read default options from after the global defaults files has been read
--defaults-file=filename # Set filename as the file to read default options from, override global defaults files
--defaults-group-suffix=suffix # In addition to the groups named on the command line, read groups that have the given suffix
--disable-named-commands # Disable named commands
-i, --ignore-spaces # Ignore spaces after function names
--init-command=str # SQL Command to execute when connecting to the MariaDB server
--local-infile[={0|1}] # Enable or disable LOCAL capability for LOAD DATA INFILE
--max-join-size=num # Set the automatic limit for rows in a join when using --safe-updates. (Default value is 1,000,000.)
-G, --named-commands # Enable named mysql commands. Long-format commands are allowed, not just short-format commands
--net-buffer-length=size # Set the buffer size for TCP/IP and socket communication. (Default value is 16KB.)
-A, --no-auto-rehash # This has the same effect as --skip-auto-rehash
-b, --no-beep # Do not beep when errors occur
--no-defaults # Do not read default options from any option file
-o, --one-database # Ignore statements except those those that occur while the default database is the one named on the command line
--pager[=command] # Use the given command for paging query output
--password[=password], -p[password] # The password to use when connecting to the server
-W, --pipe # On Windows, connect to the server via a named pipe
--plugin-dir=dir_name # Directory for client-side plugins #
--print-defaults # Print the program argument list and exit
--progress-reports Get progress reports for long running commands (such as ALTER TABLE)
--prompt=format_str # Set the prompt to the specified format
--protocol={TCP|SOCKET|PIPE|MEMORY} # The connection protocol to use for connecting to the server
--quick, -q # Do not cache each query result, print each row as it is received
--reconnect # If the connection to the server is lost, automatically try to reconnect
-U, --safe-updates, --i-am-a-dummy # Allow only those UPDATE and DELETE statements that specify which rows to modify by using key values
--secure-auth # Do not send passwords to the server in old (pre-4.1.1) format
--select-limit=limit # Set automatic limit for SELECT when using --safe-updates. (Default value is 1,000.)
--server-arg=name # Send name as a parameter to the embedded server
--sigint-ignore # Ignore SIGINT signals
--skip-auto-rehash # Disable automatic rehashing
--socket=path, -S path # For connections to localhost, the Unix socket file to use
# ssl connection
--ssl # Enable SSL for connection (automatically enabled with other flags)
--ssl-ca=name # CA file in PEM format
--ssl-capath=name # CA directory
--ssl-cert=name # X509 cert in PEM format
--ssl-cipher=name # SSL cipher to use
--ssl-key=name # X509 key in PEM format
--ssl-crl=name # Certificate revocation list
--ssl-crlpath=name # Certificate revocation list path
--ssl-verify-server-cert # Verify server's "Common Name" in its cert against hostname used when connecting
MySQL Commands
mysql sends each SQL statement that you issue to the server to be executed. There is also a set of commands that mysql itself interprets. For a list of these commands, type help or \h at the mysql> prompt:
List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
? (\?) Synonym for `help'
clear (\c) Clear command
connect (\r) Reconnect to the server. Optional arguments are db and host
delimiter (\d) Set statement delimiter
edit (\e) Edit command with $EDITOR
ego (\G) Send command to mysql server, display result vertically
exit (\q) Exit mysql. Same as quit
go (\g) Send command to mysql server
help (\h) Display this help
nopager (\n) Disable pager, print to stdout
notee (\t) Don't write into outfile
pager (\P) Set PAGER [to_pager]. Print the query results via PAGER
print (\p) Print current command
prompt (\R) Change your mysql prompt
quit (\q) Quit mysql
rehash (\#) Rebuild completion hash
source (\.) Execute an SQL script file. Takes a file name as an argument
status (\s) Get status information from the server
system (\!) Execute a system shell command
tee (\T) Set outfile [to_outfile]. Append everything into given outfile
use (\u) Use another database. Takes database name as argument
charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets
warnings (\W) Show warnings after every statement
nowarning (\w) Don't show warnings after every statement
For server side help, type 'help contents'
option examples
# remove title and format
mysql -uroot -p$pwd -sBe "$cmd"
# upgrade databases
mysql_upgrade -uroot -p$pwd
SQL
create database
CREATE DATABASE $db_name CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci';
# show tables by engine
SELECT ENGINE, COUNT(*) AS count FROM INFORMATION_SCHEMA.TABLES GROUP BY ENGINE;
# show log variables
SHOW VARIABLES LIKE '%log%';
collation
https://mariadb.com/kb/en/supported-character-sets-and-collations/
https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
Change collation for database $db to 'utf8mb4_general_ci', utf8-unicode-ci is more exact but longer
ALTER DATABASE $db COLLATE = 'utf8mb4_general_ci';
privileges
SELECT user,host,password FROM mysql.user WHERE Host <> 'localhost'; # show users
SHOW GRANTS; # show grants
SHOW PRIVILEGES\G; # show privileges
GRANT ALL PRIVILEGES ON *.* TO $user@'$host' IDENTIFIED BY '$pwd' WITH GRANT OPTION; # gives all privileges with grant option to user
GRANT USAGE ON *.* TO `$user`@`%` IDENTIFIED BY '$pwd';
GRANT SELECT, INSERT, UPDATE, DELETE ON `db_name`.* TO `$user`@`%`;
GRANT PROXY ON ''@'%' TO 'root'@'$host' with GRANT OPTION; # gives proxy privileges with grant option to user
REVOKE ALL PRIVILEGES, GRANT OPTION FROM $user; # revoke all privileges for user
DROP USER IF EXISTS $user1, $user2; # drop users
DUMP
dump all databases in separates files
[ -z "${pwd}" ] && echo -n 'pwd: ' && read pwd
path="/var/share/mariadb/default/dump-$(grep $HOSTNAME /etc/hosts|cut -d' ' -f1)-$(date +%s)"
! [ -d "${path}" ] && mkdir -p "${path}"
for db in $(mysql -u$db_user -p$db_pwd -Bse "SHOW SCHEMAS"); do
[[ $db =~ _schema$ ]] && opt='--skip-lock-tables' || opt=
echo "$db"; mysqldump -uroot -p$pwd $db --no-data $opt > "${path}/${db}.sql"
mysqldump -uroot -p${pwd} ${db} --no-create-info ${opt} | gzip -c > "${path}/${db}-data.sql.gz"
done
echo -e "\e[0;33m$path\e[0;0m"
ls -al "${path}"
data & structure
mysqldump -uroot -p$pwd $db_name --no-data > ${file}.sql # dump only structure
mysqldump -uroot -p$pwd $db_name --no-create-info --ignore-table='$tables' > ${file}-data.sql # dump only data
mysqldump -u$user -p$pwd $db_name --dump-slave --no-data > "${path2}/${file}-struct.sql" # dump only structure for slave in replication
mysqldump -u$user -p$pwd $db_name --dump-slave --no-create-info | gzip -c > "${path2}/${file}.sql.gz" # dump only data for slave replication
SSL
https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/
IPTABLES
iptables -nvL --line-number # show rules with line number
iptables -nvL -t nat --line-number # show rules with line number for NAT table
iptables -nvL -t mangle --line-number # show rules with line number for MANGLE table
iptables -S # show source command of rules
chain
iptables -L $CHAIN -v -n --line-numbers # list rules for chain $CHAIN
iptables -D $CHAIN $LINE_NUMBER # delete rule $LINE_NUMBER for chain $CHAIN
iptables -t $TABLE -D $CHAIN $LINE_NUMBER # delete rule $LINE_NUMBER for chain $CHAIN and specific table
FAIL2BAN
fail2ban client
fail2ban-client status # get global status
fail2ban-client status $jail # get ssh status
fail2ban-client get loglevel # get log level
fail2ban-client get setlogvel $level # set level for log
fail2ban-client get $jail ignoreip # get ignore ip for $jail
fail2ban-client set $jail addignoreip IP # add ignore ip IP for $jail